我的是Vue3 + vite + javascript ,了解到的信息是
1、jsts没有类型声明文件,npm引用时有问题。据说有方法:
我是在index.html中直接引用在线的
<script src="https://unpkg.com/jsts@1.6.1/dist/jsts.min.js"></script>
2、JSTS是一个符合OGC标准的,包含空间拓扑功能的JavaScript类库。
JSTS是通过原始JTS Java 源代码翻译来的,保留了JTSAPI;
3、可以直接适用OpenLayers(以下简称OL)的几何对象
4\数据代码里也有,来自这里zd4---.json:
{"type":"FeatureCollection", "features": [
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[40492442.5521,3588310.519099999],[40492442.5521,3588133.6675000004],[40493429.9736,3588133.6675000004],[40493429.9736,3588310.519099999],[40492442.5521,3588310.519099999]]]},"properties":{"BSM":0,"YSDM":"","DJZQDM":"","BDCDYH":"","YBZDDM":"","ZDDM":"","ZDTZM":"","DJH":"","ZT":"","BZ":"","YWH":"","SFYX":"","XMMC":"","XMBH":"","ID":"","CJR":"","CJRMC":"","CJSJ":"1899-11-30T00:00:00.000Z","ZHXGR":"","ZHXGRMC":"","ZHXGSJ":"1899-11-30T00:00:00.000Z","SFDYZ":"","SFDYZ3":"","QLRMC":"","ZL":"","TDYT":"","QLLX":"","QLXZ":"","FZMJ":0,"LSID":"","MJDW":0,"ZDMJ":0,"YT":"","JG":0,"CREATED_US":"","CREATED_DA":"1899-11-30T00:00:00.000Z","LAST_EDITE":"","LAST_EDI_1":"1899-11-30T00:00:00.000Z","LFY":0,"SFFZ":"","JZZDMJ":0,"SYNCFLAG":"","DELFLAG":0,"QXDM":"","JZXG":0,"SFMD":"","MDQK":"","Z":0,"SHAPE_AREA":174627.072149,"SHAPE_LEN":2328.5462}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[40492991.905961156,3588538.3426410276],[40493341.905961156,3587932.124858383],[40493441.905961156,3587932.124858383],[40493091.905961156,3588538.3426410276],[40492991.905961156,3588538.3426410276]]]},"properties":{"BSM":0,"YSDM":"","DJZQDM":"","BDCDYH":"","YBZDDM":"","ZDDM":"","ZDTZM":"","DJH":"","ZT":"","BZ":"","YWH":"","SFYX":"","XMMC":"","XMBH":"","ID":"","CJR":"","CJRMC":"","CJSJ":"1899-12-30T00:00:00.000Z","ZHXGR":"","ZHXGRMC":"","ZHXGSJ":"1899-12-30T00:00:00.000Z","SFDYZ":"","SFDYZ3":"","QLRMC":"","ZL":"","TDYT":"","QLLX":"","QLXZ":"","FZMJ":0,"LSID":"","MJDW":0,"ZDMJ":0,"YT":"","JG":0,"CREATED_US":"","CREATED_DA":"1899-12-30T00:00:00.000Z","LAST_EDITE":"","LAST_EDI_1":"1899-12-30T00:00:00.000Z","LFY":0,"SFFZ":"","JZZDMJ":0,"SYNCFLAG":"","DELFLAG":0,"QXDM":"","JZXG":0,"SFMD":"","MDQK":"","Z":0,"SHAPE_AREA":0,"SHAPE_LEN":0}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[40492647.99226973,3588253.3539021313],[40492647.99226973,3588203.353902133],[40492747.99226973,3588203.353902133],[40492747.99226973,3588253.3539021313],[40492647.99226973,3588253.3539021313]]]},"properties":{"BSM":22,"YSDM":"","DJZQDM":"","BDCDYH":"","YBZDDM":"","ZDDM":"","ZDTZM":"","DJH":"","ZT":"","BZ":"","YWH":"","SFYX":"","XMMC":"","XMBH":"","ID":"","CJR":"","CJRMC":"","CJSJ":"1899-12-30T00:00:00.000Z","ZHXGR":"","ZHXGRMC":"","ZHXGSJ":"1899-12-30T00:00:00.000Z","SFDYZ":"","SFDYZ3":"","QLRMC":"","ZL":"","TDYT":"","QLLX":"","QLXZ":"","FZMJ":0,"LSID":"","MJDW":0,"ZDMJ":0,"YT":"","JG":0,"CREATED_US":"","CREATED_DA":"1899-12-30T00:00:00.000Z","LAST_EDITE":"","LAST_EDI_1":"1899-12-30T00:00:00.000Z","LFY":0,"SFFZ":"","JZZDMJ":0,"SYNCFLAG":"","DELFLAG":0,"QXDM":"","JZXG":0,"SFMD":"","MDQK":"","Z":0,"SHAPE_AREA":0,"SHAPE_LEN":0}},
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[40492259.70328914,3588401.7665791605],[40492359.70328914,3588401.7665791605],[40492359.70328914,3588601.7665791586],[40492259.70328914,3588601.7665791586],[40492259.70328914,3588401.7665791605]]]},"properties":{"BSM":11,"YSDM":"","DJZQDM":"","BDCDYH":"","YBZDDM":"","ZDDM":"","ZDTZM":"","DJH":"","ZT":"","BZ":"","YWH":"","SFYX":"","XMMC":"","XMBH":"","ID":"","CJR":"","CJRMC":"","CJSJ":"1899-12-30T00:00:00.000Z","ZHXGR":"","ZHXGRMC":"","ZHXGSJ":"1899-12-30T00:00:00.000Z","SFDYZ":"","SFDYZ3":"","QLRMC":"","ZL":"","TDYT":"","QLLX":"","QLXZ":"","FZMJ":0,"LSID":"","MJDW":0,"ZDMJ":0,"YT":"","JG":0,"CREATED_US":"","CREATED_DA":"1899-12-30T00:00:00.000Z","LAST_EDITE":"","LAST_EDI_1":"1899-12-30T00:00:00.000Z","LFY":0,"SFFZ":"","JZZDMJ":0,"SYNCFLAG":"","DELFLAG":0,"QXDM":"","JZXG":0,"SFMD":"","MDQK":"","Z":0,"SHAPE_AREA":0,"SHAPE_LEN":0}}
]}
xxx.vue文件import 及 方法里:
import {Polygon, LineString, LinearRing, MultiPoint, MultiLineString, MultiPolygon} from 'ol/geom';
import Point from "ol/geom/Point";
const originalPolygon = new Feature(
new Polygon([[
[40492442.5521, 3588310.519099999],
[40492442.5521, 3588133.6675000004],
[40493429.9736, 3588133.6675000004],
[40493429.9736, 3588310.519099999],
[40492442.5521, 3588310.519099999] // 闭合环
]])
);
//倾斜的面,与初始的面相交
const polygonFea3 = new Feature(
new Polygon([[
[40492991.905961156,3588538.3426410276],
[40493341.905961156,3587932.124858383],
[40493441.905961156,3587932.124858383],
[40493091.905961156,3588538.3426410276],
[40492991.905961156,3588538.3426410276]
]])
);
//在originPolygon内部的,完全被包含的
const polygonFea22 = new Feature(
new Polygon([[[40492647.99226973,3588253.3539021313],
[40492647.99226973,3588203.353902133],
[40492747.99226973,3588203.353902133],
[40492747.99226973,3588253.3539021313],
[40492647.99226973,3588253.3539021313]]])
);
//分离不相交的
const polygonFea11 = new Feature(
new Polygon([[[40492259.70328914,3588401.7665791605],
[40492359.70328914,3588401.7665791605],
[40492359.70328914,3588601.7665791586],
[40492259.70328914,3588601.7665791586],
[40492259.70328914,3588401.7665791605]]])
);
// 分割线
const line = new LineString([
[40492655.54599426, 3588549.311891992],
[40492986.11216243, 3587904.8227127804]
]);
let lineFeature = new Feature({
geometry: line,
style: new Style({
stroke: new Stroke({ color: 'red', width: 3 })
})
});
//ol geometry:
const originalPolygonGeo = originalPolygon.getGeometry();
const polygonGeo3 = polygonFea3.getGeometry();
const polygonGeo11 = polygonFea11.getGeometry();//分离的那个
const polygonGeo22 = polygonFea22.getGeometry();//完全被包含的那个
const splitLineGeo = lineFeature.getGeometry();
//面缓冲
// let ret = getBuffer(originalPolygonGeo, 20);
// console.log('ret',ret)
// let fea1 = new Feature(ret)
// fea1.setStyle(new Style({
// fill: new Fill({ color: 'rgba(2,31,194,1)' }),
// stroke: new Stroke({ color: 'green', width: 2 })
// }));
// source.addFeature(fea1)
//source.addFeature(new Feature(ret)) //test ok
//线缓冲
// let ret = getBuffer(splitLineGeo, 20);
// console.log('ret',ret)
// source.addFeature(new Feature(ret)) //test ok
// let lineBuf = getBuffer(splitLineGeo, 20);
// let ret = intersects(originalPolygonGeo, lineBuf);
// console.log('ret',ret)
// let fea1 = new Feature(ret)
// fea1.setStyle(new Style({
// fill: new Fill({ color: 'rgba(2,31,194,1)' }),
// stroke: new Stroke({ color: 'green', width: 2 })
// }));
// source.addFeature(fea1) //test ok
//线缓冲之后,再与 polygon1 Diff, 即是挖空相交的部分。然后再multipolygon 是哪几个,打算再分解出来,判断哪个是切剩下的polygon
// let lineBuf = getBuffer(splitLineGeo, 20);
// console.log('line-wkt,', geometryToWKT(lineBuf))
// let ret = symDifference(originalPolygonGeo, lineBuf);
// console.log('ret',ret,ret.getCoordinates()[1][0]) //结果为multiPolygon,这里输出第一个polygon的环
// source.addFeature(fea1) //test ok
//从 ret.getCoordinates()[1][0] 坐标,手动在arcmap中添加xy 点中以判断出来是 倾斜的面上裁剪剩余的。
// let ret = symDifference(originalPolygonGeo, polygonGeo3);
// console.log('ret',ret,ret.getCoordinates()[1][0]) //结果为multiPolygon,这里输出第一个polygon的环
// let fea1 = new Feature(ret)
// fea1.setStyle(new Style({
// fill: new Fill({ color: 'rgba(2,31,194,1)' }),
// stroke: new Stroke({ color: 'green', width: 2 })
// }));
// source.addFeature(fea1) //test ok
//初始面与 11相交吗 ?
// let retGeo = intersects(originalPolygonGeo, polygonGeo11);
// console.log('ret',retGeo, isGeometryEmpty(retGeo)) //结果要判断,可能是POLYGON,也可能是multiPolygon,按前面数据,这里ret.getCoordinates()[0].length == 0
// let fea1 = new Feature(retGeo)
// fea1.setStyle(new Style({
// fill: new Fill({ color: 'rgba(2,31,194,1)' }),
// stroke: new Stroke({ color: 'green', width: 2 })
// }));
// source.addFeature(fea1) //test ok
//初始面与 22相交吗 ?
let retGeo = intersects(originalPolygonGeo, polygonGeo22);
if(!isGeometryEmpty(retGeo)){
console.log('ret 有图形') //结果要判断,可能是POLYGON,也可能是multiPolygon,按前面数据,这里ret.getCoordinates()[0].length == 0
let fea1 = new Feature(retGeo)
fea1.setStyle(new Style({
fill: new Fill({ color: 'rgba(2,31,194,1)' }),
stroke: new Stroke({ color: 'green', width: 2 })
}));
source.addFeature(fea1) //test ok
}
// 实例化OL解析类
const OLParser = new jsts.io.OL3Parser();
// 注入OL几何对象
OLParser.inject(Point, LineString, LinearRing, Polygon, MultiPoint, MultiLineString, MultiPolygon);
函数:
const getBuffer = (geom, len) => { const jstsGeom = OLParser.read(geom); if (!jstsGeom.isValid()) { console.error("几何对象出现拓扑错误,请检查修复"); return null; } const buffered = jstsGeom.buffer(len); return OLParser.write(buffered); }; /** * import Polygon from 'ol/geom/Polygon'; * import LineString from 'ol/geom/LineString'; * OL 中检查几何坐标是否为空 * @param {ol/geom/Geometry} geometry - OpenLayers几何对象 * @returns {boolean} 是否为空 */ function isGeometryEmpty(geometry) { if (!geometry) return true; const coords = geometry.getCoordinates(); switch (geometry.getType()) { case 'Point': return coords.length === 0 || coords.some(isNaN); case 'LineString': return coords.length === 0; case 'Polygon': // 多边形需检查外环是否为空 return coords.length === 0 || coords[0].length === 0; case 'MultiPolygon': // 检查所有子多边形 return coords.length === 0 || coords[0][0].length === 0; default: return coords.length === 0; } } /** * 取交 * @param geom * @param geomB * @returns */ const intersects = (geom, geomB) => { const jstsGeom = OLParser.read(geom); const jstsGeomB = OLParser.read(geomB); if (!jstsGeom.isValid() || !jstsGeomB.isValid()) { console.error("几何对象出现拓扑错误,请检查修复"); return null; } const difference = jstsGeom.intersection(jstsGeomB); return OLParser.write(difference); }; /** * 取geom中geomB的补集 * @param geom * @param geomB * @returns */ const getDifference = (geom, geomB) => { const jstsGeom = OLParser.read(geom); const jstsGeomB = OLParser.read(geomB); if (!jstsGeom.isValid() || !jstsGeomB.isValid()) { console.error("几何对象出现拓扑错误,请检查修复"); return null; } const difference = jstsGeom.difference(jstsGeomB); return OLParser.write(difference); }; /** * 融合 * @param geom * @param geomB * @returns */ const union = (geom, geomB) => { const jstsGeom = OLParser.read(geom); const jstsGeomB = OLParser.read(geomB); if (!jstsGeom.isValid() || !jstsGeomB.isValid()) { console.error("几何对象出现拓扑错误,请检查修复"); return null; } const difference = jstsGeom.union(jstsGeomB); return OLParser.write(difference); }; /** * 对等差分 * @param geom * @param geomB * @returns */ const symDifference = (geom, geomB) => { const jstsGeom = OLParser.read(geom); const jstsGeomB = OLParser.read(geomB); if (!jstsGeom.isValid() || !jstsGeomB.isValid()) { console.error("几何对象出现拓扑错误,请检查修复"); return null; } const difference = jstsGeom.symDifference(jstsGeomB); return OLParser.write(difference); }; /** * 手动转wkt 格式 * 将OpenLayers几何对象转换为WKT格式 * @param {ol/geom/Geometry} geom - OpenLayers几何对象 * @returns {string} WKT字符串 */ function geometryToWKT(geom) { const type = geom.getType(); switch (type) { case 'Point': return `POINT(${coordToWKT(geom.getCoordinates())})`; case 'LineString': return `LINESTRING(${geom.getCoordinates().map(coordToWKT).join(', ')})`; case 'Polygon': const rings = geom.getCoordinates(); // 外环 + 内环(孔洞) return `POLYGON(${rings.map(ring => `(${ring.map(coordToWKT).join(', ')})`).join(', ')})`; case 'MultiPolygon': return `MULTIPOLYGON(${geom.getCoordinates().map(poly => `(${poly.map(ring => `(${ring.map(coordToWKT).join(', ')})`).join(', ')})` ).join(', ')})`; default: throw new Error(`未支持的几何类型: ${type}`); } } // 辅助函数:坐标数组转WKT格式 function coordToWKT(coord) { return coord.join(' '); }
学习自这里
https_://blog.csdn.net/Neuromancerr/article/details/123345148
浙公网安备 33010602011771号