Select to view content in your preferred language

Geometry Service Buffer only works in WebMercator

3209
6
09-27-2010 09:36 AM
BryanLin
Emerging Contributor
So an interesting thing that I've found about the Geometry Service is that it seems to only work for geometries in WebMercator. I have a map in WGS 1984 where I tried to buffer a feature. The problem occurred when after buffering the feature, the results returned were way out of bounds of the current coordinate system. I basically dug through all the API reference with no luck until I came up with a hack:

I would use the WebMercatorUtil class and project the feature on WGS 1984 map to WebMercator, then buffer the feature in webmercator, then on the buffer complete, I would project it back to geographic with WebMercatorUtil.webMercatorToGeographic.  This seems like a bug in the ESRI Flex API and I was wondering if there will be a fix for this because anyone should be able to buffer any feature and get the result back in its original coordinate system without manually typing in code to do it.

Any thoughts?
Tags (2)
0 Kudos
6 Replies
DasaPaddock
Esri Regular Contributor
Have you tried setting the bufferSpatialReference on your BufferParameters?
http://help.arcgis.com/en/webapi/flex/apiref/com/esri/ags/tasks/supportClasses/BufferParameters.html...
0 Kudos
BryanLin
Emerging Contributor
Have you tried setting the bufferSpatialReference on your BufferParameters?
http://help.arcgis.com/en/webapi/flex/apiref/com/esri/ags/tasks/supportClasses/BufferParameters.html...



I did set the bufferSpatialReference to map.spatialReference  (which is in WGS 1984 or WKID 4326), but that didn't work. The only way was to convert the feature to web mercator, call the geometry service, then after it buffered, reproject back to geographic coordinates.

I would say this is an ESRI bug.
0 Kudos
DasaPaddock
Esri Regular Contributor
Try setting bufferSpatialReference to 102100 if you want to use Web Mercator and the outSpatialReference to 4326.

Note from: http://sampleserver3.arcgisonline.com/ArcGIS/SDK/REST/buffer.html
Note that when the bufferSR is GCS:

Points and Multipoints: if unit is linear such as feet or meters, geodesic buffering is performed.
Polylines and Polygons: unit must be angular such as decimal degrees for buffering to be performed.
0 Kudos
BryanLin
Emerging Contributor
Try setting bufferSpatialReference to 102100 if you want to use Web Mercator and the outSpatialReference to 4326.

Note from: http://sampleserver3.arcgisonline.com/ArcGIS/SDK/REST/buffer.html


I agree that would work, but the underlying issue is that the GEOMETRY SERVICE should not always take in features of mercator. Shouldn't it take in of any spatial reference?
0 Kudos
DasaPaddock
Esri Regular Contributor
Yes, that's defined by the inSR REST parameter. The Flex API's BufferParameters doesn't have a property for this since the GeometryService gets it automatically from the first geometry in the geometries Array. Can you use a tool like HttpFox to verify if the inSR is being sent correctly in the REST request?
0 Kudos
DasaPaddock
Esri Regular Contributor
Here's a modification of the BufferSample at:
http://help.arcgis.com/en/webapi/flex/samples/index.html?sample=BufferSample

I've fixed the myGeometryService url and changed the base layer to a 4326 service.

An example of the requests it sends is:
http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer/buffer?unionResul...

<?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="Buffer using the Geometry Service">
    <!--
         This sample creates buffers around the center of the map. This example just draws the buffers,
         but the buffers could also be used to perform a task such as returning a list of addresses of
         people who live within the buffered area.
    -->

    <s:controlBarLayout>
        <s:HorizontalLayout horizontalAlign="center"
                            paddingBottom="7"
                            paddingTop="7"/>
    </s:controlBarLayout>
    <s:controlBarContent>
        <s:Button click="bufferCenterOfMap()" label="Buffer Center Of Map"/>
    </s:controlBarContent>

    <fx:Declarations>
        <esri:SimpleFillSymbol id="sfs" color="0xFF0000">
            <esri:SimpleLineSymbol color="0x000000"/>
        </esri:SimpleFillSymbol>
        <esri:GeometryService id="myGeometryService" url="http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"/>
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import com.esri.ags.Graphic;
            import com.esri.ags.SpatialReference;
            import com.esri.ags.events.GeometryServiceEvent;
            import com.esri.ags.geometry.MapPoint;
            import com.esri.ags.geometry.Polygon;
            import com.esri.ags.tasks.supportClasses.BufferParameters;

            private function bufferCenterOfMap():void
            {
                var myMapCenterPoint:MapPoint = MapPoint(myMap.extent.center);

                var bufferParameters:BufferParameters = new BufferParameters();
                // Note: As of version 2.0, the GeometryService input is geometries (instead of graphics).
                bufferParameters.geometries = [ myMapCenterPoint ];
                bufferParameters.distances = [ 50, 100 ];
                // Note: As of version 2.0, the buffer constants have been moved to GeometryService.
                bufferParameters.unit = GeometryService.UNIT_KILOMETER;
                bufferParameters.bufferSpatialReference = new SpatialReference(102100);

                myGeometryService.addEventListener(GeometryServiceEvent.BUFFER_COMPLETE, bufferCompleteHandler);
                myGeometryService.buffer(bufferParameters);

                function bufferCompleteHandler(event:GeometryServiceEvent):void
                {
                    myGeometryService.removeEventListener(GeometryServiceEvent.BUFFER_COMPLETE, bufferCompleteHandler);
                    // Note: As of version 2.0, GeometryService returns geometries (instead of graphics)
                    for each (var geometry:Polygon in event.result)
                    {
                        var graphic:Graphic = new Graphic();
                        graphic.geometry = geometry;
                        graphic.symbol = sfs;
                        graphicsLayer.add(graphic);
                    }
                }
            }
        ]]>
    </fx:Script>

    <esri:Map id="myMap"
              crosshairVisible="true"
              level="2">
        <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
        <esri:GraphicsLayer id="graphicsLayer"/>
    </esri:Map>

</s:Application>
0 Kudos