Select to view content in your preferred language

map.setExtent() bug

3313
4
03-28-2012 09:52 AM
JasonKnisley
Deactivated User
Several months ago I made a post similar to this on the forums for the ArcGIS API for Android.  I'm now exploring mobile web apps using Javascript instead, and discovered what appears to be a bug in the setExtent() method.  I'm using this method to zoom the map into an extent which includes the user's location and a selected destination including a small buffer.

When you specify the boundaries for the extent, a logical assumption is that a rectangle will be created which contains, at a minimum, the points xmin,ymin and xmax,ymax.  Obviously the parameters given may need to be adjusted to accommodate the current map dimensions, but this does not happen correctly in some cases.  In its current implementation setExtent() creates an extent which encompasses the x-boundaries, but not necessarily the y-boundaries.

For the following examples I'll refer to dx (xmax-xmin) and dy (ymax-ymin).  If dx is large relative to dy (for example, the user selects a point that is west or east of their current location), then then ymax and ymin are adjusted as needed and the map zooms appropriately.  On the other hand, if dx is very small relative to dy (for example, the user selects a point that is north or south of their current location), then the map zooms in much too close.  It sets the x borders at xmin and xmax, but ymin and ymax are placed off of the screen.

Below is code that I currently use as a workaround.  It assumes the device is in portrait mode, but could easily be modified to handle screens of various dimensions.

function zoomToPoints(point1, point2) {
 var xmin, ymin, xmax, ymax;
 
 if (point1.x < point2.x) {
  xmin = point1.x;
  xmax = point2.x;
 } else {
  xmin = point2.x;
  xmax = point1.x;
 }
 if (point1.y < point2.y) {
  ymin = point1.y;
  ymax = point2.y;
 } else {
  ymin = point2.y;
  ymax = point1.y;
 }
 
 // add buffer to envelope so that points aren't on the edge of the screen
 var xBuffer = (xmax - xmin) * 0.2;
 var yBuffer = (ymax - ymin) * 0.4;
 xmax += xBuffer;
 xmin -= xBuffer;
 ymax += yBuffer;
 ymin -= yBuffer;
 
 // to zoom appropriately under the current API, dY/dX should be approximately 127/80 based on emulator experiments in portrait mode
 // if dX is small then it needs to be adjusted based on dY before calling setExtent()
 if ((ymax-ymin) / (xmax-xmin) > 127.0/80.0) {
  var dX = 80.0 * (ymax-ymin) / 127.0; 
  xmax = ((xmax+xmin)/2.0) + (dX / 2.0);
  xmin = ((xmax+xmin)/2.0) - (dX / 2.0);
 }
 
 // set the map's new extent
    map.setExtent(new esri.geometry.Extent({
        "xmin": xmin,
        "ymin": ymin,
        "xmax": xmax,
        "ymax": ymax,
        "spatialReference": {
            "wkid": 102100
        }
    }));
}
0 Kudos
4 Replies
JasonKnisley
Deactivated User
Any thoughts from a dev?  Is that a bug or intended behavior?
Thanks!
0 Kudos
derekswingley1
Deactivated User
setExtent takes an optional, boolean parameter that can be used to specify that the map should fit the entire extent. Does using setExtent(extent, true) fix this for you?
0 Kudos
JasonKnisley
Deactivated User
Derek,
That does indeed fix it.  I had overlooked that parameter in the API reference.  Thanks!
0 Kudos
derekswingley1
Deactivated User
My pleasure! Can you mark my post as an answer?
0 Kudos