Search code examples
javascriptiosgoogle-maps-api-3mobile-safari

google map imageMapType crashes iOS safari


I am loading custom png tiles onto a google map, and it seems that performance is killing the app in iOS Safari, and making it crawl with most other browsers. I believe that this is due to the number of tiles being loaded onto the map (loading 73 Illinois counties, with tile number depended on zoom level), and the limited amount of memory that iOS gives to Safari.

First, I am only creating a new imageMapType overlay for tiles that I have, and am not trying to retrieve images for every tile on the screen, by using google.maps.LatLngBounds.intersects

        function createBoundedTileLayer(sourceUrl, bounds) {
        var imageMapType = new google.maps.ImageMapType({
            getTileUrl: function (coord, zoom) {
                var tileBounds = getTileBounds(coord, zoom);
                if (bounds.intersects(tileBounds)) {
                    return app.stringFormat(sourceUrl, coord.x, coord.y, zoom);
                }
                return null;
            },
            tileSize: new google.maps.Size(256, 256),
            isPng: true,
            opacity: 0.7
        });
        return imageMapType;
    }

    function getTileBounds(coord, zoom) {
        var mapSize = Math.pow(2, zoom);
        var west = ((coord.x * 360) / mapSize) - 180;
        var east = (((coord.x + 1) * 360) / mapSize) - 180;

        var efactor = Math.exp((0.5 - coord.y / mapSize) * 4 * Math.PI);
        var north = (Math.asin((efactor - 1) / (efactor + 1))) * (180 / Math.PI);

        efactor = Math.exp((0.5 - (coord.y + 1) / mapSize) * 4 * Math.PI);
        var south = (Math.asin((efactor - 1) / (efactor +1))) * (180/Math.PI);

        return new google.maps.LatLngBounds(new google.maps.LatLng(south, west), new google.maps.LatLng(north, east));
    }

Second, I for a "desktop" browser, I am loading all tiles simultaneously and it does not crash (just crawls when I zoom or pan the map). For a mobile browser, to stop the crashing behavior, I am only loading enough tiles for 5 counties at a time, using a setTimeout for 2000 milliseconds, and then loading 5 more counties in a loop until all 73 counties are loaded.

Has anyone out there had and beat this issue with Google Maps? Thanks in advance!


Solution

  • @xmux was partially right here. While he suggested the Google Maps Engine to have the server render the tiles, and this probably would have also solved the issue, his comment on the amount of RAM used for the javascript virtual machine was the real solution.

    These 73 counties were loading into 73 layers on the map. Clearly for a device with limited amounts of memory, this would never work. What we ended up doing to resolve the issue was to not display this custom layer until the user was zoomed in close enough to read the contents of the custom layer (> 12). Then, only get the counties that happen to fit within this viewport. With the zoom this high before getting a custom layer, at most 5 layers were being added to the map.

    For better memory management, this could probably be reduced to fewer layers with the zoom level being higher before displaying the overlay.

    Also, after zooming back out, or panning around, clean up after yourself. These overlays stay on the map forever unless you tell them to go away.

    So moral of the story -- think about memory management and clean up after yourself. Thanks, @xmux!