MarkerClusterer in an All New Flavor – ActionScript! (GoogleGeoDev)

[Editor's note: An AS3 Flash / Flex library for auto-clustering near map location markers into groups symbols. This speeds map rendering and groups points all within the same neighborhood, avoiding "red dot fever" marker overload. An AS3 implementation of existing JavaScript extension. Still needs to account for geographic region clustering (not just within a grid). Thanks Laris!]

Republished from Google Geo Developer Blog.
Monday, July 27, 200. 

My name is XIAO Juguang – just call me Juguang. I am a freelance software developer based in Beijing, China. Technically speaking, I’m double sided. On one side, I specialize in knowledge management and business modeling, traditionally using LAMP and now experimenting with offerings like Google App Engine. On the other side, I love visualization in time and space, with charts, trees, graphs, and maps, always using the power of ActionScript/Flex, with the help of open-source projects like Degrafa, Axiis, and Birdeye, and of course, APIs like the Google Maps API for Flash.

A few month ago, Xiaoxi Wu (also from China!) created the MarkerClusterer library for the Google Maps JavaScript API v2 and released it in their open source utility library. This library did automatic clustering of markers placed on a map, so that a large amount of markers wouldn’t overcrowd the map or overwhelm the user. This is a great technique for having a better performing map (see this talk for more tips on improving map performance), and the Flash map community immediately rushed to port the code to ActionScript. Developer Sean Toru posted the first port, a version that was only Flash-compatible, Ian Watkins modified that port to use Flex packages, and then I refactored the code to be more ActionScript-friendly and released it into the open-source library. It’s great when random strangers can collaborate together on a common code goal. :)

To see how the AS3 MarkerClusterer works, try out the demo (shown above). As you zoom and pan the map, you can witness how the markers are clustered and re-clustered. To learn how to use MarkerClusterer on your own map, view the source code of the demo. To use the library, check out the source code and import it into your project.

The current algorithm is quite simple, just clustering markers in a grid and using static images for the cluster markers. Future extensions could include support for regional clustering or using arbitrary DisplayObjects for the cluster markers. If you’re interested in extending the library, join the project.

Tags: , , , , , , , , , ,

