Search code examples
javascriptmapsopenlayerscloudmade

Strange bug with OpenLayers + CloudMade


I am trying something fairly simple, you can see a demo here: http://www.jsfiddle.net/VVe8x/19/

This bug only appears in Firefox, so to see it press either one of the links once (it will take you to either NY or Israel) then press the other link. The bug is that it will not show me the tiles in that location, instead it will show me the background of the div.

P.S In Chrome this works flawlessly.

I dont know if this is a clue or it might confuse you, if in between pressing either NY or Israel links you press the "view the world" link it will allow you then to see the other location..

Full Source for reference

<!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" xml:lang="en" lang="en">
    <body>

    <a href="#" onclick="javascript:show1()">show me NY</a>
    <a href="#" onclick="javascript:show2()">show me TLV</a>
    <a href="#" onclick="javascript:map.zoomToExtent(map.getMaxExtent());">show world map(a "workaround"</a>


    <div id='myMap' style="height: 600px; width: 600px; position: relative"></div>

    <script src="http://openlayers.org/api/OpenLayers.js" type="text/javascript"></script>
    <script src="http://developers.cloudmade.com/attachments/download/58/cloudmade.js" type="text/javascript"></script>
    <script type="text/javascript" charset="utf-8">
        map = new OpenLayers.Map("myMap", {
            controls: [
                new OpenLayers.Control.Navigation(),
                new OpenLayers.Control.PanZoomBar()
            ]
        });

        var cloudmade = new OpenLayers.Layer.CloudMade("CloudMade", {
            key: 'd5da652e33e6486ba62fca3d18ba70c9'
        });
        map.addLayer(cloudmade);

        var epsg4326 = new OpenLayers.Projection("EPSG:4326");

        map.setCenter(new OpenLayers.LonLat(40, 32), 2);

        show1 = function(){
        var bound1 = new OpenLayers.Bounds(-8236567.917898,4972686.066032,-8236148.409989,4972889.624407);
            map.zoomToExtent(bound1); // to NY
        };

        show2 = function(e){
            var bound2 = new OpenLayers.Bounds(3874818.203389,3773932.267033,3875217.305962,3774226.370443);   
            map.zoomToExtent(bound2); // to Israel
            return false;
        };

    </script>
    </body>
</html>

Solution

  • The myMap_OpenLayers_Container has the following CSS when the tiles are invisible:

    position: absolute; z-index: 749; left: -2.02815e+7px; top: -2007340px;

    If you change these around you can see that the correct tiles were loaded, so its likely to be jsFiddle messing them up. The tiles CSS when they don't show also have strange values.

    Update:

    Testing locally also produces the issue, so that rules out jsFiddle.

    A fix would be to set this value after the zoom by calling a function such as:

            updateCSS = function(){
                OpenLayers_Container = document.getElementById("myMap_OpenLayers_Container").style.left = "0px";
            }
    

    This looks like a bug, although if it is in OpenLayers or the CloudMade layer properties is hard to tell - I'd imagine the latter, or it would be a widely reported bug. The relevant code in OpenLayers.js appears to be:

    centerLayerContainer: function(lonlat){
        var originPx = this.getViewPortPxFromLonLat(this.layerContainerOrigin);
        var newPx = this.getViewPortPxFromLonLat(lonlat);
        if ((originPx != null) && (newPx != null)) {
            this.layerContainerDiv.style.left = Math.round(originPx.x - newPx.x) + "px";
            this.layerContainerDiv.style.top = Math.round(originPx.y - newPx.y) + "px";
        }