turf.js Intersect Error for Self-intersecting Poly

2019-09-06 03:47发布

I am using OpenLayers3 ol.interaction.Draw to let the user draw a shape on the map, either by clicking vertices or by Shift+Drag to draw a freeform polygon (this is important to my application). Once a shape is drawn, I use turf.js to compare the drawn shape to a WFS layer in the client, running intersect() to see if the WFS features intersect the drawn shape. However, if the hand drawn shape has even the slightest self-intersection, the turf.js intersect() function fails with the following error (Line 326 is where I call intersect()).

turf.min.js:9 Uncaught [object Object]
getResultGeometry @ turf.min.js:9
si.overlayOp @ turf.min.js:9
intersection @ turf.min.js:15
e.exports @ turf.min.js:16
(anonymous function) @ main.js:326

Follows is a sketch of my code.

var features = new ol.Collection();

var vs = new ol.source.Vector({
  format: new ol.format.GeoJSON(),
  url: function(extent) {
    return XXXXXX;
  },
  strategy: ol.loadingstrategy.bbox
});

features.on('add', function() {
  vs.forEachFeatureIntersectingExtent(extent, function(feature) {
    // use to turf.js to intersect each feature with drawn feature
    var bt = gjformat.writeFeatureObject(feature, {rightHanded: false});
    var dt = gjformat.writeFeatureObject(features.item(0), {rightHanded: false} );

    var intersection = turf.intersect(bt, dt);
  }
});

I have tried to use both turf.js simplify() and ol.geom.Geometry.simplify() to no avail. Does anyone have any suggestions for getting turf.js intersect() to handle the hand-drawn self-intersecting polygons? Or a way to remove the self-intersections before running the intersection?

2条回答
Deceive 欺骗
2楼-- · 2019-09-06 04:06

You can at least warn the user about self-intersections. These can be detected with JSTS. See Google Maps Polygons self intersecting detection. Removing self-intersections is harder, but it should also be possible with JSTS: Using JSTS buffer to identify a self-intersecting polygon.

查看更多
▲ chillily
3楼-- · 2019-09-06 04:12

Inspired by the answer to Using JSTS buffer to identify a self-intersecting polygon (thanks for the lead, @ahocevar), I ported the solution to turf.js. Buffering the drawn feature with self-intersections by 0 removes the smaller, self-intersected polygons and leaves you with a clean feature for running through intersect().

    features.on('add', function() {
      vs.forEachFeatureIntersectingExtent(extent, function(feature) {
        // create geojson of wfs features and drawn feature
        var bt = gjformat.writeFeatureObject(feature, {rightHanded: false});
        var dt = gjformat.writeFeatureObject(features.item(0), {rightHanded: false} );

        // check for kinks in the drawn feature
        var kinks = turf.kinks(dt);
        var dtf;

        if(kinks.features.length > 0) {
          // if there are self-intersections, buffer by 0 to get rid of them
          dtf = turf.buffer(dt, 0, 'meters');
        } else {
          // if there are no self-intersection, intersect by unbuffered features
          dtf = dt; 
        }

        var intersection = turf.intersect(bt, dtf);
      }
    });
查看更多
登录 后发表回答