I'm trying to create a map with marker cluster and popup using Openlayers 5.
I'm be able to show a popup on click as you can see below
but when I try to use marker cluster the contents are no longer available.
The popup's contents are handed out using a GeoJson serialized by GeoDjango.
Here the code of working solution:
var source_url = '{% url 'illegal_dump_geojson' %}'
var vectors = new ol.layer.Vector({
source: new ol.source.Vector({
url: source_url,
format: new ol.format.GeoJSON(),
}),
});
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectors,
],
view: new ol.View({
center: [0, 0],
zoom: 2
}),
overlays: [overlay],
});
var feature_onClick;
map.on('click', function(evt) {
feature_onClick = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
return feature;
});
if (feature_onClick) {
overlay.setPosition(evt.coordinate);
content.innerHTML =
'<h4 class="text-center"> Report n.'+ feature_onClick.getProperties().pk + '</h4>'
+ '<hr>'
+ '<p class="text-justify">' + feature_onClick.getProperties().description + '</p>'
+ '<p class="">' + feature_onClick.getProperties().volume_extension + ' mc</p>'
+ '<a class="btn btn-outline-warning" href="/geomonitor/illegal-dump/report-'+ feature_onClick.getProperties().pk + '/">Read more..</a>'
+ '<hr>'
+ '<p class="text-right py-0 my-0"><small class="text-muted"> posted by <strong>' + feature_onClick.getProperties().user_name + '</strong></small></p>'
+ '<p class="text-right py-0 my-0"><small class="text-muted"> at <em>' + feature_onClick.getProperties().publishing_date + '</em></small></p>'
}
});
This is the solution that didn't work:
var source_url = '{% url 'illegal_dump_geojson' %}'
var clusterSource = new ol.source.Cluster({
source: new ol.source.Vector({
url: source_url,
format: new ol.format.GeoJSON(),
}),
distance: 100,
});
var styleCache = {};
var vectors = new ol.layer.Vector({
source: clusterSource,
style: function(feature) {
var size = feature.get('features').length;
var style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 15,
stroke: new ol.style.Stroke({
color: 'rgba(200,200,200,1.0)',
width: 5,
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,1.0)'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#000'
})
})
});
styleCache[size] = style;
}
return style;
}
});
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectors,
],
view: new ol.View({
center: [0, 0],
zoom: 2
}),
overlays: [overlay],
});
var feature_onClick;
map.on('click', function(evt) {
feature_onClick = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
return feature;
});
if (feature_onClick) {
overlay.setPosition(evt.coordinate);
content.innerHTML =
'<h4 class="text-center"> Report n.'+ feature_onClick.getProperties().pk + '</h4>'
+ '<hr>'
+ '<p class="text-justify">' + feature_onClick.getProperties().description + '</p>'
+ '<p class="">' + feature_onClick.getProperties().volume_extension + ' mc</p>'
+ '<a class="btn btn-outline-warning" href="/geomonitor/illegal-dump/report-'+ feature_onClick.getProperties().pk + '/">Read more..</a>'
+ '<hr>'
+ '<p class="text-right py-0 my-0"><small class="text-muted"> posted by <strong>' + feature_onClick.getProperties().user_name + '</strong></small></p>'
+ '<p class="text-right py-0 my-0"><small class="text-muted"> at <em>' + feature_onClick.getProperties().publishing_date + '</em></small></p>'
}
});
.
Best Answer
A cluster is an auto-created and doesn't have those properties, instead it has an array of real features making up the cluster. This would return the first feature in the cluster if you clicked on one: