I am working with OpenLayers angular dependency, actually, I'm uing v4.1.1 and, at current' I can't update it to the latest version.
I have a map with an ol.source.Cluster. It clusterizes all my ol.layer.Vector layers, which are composed by pushpin features, similar to this example.
The features in my application can be selected by the user. This action highlights the single specified feature and zooms the map in to the feature in order to let user know which one is selected. My problem arises when the feature is clusterized; I would like that the feature could be rendered outside the cluster, and that it could be added again to a cluster when it is unselected. Is this possible easily? I have read the documentation of the involved classes, ol.source.Cluster and ol.source.Vector (I know they are v4.6.5 but I didn't find the v4.1.1) and perhaps I'm skipping something or maybe you know a way to do this.
I have tried two solutions, but I don't like very much:
- Modify
distanceproperty of the cluster, setting it to 0. By this way, clusterizing is disabled and all features are displayed individually. This is not the best approach becuase user can zoom out the map and there could be too many pushpins on the map. Even if I handle the zoom level and I enable the cluster feature when zoom is too low, the selected pushpin would be clustered as well, and it's not the desired behavior. To use an auxiliar layer and represent the selected pushpin there. This layer would contain on its source just one feature, the selected one, and it would be removed once it is unselected. I have to admit that I've not implemented yet this example because it is a little complex (I would have to handle also the visibility of this layer along of the cluster layers and so on) and I have not much time to do the POC.
UPDATE: I just reached to set a
geometryFunctionin the cluster source options that filters the pushpins and just clusters those that are not selected. The problem is that the selected one are not rendered, and because of that I need the auxiliar layer in order to pass to it the selected feature to be represented:
let clusterSource = new ol.source.Cluster({
distance: 40,
source: vectorSource,
geometryFunction: (feature) => {
if (feature.get('selected')) {
return null;
}
return feature.getGeometry() as ol.geom.Point;
}
});
So, to sum up, is there a way to remove a feature from a cluster and represent it individually along with the clusters?
geometryFunctionin the cluster source options and return null for features which have been selected - MikegeometryFunctionrendered a single feature, out of a cluster, when it returns null, it would solve my issue. But when it returns null,openlayersbehavior is just to not render any object in the map. - christiansr85vectorSourcedirectly and have a style function which only returns a style whenfeature.get('selected')is true, so you would not need to maintain a source specifically for selected features. - MikevectorSourcein the aux layer, but I still think that I need to manage it together with the main one, because of the required functionality. Anyway, I've done a little POC and don't seems to be much painful as I thought. So if I don't find a better solution, I will answer this post with the second approach related in the question. - christiansr85