如何有效地找到大型多边形相交?

时间:2019-06-20 21:25:38

标签: geospatial polygon intersection turfjs mapshaper

我有一个带有〜5000个多边形(无孔)的图层的情况,我需要清除所有交点。这是一个面向web应用程序的用户,因此我更喜欢JavaScript,但是如果Python或JVM或其他工具中有更好的工具,我可以使用服务器调用。我发现https://github.com/mbloch/mapshaper/具有自动清洁算法,但首先,用户需要手动照顾大型的交叉路口。为此,我尝试使用https://github.com/Turfjs/turf比较所有多边形对的交点,然后检查交点面积是否大于其中一个多边形的指定百分比(例如50%),但需要10- 20分钟,这需要成为一个互动工具。我通过首先找到多边形边界框的交点来对其进行优化,并且仅当边界相交时才检查多边形的交点,但是仍然需要10到20秒。代码现在看起来像这样:

// fc is a GeoJSON feature collection

const overlapThreshold = 0.5

let largeOverlappingIds = []

fc.features.forEach(feature => {
  feature.bounds = turf.bbox(feature)
  feature.area = turf.area(feature)
})

fc.features.forEach(f1 => {
  if(largeOverlappingIds.includes(f1.properties.id)) {
    return
  }
  const [ f1x1, f1y1, f1x2, f1y2 ] = f1.bounds
  const f1minX = Math.min(f1x1, f1x2)
  const f1maxX = Math.max(f1x1, f1x2)
  const f1minY = Math.min(f1y1, f1y2)
  const f1maxY = Math.max(f1y1, f1y2)

  fc.features.forEach(f2 => {
    if(f1.properties.id === f2.properties.id || largeOverlappingIds.includes(f2.properties.id)) {
      return
    }

    const [ f2x1, f2y1, f2x2, f2y2 ] = f2.bounds
    const f2minX = Math.min(f2x1, f2x2)
    const f2maxX = Math.max(f2x1, f2x2)
    const f2minY = Math.min(f2y1, f2y2)
    const f2maxY = Math.max(f2y1, f2y2)

    if(f1maxX < f2minX || f1minX > f2maxX || f1maxY < f2minY || f1minY > f2maxY) {
      return
    }

    const i = turf.intersect(f1, f2)
    if(i && i.geometry.type === 'Polygon') {
      const intersectionArea = turf.area(i)
      if(intersectionArea > f1.area * overlapThreshold) {
        largeOverlappingIds.push(f1.properties.id)
      }
      if(intersectionArea > f2.area * overlapThreshold) {
        largeOverlappingIds.push(f2.properties.id)
      }
    }
  })
})

我阅读了有关找到相交点的算法的信息,但我仍然只需要查找相交面积较大的情况。您能想到什么有效的方法吗?

0 个答案:

没有答案