1

I have a geojson and use openlayers to show features on a map. I cluster them. Now I want to add a filter to the UI, allowing users to filter the map depending on some feature properties.

      const vectorSource = new VectorSource({
        format: new GeoJSON(),
        url: this.dataSourceUrl,
      })

      const clusterSource = new Cluster({
        distance: 30,
        minDistance: 1,
        source: vectorSource,
        geometryFunction: (feature) => {
          if (feature.get('poles') < this.filter) {
            return feature.getGeometry()
          } else {
            return null
          }
        },
      })

      const styleCache = {}
      const clusterLayer = new VectorLayer({
        source: clusterSource,
        style: (feature) => {
          const size = feature.get('features')?.length
          let style = styleCache[size]
          if (!style) {
            style = new Style({
              image: new CircleStyle({
                radius: 10,
                stroke: new Stroke({
                  color: '#fff',
                }),
                fill: new Fill({
                  color: '#3399CC',
                }),
              }),
              text: new Text({
                text: size.toString(),
                fill: new Fill({
                  color: '#fff',
                }),
              }),
            })
            styleCache[size] = style
          }
          return style
        },
      })

      this.map.addLayer(clusterLayer)

whereas this.filter is just a number for now. If I update that filter, I want to redraw the clusters, but so far I am not successful.

First I thought I could use the changed() method of Cluster: https://openlayers.org/en/latest/apidoc/module-ol_source_Cluster-Cluster.html#changed

but it has no effect.

I found out how I can clear the clusters.

clusterSource.getSource().clear()

but that is really all. How can I update the clusters, now showing more or less feature points?

Thank you so much for your input!

Merc
  • 4,241
  • 8
  • 52
  • 81

1 Answers1

2

You need to refresh the cluster source

clusterSource.refresh()

https://codesandbox.io/s/cluster-forked-u3pywq?file=/main.js

Mike
  • 16,042
  • 2
  • 14
  • 30
  • aaaand it's so easy... :) – Merc Mar 23 '23 at 09:35
  • `clusterSource.getSource().changed()` works as well. Is there any advantage or disadvantage between the two? – Merc Mar 23 '23 at 12:55
  • 1
    If you check the source https://github.com/openlayers/openlayers/blob/main/src/ol/source/Cluster.js a change event on the internal source triggers a refresh, as can calling setDistance, setMinDistance or setSource when they change something. If all that is needed is a refresh it is slightly more efficient to call it directly. – Mike Mar 23 '23 at 13:56