openlayersopenlayers-6

How to cluster different types of geometry in openlayers 6?


I need to cluster some features that have different types of geometry (Point, LineString and Polygon), which is the best way to do that? In addition, when I zoom to a single feature which is the best way to use the appropriate style of the feature itself (say Polygon if polygon and etc...)


Solution

  • The cluster source must have a geometry function to handle non-point features. The most basic would be to return a point at the center of the extent

    geometryFunction: functionfunction(feature) {
      return new Point(getCenter(feature.getGeometry().getExtent()));
    }
    

    You could also use the label points (the midpoints of linestrings and the interior points of polygons). For styling the style function should style as a cluster if the cluster contains multiple features, but if it contains a single feature style for the geometry of that feature

    var clusterLayer = new Vectorlayer({
        source: new ClusterSource({
            distance: distance,
            source: vectorSource,
            geometryFunction: function (feature) {
                var geometry = feature.getGeometry();
                var type = geometry.getType();
                if (type == 'Point') {
                    return geometry;
                    if (type == 'LineString') {
                        return new Point(geometry.getCoordinateAt(0.5));
                    } else if (type == 'Polygon') {
                        return geometry.getInteriorPoint();
                    } else {
                        return new Point(getCenter(feature.getGeometry().getExtent()));
                    }
                }
            },
            style: function (feature) {
                var features = feature.get('features');
                if (features.length > 1) {
                    return clusterStyle;
                } else {
                    defaultStyles.setGeometry(features[0].getGeometry());
                    return defaultStyles;
                }
            },
        }),
    });