我的是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