GMarkerManager and setImage – why it fails?

I wrote simple howto about changing icons in markers when markers is already placed on map. And I was asked question about setImage and GMarkerManger.

Problem is that when changing image with setImage old image will be displayed when user zooms map in or out – when GMarkerManager is used to place markers on map.

GMarkerManager was introduced in November 2006, and it has goal to help manage huge amounts of markers on map. For markers added to map via manager You can define on which zoom levels markers should be visible. This allow to keep map not so crowded, when displaying larger area.

GMarkerManager tracks zoom level and display only needed markers and tries to keep memory usage as low as possible. This mean that not all data about markers is keep in memory. For example – if marker is not visible on current zoom level or in viewport image representing it is discarded. To display markers properly GMarkerManager creates new images from GIcon class, when changing zoom.

This is why setImage fails in this case – image is changed, but when user changes zoom all markers images gets recreated from GIcon. So what can be done? We can change image in icon definition:

marker.setImage("htp://example.com/new_image.png")
marker.getIcon().image = "htp://example.com/new_image.png"

However can backfire if we use common GIcon object to initialize more than one marker (and this is usually the case). When we change image in GIcon, after next refresh all markers created from this GIcon instance will get new image. Like in this example. Place two icons on map (just click) and click Change image. After zoom out You will see that both markers has new icon…

So what we can do about it?

First we can create separate GIcon for each marker – but this will have impact on memory usage. If this is not suitable, so You have to write some own replacement for GMarkerManager. But there is good news – You don’t have to start from a scratch. Google has opensourced GMarkerManager and full code (not obfuscated) is available in GMaps Utility Library (library announcement, GMarkerManager code is available under this link).

I guess there is already some solution written to solve this problem, but I’m not aware of any – does anybody found/wrote something useful?

4 thoughts on “GMarkerManager and setImage – why it fails?

  1. We came up with an idea for markers that does nott use setImage at all because of several problems we had with it.
    Instead, if you dig up on the internet you’ll find that there is an option to set the GMarkerOptions with an id attribute which can get you a reference to the actual icon object which is on the screen. For instance, if you set your GMarkerOptions.id to “12345”
    then the DOM node specified by the icon will have the id
    mtgt_12345 (they always have the mtgt_ prefix).
    This worked well in our application because each icon corresponded to a unique real estate listing that had an ID in a database.

    Anyways, so then what we did was we set all of our icons with a transparent gif image. Then we created several classes in CSS which corresponded to the different icon images we wanted to have (we wanted the icons to be a different color depending on how the listings were sorted).
    So anyways, we could figure out which class to assign to each icon based on its ranking… in javascript if you have a reference to the icon (gmarker displayed on screen) then you can do icon.className=[class to assign]
    Anyways, this is much faster, although if you were to print this out they would be background images so they won’t show up unless you tell your browser to print background images. According to the google documentation, the setImage function won’t change the image out for printing either.
    Note that you may have some issues with zooming in and out when using this method but those can also be fixed.. You’ll have to pm me though for details.
    Note that this method should also be a lot faster for browsers to render (probably won’t matter unless you are resetting many icons at the same time like we were).

  2. @Matt
    Nice tip, however I can run it only with in-place hash as GMarkerOptions like that:

    new GMarker(point, {id: “some_id”, icon: iconObject})

    and

    var o = {id: “some_id”, icon: iconObject}
    new GMarker(point,o)

    fails (does not set DOM id for that marker).

    Anyway – very valuable tip :)

  3. Do you know if this applies to the clustermarker also. I am guessing it is a similar principal because my changed markers using SetImage revert back to their original definition when I scroll off the current map view.

    It also seems to do the same when I remove the current marker and display a new one.

    I’m interested to know a way around this.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.