- 公司需求,所以写了一个公共的class来进行多边形的分割:(画一条线去分割一个多边形)
class chunkUtil {
constructor() {
this.turf = window.turf || "";
if (!this.turf) {
throw new Error("请确定turf已挂载至window");
}
}
clipPolygon(polygon, polyline) {
const types = typeof polygon;
const types1 = typeof polyline;
if (!polygon) {
throw console.error("请传入面");
}
if (!polyline) {
throw console.error("请传入线");
}
if ([types, types1].includes('string')) {
const polygonParse = JSON.parse(polygon);
const polylineParse = JSON.parse(polyline);
const isLon = !polygonParse && !polygonParse.features && !polygonParse.features.length;
const isLine = !polylineParse && !polylineParse.features && !polylineParse.features.length;
if (isLon || isLine) {
throw new Error("请确定为面与线都为json串格式");
}
return this._setFloors(polygonParse, polylineParse)
} else {
throw new Error("暂时只支持json串格式的转换,如需支持json格式,请与作者沟通。");
}
}
_setFloors(A, B) {
const { turf } = this;
if ([A.type, B.type].includes('FeatureCollection')) {
const geojsonA = A.features[0];
if (geojsonA.geometry.type !== 'Polygon') {
throw new Error("第一个值请传入面");
}
const polyline = turf.polygonToLine(geojsonA);
if (polyline.geometry.type === "LineString") {
const lines = B.features[0]
const singClip = this._singeClips(polyline, lines)
return singClip
}
}
}
_singeClips(A, B) {
const { turf } = this;
const C = turf.lineIntersect(A, B);
if (C.features.length !== 2) {
throw new Error("请确定线与面有两个相交点");
}
const L = B.geometry.coordinates.length;
const SP = turf.point(B.geometry.coordinates[0]);
const EP = turf.point(B.geometry.coordinates[L - 1]);
const P = turf.polygon([A.geometry.coordinates])
if (turf.booleanPointInPolygon(SP, P) || turf.booleanPointInPolygon(EP, P)) {
throw new Error("线起点或终点不能在面内部");
}
const PL = turf.lineSlice(C.features[0], C.features[1], A);
const CL = turf.lineSlice(C.features[0], C.features[1], B);
const RL = this.connectLine(PL, CL);
RL.geometry.coordinates.push(RL.geometry.coordinates[0]); //闭合
const RP1 = turf.lineToPolygon(RL);
const FL = this.isLines(turf.point(A.geometry.coordinates[0]), PL);
const pList = [];
if (FL) {
for (let i = 0; i < A.geometry.coordinates.length; i++) {
const coordinate = A.geometry.coordinates[i];
if (!this.isLines(turf.point(coordinate), PL)) {
pList.push(coordinate)
}
}
} else {
let sNum = 0;
let isStartPush = false;
for (let i = 0; i < A.geometry.coordinates.length; i++) {
const coordinate = A.geometry.coordinates[i];
if (!this.isLines(turf.point(coordinate), PL)) {
if (isStartPush) {
pList.push(coordinate)
} else {
sNum++;
}
} else {
isStartPush = true;
}
}
for (let i = 0; i < sNum; i++) {
pList.push(A.geometry.coordinates[i]);
}
}
const PL2 = turf.lineString(pList);
const RL2 = this.connectLine(PL2, CL);
RL2.geometry.coordinates.push(RL2.geometry.coordinates[0]);
const RP2 = turf.lineToPolygon(RL2);
return turf.featureCollection([RP1, RP2])
}
connectLine(l1, l2) {
const l2l = l2.geometry.coordinates.length;
const l1sp = l1.geometry.coordinates[0];
const l2sp = l2.geometry.coordinates[0];
const l2ep = l2.geometry.coordinates[l2l - 1];
const pList = [];
for (let i = 0; i < l1.geometry.coordinates.length; i++) {
const coordinate = l1.geometry.coordinates[i];
pList.push(coordinate);
}
if (this.turf.distance(l1sp, l2sp) < this.turf.distance(l1sp, l2ep)) {
l2.geometry.coordinates = l2.geometry.coordinates.reverse();
}
for (let i = 0; i < l2.geometry.coordinates.length; i++) {
const coordinate = l2.geometry.coordinates[i];
pList.push(coordinate);
}
return this.turf.lineString(pList)
}
isLines(P, L) {
for (let i = 0; i < L.geometry.coordinates.length; i++) {
const coordinate = L.geometry.coordinates[i];
if (P.geometry.coordinates[0] === coordinate[0] && P.geometry.coordinates[1] === coordinate[1]) {
return true
}
}
return false;
}
}
export { chunkUtil }
提示:
- 请确保turf已挂载至window;
- 请确保传入的面、线为字符串格式的json串;
- 如报错,请按照提示修改;
//引入该js;
try{
const chunkFn = new chunkUtil();
const json = aaa.clipPolygon(a,c);
console.log(json);
\\json 为 多面。包括已分割的两个面,如需分开,把json.features中两个数组拎出即可。
}catch(err){
console.log(err.message);
}
如需支持更多格式,请在该基础上进行修改或者联系我。有时间可进行优化。 如有错误处,请指正~~