How to apply Cluster Source for Circle geom in openlayers?

190 Views Asked by At

I'm trying to apply clustering to circle features. Having read the documentation it seems that for anything different then a point a geometryFunction needs to be defined: my attempt looks like this:

var source = new ol.source.Vector({wrapX: false});

var clusterSource = new ol.source.Cluster({
    geometryFunction: function(feature){
        let circlePoint = new ol.geom.Point(feature.getGeometry().getCenter());
        return circlePoint;
    },
    distance: 0,
    source: source,
});

var vector = new ol.layer.Vector({
  source: clusterSource,
  style: function(feature, resolution) {
        var styles = [style1];
        if (feature.getGeometry().getType() == 'Circle') {
            style2.setGeometry(new ol.geom.Point(feature.getGeometry().getCenter()));
            style2.getImage().setScale(feature.getGeometry().getRadius() / (180 * resolution));
            styles.push(style2);
        }
        return styles;
    },
    updateWhileAnimating: true,
    visible: true

});

and an example feature I add:

circle = new ol.geom.Circle(ol.proj.transform([_lon, _lat], 'EPSG:4326', 'EPSG:3857'), 1);
feature=new ol.Feature({
geometry: circle
});

I tried this with 5000 circles with different distance argument for the cluster, and it shows them at first load then they disappear when I change zoom level. Any idea what I'm doing wrong?

Edit: styles used:

var style1 = new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(0, 255,0, 0.3)'
        }),
        stroke: new ol.style.Stroke({
            color: '#737373',
            width: 2
        })
    });
var style2 = new ol.style.Style({
        image: new ol.style.Icon({
            src: 'https://www.freeiconspng.com/uploads/photoshop-tree-top-view-png-3.png'
        })
    });
1

There are 1 best solutions below

1
On

Maybe a style function such as this, you would need to multiple the size of the cluster by a value appropriate to you application to get a radius

  style: function(feature, resolution) {
        var geometry;
        var features = feature.get('features');
        if (features) {
             // this is cluster
             if (features.length == 1) {
                 // cluster of 1, use that feature
                 geometry = features[0].getGeometry();
             } else {
                 // more than 1, use a circle based on size of the cluster
                 geometry = new ol.geom.Circle(feature.getGeometry().getCoordinates(), features.length * ???);
             }
        } else {
             // some other feature, not a cluster
             geometry = feature.getGeometry();
        }
        style1.setGeometry(geometry):
        var styles = [style1];
        if (geometry.getType() == 'Circle') {
            style2.setGeometry(new ol.geom.Point(geometry.getCenter()));
            style2.getImage().setScale(geometry.getRadius() / (180 * resolution));
            styles.push(style2);
        }
        return styles;
    },