IE 7 throws error, firefox does not

1634
20
11-15-2010 11:59 AM
TerryGiles
Occasional Contributor III
I have a series of anchor tags in a panel next to my map, each the name of a person.  The map contains just the ESRI street map service and points in the map's graphicslayer that are the person's location (not dynamic, just hard coded x,y). 

When you click one of the name <a> tags, it should zoom the map to their location and display the info window.  This works great in Firefox, but IE 7 does 2 things -
the graphics disappear from the map &
  if you try to pan the map or zoom out it throws an error about 'illegal string in Vector 2d' (see attached).

Any idea what's causing this and how to fix it (other than not using IE...)?

note - I added a demo version of html page to this post.  Try it in IE - click on Person 1 in the left and it will work.  Now click on Person 2 and you'll notice the graphic is gone and if you try to pan you'll get the error..  The Esri forums do not allow for uploading .htm files so rename it from .txt to .htm and give it a try.

Thanks, TG


sample html <a> tag -

<a href ='' title='some name' onclick='clickLink(1);return false;' >some name</a>



        //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));

        }


0 Kudos
20 Replies
TerryGiles
Occasional Contributor III
Harold,

I hit this issue while working on a small project I was doing for my kid's school, and I haven't messed w/ the JavaScript API since..
0 Kudos
by Anonymous User
Not applicable
Original User: cwright25

I just wanted to bump this as it is now 2012, I'm using IE9, version 2.6 of the API, & it is still not resolved.  I just submitted a support request that references this thread.

Here is another example of the bug.  When the graphics are present, the zoom and center doesn't even take you the correct map position in IE.  Remove the graphics and everything works great.

<!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>
0 Kudos
JeffPace
MVP Alum
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.
0 Kudos
by Anonymous User
Not applicable
Original User: cwright25

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.


Hi Jeff,

Thanks for the response.  You are correct when looking at the original posted code.  However, if you look at the code I posted, you will see that I've got the values hard-coded already.  The exact behavior is that on the 2nd ZoomAndCenter, the graphic no longer displays AND if you try to pan the map over you get the additional error from the dojo vml.xd.js script: "Microsoft JScript runtime error: Arg: Illegal input string in Vector2D".  I can see where this one would be easy to pass the buck and say it's a DOJO problem or a VML problem, but I can't help shaking the feeling that the Javascript API is passing in some invalid values, quite possibly due to a race condition with the extent not being set correctly.  I'm on day number 2 of trying to find an acceptable work-around.  The work-around above:

if (dojo.isIE) {
                map.centerAndZoom(pt, zoomLevel);
                map.setLevel(zoomLevel -2 );
                map.setLevel(zoomLevel);
            }
            else {
                map.centerAndZoom(pt, zoomLevel);
            }


doesn't seem to be of help.  I have also tried clearing the graphics layer prior to calling ZoomAndCenter and re-adding the graphics via a button click (and in the map OnExtentChange event, OnPanEnd event, and OnZoomEnd).  This don't work either.  Iv'e tried putting the graphics on a custom graphics layer and removing the layer prior to the ZoomAndCenter.  This prevents the Vector 2D error, until I create a new graphics layer, add the graphics in and add it to the map.  Then it immediately errors.

It seems to be related to the fact that the points are distant from one another as well.  When moving between points that are close to one another, the issue does not rear it's head as frequently.  Also when using the function at zoom levels that are further out the issue seems to not occur as frequently.  It's zooming in close on points that are far apart.  This is why I can't help but think a number that is either too big or too small is being passed in to DOJO. 

If anyone could can try the sample code I posted and tell me where I have gone wrong, I would be thrilled.
0 Kudos
ChuckWright
New Contributor II
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>
0 Kudos
by Anonymous User
Not applicable
Original User: jeff.pace

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>



You arent going to like this either, but i have had issues with center and zoom in the past (since about 1.6), so we dont use it
i call two separate commands, first center, then zoom.  You might want to try that, at least to rule it out.
0 Kudos
derekswingley1
Frequent Contributor
I hope this info helps ESRI devs to locate and fix this issue.


Can you open a call with support?
0 Kudos
by Anonymous User
Not applicable
Original User: cwright25

@Jeff - Can you be a little more specific about your workaround?  It may be better than what I am about to use.  I'm using background maps from ArcOnline so I have various LODs to zoom to.  If I try "centerAt()" then "setLevel()" in the same function call, it causes a race condition and the second function, "setLevel()" wins.  I tried calling "setLevel()" in the "onPanEnd" event, but it does not help when staying at the same zoom level.  What I've found works is calling "setLevel(1)" to zoom almost all the way out, and then in the "onExtentChange" event calling "centerAndZoom()".  Obviously this involves some bad programming practices, such as using a global variable to store the point to while waiting for the "OnExtentChange" to fire.  Ultimately I think this is a better solution than what I was about to do, which is pop up an alert for IE users stating "To see labels, switch to Chrome, Firefox, or Safari". 🙂  Also, if I didn't state it before, I originally had this issue with the "setExtent()" function, and moved to "centerAndZoom()" only after "setExtent()" failed with the same issue.  I'm guessing these 2 function calls share the same dependency code.

@swingley - I have done so (Incident 1005617), and was informed that this is Bug NIM054233: Zooming in twice using map.centerAndZoom to level 14 produces odd results in Internet Explorer.  So two comments:

1. As Jeff stated, this bug has been around a while - it was originally reported nearly 2 years ago, Feb. 17, 2010.
2. The bug description is not really accurate, as Level 14 is not the only one affected, and I wouldn't simply call it "odd results", as it consistantly causes an error to be thrown when panning after the second zoom, and the graphics consistantly fail to draw.

Would it make any difference at this point if I also placed a request to escalate this bug, or are you guys on it?  Thanks for all you do.
0 Kudos
derekswingley1
Frequent Contributor
Hi Chuck,

I spent a little time looking into this today and briefly discussed it with the team. The underlying issue that IE's VML coordinate system is a fixed size. This coordinate space is recomputed each time the map level changes. When you're at a larger map scale (e.g., zoomed in) and then call centerAndZoom() to a point that's a large distance from the map's current center, the new center is outside the VML coordinate system bounds. This is the source of the error you're seeing in IE. Unfortunately, we don't have a quick, easy fix for this.

I have found that zooming out before re-centering and zooming seems to work. Try this:  http://jsfiddle.net/h6Qkf/
0 Kudos
by Anonymous User
Not applicable
Original User: cwright25

Derek,

Thank you for reviewing this so quickly.  Even though this is not leading to a direct fix, the responsivness speaks highly of ESRI.  Based on your reply, I will continue with the work around of zooming out prior to recentering for IE.  I actually got this implemented successfully yesterday.

Also, if I understand correctly, you are defining a Local Coordinate Space (LCS), probably for a VML Group, that is only updated when the map level changes.  Would the following be possible (just brainstorming):

1. Detect when the map is about to recenter with any part of the extent outside the LCS and recompute it prior to this (pretend the zoom level changed even when it didn't)?
2. Simply have any option to force a recompute of the LCS on any Extent Change and let the end-developer decide if the performance hit is worth it (I'm generally not working with more than 200 graphics objects at any given time.)?

Since zooming out then back in effectively recomputes the LCS, I just want to cut out the additional overhead associated with changing zoom levels while still having the effect of recomputing the LCS.

Thanks again, I certainly understand that sometimes coding problems that sound easy can be very complicated.  I also know that VML is going away, but as I design web sites for the public, we still offer support back to IE6...

Finally, is there a place where "known workarounds" are compiled and officially posted?
0 Kudos