Vue項目openlayers中使用jsts處理wkt和geojson的交集-(geojson來源zpi解析)
讀取壓縮包中的shape看上一篇筆記:Vue項目讀取zip中的ShapeFile文件,并解析為GeoJson
openlayers使用jsts官方示例:https://openlayers.org/en/latest/examples/jsts.html
jsts官方代碼地址:https://github.com/bjornharrtell/jsts
我們從shape中讀取到的geojson格式如下:
只有邊界的一些坐標點,下面的把geojson和wkt做交集然后轉化為wkt返回的方法:
import { Component, Emit, Vue } from 'vue-property-decorator';
import { mapGetters, mapMutations } from 'vuex';import WKT from 'ol/format/WKT';
// eslint-disable-next-line import/extensions
import * as jsts from 'jsts/dist/jsts.min.js';
import {Geometry,GeometryCollection, LinearRing, LineString, MultiLineString, MultiPoint, Point,
} from 'ol/geom';
import Polygon from 'ol/geom/Polygon';
import MultiPolygon from 'ol/geom/MultiPolygon';@Component({name: 'MapMxins',computed: {...mapGetters('map', ['getDrawingType',]),},methods: {...mapMutations('map', ['updateDrawingType',]),},
})
export default class MapMxins extends Vue {getDrawingType;updateDrawingType;/*** 處理工作區范圍-如果上傳了shpe** @params xzqData: 行政區數據* @params geojson:工作區范圍數據* 用工作區范圍和行政區范圍做相交處理,保留交集就是最后的范圍* return: {* geom: 工作區范圍和行政區相交的geom,如果沒有相交或者工作區范圍無效則返回行政區geom* isValid: 工作區范圍是否有效* }*/hansleWorkspace(xzqData, geojson) {// console.log('處理工作區范圍-如果上傳了shpe:', xzqData, geojson);const xzqGeom = xzqData.geom; // 行政區geomconst format = new WKT();const parser = new jsts.io.OL3Parser();parser.inject(Point,LineString,LinearRing,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection,);// eslint-disable-next-line consistent-returnreturn new Promise((resolve) => {// 工作區范圍featuresconst workspaceFeatures = geojson.features;// 行政區featuresconst xzqFeatures = format.readFeatures(xzqGeom);// 行政區Geometryconst xzqGeometry = parser.read(xzqFeatures[0].getGeometry());const xzqReturn = {geom: xzqGeom,isValid: false,};console.log('xzqFeatures-workspaceFeatures:', xzqFeatures, workspaceFeatures);try {// 如果工作區范圍是多個feature,合并成一個let newWfGeometry;if (workspaceFeatures.length > 0) {workspaceFeatures.forEach((wkFeature) => {// 獲取類型const { type, coordinates: mapdata } = wkFeature.geometry;let geometry: Geometry;if (type === 'Polygon') {geometry = new Polygon(mapdata); // 創建一個 Polygon 對象const wfGeometry1 = parser.read(geometry);newWfGeometry = newWfGeometry ? newWfGeometry.union(wfGeometry1) : wfGeometry1;} else if (type === 'MultiPolygon') {// 為每個多邊形創建 Polygonconst polygons = mapdata.map((polygonCoords) => new Polygon(polygonCoords));geometry = new MultiPolygon(polygons); // 創建一個 MultiPolygon 對象const wfGeometry1 = parser.read(geometry);newWfGeometry = newWfGeometry ? newWfGeometry.union(wfGeometry1) : wfGeometry1;} else {this.$message.error('工作區范圍必須是面數據');resolve(xzqReturn);}});} else {this.$message.error('工作區范圍不能為空');return resolve(xzqReturn);}// console.log('合并后的作曲范圍數據newWfGeometry:', newWfGeometry, xzqGeometry);// 判斷工作區范圍和行政區范圍是否相交if (newWfGeometry && xzqGeometry) {const intersects = newWfGeometry.intersects(xzqGeometry);if (intersects) {// 如果相交,取交集做工作區范圍newWfGeometry = newWfGeometry.intersection(xzqGeometry);// 轉為wktconst newWkt = format.writeGeometry(parser.write(newWfGeometry));// console.log(newWkt);return resolve({geom: newWkt,isValid: true,});}console.log('不相交相交');// 如果不相交,則返回行政區范圍return resolve(xzqReturn);}} catch (err) {console.log('工作區范圍數據解析出錯:', err);return resolve(xzqReturn);}});}
}
使用:
// res 是我這里固定的wkt-行政區邊界wkt
const geomWorkspace: any = await this.hansleWorkspace(res, this.shpeState.geojson);
console.log('處理后返回的geomWorkspace:', geomWorkspace);
調用后返回效果: