protected function drawTool_drawEndHandler(event:DrawEvent):void { // reset after finished drawing a feature myDrawTool.deactivate(); drawbutton.selected= false; var polygon:Polygon = event.graphic.geometry as Polygon; if (GeometryUtil.polygonSelfIntersecting(polygon)) { // simplify the drawn polygon // Note: As of version 2.0, GeometryService input is geometries (instead of graphics). geometryService.simplify([ polygon ]); } else { //addPolygonToMap(polygon); projectPolygon(polygon); myDrawTool.deactivate(); } } private function geometryService_simplifyCompleteHandler(event:GeometryServiceEvent):void { // Note: GeometryService returns geometries instead of graphics as of Flex API 2.0 if (event.result) { var polygon:Polygon = (event.result as Array)[0]; // we only draw one area at a time projectPolygon(polygon); } } private function projectPolygon(polygon:Polygon):void { // project to 54034 (World_Cylindrical_Equal_Area) const projectParameters:ProjectParameters = new ProjectParameters; projectParameters.geometries = [ polygon ]; projectParameters.outSpatialReference = new SpatialReference(54034); geometryService.project(projectParameters, new AsyncResponder(project_resultHandler, project_faultHandler, polygon)); } private function project_resultHandler(result:Object, token:Object = null):void { if (result) { var polygon:Geometry = (result as Array)[0]; var areasAndLengthsParameters:AreasAndLengthsParameters = new AreasAndLengthsParameters(); areasAndLengthsParameters.areaUnit = GeometryService.UNIT_ACRES; areasAndLengthsParameters.polygons = [ polygon ]; geometryService.areasAndLengths(areasAndLengthsParameters, new AsyncResponder(areasAndLengths_resultHandler, areasAndLengths_faultHandler, token)); // project to 54034 (World_Cylindrical_Equal_Area) } } private function project_faultHandler(fault:Fault, token:Object = null):void { Alert.show(fault.faultString + "\n\n" + fault.faultDetail, "project Fault " + fault.faultCode); } private function areasAndLengths_resultHandler(result:AreasAndLengthsResult, token:Object = null):void { const area:String = myNumberFormatter.format(result.areas[0]); geometryService.labelPoints([ token ], new AsyncResponder(labelPoints_resultHandler, labelPoints_faultHandler, area + " acres")); } private function areasAndLengths_faultHandler(fault:Fault, token:Object = null):void { Alert.show(fault.faultString + "\n\n" + fault.faultDetail, "areasAndLengths Fault " + fault.faultCode); } private function labelPoints_resultHandler(result:Object, token:Object = null):void { for each (var geom:Geometry in result) { var g:Graphic = new Graphic(); g.geometry = geom; var tf:TextFormat = new TextFormat(null, 16, 0x41423A); g.symbol = new TextSymbol(String(token), null, 0xFFFFFF, 1, true, 0x41423A, true, 0xD8DACC, "middle", 0, 0, 0, tf); myGraphicsLayer.add(g); } } private function labelPoints_faultHandler(fault:Fault, token:Object = null):void { Alert.show(fault.faultString + "\n\n" + fault.faultDetail, "labelPoints Fault " + fault.faultCode); }
private function myMap_mapMouseDownHandler(event:MapMouseEvent):void { event.currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, map_mouseMoveHandler); event.currentTarget.addEventListener(MouseEvent.MOUSE_UP, map_mouseUpHandler); } private function map_mouseMoveHandler(event:MouseEvent):void { event.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, map_mouseMoveHandler); event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, map_mouseUpHandler); } private var graphic:Graphic; private var lastEditGraphic:Graphic; private var lastActiveEditTypes:String; private function map_mouseUpHandler(event:MouseEvent):void { event.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, map_mouseMoveHandler); event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, map_mouseUpHandler); if (event.target is Graphic) { graphic = Graphic(event.target); if (lastEditGraphic !== graphic) { lastEditGraphic = graphic; lastActiveEditTypes = "moveRotateScale"; // make sure move and edit vertices is the 1st mode } if (graphic.geometry is Polyline || graphic.geometry is Polygon) { if (lastActiveEditTypes == "moveEditVertices") { lastActiveEditTypes = "moveRotateScale"; myEditTool.activate(EditTool.MOVE | EditTool.SCALE | EditTool.ROTATE, [ graphic ]); } else { lastActiveEditTypes = "moveEditVertices"; myEditTool.activate(EditTool.MOVE | EditTool.EDIT_VERTICES, [ graphic ]); } } else if (graphic.geometry is Extent) { myEditTool.activate(EditTool.MOVE | EditTool.SCALE, [ graphic ]); } else if (graphic.graphicsLayer == myGraphicsLayer) { myEditTool.activate(EditTool.MOVE | EditTool.EDIT_VERTICES, [ graphic ]); } } else { myEditTool.deactivate(); lastActiveEditTypes = "moveRotateScale"; // make sure move and edit vertices is the 1st mode } }
Solved! Go to Solution.
/** * Adds event listeners to the current edit tool */ private function addEditToolEventListeners():void { editTool.addEventListener(EditEvent.GHOST_VERTEX_MOUSE_DOWN, handleHideMeasureLabel); editTool.addEventListener(EditEvent.CONTEXT_MENU_SELECT, handleHideMeasureLabel); editTool.addEventListener(EditEvent.VERTEX_MOVE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.GRAPHICS_MOVE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.GRAPHIC_ROTATE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.GRAPHIC_SCALE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.VERTEX_ADD, editTool_vertexAddDeleteHandler); editTool.addEventListener(EditEvent.VERTEX_DELETE, editTool_vertexAddDeleteHandler); editTool.addEventListener(EditEvent.VERTEX_MOVE_STOP, editTool_vertexMoveStopHandler); editTool.addEventListener(EditEvent.GRAPHICS_MOVE_STOP, editTool_graphicsMoveStopHandler); editTool.addEventListener(EditEvent.GRAPHIC_ROTATE_STOP, editTool_graphicRotateStopHandler); editTool.addEventListener(EditEvent.GRAPHIC_SCALE_STOP, editTool_graphicScaleStopHandler); }
/** * Handle graphic move complete */ private function editTool_graphicsMoveStopHandler(event:EditEvent):void { handleEditEvent(event); }
/** * Handle graphic editing */ private function handleEditEvent(event:EditEvent):void { var graphic:Graphic = event.graphic; if (!graphic && event.graphics) { graphic = event.graphics[0]; } if (map.wrapAround180) { normalizeGraphicGeometry(graphic); } else if (measurementLabelExists) { recalculate(graphic); } }
/** * Adds event listeners to the current edit tool */ private function addEditToolEventListeners():void { editTool.addEventListener(EditEvent.GHOST_VERTEX_MOUSE_DOWN, handleHideMeasureLabel); editTool.addEventListener(EditEvent.CONTEXT_MENU_SELECT, handleHideMeasureLabel); editTool.addEventListener(EditEvent.VERTEX_MOVE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.GRAPHICS_MOVE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.GRAPHIC_ROTATE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.GRAPHIC_SCALE_START, handleHideMeasureLabel); editTool.addEventListener(EditEvent.VERTEX_ADD, editTool_vertexAddDeleteHandler); editTool.addEventListener(EditEvent.VERTEX_DELETE, editTool_vertexAddDeleteHandler); editTool.addEventListener(EditEvent.VERTEX_MOVE_STOP, editTool_vertexMoveStopHandler); editTool.addEventListener(EditEvent.GRAPHICS_MOVE_STOP, editTool_graphicsMoveStopHandler); editTool.addEventListener(EditEvent.GRAPHIC_ROTATE_STOP, editTool_graphicRotateStopHandler); editTool.addEventListener(EditEvent.GRAPHIC_SCALE_STOP, editTool_graphicScaleStopHandler); }
/** * Handle graphic move complete */ private function editTool_graphicsMoveStopHandler(event:EditEvent):void { handleEditEvent(event); }
/** * Handle graphic editing */ private function handleEditEvent(event:EditEvent):void { var graphic:Graphic = event.graphic; if (!graphic && event.graphics) { graphic = event.graphics[0]; } if (map.wrapAround180) { normalizeGraphicGeometry(graphic); } else if (measurementLabelExists) { recalculate(graphic); } }
/** * Update the graphic's measurement label and positioning */ private function recalculate(graphic:Graphic):void { var geom:Geometry = graphic.geometry; measureGeometry(geom, graphic); } /** * Depending on the geometry's spatial reference, calculate measurement or * create a new geometry service project call */ private function measureGeometry(geom:Geometry, graphic:Graphic):void { var wkid:Number = geom.spatialReference.wkid; if ((wkid == EPSG_GEOGRAPHIC) || (isWebMercator(wkid))) { calculateMeasurements(geom, graphic); } else { var geographicSpatialReference:SpatialReference = new SpatialReference(EPSG_GEOGRAPHIC); const projectParameters:ProjectParameters = new ProjectParameters; projectParameters.geometries = [ geom ]; projectParameters.outSpatialReference = geographicSpatialReference; geometryService.project(projectParameters, new AsyncResponder(project_resultHandler, project_faultHandler, geom)); } } /** * Determine if specified spatial reference is web mercator */ private function isWebMercator(wkid:Number):Boolean { return wkid == 102100 || wkid == 3857 || wkid == 102113; } /** * Calculate geometry measurements depending on geometry type */ private function calculateMeasurements(geom:Geometry, graphic:Graphic):void { (graphic.attributes as GraphicPropertiesVO).measurementGeometry = geom; switch (geom.type) { case Geometry.POLYLINE: { var polyline:Polyline = Polyline(geom); calculatePolylineLengths(polyline, graphic); break; } case Geometry.POLYGON: { var polygon:Polygon = Polygon(geom); calculatePolygonAreasAndLengths(polygon, graphic); break; } case Geometry.EXTENT: { var extent:Extent = Extent(geom); calculatePolygonAreasAndLengths(extent.toPolygon(), graphic); //convert it to polygon for measurement break; } case Geometry.MAPPOINT: { var mapPoint:MapPoint = MapPoint(geom); calculateMapPointCoordinates(mapPoint, graphic); } } } /** * Calculate polyline lengths */ private function calculatePolylineLengths(polyline:Polyline, graphic:Graphic):void { var polylineToMeasure:Polyline var wkid:Number = polyline.spatialReference.wkid; if (wkid == EPSG_GEOGRAPHIC) { polylineToMeasure = polyline; } else if (isWebMercator(wkid)) { polylineToMeasure = WebMercatorUtil.webMercatorToGeographic(polyline) as Polyline; } var lengths:Array = GeometryUtil.geodesicLengths([ polylineToMeasure ], Units.METERS); var length:Number = lengths[0] * distanceConversion; var label:String = createLengthsLabel(length, distanceAbbr); addDrawLabel(label, graphic); } /** * Create lengths label */ private function createLengthsLabel(length:Number, lengthAbbrev:String):String { return lengthLabel + " " + numFormatter.format(length) + " " + lengthAbbrev; } /** * Calculate map point coordinates */ private function calculateMapPointCoordinates(point:MapPoint, graphic:Graphic):void { var label:String = createPointMeasurementLabel(point); addDrawLabel(label, graphic); } /** * Formats the length measurement into a string to displayed on the map. * <p> * <b>Parameters</b><br/> * <ul> * <li><i>point [MapPoint]: </i>The map point that represents the location whose coordinates should be labelled.</li> * </ul> * </p> */ private function createPointMeasurementLabel(point:MapPoint):String { var wkid:Number = point.spatialReference.wkid; if (wkid == EPSG_GEOGRAPHIC) { numFormatter.precision = 6; return "Latitude: " + numFormatter.format(point.y) + "\n" + "Longitude: " + numFormatter.format(point.x); } else { numFormatter.precision = 0; return "X: " + numFormatter.format(point.x) + "\n" + "Y: " + numFormatter.format(point.y); } } /** * Calculate Polygon areas and lengths */ private function calculatePolygonAreasAndLengths(polygon:Polygon, graphic:Graphic):void { var polygonToMeasure:Polygon; var wkid:Number = polygon.spatialReference.wkid; if (wkid == EPSG_GEOGRAPHIC) { polygonToMeasure = polygon; } else if (isWebMercator(wkid)) { polygonToMeasure = WebMercatorUtil.webMercatorToGeographic(polygon) as Polygon; } var lengths:Array = GeometryUtil.geodesicLengths([ new Polyline(polygonToMeasure.rings)], Units.METERS); var areas:Array = GeometryUtil.geodesicAreas([ polygonToMeasure ], Units.SQUARE_METERS); var area:Number = areas[0] * areaConversion; var length:Number = lengths[0] * distanceConversion; var label:String = createAreasAndLengthsLabel(area, areaAbbr, length, distanceAbbr); addDrawLabel(label, graphic); } /** * Create area and lengths label */ private function createAreasAndLengthsLabel(area:Number, areaAbbrev:String, length:Number, lengthAbbrev:String):String { return areaLabel + " " + numFormatter.format(area) + " " + areaAbbrev + "\n" + perimeterLabel + " " + numFormatter.format(length) + " " + lengthAbbrev; } /** * Determine the ideal positioning of the measurement label */ private function getMeasureLabelPosition(geom:Geometry):MapPoint { var measurePt:MapPoint = null; switch (geom.type) { case Geometry.POLYLINE: { var polyline:Polyline = geom as Polyline; var polylineExtent:Extent; if (polyline.paths.length == 1) { polylineExtent = polyline.extent; } else { // Multiple paths, hence show the measurement label at the center of first path var tempPolyline:Polyline = new Polyline; tempPolyline.paths = [ polyline.paths[0]]; polylineExtent = tempPolyline.extent; } measurePt = polylineExtent.center; break; } case Geometry.POLYGON: { var polygon:Polygon = geom as Polygon; var polygonExtent:Extent; if (polygon.rings.length == 1) { polygonExtent = polygon.extent; } else { // Multiple rings, hence show the measurement label at the center of first ring var tempPolygon:Polygon = new Polygon; tempPolygon.rings = [ polygon.rings[0]]; polygonExtent = tempPolygon.extent; } measurePt = polygonExtent.center; break; } case Geometry.EXTENT: { measurePt = geom.extent.center; break; } case Geometry.MAPPOINT: { var screenPoint:Point = map.toScreen(geom as MapPoint); screenPoint.x = screenPoint.x + 10; screenPoint.y = screenPoint.y - 20; measurePt = map.toMap(screenPoint); } } return measurePt; } /** * Create and place the measurement label */ private function addDrawLabel(label:String, graphic:Graphic):void { // create a text symbol var txtSym:TextSymbol = new TextSymbol(label); txtSym.yoffset = 8; var txtFormat:TextFormat = new TextFormat("Arial", 12, 0x000000, true); // black label txtSym.textFormat = txtFormat; // remove the current graphic's measurement label labelsLayer.remove(getMeasurementGraphic(graphic)); // create the new measurement graphic label var gra:Graphic = new Graphic(); gra.name = graphic.id; gra.geometry = getMeasureLabelPosition(graphic.geometry); gra.symbol = txtSym; gra.mouseEnabled = false; gra.mouseChildren = false; gra.filters = [ measurementBorderFilter ]; labelsLayer.add(gra); // associate the measurement label text to the editing or previous graphic's attributes (graphic.attributes as GraphicPropertiesVO).measurementLabel = label; // update the graphic context menu with the ability to hide or show the measurement label graphic_updateContextMenu(graphic); }