15

I'm POC-ing clusters with Mabpox-gl-js v0.45.

I would like to customize my cluster's properties (actual default values are point_count and point_count_abbreviated). Each of my points (one for each city) have a surface property (an integer) which I want to sum when points are clustered.

I see in mapbox's sources a reference to a reduce function to calculate custom properties:

SuperCluster.prototype = {
    options: {
        minZoom: 0,   // min zoom to generate clusters on
        // .....
        log: false,   // whether to log timing info

        // a reduce function for calculating custom cluster properties
        reduce: null, // function (accumulated, props) { accumulated.sum += props.sum; }

        // initial properties of a cluster (before running the reducer)
        initial: function () { return {}; }, // function () { return {sum: 0}; },

        // properties to use for individual points when running the reducer
        map: function (props) { return props; } // function (props) { return {sum: props.my_value}; },
    },

But I don't see any mention about it on the documentation. How can I set these options?

Mapbox seems not to publish these interface (see cluster's documentation) and no mention are done on provided exemple:

map.addSource("earthquakes", {
    type: "geojson",
    // Point to GeoJSON data. This example visualizes all M1.0+ earthquakes
    // from 12/22/15 to 1/21/16 as logged by USGS' Earthquake hazards program.
    data: "/mapbox-gl-js/assets/earthquakes.geojson",
    cluster: true,
    clusterMaxZoom: 14, // Max zoom to cluster points on
    clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
});
Fractaliste
  • 5,777
  • 11
  • 42
  • 86

2 Answers2

3

Someone gave me a workaround : do not use the embedded supecluster, but create your own and use it as a source :

var myCluster = supercluster({
    radius: 40,
    maxZoom: 16,
    reduce: function(p) { /* I can use reduce/map/... functions! */ }
});

// My clustered source is created without Mapbox's clusters since I managed my clusters outside Mapbox library.
map.addSource("earthquakes", {
    type: "geojson",
    data : {
      "type" : "FeatureCollection",
      "features" : []
    }
});

function loadRemoteGeoJson() {
    var features
    // Do what you want, when you want to retrieve remote features...
    // ...
    // In the end set features into your supercluster
    myCluster.load(features)
    pushClusterIntoMapbox(map)
}

// Function to call when you load remote data AND when you zoom in or out !
function pushClusterIntoMapbox(map) {
  // I maybe should be bounded here...
  var clusters = myCluster.getClusters([ -180.0000, -90.0000, 180.0000, 90.0000 ], Math
      .floor(map.getZoom()))

  // My colleague advice me to use http://turfjs.org as helper but I think it's quite optionnal
  var features = turf.featureCollection(clusters)
  map.getSource("earthquakes").setData(features)
}
Fractaliste
  • 5,777
  • 11
  • 42
  • 86
  • This looks interesting. I'm having a hard time figuring out how to implement it with a simple geojson example though. I just asked a related question with a dataset, if you have time to take a look: https://stackoverflow.com/questions/51937339/mapbox-clusters-data-driven-styling – Lucien S. Aug 20 '18 at 20:15
  • Mapbox still doesn't integrate supercluster so that we can do it with Mapbox only. I also would like to use supercluster but the only example I can find of the map/reduce functions is broken (when zooming in) and doesn't include comments so it's a bit hard to understand. It also doesn't show unclustered points at all when the zoom level is high enough. I have mentioned all of this in a new question. Would you mind taking a look: https://stackoverflow.com/questions/52359737/data-driven-cluster-colour-with-mapboxgl?noredirect=1#comment91840406_52359737 – LBes Sep 24 '18 at 09:16
0

It looks as if it works like a regular reduce. It will be called one for each point, and allows you to use the properties of the point to create properties for the cluster overall.

So if you define your reduce like this;

supercluster({
  reduce: (clusterProps, pointProps) => {
    clusterProps.sum += pointProps.surface;
  }
});

Then the sum property on the cluster will be the sum of all the surface properties on the points.

Jivings
  • 22,834
  • 6
  • 60
  • 101
  • I'was maybe quite unclear on my question, I wonder how can I set these methods which seems not to be exposed to users by Mapbox's API. – Fractaliste Jun 04 '18 at 06:07