前言
前端借助Turf.js工具库,实现绘制线分割多边形、绘制面分割多边形、导入shapefile面数据实现多边形分割功能。
一、绘制线分割图斑
1、图斑分割大概思路
大概思路是通过获取线与面的交点将分割线和被分割面打散成点,将打散后的点合成线段,再根据线段将封闭的线段合成多边形,去除无效多边形,保留有效多边形。
实现过程:分割线、被分割面 → 点数据 → 线段数据 → 面数据 → 分割后目标面数据
2、图斑分割具体流程
- 将被分割的面图斑数据转换为单面,同时判断面数据坐标的有效性
- 使用
truncate()
方法处理被分割面图斑数据的坐标精度为8位,避免切割时产生误差。坐标小数点后8位精度我0.011111米。 - 使用
lineIntersect()
方法获取分割线和分割面数据的交点。此时返回的是FeatureCollection的单点集合数据。 - 使用
combine()
将FeatureCollection的单点类型数据转换为MULTIPOINT的多点类型数据。 - 使用
lineSplit()
方法使用分割线数据分割、分割面数据分割。 - 使用
featureCollection()
将所有分割线段放到一起,使用polygonize()
方法将闭合线合并成组合成多边形。 - 根据多边形中点与分割图斑的内外关系,去除掉分割图斑外的多变形面
3、图斑分割具体实现代码
二、绘制面分割图斑
1、面分割图斑大概思路
通过两个面相比较求出被分割面相对于绘制面的差异部分,和分割面与绘制面相交的交集部分,取这两个集合即可获取分割后的图斑;
实现过程:求出分割面相对于绘制面的差集 → 求出分割面与绘制面的交集 → 差集和交集合并获取数据分割结果
2、面分割图斑具体流程
- 使用
difference(polygon1,polygon2)
方法获取面polygon1相对于面polygon2的差集。 - 使用
intersect(polygon1,polygon2)
方法获取面polygon1与polygon2的交集。 - 获取第一步和第二步的结果,进行合并处理返回分割后的结果
3、面分割图斑详细代码
export function splitPolygonByFill(drawPolygon, outerPolygon) {
var polygon1 = turf.polygon(drawPolygon.geometry.coordinates)
var polygon2 = turf.polygon(outerPolygon.geometry.coordinates);
var difference = turf.difference(polygon2,polygon1);
var intersection = turf.intersect(polygon2, polygon1);
console.log('difference123', difference);
console.log("intersection",intersection);
return difference;
}
三、通过导入Shpfile面文件实现图斑分割
1、导入Shpfile文件分割图斑大概思路
导入Shpfile面数据,通过对比导入Shpfile面数据与分割图斑的差集和交集运算,实现图斑分割。
2、导入Shpfile文件分割图斑具体流程
- 选择上传Shpfile文件,使用插件解析Shpfile文件为geojson数据
- 使用
difference(polygon1,polygon2)
方法获取面polygon1相对于面polygon2的差集。 - 使用
intersect(polygon1,polygon2)
方法获取面polygon1与polygon2的交集。 - 获取第一步和第二步的结果,进行合并处理返回分割后的结果
3、导入Shpfile文件分割图斑具体实现代码
(1)安装jszip工具,解压上传shapefile的zip压缩文件
npm install jszip
(2)安装shp.js工具,解析shapefile文件为geojson数据
npm install shp.js
(3)使用 shp.js工具,将shapefile文件解析为geojson数据
// shp数据转换
import JSZip from 'jszip'
import shp from 'shpjs'
// 这里的zip为上传的zip文件
const parseZip = async(zip)=>{
// 解析zip数据为二进制数据
const jsZip = new JSZip()
const zipData = await jsZip.loadAsync(zip)
// 将zip文件转化为二进制流
const data = await zipData.generateAsync({ type: 'arraybuffer' })
return await shp(data)
}
(4)调用第二步中通过绘制面分割方式分割图斑
// 文件选择
const handleImportShapeFileChange = (e)=>{
parseZip(e).then(res=>{
let geojson = JSON.parse(JSON.stringify(res))
// 绘制导入的shapgefile图斑
handlerDetails(
res,
'shapefileSource',
'shapefileLayer',
{
lineStyle: { 'line-color': '#ff0000', 'line-width': 3 },
fillStyle: { 'fill-color': '#ff0000', 'fill-opacity': 0.1 },
}
)
Modal.confirm({
title: '是否确认分割图斑?',
onCancel() {
handlerDetails(
{type:"FeatureCollection",features:[]},
'shapefileSource',
'shapefileLayer',
{
lineStyle: { 'line-color': '#ff0000', 'line-width': 3 },
fillStyle: { 'fill-color': '#ff0000', 'fill-opacity': 0.1 },
}
)
},
async onOk() {
splitFeatureByFill(geojson.features[0].geometry.coordinates[0]);
handlerDetails(
{type:"FeatureCollection",features:[]},
'shapefileSource',
'shapefileLayer',
{
lineStyle: { 'line-color': '#ff0000', 'line-width': 3 },
fillStyle: { 'fill-color': '#ff0000', 'fill-opacity': 0.1 },
}
)
},
});
});
}
参考文章:https://juejin.cn/post/7268533072987045927
前端解析ShapeFile文件为geojson数据