How to tell when an ImageMapType overlay's tiles are finished loading?

982 views
Skip to first unread message

millz

unread,
Sep 7, 2011, 9:27:40 PM9/7/11
to google-map...@googlegroups.com

Hi,

I'm working with the Google Maps v3 API, and I have a custom overlay layer based on the ImageMapType class. I would like to show a loading indicator of some sort while the overlay's tiles are loading, but I don't see any way to know when they are finished.

The code to create the overlay looks similar to the following:

var myOverlay = new google.maps.ImageMapType({
    getTileUrl
: myGetTileUrl,
    tileSize
: new google.maps.Size(256, 256),
    isPng
: true
});
myMap
.overlayMapTypes.push(myOverlay);

The above works just fine, and the overlay successfully loads; it just seems that no events are emitted by the map to indicate anything about the ImageMapType overlay's status. I would expect the map to at least emit an "idle" event when the tiles are finished loading, but as far as I can tell it does not.

How may I know when the ImageMapType overlay is finished loading?

(I posted the same question on SO: http://stackoverflow.com/questions/7341769/google-maps-v3-how-to-tell-when-an-imagemaptype-overlays-tiles-are-finished-loa. If I get an answer in one place I'll make sure to copy it to the other.)

Thanks!

Regards,
Dave

Martin™

unread,
Sep 7, 2011, 10:37:39 PM9/7/11
to Google Maps JavaScript API v3
Hi.

You could keep an array of requested tiles - each time your
getTileUrl() method is called it add's a reference to the requested
tile to the array.

Then you can add an event listener to the tile image listening for the
'onload' event.
The event listener can remove the reference to the tile from the array
once it has loaded and if the array length is now zero then all
requested tiles have been loaded.

Martin.

On Sep 8, 2:27 am, millz <d...@millz.com> wrote:
> Hi,
>
> I'm working with the Google Maps v3 API, and I have a custom overlay layer
> based on the ImageMapType class. I would like to show a loading indicator of
> some sort while the overlay's tiles are loading, but I don't see any way to
> know when they are finished.
>
> The code to create the overlay looks similar to the following:
>
> var myOverlay = new google.maps.ImageMapType({
>     getTileUrl: myGetTileUrl,
>     tileSize: new google.maps.Size(256, 256),
>     isPng: true});
>
> myMap.overlayMapTypes.push(myOverlay);
>
> The above works just fine, and the overlay successfully loads; it just seems
> that no events are emitted by the map to indicate anything about the
> ImageMapType overlay's status. I would expect the map to at least emit an
> "idle" event when the tiles are finished loading, but as far as I can tell
> it does not.
>
> How may I know when the ImageMapType overlay is finished loading?
>
> (I posted the same question on SO:http://stackoverflow.com/questions/7341769/google-maps-v3-how-to-tell....
Message has been deleted

millz

unread,
Sep 8, 2011, 11:19:01 AM9/8/11
to google-map...@googlegroups.com
Thanks for the reply, Martin. 

That sure sounds like it would work, but how can I obtain a reference to the individual tile images such that I can listen for the "onload" event?

Martin™

unread,
Sep 8, 2011, 12:57:56 PM9/8/11
to Google Maps JavaScript API v3
Can you post the code which is your GetTileUrl() method?

Martin.

millz

unread,
Sep 8, 2011, 1:00:49 PM9/8/11
to google-map...@googlegroups.com
Sure, I wrote up a test case here: http://jsfiddle.net/6yvcB/

millz

unread,
Sep 8, 2011, 5:43:49 PM9/8/11
to google-map...@googlegroups.com
I managed to get it working!

I was able to obtain references to the individual tile DOM image elements by overriding the ImageMapType.getTile() function. The override invokes the out-of-the-box version of the function, and then acts the result in order to wire up "onload" event listeners.

I've copied the code below for posterity, but you can see it in action on jsFiddle: http://jsfiddle.net/6yvcB/15/

// Create a base map
var options {
    zoom3,
    centernew google.maps.LatLng(37.59-99.13),
    mapTypeId"terrain"
};
var map new google.maps.Map($("#map")[0]options);

// Listen for the map to emit "idle" events
google.maps.event.addListener(map"idle"function(){
    console.log("idled");
});

// Keep track of pending tile requests
var pendingUrls [];

$("#btn").click(function({
    var index 0;   
    var urls "http://placekitten.com/256/256"
                 "http://placekitten.com/g/256/256",
                 "http://placekitten.com/255/255"
                 "http://placekitten.com/g/255/255",
                 "http://placekitten.com/257/257"
                 "http://placekitten.com/g/257/257];

    var overlay new google.maps.ImageMapType({
        getTileUrlfunction(
            var url urls[index urls.length];
            index++;
            
            // Add this url to our list of pending urls
            pendingUrls.push(url);
            
            return url

        },
        tileSizenew google.maps.Size(256256),
        isPngtrue,
        opacity0.60
    });
    
    // Listen for our custom "overlay-idle" event
    $(overlay).bind("overlay-idle"function({
        console.log("overlay idled")
    });
    
    // Copy the original getTile function so we can override it, 
    // but still make use of the original function
    overlay.baseGetTile overlay.getTile;

    // Override getTile so we may add event listeners to know when the images load
    overlay.getTile function(tileCoordzoomownerDocument{
        
        // Get the DOM node generated by the out-of-the-box ImageMapType
        var node overlay.baseGetTile(tileCoordzoomownerDocument);
        
        // Listen for any images within the node to finish loading
        $("img"node).one("load"function({

            // Remove the image from our list of pending urls
            var index $.inArray(this.__src__pendingUrls);
            pendingUrls.splice(index1);
            
            // If the pending url list is empty, emit an event to 
            // indicate that the tiles are finished loading
            if (pendingUrls.length === 0{
                $(overlay).trigger("overlay-idle");
            }
        });

        return node;
    };
    
    map.overlayMapTypes.push(overlay);
});
Reply all
Reply to author
Forward
0 new messages