一组多边形的外部包络线

4

我有一个包含多个多边形的GeoJson文件。

类似于这样的内容:enter image description here

我使用Leaflet在网站上呈现此GeoJson。
我想绘制一个围绕所有多边形的轮廓线。类似于这样的效果:enter image description here

我使用的GeoJSON格式为:

{
"features": [
  {
    "geometry": {
      "coordinates": [
        [
          [
            1074.426,
            -1136.986
          ],
          [
            1088.241,
            -1123.171
          ]
        ]
      ],
      "type": "Polygon"
    },
    "properties": {
      "number": "2009",
      "type": "",
      "spaceid": null,
      "alias": null,
      "roomkey": "5/2009"
    },
    "type": "Feature"
  }
],
"bbox": [
  2445.578,
  2445.578
],
"crs": {
  "properties": {
    "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
  },
  "type": "name"
},
"type": "FeatureCollection"

有任何指针都会很有帮助 :) 谢谢


您希望包围的多边形是否共享边缘?如果不是,凸包是您的首选选项(如其他答案所述)。如果您的多边形共享边缘,则有可能的解决方案可以根据未共享的边缘(因此是组合多边形的外限)组装外部多边形(和内部环)。 - Andrew Reid
3个回答

8
您正在寻找“凸包”:
在数学中,欧几里得平面或欧几里得空间(或更一般地,在实数上的仿射空间)中点集X的凸包是包含X的最小凸集。
参考:https://en.wikipedia.org/wiki/Convex_hull 您可以使用Turf.js的convex方法来实现:
接受一个Feature或FeatureCollection并返回一个凸包多边形。
参考:http://turfjs.org/docs/#convex 示例:

var map = new L.Map('leaflet', {center: [0, 0], zoom: 0});

var collection = turf.featureCollection([
    turf.polygon([[[-80,-80],[-40,-80],[-40,-40],[-80,-40],[-80,-80]]]),
    turf.polygon([[[80,80],[40,80],[40,40],[80,40],[80,80]]])
]);

new L.GeoJSON(collection, {color: 'red'}).addTo(map);

var polygon = turf.convex(collection);

new L.GeoJSON(polygon, {color: 'black', 'fill': false }).addTo(map);
body {
    margin: 0;
}

html, body, #leaflet {
    height: 100%;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Leaflet 1.2.0</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link type="text/css" rel="stylesheet" href="//unpkg.com/leaflet@1.2.0/dist/leaflet.css" />
  </head>
  <body>
    <div id="leaflet"></div>
    <script type="application/javascript" src="//unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
    <script type="application/javascript" src="//npmcdn.com/@turf/turf/turf.min.js"></script>
</script>
  </body>
</html>


2
但是凸包会忽略内部的点。如果你考虑到一个L形的角落……那么最上面的两个点会被选中。如果您查看此图像https://raw.githubusercontent.com/AndriiHeonia/hull/master/readme-imgs/1.png,我不希望有那些空白区域。边界必须沿着边缘运行。 - Shaswat Rungta

0

我设法做到了,但是使用了TopoJSON。 我在这里发布了一个视频

首先,我尝试使用tuffjs中的“union”函数。但是它非常慢(我有一个非常详细的geojson)。

所以我转而使用topojson。首先需要将您的geojson转换为topojson。然后在topojson-client库中使用“merge”函数。合并返回多边形,但比原始几何形状简单得多。

然后您需要在代码中进行其他处理,以删除一些落在其他多边形内部的多边形。


0

@Shaswat,你说得对,凸包缺少内部点。所以我尝试使用turf.union:

const turf = require('@turf/turf')

const originGeojson = require('./SECCIONES_13_geo.json')

const totalUnion = originGeojson.features.reduce((union, feature, index) => {
  if (!union) {
    return turf.polygon(feature.geometry.coordinates)
  }

  try {
    return turf.union(union, turf.polygon(feature.geometry.coordinates))
  } catch (err) {
    return union
  }
})

console.log(JSON.stringify(totalUnion))

但它会产生类似这样的东西,里面有很多洞。

enter image description here

代码本身是不正确的,对于 catch 块来说,它只是一种通过整个列表的方式。catch 中的错误是:
“错误:多边形的每个 LinearRing 必须具有 4 个或更多 Positions。”
如果有人能分享解决这个问题的正确方法,我会非常感激。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接