//in my init function, the maps extent changed handler is set using dojo.connect(map, 'onExtentChange', Extent_Change); function clickLink(id) { //generic handler for all of the links in the student list map.infoWindow.hide(); var graphic; dojo.forEach(map.graphics.graphics, function (g) { if (g.attributes["ID"] == id) { graphic = g; } }); //tmpGraphic and bolClickLink are global in scope tmpGraphic = graphic; bolClickLink = true; map.centerAndZoom(graphic.geometry, map.getNumLevels()-3); } function Extent_Change(ext, delta, bolLevel,lod) { var e = new Object; if (bolClickLink) { e.graphic = tmpGraphic; e.screenPoint = map.toScreen(tmpGraphic.geometry); e.mapPoint = tmpGraphic.geometry; graphicClick(e); } bolClickLink = false; } function graphicClick(evt) { map.infoWindow.setTitle("Flat Stanley"); map.infoWindow.setContent(evt.graphic.attributes["Name"] + "<br/>" + evt.graphic.attributes["Place"]); map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint)); }
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Test Project</title> <style type="text/css"> @import "http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/tundra/tundra.css"; </style> <script type="text/javascript">djConfig = { parseOnLoad: true }</script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6"></script> <script type="text/javascript"> dojo.require("esri.map"); var myMap; var pt1; var pt2; function init() { //Initialize the map myMap = new esri.Map("divMap", { logo: false, nav: true }); var lyr1 = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", { id: "lyr1" }); myMap.addLayer(lyr1, 0); dojo.connect(myMap, "onLoad", myMap_OnLoad); } function myMap_OnLoad(map) { pt1 = new esri.geometry.Point(-8772700, 4264100, myMap.spatialReference); pt2 = new esri.geometry.Point(-13590000, 4498000, myMap.spatialReference); //Comment out the following 4 lines and everything works var sy1 = new esri.symbol.TextSymbol("1"); var sy2 = new esri.symbol.TextSymbol("2"); myMap.graphics.add(new esri.Graphic(pt1, sy1)); myMap.graphics.add(new esri.Graphic(pt2, sy2)); } function gotoPoint1() { myMap.centerAndZoom(pt1, 16); } function gotoPoint2() { myMap.centerAndZoom(pt2, 16); } dojo.addOnLoad(function() { init(); }); </script> </head> <body style="height:100%;margin:0px;"> <form id="form1" runat="server" style="height:100%;margin:0px;"> <div><a href="javascript:gotoPoint1();">Go to Point 1</a> <a href="javascript:gotoPoint2();">Go to Point 2</a></div><br /> <div id="divMap" class="tundra" style="height:600px;width:600px;"></div> </form> </body> </html>
you are not going to like this answer
apparently map.getNumLevels() is not a valid function (it is not listed as a method in the API)
if you hardcode a value
map.centerAndZoom(pt, 17);
the error goes away.
if (dojo.isIE) { map.centerAndZoom(pt, zoomLevel); map.setLevel(zoomLevel -2 ); map.setLevel(zoomLevel); } else { map.centerAndZoom(pt, zoomLevel); }
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Test Project</title> <style type="text/css"> @import "http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/tundra/tundra.css"; </style> <script type="text/javascript">djConfig = { parseOnLoad: true }</script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6"></script> <script type="text/javascript"> dojo.require("esri.map"); var levelToZoomTo = 14; var distanceToMove = -4000000; var myMap; var pt1; var pt2; var lyrG; function init() { //Initialize the map myMap = new esri.Map("divMap", { logo: false, nav: true, wrapAround180: false, showInfoWindowOnClick: false, fitExtent: true }); var lyr1 = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", { id: "lyr1" }); myMap.addLayer(lyr1, 0); lyrG = new esri.layers.GraphicsLayer({ displayOnPan: false }, "lyrG"); myMap.addLayer(lyrG, 1); dojo.connect(myMap, "onLoad", myMap_OnLoad); } function myMap_OnLoad(map) { pt1 = new esri.geometry.Point(0, 0, myMap.spatialReference); pt2 = new esri.geometry.Point(distanceToMove, 0, myMap.spatialReference); } function gotoPoint1() { myMap.centerAndZoom(pt1, levelToZoomTo); } function gotoPoint2() { myMap.centerAndZoom(pt2, levelToZoomTo); } function drawGraphics() { var sy1 = new esri.symbol.TextSymbol("1"); var sy2 = new esri.symbol.TextSymbol("2"); if (myMap.extent.contains(pt1)) { lyrG.add(new esri.Graphic(pt1, sy1)); } if (myMap.extent.contains(pt2)) { lyrG.add(new esri.Graphic(pt2, sy2)); } } function removeGraphics() { lyrG.clear(); } dojo.addOnLoad(function() { init(); }); </script> </head> <body style="height:100%;margin:0px;"> <form id="form1" runat="server" style="height:100%;margin:0px;"> <div><a href="javascript:gotoPoint1();">Go to Point 1</a> <a href="javascript:gotoPoint2();">Go to Point 2</a> <a href="javascript:drawGraphics();">Draw Graphics</a> <a href="javascript:removeGraphics();">Remove Graphics</a></div><br /> <div id="divMap" class="tundra" style="height:600px;width:600px;"></div> </form> </body> </html>
Ok - Last post for the night. This issue is definitely when a single graphic is too far away from the current map location. To replicate it only requires a single graphic to the map. ZoomAndCenter to that location, then ZoomAndCenter to a location that is far enough away (distance determined by your current zoom level), and then do a standard Pan. At zoom level 14 a distance from graphic (x) of 4000000 will do the trick. Switch to zoom level 13, and then the point has to be further away, zoom level 15, the graphic doesn't have to be as far. I tried removing graphics prior to the ZoomAndCenter and then adding them back after (see latest sample). Doesn't matter. Something in the process is killing the parent graphic matrix when doing the applyTransform at the end on the PanComplete operation. I hope this info helps ESRI devs to locate and fix this issue.
I'm not sure what I'm going to do right now. Most of my apps will have the graphics close enough that it won't matter, but some will, especially as my users like to zoom in very close. I really am not looking foward to telling them they have to use a different browser just because their points are spread out.
Here's my latest test code - Similar to the first, but allows you to draw and clear the graphics on demand.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Test Project</title> <style type="text/css"> @import "http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/tundra/tundra.css"; </style> <script type="text/javascript">djConfig = { parseOnLoad: true }</script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6"></script> <script type="text/javascript"> dojo.require("esri.map"); var levelToZoomTo = 14; var distanceToMove = -4000000; var myMap; var pt1; var pt2; var lyrG; function init() { //Initialize the map myMap = new esri.Map("divMap", { logo: false, nav: true, wrapAround180: false, showInfoWindowOnClick: false, fitExtent: true }); var lyr1 = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer", { id: "lyr1" }); myMap.addLayer(lyr1, 0); lyrG = new esri.layers.GraphicsLayer({ displayOnPan: false }, "lyrG"); myMap.addLayer(lyrG, 1); dojo.connect(myMap, "onLoad", myMap_OnLoad); } function myMap_OnLoad(map) { pt1 = new esri.geometry.Point(0, 0, myMap.spatialReference); pt2 = new esri.geometry.Point(distanceToMove, 0, myMap.spatialReference); } function gotoPoint1() { myMap.centerAndZoom(pt1, levelToZoomTo); } function gotoPoint2() { myMap.centerAndZoom(pt2, levelToZoomTo); } function drawGraphics() { var sy1 = new esri.symbol.TextSymbol("1"); var sy2 = new esri.symbol.TextSymbol("2"); if (myMap.extent.contains(pt1)) { lyrG.add(new esri.Graphic(pt1, sy1)); } if (myMap.extent.contains(pt2)) { lyrG.add(new esri.Graphic(pt2, sy2)); } } function removeGraphics() { lyrG.clear(); } dojo.addOnLoad(function() { init(); }); </script> </head> <body style="height:100%;margin:0px;"> <form id="form1" runat="server" style="height:100%;margin:0px;"> <div><a href="javascript:gotoPoint1();">Go to Point 1</a> <a href="javascript:gotoPoint2();">Go to Point 2</a> <a href="javascript:drawGraphics();">Draw Graphics</a> <a href="javascript:removeGraphics();">Remove Graphics</a></div><br /> <div id="divMap" class="tundra" style="height:600px;width:600px;"></div> </form> </body> </html>
I hope this info helps ESRI devs to locate and fix this issue.