GeometryService - Factor issue while plotting a circle on map with a distance

1147
7
01-30-2012 11:47 AM
PraveenTipirneni
New Contributor
I am trying to plot a map in Esri Maps using the ArcGIS JavaScript API. I am using Geometry Service to plot a circle on the map. For example if I plot a circle with a radius of 1 mile. When I measure a 1 mile distance in  Google maps I am just short with the radius by a factor of 1.3. Did anyone observe this pattern or am I doing any mistake? Please refer to the code I used from the sample

http://help.arcgis.com/en/webapi/javascript/arcgis/demos/util/util_buffer.html

Here is the code

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
   <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
  <title>Buffer</title>
 
  <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/claro/claro.css">
  <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6" type="text/javascript"></script>

  <script type="text/javascript">
    dojo.require("esri.map");
    dojo.require("esri.tasks.geometry");

    var map = null;
    var gsvc = null;

    function initialize() {
      map = new esri.Map("map");
      var layer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
      map.addLayer(layer);
      map.setExtent(esri.geometry.geographicToWebMercator(new esri.geometry.Extent(-77.550, 38.600, -77.020, 39.070, new esri.SpatialReference({wkid: 4326}))));

      gsvc = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
      dojo.connect(map, "onClick", doBuffer);
    }

    function doBuffer(evt) {
      map.graphics.clear();
      var params = new esri.tasks.BufferParameters();
      params.geometries = [ evt.mapPoint ];

      //buffer in linear units such as meters, km, miles etc.
  params.distances = [ 1 ];
      params.unit = esri.tasks.GeometryService.UNIT_STATUTE_MILE;
      params.outSpatialReference = map.spatialReference;

      gsvc.buffer(params, showBuffer);
    }

    function showBuffer(geometries) {

      var symbol = new esri.symbol.SimpleFillSymbol(
        esri.symbol.SimpleFillSymbol.STYLE_SOLID,
        new esri.symbol.SimpleLineSymbol(
          esri.symbol.SimpleLineSymbol.STYLE_SOLID,
          new dojo.Color([0,0,255,0.65]), 2
        ),
        new dojo.Color([0,0,255,0.15])
      );

      dojo.forEach(geometries, function(geometry) {
        var graphic = new esri.Graphic(geometry,symbol);
        map.graphics.add(graphic);
      });
    }

    dojo.addOnLoad(initialize);
  </script>

</head>

<body class="claro">
  <b>Click a location on the map to buffer. Click again on another location to buffer again.</b>
  <div id="map" style="width:800px; height:600px; border:1px solid #000;"></div>
</body>

</html> 

0 Kudos
7 Replies
DavidErickson
New Contributor
I am experiencing the same problem.  Using the BufferParameters with the public geometry service in both spatial reference 4326 and 102100 the radius of the circle appears to be too small.

Using venkatap's example code below, when I place a circle with radius of 1 mile on the intersection of Chainbridge Rd and Old Courthosue Rd in Tysons Corner, VA the circle edge runs directly through the intersection of International Drive and Westpark Drive. 
[ATTACH=CONFIG]11559[/ATTACH]

However, when I measure the distance between these two intersections in Google Earth, I get 0.78 miles.  What am I not understanding?
[ATTACH=CONFIG]11560[/ATTACH]

Many thanks in advance,
Dave
0 Kudos
JohnGrayson
Esri Regular Contributor
Try setting the 'esri.tasks.BufferParameters.bufferSpatialReference' to a Spatial Reference with an equal area projection that is appropriate to your location.
0 Kudos
DavidErickson
New Contributor
Thank you for the suggestion. I'm afraid the behavior is the same. In my code:

map = new esri.Map("map");
var layer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");  
map.addLayer(layer);
var initialExtent = new esri.geometry.Extent({
  "xmin":-8673921.42,
  "ymin":4654250.49,
  "xmax":-8536334.77,
  "ymax":4745974.92,
  "spatialReference":{"wkid":102100}});
map.setExtent(initialExtent);

...

var params = new esri.tasks.BufferParameters();
params.geometries = [ evt.mapPoint ];

params.distances = [ 1 ];
params.unit = esri.tasks.GeometryService.UNIT_STATUTE_MILE;
params.outSpatialReference = new esri.SpatialReference({wkid : 102100});
params.bufferSpatialReference = new esri.SpatialReference({wkid : 102100});


0 Kudos
JohnGrayson
Esri Regular Contributor
I believe 102100 is based on Mercator which is a conformal projection so it does not maintain areas or distances.  Try using a Spatial Reference which uses an equal area projection which is appropriate to the location.
0 Kudos
JeffPace
MVP Alum
I ran into this same problem.  You can replicate in ArcMAP with the measure tool by switching between planar and geodesic measurement

The fastest (read, not easiest) way I found to handle this was converting all my locations to State Plane (my reference coord system) prior to doing calculations.

So for our home built "make a circle" method it would be

1. Get centroid in webmerc
2. Convert centroid back to state plane
3. Create circle in state plane with given (accurate) diameter
4. project circle back to webmerc
5. draw circle.

Otherwise you have to do the math to compensate for the geodesic measurements, which is very ugly calculus.
0 Kudos
JianHuang
Occasional Contributor III
From ArcGIS Server 10.1, buffer operation will support geodesic(true/false) parameter. bufferSR input parameter will be ignored when geodesic is set to true, which means you don't have to worry about the spatial reference any more.
JavaScript API 2.7 will support this along with server 10.1 beta2 or pre-release.
Here is a sample service running on beta2.
http://servicesbeta4.esri.com/arcgis/rest/services/Geometry/GeometryServer/buffer

Hope this helps.
0 Kudos
PraveenTipirneni
New Contributor
Thank you all for the replies.
0 Kudos