Incorrect buffers

4897
7
03-27-2012 02:30 PM
DarrenJohnston
New Contributor
Hello all,

I'm trying to write an application to create buffers, but I'm finding the results are not as desired. In particular, there attempts to be no compensation for the projection at northern latitudes (and possibly southern, I haven't tested them). I am using Google Maps as my base map. Essentially, if I draw a line between 2 location fairly far north, say Moosonee, Ontario to London, Ontario (a relatively N-S line), the buffered polygon appears, visually, to be the same width all the way along. Of course, this isn't correct as northern latitudes are much further apart, so the shape should be wider at the top. For example, I set a 150 nautical mile circle around both Moosonee and London using Google maps circle overlays. Ground-truthing these with the underlying geography, they appear to be 150 nautical miles. When I then buffer a line between them at 150NM using arcGIS services, the portion around Moosonee is closer to 95NM while the portion around London is closer to 110NM.

I assume this is an error with my buffering spatial reference, but I can't seem to find a solution. If I use 4326, a 150NM buffer covers the entire planet. If I use 102100, I get the problem above. Does anyone know how I can fix this issue?

At the moment I don't have a public-facing application, but I could probably fiddle one up if someone wanted to see the entire thing. The parameters I am using are as follows:

var params = {
  geometries: [geometry],
  bufferSpatialReference: 102100,
  distances: [150],
  unit: 9030,
  unionResults: false
};

Where geometry is simply a Google maps polyline between 51.287732,-80.625488 and 42.980791, -81.246983.
0 Kudos
7 Replies
DarrenJohnston
New Contributor
I created a basic demonstration of the problem. As you can see in the attached image, the buffer is a constant visual width. But this should not be the case as the mercator projection squishes horizontal distances at the equator and stretches them at the poles. The line should be much, much wider at the poles. I have ground truthed this line and found that it is the correct width at the equator, and much too narrow closer to the poles. Just for reference: at about 40N the error is about 36% (this buffer should be 277,800m on either side of the line, but it is closer to 203,000m, by 50N this error is almost 60% (176,000m) and by 80N, the error appears to be well over 100%. For geodetic purposes, this is wholly unacceptable. Any feedback on what I'm doing wrong would be appreciated.

NB: The markers on the map were part of my initial tests...they do not represent any specific distance and can be ignored.

EDIT: It just occured to me that perhaps this should be under the ArcGIS Server section of the forums...should I repost or can a moderator move it?

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps JavaScript API Example</title>
    <script src="http://maps.google.com/maps?file=api&amp;v=2&sensor=false"
            type="text/javascript"></script>
    <script src="http://serverapi.arcgisonline.com/jsapi/gmaps/?v=1.6" 
            type="text/javascript" ></script>
    <script type="text/javascript">

    function initialize() {
      var mapext = null;
      var gsvc;
      var buffParams;
      var myMap = new GMap2(document.getElementById("map_canvas"));
      myMap.setCenter(new GLatLng(48,-82), 2);
      
      var polyOptions = {geodesic:true};
      
      polyline = new GPolyline([
        new GLatLng(80,-80),
        new GLatLng(60,-80),
        new GLatLng(30,-80),
        new GLatLng(0,-80)
        ], "#ff0000", 3, 1, polyOptions);
      myMap.addOverlay(polyline);
    
      mapext = new esri.arcgis.gmaps.MapExtension(myMap);
      
      gsvc = new esri.arcgis.gmaps.Geometry("http://sampleserver1.arcgisonline.com/arcgis/rest/services/Geometry/GeometryServer/");
      buffParams = new esri.arcgis.gmaps.BufferParameters();
      buffParams.unit = esri.arcgis.gmaps.SRUnitType.METER;
      buffParams.unionResults = true;
      buffParams.distances = [277800];
      buffParams.geometries = [polyline];
      gsvc.buffer(buffParams,function(results) {
        mapext.addToMap(results);
      });
    }

    </script>
  </head>
  <body onload="initialize()" onunload="GUnload()">
    <div id="map_canvas" style="width: 100%; height: 100%"></div>
  </body>
</html>


[ATTACH=CONFIG]13126[/ATTACH]
0 Kudos
AnnetteLocke
Esri Contributor
I believe what you want is geodesic buffering which is available in ArcGIS 10.1.

In ArcGIS 10, you can emulate geodesic buffering by setting the buffer spatial reference to an equal distance or equal area projection.

For example, if you set your buffer spatial reference to World_Azimuthal_Equidistant (wkid = 54032), you will see a buffer similar to that in the attached screenshot AzimuthalBuffer.jpg.

To set the buffer spatial reference, set it in the BufferParameters variable.
e.g. buffParams.bufferSpatialReference = 54032;

For help in choosing your projection, see

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00130000004z000000.htm

Hope this helps,
Annette Locke
Esri Product Engineer, Geometry Team
0 Kudos
AnnetteLocke
Esri Contributor
You might also want to densify your polyline before buffering. See attached screenshot AzimuthalBufferDensified.jpg.

Annette Locke
Esri Product Engineer, Geometry Team
0 Kudos
DarrenJohnston
New Contributor
Thanks for your reply, Annette. Do you know if this is possible with the Google Maps API using the ArcGIS server or is it only possible using the ERSI desktop server?
0 Kudos
DarrenJohnston
New Contributor
Thanks for your reply, Annette. I tried using spatial reference 54032 with the Google Maps API, and that actually caused the returned buffer to compensate longitudinally. The E-W distance were of the proper size. However, it remained too small with respect to the N-S distances from the line that was being buffered. Based on that, I tried a few other references. Some were fairly accurate, so I'm pretty sure that it is, indeed, a problem with the spatial reference. Based on my research, Google Maps seems to use a form of Mercator, so I started trying anything from the supported list (http://resources.esri.com/help/9.3/arcgisserver/apis/javascript/arcgis/help/jsapi_start.htm#jsapi/sp...) that was a Mercator.

Here's where things get odd. I meant to try 3349 - WGS_1984_PDC_Mercator, but I made a typo and ended up putting 3394, which is apparently Nahrwan_1934_Iraq_Zone. But oddly enough, it's really close. I mean really. Around the US/Canada border the margin of error is about 5 Nautical Miles, up near 50N, it's only off by about 12 Nautical Miles. That's much better than the 60% margin of error I was seeing with 102100 which was listed as the WKID of Google Maps on multiple ArcGIS and ERSI pages. I'm a little concerned that an Iraq Zone projection from 1934 seems to be the closest spatial reference available, and I would hate for someone to attempt to buffer an area outside of what I have tested unaware that it may be nowhere near true. I'm hoping you can shed some light on the situation.

I realize that "measurements" of distance shouldn't be done on a Mercator, but as I am not measuring but simply buffering a line, I would assume that the ArcGIS server takes this into account to calculate the buffer when passed the proper (Web Mercator) spatial reference. So I remain confused as to why 102100 doesn't result in a proper buffer, and even more confused why a projection from Iraq in 1934 does.
0 Kudos
JulianaLandor
New Contributor
I created a basic demonstration of the problem.
0 Kudos
AnnetteLocke
Esri Contributor
Darren,
The Mercator projection distorts areas and distances. The server won't automatically adjust for the distortions when buffering unless you supply a buffer spatial reference.
You can read more about Mercator projections here:
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Mercator/003r00000038000000/

A coordinate system that may be more appropriate for the area in which you are buffering is NAD_1983_Statistics_Canada_Lambert (wkid=3347).  See attached screenshot. Note that the buffer is close to the buffer you get when using the Nahrwan_1934_Iraq_Zone (wkid=3394) that you mentioned. Both of these coordinate systems use the Lambert_Conformal_Conic projection but with different parameters. You can see the parameters by looking at the well-known text format of the coordinate systems found here:
http://sampleserver1.arcgisonline.com/ArcGIS/SDK/REST/pcs.html

Some good reading on coordinate systems can be found by going to the ArcGIS Resource Center (http://resources.arcgis.com/)
Under "Products" click on Desktop->Help->Professional Library->Guide Books->Map Projections.

Annette Locke
Esri Product Engineer, Geometry Team

Thanks for your reply, Annette. I tried using spatial reference 54032 with the Google Maps API, and that actually caused the returned buffer to compensate longitudinally. The E-W distance were of the proper size. However, it remained too small with respect to the N-S distances from the line that was being buffered. Based on that, I tried a few other references. Some were fairly accurate, so I'm pretty sure that it is, indeed, a problem with the spatial reference. Based on my research, Google Maps seems to use a form of Mercator, so I started trying anything from the supported list (http://resources.esri.com/help/9.3/arcgisserver/apis/javascript/arcgis/help/jsapi_start.htm#jsapi/sp...) that was a Mercator.

Here's where things get odd. I meant to try 3349 - WGS_1984_PDC_Mercator, but I made a typo and ended up putting 3394, which is apparently Nahrwan_1934_Iraq_Zone. But oddly enough, it's really close. I mean really. Around the US/Canada border the margin of error is about 5 Nautical Miles, up near 50N, it's only off by about 12 Nautical Miles. That's much better than the 60% margin of error I was seeing with 102100 which was listed as the WKID of Google Maps on multiple ArcGIS and ERSI pages. I'm a little concerned that an Iraq Zone projection from 1934 seems to be the closest spatial reference available, and I would hate for someone to attempt to buffer an area outside of what I have tested unaware that it may be nowhere near true. I'm hoping you can shed some light on the situation.

I realize that "measurements" of distance shouldn't be done on a Mercator, but as I am not measuring but simply buffering a line, I would assume that the ArcGIS server takes this into account to calculate the buffer when passed the proper (Web Mercator) spatial reference. So I remain confused as to why 102100 doesn't result in a proper buffer, and even more confused why a projection from Iraq in 1934 does.
0 Kudos