Ошибка пересечения turf.js для самопересекающихся полигонов из OpenLayers3 Draw

Я использую OpenLayers3 ol.interaction.Draw, чтобы позволить пользователю рисовать фигуру на карте, либо щелкая вершины, либо Shift+Drag, чтобы нарисовать многоугольник произвольной формы (это важно для моего приложения). После того, как фигура нарисована, я использую turf.js для сравнения нарисованной фигуры со слоем WFS в клиенте, запуская intersect(), чтобы увидеть, пересекаются ли объекты WFS с нарисованной фигурой. Однако, если нарисованная от руки фигура имеет хотя бы малейшее самопересечение, функция intersect() turf.js завершается со следующей ошибкой (в строке 326 я вызываю intersect()).

turf.min.js:9 Uncaught [object Object]
getResultGeometry @ turf.min.js:9
si.overlayOp @ turf.min.js:9
пересечение @ turf.min.js:15
e.exports @ turf.min.js:16
(анонимная функция) @ main.js:326

Ниже приведен набросок моего кода.

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);
  }
});

Я пытался использовать оба turf.js simplify() и ol.geom.Geometry.simplify() безрезультатно. Есть ли у кого-нибудь какие-либо предложения о том, как заставить turf.js intersect() обрабатывать нарисованные от руки самопересекающиеся многоугольники? Или способ удалить самопересечения перед запуском пересечения?


person the_skua    schedule 26.07.2016    source источник


Ответы (2)


Вдохновленный ответом на Использование буфера JSTS для идентификации самопересекающегося polygon (спасибо за наводку, @ahocevar), я портировал решение на turf.js. Буферизация нарисованного объекта с самопересечениями на 0 удаляет меньшие самопересекающиеся полигоны и оставляет вам чистый объект для прохождения через 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);
      }
    });
person the_skua    schedule 28.07.2016

Можно хотя бы предупредить пользователя о самопересечениях. Их можно обнаружить с помощью JSTS. См. Обнаружение самопересечения полигонов Google Maps. Удаление самопересечений сложнее, но это также должно быть возможно с JSTS: Использование буфера JSTS для идентификации самопересекающегося многоугольника.

person ahocevar    schedule 28.07.2016
comment
В Turfjs есть метод kinks() для обнаружения самопересечений, поэтому мне не нужно для этого перейдите в другую библиотеку, но я рассмотрю буферизацию для очистки самопересекающихся полигонов. - person the_skua; 28.07.2016