React-mapbox-gl: Cluster a GeoJSON Source component

Created on 4 Aug 2017  路  2Comments  路  Source: alex3165/react-mapbox-gl

Is it possible to generate clusters / grouping from a <Source> component, like this example by the official mapbox documentation? https://www.mapbox.com/mapbox-gl-js/example/cluster/

I can only figure out how to make clusters using <Marker> and <Cluster>

Is there a way I can pass cluster, clusterMaxZoom and clusterRadius to a <Source> component.
I know that <Layer> has a layerOptions prop, that will be passed directly to the component, is there a way I do the same with <Source>, like the example below?

<Source cluster={true} clusterMaxZoom={14} clusterRadius={50} />

This is what I have so far (without clustering)

return (
      <div>
        <Source
          id='spots_source'
          geoJsonSource={{
            type: 'geojson',
            data: this.props.spots
          }}
          circlePaint={{
            'circle-color': 'green',
            'circle-radius': 10
          }} />
        <Layer
          id='spots_layer'
          sourceId='spots_source'
          paint={{
            'circle-color': 'green',
            'circle-radius': 10
          }}
          type='circle' />
      </div>
    )

Most helpful comment

Thank you for your response @alex3165 , I managed to get it to work, but I had to change <Source> to <GeoJSONLayer>, because <Source> doesn't have a sourceOptions prop. I don't know if there is any reason for that?

Nevermind, it isn't a problem in my case, because the source is already formatted as GeoJSON.
This is what I came up with.

return (
  <div>
    <GeoJSONLayer
      id='source_id'
      data={this.props.geoJson}
      sourceOptions={{
        cluster: true,
        clusterMaxZoom: 14,
        clusterRadius: 50
      }}
    />
    // Layer of clustered spots
    <Layer
      id='cluster_layer'
      sourceId='source_id'
      layerOptions={{
        filter: [
          'has', 'point_count'
        ]
      }}
      paint={{
        'circle-color': {
          property: 'point_count',
          type: 'interval',
          stops: [
            [0, '#51bbd6'],
            [100, '#f1f075'],
            [750, '#f28cb1']
          ]
        },
        'circle-radius': {
          property: 'point_count',
          type: 'interval',
          stops: [
            [0, 20],
            [100, 30],
            [750, 40]
          ]
        }
      }}
      type='circle'
    />
    // Layer of unclustered spots
    <Layer
      id='unclustered_layer'
      sourceId='source_id'
      layerOptions={{
        filter: [
          '!has', 'point_count'
        ]
      }}
      paint={{
        'circle-color': 'green',
        'circle-radius': 10
      }}
      type='circle' />
  </div>
)

All 2 comments

Hey @viktorstrate, you can cluster Source and Layer components yes, you will need to play with layerOptions and sourceOptions props to match the implementation of this example on MapboxGL assuming that each addLayer is a new Layer component. Don't hesitate to share your implementation I can help you if needed too.

Thank you for your response @alex3165 , I managed to get it to work, but I had to change <Source> to <GeoJSONLayer>, because <Source> doesn't have a sourceOptions prop. I don't know if there is any reason for that?

Nevermind, it isn't a problem in my case, because the source is already formatted as GeoJSON.
This is what I came up with.

return (
  <div>
    <GeoJSONLayer
      id='source_id'
      data={this.props.geoJson}
      sourceOptions={{
        cluster: true,
        clusterMaxZoom: 14,
        clusterRadius: 50
      }}
    />
    // Layer of clustered spots
    <Layer
      id='cluster_layer'
      sourceId='source_id'
      layerOptions={{
        filter: [
          'has', 'point_count'
        ]
      }}
      paint={{
        'circle-color': {
          property: 'point_count',
          type: 'interval',
          stops: [
            [0, '#51bbd6'],
            [100, '#f1f075'],
            [750, '#f28cb1']
          ]
        },
        'circle-radius': {
          property: 'point_count',
          type: 'interval',
          stops: [
            [0, 20],
            [100, 30],
            [750, 40]
          ]
        }
      }}
      type='circle'
    />
    // Layer of unclustered spots
    <Layer
      id='unclustered_layer'
      sourceId='source_id'
      layerOptions={{
        filter: [
          '!has', 'point_count'
        ]
      }}
      paint={{
        'circle-color': 'green',
        'circle-radius': 10
      }}
      type='circle' />
  </div>
)
Was this page helpful?
0 / 5 - 0 ratings