190 lines
6.6 KiB
TypeScript
190 lines
6.6 KiB
TypeScript
import { reject } from 'lodash-es';
|
||
import { generateUUID } from '../src/tool';
|
||
|
||
/**
|
||
* 使用turf工具进行切割面
|
||
* @param line 线段数据
|
||
* @param outerPolygon 面数据
|
||
* return 返回切割的面数据
|
||
*/
|
||
export function splitPolygonByLine(line, outerPolygon) {
|
||
console.log("************** 分割开始 start **************")
|
||
console.log("第1步:传入的分割线数据",line);
|
||
console.log("第2步:传入的分割面数据",outerPolygon)
|
||
|
||
// 处理被分割的面数据坐标小数点保留多少位
|
||
let truncatedSplitter = turf.truncate(turf.lineString(outerPolygon.geometry.coordinates[0]), {
|
||
precision: 7,
|
||
});
|
||
console.log("第3步:分割面转换为线数据",truncatedSplitter);
|
||
//求交点
|
||
let intersectCollection = turf.lineIntersect(line, truncatedSplitter);
|
||
console.log("第4步:与分割面的交点",intersectCollection);
|
||
// printLngLat(intersectCollection.geometry.coordinates);
|
||
// 交点小于2个 返回null
|
||
if (intersectCollection.features.length < 2) {
|
||
return null;
|
||
}
|
||
//将点合并成MultiPoint
|
||
let intersectCombined = turf.combine(intersectCollection).features[0];
|
||
|
||
console.log("第5步:分割后所有点数据",intersectCombined)
|
||
|
||
|
||
//分别获取切割线
|
||
let outerPieceCollection = turf.lineSplit(line, intersectCombined);
|
||
let splitterPieceCollection = turf.lineSplit(truncatedSplitter, intersectCombined);
|
||
|
||
console.log("第6步:切割线被分割后所有线段",outerPieceCollection);
|
||
|
||
console.log("第7步:切割面被分割后所有线段",splitterPieceCollection);
|
||
|
||
//将所有的线段放到一起
|
||
let pieceCollection = turf.featureCollection(
|
||
outerPieceCollection.features.concat(splitterPieceCollection.features),
|
||
);
|
||
console.log("第8步:所有分割线段",pieceCollection);
|
||
//使用turf将闭合线组成多边形
|
||
let polygonCollection = turf.polygonize(pieceCollection);
|
||
|
||
console.log("第9步:分割线合并面数据",polygonCollection)
|
||
|
||
//对多边形进行判断,切割外的多边形丢弃
|
||
let innerPolygons = polygonCollection.features.filter((polygon) => {
|
||
// 获取多边形质心 多边形不规则时有问题
|
||
// let newcenter = turf.centroid(polygon);
|
||
let randomCenterPoint = getRandomPointInPolygon(polygon);
|
||
|
||
// 获取多边形表面一点
|
||
let newcenter = turf.pointOnFeature(polygon);
|
||
// 图斑中心点
|
||
let centerPoint = turf.point(randomCenterPoint.geometry.coordinates);
|
||
console.log('第10步:封闭图形中心点数据',randomCenterPoint,centerPoint)
|
||
return turf.booleanWithin(centerPoint, outerPolygon);
|
||
|
||
});
|
||
|
||
console.log("第11步:返回最终处理后的数据",innerPolygons)
|
||
// let innerPolygons = polygonCollection.features;
|
||
|
||
//处理镂空数据(多处镂空数据会导致计算错误,因为polygonize方法无法正常的返回数据)
|
||
if (outerPolygon.geometry.coordinates?.length > 1) {
|
||
//获取镂空的面数据
|
||
let holeCollection = turf.featureCollection(
|
||
outerPolygon.geometry.coordinates.slice(1).map((item) => turf.polygon([item])),
|
||
);
|
||
|
||
//剔除掉镂空的部分数据
|
||
innerPolygons = innerPolygons.map((polygon) => {
|
||
let diff = polygon;
|
||
turf.featureEach(holeCollection, (hole) => {
|
||
// diff = turf.difference(diff, hole);
|
||
diff = turf.difference(turf.featureCollection([diff, hole]))
|
||
});
|
||
return diff;
|
||
});
|
||
}
|
||
|
||
// 每个图斑配置UUID
|
||
innerPolygons.forEach((item, index) => {
|
||
innerPolygons[index].properties.id = generateUUID();
|
||
});
|
||
console.log("************** 分割结束 end **************")
|
||
return innerPolygons;
|
||
}
|
||
|
||
// 获取多边形内随机点
|
||
function getRandomPointInPolygon(polygon) {
|
||
const bbox = turf.bbox(polygon); // 获取多边形的边界框
|
||
let point;
|
||
|
||
do {
|
||
point = turf.randomPoint(1, {bbox: bbox}).features[0]; // 从边界框中生成一个随机点
|
||
} while (!turf.booleanWithin(point, polygon)); // 检查点是否在多边形内部
|
||
// 直到找到在内部的点再返回数据
|
||
return point;
|
||
}
|
||
|
||
// 单个面数据分割
|
||
export async function splitPolygonByFill(drawPolygon, outerPolygon) {
|
||
|
||
return new Promise((resolve,reject)=>{
|
||
try{
|
||
console.log("第1步:传入的绘制面数据",drawPolygon);
|
||
console.log("第2步:传入的被切割面数据",outerPolygon)
|
||
|
||
var polygon1 = turf.polygon(drawPolygon.geometry.coordinates);
|
||
var polygon2 = turf.polygon(outerPolygon.geometry.coordinates);
|
||
|
||
// var intersection = turf.intersect(polygon1, polygon2);
|
||
let intersection = turf.intersect(turf.featureCollection([polygon1, polygon2]));
|
||
console.log("第4步:获取绘制图斑和分割图斑的交集",JSON.stringify(polygon2),JSON.stringify(polygon1),intersection);
|
||
|
||
var difference = turf.difference(turf.featureCollection([polygon2, polygon1]));
|
||
console.log("第3步:获取绘制图斑和分割图斑的差集",difference);
|
||
|
||
let splitAfterFeatures = [intersection,difference];
|
||
setTimeout(function(){
|
||
console.log("splitAfterFeatures9876",splitAfterFeatures);
|
||
},3000)
|
||
resolve(splitAfterFeatures)
|
||
}catch(e){
|
||
console.log(e);
|
||
reject(null);
|
||
}
|
||
})
|
||
|
||
}
|
||
|
||
// 多面数据分割裁剪
|
||
export async function splitPolygonByMultiFill(drawPolygons,outerPolygon){
|
||
|
||
return new Promise((resolve,reject)=>{
|
||
try{
|
||
console.log("drawPolygons",drawPolygons,outerPolygon);
|
||
// 所有结果集合
|
||
let resultArray = [];
|
||
|
||
// 绘制图斑和分割图斑集合数组
|
||
let featuresArray = [];
|
||
featuresArray.push(turf.polygon(outerPolygon.geometry.coordinates));
|
||
|
||
// 绘制图斑数组
|
||
let splitFeaturesArray = [];
|
||
|
||
// 求交集图斑
|
||
drawPolygons.forEach((item,index)=>{
|
||
let turfPolygon = turf.polygon(item.geometry.coordinates);
|
||
|
||
// 取交集
|
||
let intersection = turf.intersect(turf.featureCollection([featuresArray[0],turfPolygon]));
|
||
if(intersection){
|
||
resultArray.push(intersection);
|
||
}
|
||
|
||
console.log("交集"+index+":",intersection)
|
||
splitFeaturesArray.push(turfPolygon);
|
||
})
|
||
|
||
// 取差集
|
||
var difference = turf.difference(turf.featureCollection(featuresArray.concat(splitFeaturesArray)));
|
||
if(difference){
|
||
resultArray.push(difference);
|
||
}
|
||
|
||
// 全部图斑
|
||
console.log("resultArray",resultArray);
|
||
|
||
resolve(resultArray)
|
||
|
||
}catch(e){
|
||
reject("分割失败!");
|
||
}
|
||
})
|
||
}
|
||
|
||
export function printLngLat(arr){
|
||
arr.forEach((item,index)=>{
|
||
console.log(item[1]+","+item[0]+"\n");
|
||
})
|
||
} |