TurfJs union - 如何忽略内部但 union 略有不同的点?

TurfJs union - How to ignore point which are inside but with little bit difference in union?

我为多边形使用了 2 个 geojson 对象。它太大了,我无法在此处 post。现在我正在使用 TurfJs 合并这个多边形 geojson 并将其绘制在地图上。但它不能正常工作。

我觉得中间的一点点有点不一样。那么在turfjs union中有什么办法可以忽略中间的这个点吗?

请参阅下面的图片以便更好地理解。

多边形 1 :

多边形 2 :

现在为以下代码合并多边形:

polygons = {
          "type": "FeatureCollection",
          "features": [poly1, poly2]
        };

现在主要的 UNION 结果:

union = turf.union(poly1,poly2);

所以在这里,我想忽略边界中间的点我知道,在两个多边形的交界边界上可能有不准确的点但是我可以忽略更近或有一点点的点吗差异忽略中间点?

或者是否有任何替代方法来合并多边形,忽略一些较近的点干扰并删除中间点?

您可以尝试 运行 通过 turf.buffer(result, 0, 'kilometers') (turf-buffer docs) 生成的多边形。如果您的结果是无效的 geojson 那么使用缓冲区 0 应该清理几何(删除中间的 points/lines)。

如果没有看到结果的实际 GeoJSON,很难说什么是肯定有效的。有什么方法可以将其上传到 pastebin 或其他什么地方吗?

更新 - Turf 缓冲区在这种情况下不起作用。我可以开始工作的唯一解决方案是根据 turf.union(p1, p2).

的结果执行此操作

result.geometry.coordinates = [result.geometry.coordinates[0]]

您要谨慎使用此解决方案,因为它会从多边形中移除除外环以外的所有内容。

要了解 why/how 这是有效的,您需要确保了解 geojson 多边形的坐标是如何工作的。来自 geojson.org geojson polygon specification

For type "Polygon", the "coordinates" member must be an array of LinearRing coordinate arrays. For Polygons with multiple rings, the first must be the external ring and any others must be internal rings or holes.

外环本质上是多边形的轮廓。任何内环通常表示为孔。在您的情况下,内部环实际上是线。

查看 geojson 多边形的坐标时,您会注意到所有坐标都包含在外部数组中。这是一个只有一个(外部)环的 geojson 多边形示例。

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": **[ [ [1, 1], [1, 2], [1, 3], [1, 1] ] ]**

请注意,环的第一个坐标和最后一个坐标必须始终相同。这确保我们得到一个封闭的形状(即:多边形)。

下面是一个外环和内环的例子

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": **[ [ [1, 1], [1, 2], [1, 3], [1, 1] ], [ [1, 2], [1, 3], [1, 1] ] ]**

现在,如果我们将建议的解决方案应用于上面的示例,我们将获得与第一个示例相同的坐标,因为我们只从多边形中获取第一组坐标,它始终是外环。坐标数组中的任何后续元素都将表示内环(这就是线条的含义,即使它们在技术上不是有效的内环)。

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": **[ [ [1, 1], [1, 2], [1, 3], [1, 1] ] ]**

如您所见,我们正在从多边形中移除所有内环。这就是您必须谨慎使用它的原因。如果您有有效的内部环,它实际上会摆脱这些。

我认为发生这种情况的原因是因为您的多边形(p1p2)共享一个边界。

面临同样的问题:尝试缓冲一个小的正数和相同的负数后,线条消失了。但这使得多边形比原来的多边形有更多的点,所以我做了这个解决方法:

inner = [YOUR FEATURE COLLECTION]
var areas = []
for (var i = 0; i < inner.geometry.coordinates.length; i++) {
    let item = inner.geometry.coordinates[i]
    if (item.length > 10) areas.push(item)
}
inner = turf.polygon(areas)

如您所见,我正在删除“非复杂”多边形(假设少于 10 个点的多边形不是真实区域)

发生这种情况是因为两个多边形的坐标并非 100% 相同,在将它们合并在一起时会产生一个小间隙。

遇到这个问题,我不得不用turf的distance方法检查多边形的每一个顶点,如果它们之间有细微的差别,我就让它们一样。

实现方法可能因您使用的地图库而异,但应该是这样的:

layers.forEach(layer => {
    layers.forEach(innerLayer => {
        if (layer === innerLayer) return;
    
        // Here you would check if the vertexes are close to each other, using distance.

        // If the vertexes are close, you would make them equal and update the layer.
    })
})

只有让多边形的顶点相同后,才能用union的方式合并。

由于实现非常独特并且取决于项目,我不会在实际代码上浪费我们的时间,但我相信有了上面的见解,您应该可以开始了。