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?