The Basics

Google Maps API Tutorial

GMarkerManager

The Marker Management system allows large numbers of markers to be managed efficiently, providing that only a modest number of markers are ever visible in the viewport at once.

You can create a marker manager like this:

       var mm = new GMarkerManager(map);

Then you can add individual markers like this:

       var marker=new GMarker(point);
       mm.addMarker(marker,0,17);

Or add arrays of markers like this

       mm.addMarkers(gmarkers,0,17);
       mm.refresh();

The numbers represent the range of zoom levels for which the specified markers will be displayed.

You can perform several .addMarkers() calls for groups of markers that are to be displayed at different zoom levels, then use one .refresh() call to cause them to be displayed. By default, a GMarkerManager manages markers for zoom levels 0 to 17. If you switch to a map type that has more than 17 zoom levels, then zoom levels above 17 show the same markers as would be shown on zoon level 17.

You can change the maximum zoom range managed by a GMarkerManager like this

       var mm = new GMarkerManager(map, {maxZoom:19});

The .getMarkerCount(zoom) method returns the number of managed markers to be displayed on the specified zoom level.

In this example there are a total of 1576 markers being managed.

The 75 red markers are displayed on all zoom levels.
The 330 yellow markers are displayed on zoom level 11 and above.
The 474 green markers are displayed on zoom level 12 and above.
The 696 blue markers are displayed on zoom level 13 and above, but at that zoom level only a few are ever in the viewport at once.

There’s a GMarkerManager “changed” event returned when the GMarkerManager refreshes itself. The event returns two parameters. The first parameter is a GBounds() object which seems to return information about the region under consideration, but measured in units of 1024×1024 pixels. The second parameter is the number of active markers in the region under consideration.

Moving Markers

By default, the GMarkerManager doesn’t listen for changes in position of your markers. If you move a marker by performing marker.setPoint(), the manager will not notice the change.

With {trackMarkers:true} the GMarkerManager listens for any “changed” events on the markers, and performs a .refresh() whenever any of the managed markers moves. That’s fine if only one of your markers moves at once, but would be very inefficient if you move lots of markers at once because a refresh() would be performed for each marker.

If you move a lot of managed markers at once, then its better to perform one GMarkerManager.refresh() after moving all the markers.

Potential Pitfalls

  1. Don’t perform both map.addOverlay() and mm.addMarker() on the same marker.
  2. Don’t try to set the max zoom for a marker higher than the maxZoom setting of the GMarkerManager (default 17).
  3. If you’re using a custom map type, the max zoom value for a marker must be supported by the applied GProjection, even if you never zoom to that level.E.g. if you’re using the default max zoom of 17, like this manager.addmarker(marker,7), then your maptype could use new GMercatorProjection(18) but not new GMercatorProjection(17).
    If you have a marker that has a max zoom that’s not supported by the map type, then you might not get an error, but the marker will not be plotted correctly at any zoom level.

GMarkerManager with a Sidebar

There’s a problem with using GMarkerManager with a sidebar, because marker.openInfoWindow() doesn’t work for markers that are not currently attached to the map. GMarkerManager removes offscreen markers from the map in order to achieve the efficiency improvement.

One way round the problem is to use map.openInfoWindow() instead of marker.openInfoWindow(), calculating the map pixel offset from the infoWindowAnchor and the iconAnchor.

          var iwAnchor = marker.getIcon().infoWindowAnchor;
          var iconAnchor = marker.getIcon().iconAnchor;
          var offset = new GSize(iwAnchor.x-iconAnchor.x,iwAnchor.y-iconAnchor.y);
          map.openInfoWindow(marker.getLatLng(), html, {pixelOffset:offset});
Advertisements