turf.js OpenLayers3 Draw 中自相交多边形的相交误差
turf.js Intersect Error for Self-intersecting Polygons from OpenLayers3 Draw
我正在使用 OpenLayers3 ol.interaction.Draw
让用户在地图上绘制一个形状,通过单击顶点或通过 Shift+Drag 绘制自由多边形(这对我的应用程序很重要)。绘制形状后,我使用 turf.js 将绘制的形状与客户端中的 WFS 层进行比较,运行 intersect()
以查看 WFS 特征是否与绘制的形状相交。但是,如果手绘形状有最轻微的自相交,turf.js intersect()
函数将失败并出现以下错误(第 326 行是我调用 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
以下是我的代码草图。
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()
处理手绘的自相交多边形有任何建议?或者有一种方法可以删除 运行 交点之前的自交点?
您至少可以警告用户注意自相交。这些可以用 JSTS 检测到。参见 Google Maps Polygons self intersecting detection. Removing self-intersections is harder, but it should also be possible with JSTS: 。
受到 答案的启发(感谢@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);
}
});
我正在使用 OpenLayers3 ol.interaction.Draw
让用户在地图上绘制一个形状,通过单击顶点或通过 Shift+Drag 绘制自由多边形(这对我的应用程序很重要)。绘制形状后,我使用 turf.js 将绘制的形状与客户端中的 WFS 层进行比较,运行 intersect()
以查看 WFS 特征是否与绘制的形状相交。但是,如果手绘形状有最轻微的自相交,turf.js intersect()
函数将失败并出现以下错误(第 326 行是我调用 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
以下是我的代码草图。
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()
处理手绘的自相交多边形有任何建议?或者有一种方法可以删除 运行 交点之前的自交点?
您至少可以警告用户注意自相交。这些可以用 JSTS 检测到。参见 Google Maps Polygons self intersecting detection. Removing self-intersections is harder, but it should also be possible with JSTS:
受到 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);
}
});