2

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 enter image description here but when I try to use marker cluster the contents are no longer available. enter image description here 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>'
     }
});

.

3

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:

feature_onClick = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
    var features = feature.get('features');
    if (features) {
      return features[0];
    }
    return feature;
  });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.