12 Responses to “MarkerClusterer in an All New Flavor – ActionScript! (GoogleGeoDev)”

  1. Leo says:

    I tried to use MarkerClusterer with an xml with 8 thousand markers, but the time to read this markers it’s so much, and i have problems.. this is the code when i read the xml..


    public var marker:XML;
    public var markers:XMLList;

    private function map_onMapReady() : void
    {
    markers = misMarkers..marker;
    var markerClusterer : MarkerClusterer;
    var newLocation : LatLng;
    var marker_ : Marker_;
    var newCenter : LatLng;
    var i : Number;
    var marker_s : Array = new Array();

    // Will draw 500 randomly positioned markers
    for (i = 0; i

    <maps:Map id=”map”

    if you can help me i appreciate so much
    regards from chile

  2. nathaniel says:

    @ Leo: You need to create markers like normal for all your 8000 markers. But instead of adding them directly to the map at creation, store them into an array (marker_s). Then pass that array and the map to the MarkerClusterer object when you create it. Right now you’ve just declared the variable “markerClusterer” but haven’t said something like markerClusterer = new MarkerClusterer( map, marker_s);

  3. Leo says:

    oh, i’m sorry..
    part of the code was hidden..

    now i complete the code..

    private function map_onMapReady() : void
    {
    markers = misMarkers..marker;
    var markerClusterer : MarkerClusterer;
    var newLocation : LatLng;
    var marker_ : Marker_;
    var newCenter : LatLng;
    var i : Number;
    var marker_s : Array = new Array();

    for (i = 0; i < markers.length(); ++i) {
    marker = markers[i];
    newLocation = new LatLng(marker.@lat, marker.@lng);
    marker_ = new Marker_(newLocation);
    marker_s.push(marker_);
    }
    // Will now cluster them
    markerClusterer = new MarkerClusterer(map, marker_s);

    var centerPos : LatLng = new LatLng(-39, -72);
    map.setCenter(centerPos, 4);
    map.addControl(new ZoomControl);
    }

    with 1.500 markers it’s working, but not for 8.000 markers..

  4. Joshua Davis says:

    This no longer seems to work with Google’s Flex build 1.18.

    I ran my code and got an error. Then I copied and pasted your code and ran it and got the same error: “Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load Never Completed.”

    Please check it out and let me know.

    Thanks,
    Joshua

  5. Joshua Davis says:

    nevermind. sorry, i wasn’t downloading the images.

    good job on this by the way. thanks!

  6. Joshua Davis says:

    How do I set an icon for a custom *individual* marker – NOT marker cluster. I did it as outlined here: code.google.com/p/gmaps-samples-flash/source/browse/trunk/samplecode/IconSimple.mxml
    (with the exception of markers.push instead of map.addOverlay) and I get an error.

    Thanks.

  7. Joshua Davis says:

    nope. doesn’t work.

    let me clarify…the image gets added fine initially. however, on a drag, zoom, etc. (pretty much on a map redraw) I get the following error:

    ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/removeChild()
    at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::$removeChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5096]
    at mx.core::UIComponent/removeChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5004]
    at com.google.maps.wrappers::SpriteFactory/removeChild()
    at com.google.maps.wrappers::ISpriteFactoryWrapper/removeChild()
    at com.google.maps.overlays::Marker/renderMarker()
    at com.google.maps.overlays::Marker/redraw()
    at com.google.maps.overlays::Marker/onAddedToPane()
    at com.google.maps.overlays::Overlay/set pane()
    at com.google.maps.overlays::Pane/addOverlay()
    at com.google.maps.wrappers::IPaneWrapper/addOverlay()
    at Cluster/redraw()[C:\WebDocs\Flex\Flash Maps Test Project\src\com\google\maps\extras\markerclusterer\Cluster.as:232]
    at com.google.maps.extras.markerclusterer::MarkerClusterer/redraw_()[C:\WebDocs\Flex\Flash Maps Test Project\src\com\google\maps\extras\markerclusterer\MarkerClusterer.as:259]
    at com.google.maps.extras.markerclusterer::MarkerClusterer/resetViewport()[C:\WebDocs\Flex\Flash Maps Test Project\src\com\google\maps\extras\markerclusterer\MarkerClusterer.as:346]
    at com.google.maps.extras.markerclusterer::MarkerClusterer/mapMoved()[C:\WebDocs\Flex\Flash Maps Test Project\src\com\google\maps\extras\markerclusterer\MarkerClusterer.as:110]
    at ()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298]
    at com.google.maps.wrappers::BaseEventDispatcher/dispatchEvent()
    at com.google.maps.wrappers::EventDispatcherWrapper/dispatchEvent()
    at com.google.maps.core::MapImpl/configure()
    at com.google.maps.core::MapImpl/setCenter()
    at com.google.maps.core::MapImpl/zoomNoncontinuously()
    at com.google.maps.core::MapImpl/zoomIn()
    at com.google.maps.core::MapImpl/onDoubleClick()
    at com.google.maps.core::MapImpl/onMousePress()

  8. Daniel says:

    Dear XIAO Juguang,

    thank you very much for your great work. I’m now struggling to add an infowindow. Could you please help me do that? I would really appreciate it.

    Regards from Italy

    Daniel

  9. Sann says:

    Hallo Juguang,

    thanks for the great application. It helps me a lot, but I just cant figure out why it does not load the png’s.

    I added the required classes to my workspace, as well as the assets folder right in the same place. The project compiles and the markers cluster, but instead of the colourful, round cluster-icons I see simple white numbers on my map.

    Do you have an explanation?

    Regards

  10. hendra says:

    This nice artikel,.
    i ve question for google map v3,. im using markerclusterer, i want add keydragzoom but not working,.
    this sample my map http://gunkm.brinkster.net/test/
    ,..
    can you help me?
    or give me clue for that,..

    note: im already use map.enableKeyDragZoom({
    //hold ke “shift” for shortcut
    visualEnabled: true
    }); but not work.

    thanks, regards,..

  11. Marcelo says:

    I’m trying to integrate this API to my project, by I have problemas when I want to clear the markers. I ran the sample that is here, and it works fine, but when I clear the markers, they dissapear, but If I done any acion over the map (move or zoom), the markers appears again.
    I tried wth Flex 3 and Flex 4, and using the soure code of the api, not the swc file at revison 180.
    Any idea about my problem

    Thanks in advance

  12. herlina says:

    Dear Hendra,
    i’ve saw your example,
    and i have prombel to show marker from xml file as shown in your example,
    could you show me the way to create and solve my problem please?

    warm regards from indonesia,

    Herlina