gis - 如何合并多个相交的多边形
问题描述
我正在尝试使用 turfjs 合并或分组多边形。
下图显示了它之前的样子以及合并后的样子。
我正在使用 Openlayers 和 Typescript,它们都有多边形,因此别名 TurfPolygon 等。我首先将我的 OpenLayers 多边形转换为 Turfjs 多边形,这样我就可以使用 Turf 函数。
const mergedIds: number[] = [];
const t0 = performance.now();
for (const object of arrayTurfObjects) {
if (mergedIds.find(x => x === object.properties.mergedId)) {
continue;
}
let mergeResultPolygon: TurfFeature<TurfPolygon> | null = null;
for (let indexNested = 0; indexNested < arrayTurfObjects.length; indexNested++) {
const nestedObject = arrayTurfObjects[indexNested];
if(nestedObject === object){
continue;
}
if(mergedIds.find(x => x === nestedObject.properties.mergedId)){
continue;
}
if(mergeResultPolygon){
if(booleanIntersects(mergeResultPolygon, nestedObject)){
mergeResultPolygon = TurfUnion(mergeResultPolygon, nestedObject) as TurfFeature<TurfPolygon, any>;
mergedIds.push(nestedObject.properties.mergedId);
indexNested = 0;
}
} else {
if(booleanIntersects(object, nestedObject)){
mergeResultPolygon = TurfUnion(object, nestedObject) as TurfFeature<TurfPolygon, any>;
mergedIds.push(nestedObject.properties.mergedId);
indexNested = 0;
}
}
}
if (mergeResultPolygon) {
const polygon = new Polygon(mergeResultPolygon.geometry.coordinates);
const feature = new Feature(polygon);
feature.setStyle(new Style({
stroke: new Stroke({
color: ColorCode.BLACK,
width: 5,
}),
fill: new Fill({
color: 'rgba(255,0,0, 0.6)',
}),
}));
//Here is an function to add the mergeResultPolygon to the map to check if it's correct
}
}
const t1 = performance.now();
console.log((t1 - t0) + ' milliseconds.');
我正在迭代同一个数组,其中包含两次多边形。首先我检查多边形是否已经合并,所以我可以跳过,我声明我的合并结果多边形。然后是我跳过多边形的嵌套循环,如果它与我的外循环中的多边形相同并且它已经合并。
为了开始我的合并过程,我正在寻找与当前外部循环多边形相交的第一个多边形,因此我可以为我的 mergeResultPolygon 设置一个值。之后,我只是将更多多边形合并到该变量。
如您所见,我必须重置嵌套循环,以便再次迭代。我这样做是因为我没有任何顺序,所以前一个多边形可能与合并结果多边形相交。
我的问题是我在客户端这样做并且性能不是那么好。
这个问题有更好的解决方案吗?
解决方案
从所有多边形的联合中获取合并多边形的演示
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css">
<style>
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
<script src="https://unpkg.com/@turf/turf@6.3.0/turf.min.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<script type="text/javascript">
var count = 200;
var features = new Array(count);
var e = 4500000;
for (var i = 0; i < count; ++i) {
var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
features[i] = new ol.Feature(new ol.geom.Polygon.fromExtent(ol.extent.buffer(coordinates.concat(coordinates), 200000)));
}
var source = new ol.source.Vector({
features: features,
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
source: source
})
],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
var result;
format = new ol.format.GeoJSON();
source.forEachFeature(function(feature) {
var turfPolygon = format.writeFeatureObject(feature);
if (!result) {
result = turfPolygon;
} else {
result = turf.union(result, turfPolygon);
}
});
var results = [];
var olResult = format.readFeature(result);
if (olResult.getGeometry().getType() === 'MultiPolygon') {
olResult.getGeometry().getPolygons().forEach(function(polygon) {
results.push(new ol.Feature(polygon));
});
} else {
results.push(olResult);
}
map.addLayer(
new ol.layer.Vector({
source: new ol.source.Vector({
features: results,
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 2
})
})
})
);
</script>
</body>
</html>
推荐阅读
- python - 使用 pandas 动态导入 EXCEL 表格并将其分配给 Python 中的 DataFrame
- firebase - Firestore 为 noSQL 和 Flutter 复制 SQL 连接
- selenium - Docker 容器上的 Protractor 异步并行测试
- go - 如何导入本地模块golang?
- swift - 在 UICollectionViewCell 中动态添加 UIButtons - Swift
- javascript - React:获取组件子节点之一的 DOM 位置
- python - Rasa 特工在讲完一个故事后停止回应
- r - 如何在 R 中运行回归,同时省略所有包含 0 的行?
- mysql - MySQL UNION - 删除重复条目的好方法
- python - 如果不是这个或这个,那么在 lambda python pandas