1

Can anyone suggest how to implement a feature similar to Count Overlapping Features (https://pro.arcgis.com/en/pro-app/latest/tool-reference/analysis/count-overlapping-features.htm), but on JavaScript? Picture of an example from the article.

I have some number of polygons (about 100). I would like to get all areas of polygon overlay and their number.

As tools used: OpenLayers, turf (or jsts).

Example image:

For example, this option only makes me understand that all my polygons have some kind of intersection / overlap:

allPoly.forEach(poly1 => {
        poly1.properties.overlap = 0;    
        allPoly.forEach(poly2 => {
            let isIntersects = turf.intersect(poly1, poly2);
            if (isIntersects) {
                poly1.properties.overlap++;
            }
        })
    })

1 Answer 1

1

Instead of simply counting intersects you would need to create new features using the results of intersect and difference operations, successively working through the features and applying further intersect and difference operations to the results already obtained, keeping a count of the intersections involved in each part. Best illustrated by drawing new features to a source, otherwise you would need separate sources for the origin features and the results.

const source = new VectorSource({wrapX: false});

const style = new Style({
  stroke: new Stroke({
    color: 'blue',
    width: 2,
  }),
  text: new Text({
    font: 'bold 12px "Open Sans", "Arial Unicode MS", "sans-serif"',
    fill: new Fill({
      color: 'back',
    }),
  }),
});

const vector = new VectorLayer({
  source: source,
  style: (f) => {
    style.getText().setText(f.get('intersects').toString());
    return style;
  },
});

const draw = new Draw({
  source: source,
  type: 'Circle',
});
map.addInteraction(draw);

const format = new GeoJSON();

draw.on('drawend', (e) => {
  e.feature.setGeometry(fromCircle(e.feature.getGeometry()));
  let newFeature = format.writeFeatureObject(e.feature);
  const diffs = [];
  source.getFeatures().forEach((f) => {
    if (!f.getGeometry()) {
      return;
    }
    const intersects = f.get('intersects');
    const feature = format.writeFeatureObject(f);
    let intersect = turf.intersect(feature, newFeature);
    if (intersect) {
      intersect = format.readFeature(intersect);
      intersect.set('intersects', intersects + 1);
    }
    let diff1 = turf.difference(feature, newFeature);
    if (diff1) {
      diff1 = format.readFeature(diff1);
      diff1.set('intersects', intersects);
    }
    if (intersect) {
      source.removeFeature(f);
      source.addFeature(intersect);
      if (diff1) {
        source.addFeature(diff1);
      }
    }
    let diff2 = turf.difference(newFeature, feature);
    diffs.push(diff2);
  });
  diffs.forEach((d) => {
    newFeature = newFeature && d ? turf.intersect(newFeature, d) : null;
  });
  if (newFeature) {
    newFeature = format.readFeature(newFeature);
    e.feature.setGeometry(newFeature.getGeometry());
    e.feature.set('intersects', 1);
  } else {
    e.feature.setGeometry();
  }
});

https://codesandbox.io/s/draw-features-forked-mfuetc?file=/main.js

4
  • I added some relevant code from CodeSandbox example.
    – TomazicM
    Mar 7, 2023 at 15:55
  • @Mike, thank you! This looks very interesting. I'll try to adapt this option to my data.
    – luzhskij
    Mar 9, 2023 at 7:37
  • @TomazicM, thanks for the CodeSandbox example.
    – luzhskij
    Mar 9, 2023 at 7:38
  • @luzhskij CodeSandbox example is Mike's work, I just added part of the code to the answer.
    – TomazicM
    Mar 9, 2023 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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