0

I have a cluster layer which contains circles. Each circle contains some number of features. I need to get the smallest bounding box for a circle when it's clicked. If I could get the center and radius of each circle onclick, that would solve my problem too, but I can't seem to find an obvious way to do that.

How can I get a bounding box for an element in a cluster layer, or the center and radius of that element?

Here's my cluster layer.

  var clusterLayer = new ol.layer.Vector({
    id: 'clusterLayer',
    source: clusterSource,
    style: function addClusterStyle(feature) {
      var size = feature.get('features').length;
      var pointRadius = 8 + (size.toString().length * 2);
      var style = styleCache[size];
      if (!style) {
        style = [
          new ol.style.Style({
            image: new ol.style.Circle({
              radius: pointRadius,
              stroke: new ol.style.Stroke({
                color: '#ff0000'
              }),
              fill: new ol.style.Fill({
                color: '#ffb3b3'
              })
            }),
            text: new ol.style.Text({
              text: size.toString(),
              font: 'bold 12px arial,sans-serif',
              fill: new ol.style.Fill({
                color: 'black'
              })
            })
          })
        ];
        styleCache[size] = style;
      }
      map.removeInteraction(draw);
      return style;
    }
0

I found a way to get a bounding box around the features within the circle on cluster layer rather than a bounding box around the circle itself. I have access to the features within the circle so I can use the following:

var cFeatures = popupfeature.feature.get('features');

// if there are more than 4 items in the map pin, include a link to view all of them
if (cFeatures.length > 4) {
    // get the coordinates of all features in the cluster
    var featureCoords = cFeatures.map(x => x.getGeometry().getCoordinates());

    // get the min and max coordinates
    var maxX = featureCoords.map(x => x[0]).reduce(function(a, b) {
        return Math.max(a, b);
    });
    var maxY = featureCoords.map(x => x[1]).reduce(function(a, b) {
        return Math.max(a, b);
    });
    var minX = featureCoords.map(x => x[0]).reduce(function(a, b) {
        return Math.min(a, b);
    });
    var minY = featureCoords.map(x => x[1]).reduce(function(a, b) {
        return Math.min(a, b);
    });

    // convert to lat long
    var minCoord = ol.proj.transform([minX, minY], dstProj, srcProj);
    var maxCoord = ol.proj.transform([maxX, maxY], dstProj, srcProj);

    var textToRest = "See all " + cFeatures.length;
    var linkToRest = textToRest.link(homeURL + 'search/Results?type=AllFields&filter[]=long_lat:Intersects(ENVELOPE(' + [minCoord[0], maxCoord[0], maxCoord[1], minCoord[1]].join(",%20") + '))');
    // open link in new tab (inster targe=_blank after <a)
    linkToRest = linkToRest.slice(0,2) + " target='_blank' " + linkToRest.slice(2);
    pcontent += linkToRest;
}

While this does work, it doesn't always create an even square around the cluster. It is also quite inefficient for larger clusters since I iterate over every feature in the cluster.

Is there a more efficient way to do this? Or a way to make sure the bounding box is around the cluster rather than the items within the cluster?

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.