Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clustering custom html markers with mapbox-gl-js

I'm using the mapbox-gl-js API and I'm using it with react to create some custom markers as follows:

        let div = document.createElement('div');
        let marker = new mapboxgl.Marker(div, {
            offset: [ -20, 80 ]
        });

        marker.setLngLat(person.geometry.coordinates);

        render(
            <MapPersonIcon />,
            div,
            () => {
                marker.addTo(map);
            }
        );

result

This worked great. However I would now like to cluster these markers, producing the same affect as the functionality found with layers i.e.

https://www.mapbox.com/mapbox-gl-js/example/cluster/

clusters

Does anyone know whether this is possible (hopefully with custom clusters too) or whether it will be available in an upcoming release?

like image 835
Huw Davies Avatar asked Aug 17 '16 16:08

Huw Davies


People also ask

How do I add multiple markers to Mapbox?

To add multiple markers, or to add markers to interactive web or mobile maps, you generally must provide point data in GeoJSON format or in a vector tileset. You can add data to a map style before runtime by using the Mapbox Studio style editor to add a vector tileset as a source for a layer in a map style.

How do I add points to Mapbox?

Draw a new feature. Click inside the Search places field in the upper right side of the editor and search for Garfield Park Chicago . Use the draw tool to create a new point on the map at that location. Next, click the Add Property button.


2 Answers

This feature is now in Mapbox GL js - https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/

Key takeaways:

When setting your data source using map.addSource, make sure you define cluster: true and clusterRadius: int, like so:

        map.addSource( 'sourceName', {
            type: "geojson",
            data: {
                type: 'FeatureCollection',
                features: [JSON]
            },
            cluster: true,
            clusterRadius: 80,
        });

That will push mapbox to cluster your icons, but you need to tell mapbox what to do when it clusters those icons:

map.on( 'moveend', updateMarkers ); // moveend also considers zoomend

The business (trimmed down for relevance):

function updateMarkers(){
    var features = map.querySourceFeatures( 'sourceName' );

    for ( var i = 0; i < features.length; i++ ) {
        var coords = features[ i ].geometry.coordinates;
        var props = features[ i ].properties;

        if ( props.cluster ){ // this property is only present when the feature is clustered
            // generate your clustered icon using props.point_count
            var el = document.createElement( 'div' );
            el.classList.add( 'mapCluster' );
            el.innerText = props.point_count;
            marker = new mapboxgl.Marker( { element: el } ).setLngLat( coords );

        } else { // feature is not clustered, create an icon for it
            var el = new Image();
            el.src = 'icon.png';
            el.classList.add( 'mapMarker' );
            el.dataset.type = props.type; // you can use custom data if you have assigned it in the GeoJSON data
            marker = new mapboxgl.Marker( { element: el } ).setLngLat( coords );
        }

        marker.addTo( map );
    }

NOTE: Don't copy paste this code, rather use it in conjunction with https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/ to get the whole picture. Hope this helps!

like image 113
Abraham Brookes Avatar answered Oct 25 '22 12:10

Abraham Brookes


Answering own question:

At current it seems that this isn't possible as per mapbox's github: enter image description here

If you would like to cluster your markers you will need to use mapbox's native maki icons (please see above example picture & URL) until a plugin is available for your custom HTML markers.

like image 21
Huw Davies Avatar answered Oct 25 '22 14:10

Huw Davies