4

ArcGIS Javascript API maps allow the user to pan around the world, which is a great feature, however I am performing some processes that rely on map extents. I have discovered that despite the defined projection (wkid), extents are returned in meter coordinates with an origin of lat/lon 0,0 (off the coast of Africa). In order to get my extents in the projection I need, I use a Geometry service to project them, however when the user pans around the world, the coordinates do not reset, they just keep adding up, resulting in 'NaN' extents returned.

I saw this post, which would be one way to deal with this issue, however I would really like to keep the ability to pan around the world. Does anyone have any ideas on how to accomplish this?

1 Answer 1

3

"I have discovered that despite the defined projection (wkid), extents are returned in meter coordinates with an origin of lat/lon 0,0 (off the coast of Africa)."

With ArcGIS Javascript API, the first map service added sets coordinate system for the whole map. If you added one of ESRI's tiled map services for a basemap, it's probably one that was created using wkid 102100, which fits what you described. When you lay your map service on top of it, your services is reprojected to fit on top of this service. To fix this, you either need to create your own tiled map service basemap projected in the wkid you want, or use the geometry service to reproject points, as you have done.

"I use a Geometry service to project them, however when the user pans around the world, the coordinates do not reset, they just keep adding up, resulting in 'NaN' extents returned."

Here's a function you could use to fix the extent to something you can use for your geometry service:

function fixExtent(extent) {
    // hard-coded full extent of the world, using wkid 102100. 
    var full = new esri.geometry.Extent(-20037508.3427892430765884088807,-19971868.8804086,20037508.3427892430765884088807,19971868.8804086, new esri.SpatialReference({ wkid:102100 }));
    // calculate the extent size so that it fits within the normal extent
    var xwidth = full.xmax - full.xmin;

    var newXMin = extent.xmin;
    while (newXMin < full.xmin) {
        newXMin += xwidth;
    }
    while (newXMin > full.xmax) {
        newXMin -= xwidth;
    }

    var newXMax = extent.xmin;
    while (newXMax < full.xmin) {
        newXMax += xwidth;
    }
    while (newXMax > full.xmax) {
        newXMax -= xwidth;
    }

    // return a new geometry that is within the range of the full extent
    return new esri.geometry.Extent(newXMin, extent.ymin, newXMax, extent.ymax, extent.spatialReference);
}

I don't know how this will work if you compare an extent that crosses the dateline. Hope this helps.

3
  • This is pretty much what I was looking for. I am curious to know your source for the hardcoded full world extent, as it would have to be perfectly accurate for this to work right, is that correct?
    – bluefoot
    Commented Nov 27, 2012 at 17:32
  • 2
    This works using just (extent.xmin % xwidth) without subtracting the full.xmin, etc. Thanks!
    – bluefoot
    Commented Nov 27, 2012 at 17:45
  • 2
    I fixed the code. I forgot that you don't need to check the y axis for overlap. As for the calculations, web mercator is baseed on the WGS84 ellipsoid, and according to en.wikipedia.org/wiki/World_Geodetic_System, the Earth's semi-major axis is 6 378 137.0 m. Multiply that by pi, and you get the distance half way around the world in meters. I just added a + and - of that value for the extent xmin and xmax. The ymin and ymax I just grabbed from an ESRI mapservice.
    – raykendo
    Commented Nov 27, 2012 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.