ngx-openlayers
ngx-openlayers copied to clipboard
Getting each clustered group's number of features
Following the cluster example I have a question. How do I get the number of features within each layer, so I can show them? (Currently the demo shows a static number)
Thanks @gamesgil, same issue here, there is no way to retrieve the number of clustered elements
Demo link https://github.com/quentin-ol/ngx-openlayers/blob/master/example/src/app/cluster/cluster.component.html
So, using javascript based on an example of open layers (so skipping the template part ...) https://openlayers.org/en/latest/examples/cluster.html
// template.html
<aol-map #map>
Using ngAfterviewInit hook
import * as ol from 'openlayers';
[...]
@ViewChild('map') _map: ElementRef;
[...]
get map() {
return this._map['instance'];
}
[...]
ngAfterViewInit() {
this.initClusters();
}
[...]
public transformToCoordinates(longitude, latitude) {
const toReturn = ol.proj.transform(
[longitude, latitude],
'EPSG:4326',
'EPSG:3857'
);
return toReturn;
}
[...]
initClusters() {
const features = new Array();
for (const marker of this.deviceMarkers) {
features.push(
new ol.Feature(new ol.geom.Point(
transformToCoordinates(
marker.longitude,
marker.latitude)
)
)
);
}
const source = new ol.source.Vector({
features: features
});
const clusterSource = new ol.source.Cluster({
distance: this.distance,
source: source
});
const styleCache = {};
const clusters = new ol.layer.Vector({
source: clusterSource,
style: function (feature) {
const size = feature.get('features').length;
let style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
});
styleCache[size] = style;
}
return style;
}
});
this.map.addLayer(clusters);
}
Et voilà !
Should be fine, but it would be better if we can achieve this through templating :) Please make it happen :+1:
I tried to do it when I made this example.
// template.html
<aol-layer-vector #layer>
@ViewChild('layer') layer;
ngAfterViewInit() {
// Tricks to update style
const layerStyle: style.Style = this.layer.instance.getStyle();
this.layer.instance.setStyle(function (feature) {
let local = layerStyle.clone();
const nb = feature.get('features').length;
// Set new image when display initial point
if (nb === 1) {
local.setImage(new style.Circle({
radius: 12,
stroke: new style.Stroke({color: '#fff'}),
fill: new style.Fill({color: 'red'})
}));
}
// Display number og point in cluster
local.getText().setText(nb.toString());
return local;
});
}
But it's still javascript, I did not succeed through the templates. My reviewer advised me not to remove it.
For now, the lib doesn't support this through the template. This could be a great improvement to be done with a PR 🤩
But, we should keep the template API as close as possible to the original API of OpenLayers. This is the mindset of ngx-openlayers
🚀
Thanks
@davinkevin I'm thinking on sending a PR with the following simple change:
export class LayerVectorComponent extends LayerComponent implements OnInit, OnDestroy, OnChanges {
public source: source.Vector;
@Input() renderBuffer: number;
constructor(map: MapComponent,
@Optional() group?: LayerGroupComponent,
@Optional() style: (style.Style | style.Style[] | StyleFunction)) {
super(group || map);
}
I think it will allow setting a style function and it adheres to the OpenLayers API as much as I can see. Am I missing something? Seems too simple...
Also would be extremely nice to get this animated. I found this code that should handle animation, but it's not part of the official OpenLayers library and it seems to use JQuery... :-/ https://github.com/Viglino/ol-ext/blob/master/src/layer/AnimatedCluster.js Would be nice to have part of this here, I'm still new to OpenLayers so it's a bit too much for me right now...
Actually you don't need to use jQuery, just using open layer api
public flyToFeature(feature, clusterMode, map) {
const animateObj = {
center: feature.getGeometry().getCoordinates(),
duration: 500,
zoom: undefined
};
if (clusterMode) {
animateObj.zoom = 18;
}
map.getView().animate(animateObj);
}
Le mer. 26 sept. 2018 à 22:36, Harel M [email protected] a écrit :
Also would be extremely nice to get this animated. I found this code that should handle animation, but it's not part of the official OpenLayers library and it seems to use JQuery... :-/ https://github.com/Viglino/ol-ext/blob/master/src/layer/AnimatedCluster.js Would be nice to have part of this here, I'm still new to OpenLayers so it's a bit too much for me right now...
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/quentin-ol/ngx-openlayers/issues/186#issuecomment-424860895, or mute the thread https://github.com/notifications/unsubscribe-auth/AFx1F3K2pMZIVhiq-3cX3JOskY9CAqlHks5ue-VRgaJpZM4V_qEU .
@veakey does this animate the clusters as well? seems like it will only animate the view, but I might me missing something.
The linked library uses JQuery, it might be that the specific class that I referenced does not.
I'll be happy to do some pull requests once I get everything working on my site using this library, assuming this is some thing that this library should have (the cluster animation).
Regarding the @Input() style: (style.Style | style.Style[] | StyleFunction))
I can do a pull request in no time, but I need to know that this is the right direction first.
@HarelM, the only animation it does is the zoom effect until you reach a point which is not at cluster level ^^
I am speaking about this kind of animation https://developers.google.com/maps/documentation/javascript/marker-clustering
Hope it helps :)
Nope, I was hoping something like the following: http://viglino.github.io/ol-ext/examples/animation/map.animatedcluster.html