Select to view content in your preferred language

Geometry Service Bug, Area does not work?

2266
3
10-21-2010 01:26 PM
karldailey
Deactivated User
If you use the sample: http://help.arcgis.com/en/webapi/flex/samples/index.html?sample=MeasureArea

The Area of the drawn polygons is WAY off.  nearly 100% off.  If you draw a box around Colorado, you get an area of 436k Sq Kms, but the actual area of the state is 269k Sq Kms.  This seems like a bug to me, anyone else have the same issue?  a fix?
Tags (2)
0 Kudos
3 Replies
EokNgo
by
Deactivated User
Strange... The sample code is indeed returning the wrong results.

However, I'm using most of that same code in my application, yet the my results seems correct.
Note sure what is going on, but I don't think it's a bug.
0 Kudos
Drew
by
Frequent Contributor
Using the same map service consumed in ArcMap i get the 436k result.
I don't know what the right answer is, but i just wanted to say that ArcMap returns the same as the Geometry Service.

Drew
0 Kudos
DasaPaddock
Esri Regular Contributor
The Geometry Service's "Areas and Lengths" operation measures the area in the spatial reference of the input geometry, which in this case is web mercator. The web mercator projection stretches areas the further you go from the equator.

I've updated the sample below to first project the polygon to 54034 (World_Cylindrical_Equal_Area). This will give more accurate results, but it's best to use an appropriate projection for the area you're measuring. For even better results, you can use the Geometry Service to densify the polygon before projecting it.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:esri="http://www.esri.com/2008/ags"
               pageTitle="Measure Areas">
    <!--
         This sample shows how to use the DrawTool and GeometryService to:
         - simplify ("clean") the drawn polygon
         - measure the area of the polygon
         - create a properly placed label for the polygon

         Workflow for this sample:
         1. Click on map to draw an area
         2. Double-click to end the drawing
         -> Calls onDrawEnd (as set up in DrawTool):
         Sends polygon to geometry service for clean-up/simplication (in case lines cross etc)
         -> When simplify has completed, simplifyCompleteHandler(event) is called (as setup in GeometryService task):
         Adds cleaned up graphic to the graphics layer.
         Sends cleaned up graphic to geometry service to be "measured".
         -> When areasAndLengths has completed successfully, areasAndLengths_resultHandler is called.
         Get the area.
         Sends request for best placement of the label
         -> When labelPoints has completed successfully, labelPoints_resultHandler will:
         Display a label with the area.
    -->

    <s:layout>
        <s:VerticalLayout horizontalAlign="center" paddingTop="5"/>
    </s:layout>

    <fx:Script>
        <![CDATA[
            import com.esri.ags.Graphic;
            import com.esri.ags.SpatialReference;
            import com.esri.ags.events.DrawEvent;
            import com.esri.ags.events.GeometryServiceEvent;
            import com.esri.ags.geometry.Extent;
            import com.esri.ags.geometry.Geometry;
            import com.esri.ags.symbols.TextSymbol;
            import com.esri.ags.tasks.supportClasses.AreasAndLengthsParameters;
            import com.esri.ags.tasks.supportClasses.AreasAndLengthsResult;

            import mx.controls.Alert;
            import mx.rpc.AsyncResponder;
            import mx.rpc.Fault;

            private function activateTool():void
            {
                drawTool.activate(DrawTool.POLYGON);
                act.enabled = false;
                deact.enabled = true;
            }

            private function deactivateTool():void
            {
                drawTool.deactivate();
                deact.enabled = false;
                act.enabled = true;
            }

            private function onDrawEnd(event:DrawEvent):void
            {
                // simplify the drawn polygon
                // Note: As of version 2.0, GeometryService input is geometries (instead of graphics).
                geometryService.simplify([ event.graphic.geometry ]);
            }

            private function simplifyCompleteHandler(event:GeometryServiceEvent):void
            {
                // Note: GeometryService returns geometries instead of graphics as of Flex API 2.0
                if (event.result)
                {
                    var polygon:Geometry = (event.result as Array)[0]; // we only draw one area at a time

                    var newGraphic:Graphic = new Graphic(polygon);
                    newGraphic.autoMoveToTop = false;
                    myGraphicsLayer.add(newGraphic);

                    // project to 54034 (World_Cylindrical_Equal_Area)
                    geometryService.project([ polygon ], new SpatialReference(54034), 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_SQUARE_KILOMETERS;
                    areasAndLengthsParameters.polygons = [ polygon ];

                    geometryService.areasAndLengths(areasAndLengthsParameters, new AsyncResponder(areasAndLengths_resultHandler, areasAndLengths_faultHandler, token));
                }
            }

            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 + " km2."));
            }

            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, 0x00FF00);
                    g.symbol = new TextSymbol(String(token), null, 0xFFFFFF, true, 0xFFFFFF, true,
                                              0xFF0000, "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);
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <esri:DrawTool id="drawTool"
                       drawEnd="onDrawEnd(event)"
                       fillSymbol="{mySFS}"
                       map="{myMap}"/>

        <esri:GeometryService id="geometryService"
                              showBusyCursor="true"
                              simplifyComplete="simplifyCompleteHandler(event)"
                              url="http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"/>

        <esri:SimpleFillSymbol id="mySFS" color="0xAA0000">
            <esri:SimpleLineSymbol width="2" color="0xAA0000"/>
        </esri:SimpleFillSymbol>

        <mx:NumberFormatter id="myNumberFormatter"
                            precision="2"
                            useThousandsSeparator="true"/>
    </fx:Declarations>

    <s:Label color="0xAA0000"
             fontSize="14"
             text="Draw an area with at least three nodes."/>

    <s:HGroup>
        <s:Button id="deact"
                  click="deactivateTool()"
                  label="Stop measuring"/>
        <s:Button id="act"
                  click="activateTool()"
                  enabled="false"
                  label="Start measuring"/>
    </s:HGroup>
    <esri:Map id="myMap"
              extent="{new Extent(-13658000, 5703000, -13655000, 5705000, new SpatialReference(102100))}"
              load="drawTool.activate(DrawTool.POLYGON)">
        <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/>
        <esri:GraphicsLayer id="myGraphicsLayer" symbol="{mySFS}"/>
    </esri:Map>
</s:Application>
0 Kudos