1

I am trying to draw circle which colour depends on a "group" attribute in my geojson. I followed a simple example with these colours:

 map.addSource("data", {
    type: "geojson",
    data: url,
    cluster: true,
    clusterMaxZoom: 12, // Max zoom to cluster points on
    clusterRadius: 20 // Radius of each cluster when clustering points (defaults to 50)
});
map.addLayer({
        'id': 'population',
        'type': 'circle',
        'source': 'data',
        'paint': {
            // make circles larger as the user zooms from z12 to z22
            'circle-radius': {
                'base': 1.75,
                'stops': [[12, 2], [22, 180]]
            },
            // color circles by ethnicity, using a match expression
            // https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-match
            'circle-color': {
                'property': 'group',
                'type': 'categorical',
                stops: [
                ['1', 'rgba(252,141,98,0.5)'],
                ['2', 'rgba(141,160,203,0.5)'],
                ['3', 'rgba(141,160,203,0.5)'],
                ['4', 'rgba(141,160,203,0.5)'],
                ['5', 'rgba(141,160,203,0.5)'],
                ['6', 'rgba(141,160,203,0.5)'],
                //'4', '#3bb2d0',
                /* other 'rgba(102,194,165,0.1)'*/
                ]
            }
        }
    },'3d-buildings');

Now I would also like my clusters to follow some kind of colour-pattern. For instance, if the clusters contains a majority of group 1 then it does get the colour of group 1. Same for groupe 2 and so on.

But all I for the cluster points is black dots. I would very much like to know if there is a way to do better than that.

I have been following this example and updated it with the additional "type":"categorical" as required by the new versions of mapboxgl.

My data is a geojson that goes like this:

{"type": "FeatureCollection", "features": [{"id": 1, "type": "Feature", "properties": {"group":1}, "geometry": {"type": "Point", "coordinates": [17.8304903812012, 59.1886524824444]}}

Would anyone know how to achieve that with mapbox?

Edit:

Two images to show the problems that I currently have. The first image is basically my non-clustered visualization where you see two different colours based on the two groups.

The second image, is the clustered version, which only display black clusters. I would like for clusters with a majority of group 1 to be orange and for clusters with a majority of group 2 to be green.

Image 1, without clusters Image 2, rendering with clusters


Edit

Now I have also seen that I might have to do that with supercluster, but the only proper example that I have found is broken (stops working when we zoom too much and the points are always clustered). Also it seems that this is using old mapbox features that are now deprecated. Would someone know how to make this work easily on the provided example?

LBes
  • 3,366
  • 1
  • 32
  • 66
  • 1
    The first round of cluster-inspection methods was recently merged, so hopefully more are on the way. There's at least one discussion in mapbox-gl's Github issues about adding map-reduce stuff so clusters will have more properties than just `point_count`. As of right now, the PR is still a work in progress: https://github.com/mapbox/mapbox-gl-js/pull/7004 But it looks promising! – DMack Sep 19 '18 at 16:50
  • @DMack what about how you would achieve that with supercluster? I don't mind using that, I just can't find a lot of documentation or examples on that. – LBes Sep 19 '18 at 17:37
  • @stdob-- tagging you here as you might have done that previously or have an idea. – LBes Sep 19 '18 at 18:10
  • 1
    With Supercluster, you're able to define your own `initial`, `map`, and `reduce` functions to set the properties of the clusters. You could either do a "sum" as in [ryanbaumann's example](https://bl.ocks.org/ryanbaumann/01b2c7fc0ddb7b27f6a72217bd1461ad) or in [my related SO question](https://gis.stackexchange.com/a/263717/53293), and then you'd just need some logic in how you render it. If has the highest sum, make it red; otherwise make it blue, etc. Or you could look into figuring out the dominant property in the reducer itself. ("majority = ") – DMack Sep 20 '18 at 18:43
  • @DMack I tried using the example you mention, but as I mention in my question this example is broken (when you zoom in too much), so that's a first problem. And also it doesn't show how to stop the clustering when reaching a given level. It seems to work well enough for the data they have but it is not commented at all and makes it very difficult to understand when you're not familiar with the syntax and the concepts. How would you modify it to fix this example (which I agree can be helpful)? – LBes Sep 20 '18 at 19:03
  • How do you mean it breaks? It does appear to uncluster, but it's not obvious because a lot of the points are too close or even on top of each other so they'll never uncluster, even at max zoom. Supcluster takes a `clusterMaxZoom` value (same as Mapbox GL when you define a cluster source) that says "only do clustering up to this zoom level." In ryanbaumann's example, it's set to 14. Experiment with changing it to 9 and the effect should be more obvious. – DMack Sep 21 '18 at 17:28
  • @DMack I mean that if you zoom to a very high level then the example is broken. You can't zoom out, you're just stuck at your current zoom level. – LBes Sep 21 '18 at 17:29
  • Oh, I see that now. You can still zoom back out with the minus key on your keyboard, but something throws a fatal error if you zoom too close. That's a bug in the implementation of that example, probably in the 'zoom' event handler, it shouldn't prevent you from using it as a starting point for your own implementation though! – DMack Sep 21 '18 at 17:45
  • @DMack ok thanks for that. Well the thing that the example is not commented at all, so starting with that is kind of complicated but I’ll give it an other try. – LBes Sep 21 '18 at 18:58
  • @DMack the problem in the example doesn't seem to come from the zoom itself, but rather from the fact that this line "chroma.limits(getFeatureDomain(clusterData, select_value), 'e', 8)" doesn't return a proper domain of stops (i.e., the object doesn't exist as I get a cannot read property length of undefined). So there must be a problem with the clustering too. – LBes Sep 24 '18 at 09:40
  • All the examples I've found so far use the Mapbox map.addSource function. Am I correct that this function only takes a URL as the data source? Our data is dynamic, so there is no URL to use. Is there any example of clustering (using supercluster or whatever else) using dynamically constructed Markers instead? – Marc Oct 18 '18 at 19:36
  • @Marc you should ask a separate question, your comment here brings nothing – LBes Oct 19 '18 at 12:02

0 Answers0