UNPKG

gisviewer-vue3-arcgis

Version:

在应用中引入私服的包, 项目根目录下 新建文件 .npmrc 在 .npmrc 中对包源进行配置:

1,204 lines (1,203 loc) 38.6 kB
import g from "@arcgis/core/Graphic"; import * as k from "@arcgis/core/core/promiseUtils"; import * as $ from "@arcgis/core/core/reactiveUtils.js"; import { Polygon as L, Point as F } from "@arcgis/core/geometry"; import * as S from "@arcgis/core/geometry/geometryEngine"; import C from "@arcgis/core/layers/FeatureLayer"; import w from "@arcgis/core/layers/GraphicsLayer"; import * as D from "@turf/helpers"; import { lineSliceAlong as x } from "@turf/line-slice-along"; import b from "axios"; import { XMLParser as P } from "fast-xml-parser"; import J from "md5"; import G from "pako"; import { watch as E } from "vue"; import R from "../../stores/index.mjs"; import T from "../common-utils.mjs"; class M { constructor(e) { this.junctionNames = /* @__PURE__ */ new Map(), this.junctionScale = 5e3, this.xodrBorder = [], this.projectName = "", this.openDriveServer = "", this.currentSectionCode = "", this.selectedSectionIds = [], this.currentJunctionId = "", this.view = e, this.laneLayer = new C({ id: "OpenDriveLane", fields: [ { name: "ObjectID", alias: "ObjectID", type: "oid" }, { name: "id", alias: "编号", type: "string" }, { name: "roadId", alias: "道路号", type: "string" }, { name: "roadName", alias: "道路名称", type: "string" }, { name: "sectionId", alias: "路段号", type: "string" }, { name: "sectionIndex", alias: "路段序号", type: "string" }, { name: "laneId", alias: "车道号", type: "string" }, { name: "type", alias: "类型", type: "string" }, { name: "sumoId", alias: "sumo编号", type: "string" }, { name: "fromNode", alias: "起点路口", type: "string" }, { name: "toNode", alias: "终点路口", type: "string" } ], objectIdField: "ObjectID", geometryType: "polygon", spatialReference: { wkid: 4326 }, source: [], outFields: ["*"], renderer: { type: "unique-value", field: "type", defaultSymbol: { type: "simple-fill", color: [100, 100, 100], style: "solid", outline: { color: "white", width: 1 } }, uniqueValueInfos: [ { value: "shoulder", label: "路肩", symbol: { type: "simple-fill", color: "#008000", style: "solid", outline: { color: "white", width: 1 } } }, { value: "border", label: "路沿", symbol: { type: "simple-fill", color: "#DCDCDC", style: "solid", outline: { color: "white", width: 1 } } }, { value: "driving", label: "机动车道", symbol: { type: "simple-fill", // color: '#2F4F4F', color: [47, 79, 79, 0.8], style: "solid", outline: { color: "white", width: 1 } } }, { value: "none", label: "无", symbol: { type: "simple-fill", color: [111, 120, 135], style: "none", outline: { color: "white", width: 1 } } }, { value: "restricted", label: "禁行区", symbol: { type: "simple-fill", color: "yellow", style: "solid", outline: { color: "yellow", width: 2 } } }, { value: "parking", label: "停车区", symbol: { type: "simple-fill", color: [115, 115, 115], style: "solid", outline: { color: "white", width: 1 } } }, { value: "median", label: "中央隔离带", symbol: { type: "simple-fill", color: "#008000", style: "solid", outline: { color: "white", width: 1 } } }, { value: "biking", label: "非机动车道", symbol: { type: "simple-fill", color: "#D3D3D3", style: "solid", outline: { color: "white", width: 1 } } }, { value: "sidewalk", label: "人行道", symbol: { type: "simple-fill", color: "#C0C0C0", style: "solid", outline: { color: "white", width: 1 } } }, { value: "junction", label: "路口区域", symbol: { type: "simple-fill", color: "#2F4F4F", style: "solid", outline: { color: "white", width: 1 } } }, { value: "selected", label: "选中车道", symbol: { type: "simple-fill", color: [141, 168, 211], style: "solid", outline: { color: "white", width: 1 } } } ] } }), this.roadNameLayer = new C({ id: "OpenDriveRoadName", fields: [ { name: "ObjectID", alias: "ObjectID", type: "oid" }, { name: "roadId", alias: "道路号", type: "string" }, { name: "roadName", alias: "道路名称", type: "string" } ], objectIdField: "ObjectID", geometryType: "polyline", spatialReference: { wkid: 4326 }, source: [], renderer: { type: "simple", symbol: { type: "simple-line", style: "solid", color: [0, 0, 0, 0], width: 1 } }, labelingInfo: [ { symbol: { type: "text", color: "black", haloColor: "white", haloSize: 1, font: { size: 12, family: "sans-serif" } }, labelPlacement: this.view.type === "2d" ? "center-along" : void 0, labelExpressionInfo: { expression: "$feature.roadName" } } ] }), this.junctionLayer = new w({ id: "OpenDriveJunction" }), this.sectionLayer = new w({ id: "OpenDriveSection" }), this.highlightLayer = new w({ id: "OpenDriveHighlight" }), this.flashLayer = new w({ id: "OpenDriveFlash" }), this.drawLayer = new w({ id: "Draw" }), this.splitLaneLayer = new w({ id: "SplitLane" }), this.borderLayer = new w({ id: "OpenDriveBorder" }), this.view.map.addMany([ this.laneLayer, this.sectionLayer, this.roadNameLayer, this.junctionLayer, this.highlightLayer, this.flashLayer, this.drawLayer, this.splitLaneLayer, this.borderLayer ]); } static getInstance(e) { return this.instance || (this.instance = new M(e)), this.instance; } async makeMd5FromFile(e) { var t; try { const o = await (await fetch(e)).text(); let r = (t = new P({ ignoreAttributes: !1, allowBooleanAttributes: !0 }).parse(o).OpenDRIVE.userData) == null ? void 0 : t.border; return r ? r = JSON.parse(r) : r = [], { status: 0, message: "ok", result: { md5: J(o), border: r } }; } catch (s) { return { status: -1, message: s.message }; } } /** * 从本地文件/网络文件显示OpenDrive内容 * @param params * @returns */ async showOpenDriveFromFile(e) { var f, m; this.openDriveClickCallback = e.selectedCallback, this.scaleWatch = $.watch( () => this.view.scale, (u, p) => { u > this.junctionScale && p <= this.junctionScale ? this.updateAllJunctionSymbol("marker") : u <= this.junctionScale && p > this.junctionScale && this.updateAllJunctionSymbol("picture"); } ), console.time("md5用时"); const t = await this.makeMd5FromFile(e.file); if (t.status !== 0) return t; if (this.projectName = t.result.md5, console.timeEnd("md5用时"), this.xodrBorder = t.result.border, this.xodrBorder.length > 0) { const u = new g({ geometry: new L({ rings: [this.xodrBorder] }), symbol: { type: "simple-fill", style: "none", outline: { style: "dash", color: "black", width: 2 } } }); this.borderLayer.add(u); } this.openDriveServer = e.server; const s = `http://${this.openDriveServer}/api/openDrive/uploadXodr`; let o; try { o = await b.post( s, {}, { params: { url: e.file, projectName: this.projectName } } ); } catch (u) { return { status: -1, message: u.message }; } if (o.status !== 200) return { status: -1, message: o.statusText }; console.time("渲染用时"); const i = o.data.result.geoSetting; T.setGeoData( i.geoReference, i.offsetX, i.offsetY ); let c = o.data.result.json; c.startsWith(window.location.protocol) || (c = `${window.location.protocol}//${e.server}${c}`); const a = await (await fetch(c)).arrayBuffer(), n = G.inflate(a, { to: "string" }), l = JSON.parse(n); await this.showAllLanes( l, ((f = e.options) == null ? void 0 : f.showJunctionLane) || !1, ((m = e.options) == null ? void 0 : m.showRoadName) || !0 ); const d = o.data.result.junctions; this.showJunction(d), e.options && e.options.centerMap !== !1 && await this.view.goTo(this.allLaneGraphics), this.mouseMoveHandler || this.monitorMouseMove(), this.mouseClickHandler || this.monitorMouseClick(); const h = R.useAppDataStore; return E( () => h.isSketching, () => { var u, p; h.isSketching ? ((u = this.mouseMoveHandler) == null || u.remove(), this.mouseMoveHandler = void 0, (p = this.mouseClickHandler) == null || p.remove(), this.mouseClickHandler = void 0) : (this.monitorMouseMove(), this.monitorMouseClick()); } ), console.timeEnd("渲染用时"), { status: 0, message: "ok" }; } /** * 从服务器载入OpenDrive文件解析结果并显示 * @param server * @param projectName */ async showOpenDriveFromServer(e, t) { const s = `http://${e}/api/openDrive/analyzeXodr`, o = await b.get(s, { headers: { projectName: t }, params: { analyze: !1, compressed: !0 } }); if (o.status !== 200) throw new Error(`OpenDriveRenderer: ${o.statusText}`); let i = o.data.result.json; i.startsWith(window.location.protocol) || (i = `${window.location.protocol}//${e}${i}`); const r = await (await fetch(i)).arrayBuffer(), a = G.inflate(r, { to: "string" }), n = JSON.parse(a); return await this.showAllLanes(n, !1, !1), { status: 0, message: "ok" }; } /** * 显示所有车道 * @param roads 道路列表 * @param showJunctionLane 是否显示路口内车道 * @param showRoadName 是否显示道路名称 * @returns */ async showAllLanes(e, t, s) { const o = await this.laneLayer.queryFeatures(); return o.features.length > 0 && this.laneLayer.applyEdits({ deleteFeatures: o.features }), this.roadNameLayer.visible = s, new Promise((i) => { let c = 0; this.allLaneGraphics = [], this.allRefLineGraphics = []; const r = []; for (const n of e) { if (!t && n.junction !== "-1") continue; const { id: l, refLine: d } = n; let h = n.name; h.includes("(") && (h = h.slice(0, h.indexOf("("))), h = h.replace(/(.)/g, "$1 "); const f = new g({ geometry: { type: "polyline", paths: [d] }, attributes: { ObjectID: c++, roadId: l, roadName: h } }); this.allRefLineGraphics.push(f), n.laneSections.sort((m, u) => Number(m.id) - Number(u.id)); for (let m = 0; m < n.laneSections.length; m++) { const u = n.laneSections[m], p = Number(u.id); for (const y of u.lanePaths) { const v = Number(y.id); if (v === 0) continue; const I = y.type, O = [...y.outerPath], A = y.innerPath.concat( O.reverse() ); if (A.length <= 3) { console.warn(`lane ${v} has less than 3 points`); continue; } A.push(y.innerPath[0]); const N = new L({ rings: [A] }); if (N) { const j = new g({ geometry: N, attributes: { ObjectID: c++, id: `${l}+${p}+${v}`, fromNode: n.fromNode, toNode: n.toNode, roadId: String(l), roadName: n.name, sectionId: String(p), sectionIndex: m, laneId: v, type: I, sumoId: "", // 记录左右边线的起始点,用于按长度高亮车道的一部分 leftLine: y.innerPath, rightLine: y.outerPath } }); this.allLaneGraphics.push(j), r.push(j); } } } } const a = setInterval(() => { if (r.length > 0 || this.allRefLineGraphics.length > 0) { if (r.length > 0) { const n = r.splice(0, 100); this.laneLayer.applyEdits({ addFeatures: n }); } if (this.allRefLineGraphics.length > 0) { const n = this.allRefLineGraphics.splice(0, 10); this.roadNameLayer.applyEdits({ addFeatures: n }); } } else clearInterval(a), i(); }, 10); }); } /** * 显示路口 * @param params * @returns */ showJunction(e) { const t = []; let s; this.xodrBorder.length > 0 && (s = new L({ rings: [this.xodrBorder] })); for (const o of e) if (o && (this.junctionNames.set(o.id, o.name), o.nodeType = o.type, o.crossId)) { const i = new F({ x: o.coordinates[0], y: o.coordinates[1] }); let c = !0; if (s && (c = S.contains(s, i)), c) { const r = new g({ geometry: i, attributes: { ...o, selected: !1, type: "OpenDriveJunction" }, symbol: this.getCrossGraphicSymbol(o, "marker") }); t.push(r); } } this.junctionLayer.addMany(t); } /** * 监听鼠标移动事件,高亮显示鼠标所在路段和路口 */ monitorMouseMove() { const e = k.debounce(async (t) => { var c; const o = (c = (await this.view.hitTest(t, { include: [this.laneLayer, this.junctionLayer] })).results) == null ? void 0 : c.filter( (r) => r.type === "graphic" ); if (o.length === 0) { this.currentSectionCode !== "" && (this.currentSectionCode = "", this.highlightLayer.removeAll()), this.currentJunctionId !== "" && (this.currentJunctionId = ""), this.view.closePopup(); return; } const i = o[0]; if (this.hitGraphic = i.graphic, i.layer.id === "OpenDriveLane") { const r = `${this.hitGraphic.getAttribute( "roadId" )}+${this.hitGraphic.getAttribute("sectionId")}`; if (this.currentSectionCode === r || this.selectedSectionIds.includes(r) || this.sectionLayer.graphics.findIndex( (p) => p.getAttribute("id") === r ) >= 0) return; this.currentSectionCode = r; const n = this.allLaneGraphics.filter( (p) => `${p.attributes.roadId}+${p.attributes.sectionId}` === r ), l = S.union( n.map((p) => p.geometry) ), d = this.hitGraphic.getAttribute("fromNode"), h = this.hitGraphic.getAttribute("toNode"), f = this.junctionNames.get(d) || d, m = this.junctionNames.get(h) || h, u = new g({ geometry: l, symbol: { type: "simple-fill", color: [0, 255, 255, 0.5], style: "solid", outline: { color: [0, 255, 255], width: 1 } }, attributes: { type: "OpenDriveSection", id: r, selected: !1, fromNodeName: f, toNodeName: m, laneCount: n.length }, popupTemplate: { title: this.hitGraphic.getAttribute("roadName"), content: [ { type: "fields", fieldInfos: [ { fieldName: "fromNodeName", label: "起点路口" }, { fieldName: "toNodeName", label: "终点路口" }, { fieldName: "laneCount", label: "车道数量" } ] } ] } }); this.highlightLayer.removeAll(), this.highlightLayer.add(u); } else if (i.layer.id === "OpenDriveJunction") { const r = this.hitGraphic.getAttribute("id"); if (r === this.currentJunctionId) return; this.currentJunctionId = r; } }); this.mouseMoveHandler = this.view.on("pointer-move", async (t) => { e(t).catch(() => { }); }); } /** * 监听鼠标点击事件,获取高亮要素的拓扑信息 */ monitorMouseClick() { const e = k.debounce(async (t) => { var a; const o = (a = (await this.view.hitTest(t, { include: [this.highlightLayer, this.junctionLayer, this.sectionLayer] })).results) == null ? void 0 : a.filter( (n) => n.type === "graphic" ); if (o.length === 0) return; const i = o[0].graphic, c = i.getAttribute("type"), r = i.getAttribute("id"); if (c === "OpenDriveJunction") if (i.getAttribute("selected") === !1) { const n = `http://${this.openDriveServer}/api/sumo/getSumoJunction`, l = await b.get(n, { params: { id: r, projectName: this.projectName } }); l.status === 200 && l.data.status === 0 && (this.openDriveClickCallback && this.openDriveClickCallback({ type: "OpenDriveJunction", id: r, details: l.data.result }), i.setAttribute("selected", !0), i.symbol = { type: "picture-marker", url: "/GisViewerAssets/Images/point_red.png", width: "20px", height: "20px" }, this.increasePictureMarkerSize(i, 50)); } else this.openDriveClickCallback && this.openDriveClickCallback({ type: "OpenDriveJunction", id: r, details: void 0 }), i.setAttribute("selected", !1), i.symbol = this.getCrossGraphicSymbol( i.attributes, this.view.scale < this.junctionScale ? "picture" : "marker" ); else if (c === "OpenDriveSection") if (i.layer.id === "OpenDriveHighlight") { this.highlightLayer.remove(i), this.sectionLayer.add(i), i.setAttribute("selected", !0), this.selectedSectionIds.push(r); const n = `http://${this.openDriveServer}/api/sumo/getSumoEdge`, l = await b.get(n, { params: { id: r, projectName: this.projectName } }); if (l.status === 200 && l.data.status === 0 && this.openDriveClickCallback) { const d = l.data.result.obj_id; i.setAttribute("edgeId", d), this.openDriveClickCallback({ type: "OpenDriveSection", id: d, details: l.data.result }); } } else this.sectionLayer.remove(i), this.selectedSectionIds = this.selectedSectionIds.filter( (n) => n !== r ), this.openDriveClickCallback && this.openDriveClickCallback({ type: "OpenDriveSection", id: i.getAttribute("edgeId"), details: void 0 }); }); this.mouseClickHandler = this.view.on("immediate-click", async (t) => { e(t).catch(() => { }); }); } /** * 图标增大动画 * @param graphic * @param targetSize */ increasePictureMarkerSize(e, t) { const s = setInterval(() => { const o = e.symbol, i = o.width; i < t ? e.symbol = { type: "picture-marker", url: o.url, width: i + 1, height: i + 1 } : clearInterval(s); }, 20); } /** * 图标缩小动画 * @param graphic * @param targetSize */ decreasePictureMarkerSize(e, t) { const s = setInterval(() => { const o = e.symbol, i = o.width; i > t ? e.symbol = { type: "picture-marker", url: o.url, width: i - 1, height: i - 1 } : clearInterval(s); }, 20); } async getSumoInfo(e) { switch (e.type) { case "junction": { const t = `http://${this.openDriveServer}/api/sumo/getSumoJunction`, s = await b.get(t, { params: { id: e.id, projectName: this.projectName } }); return s.status === 200 ? s.data : { status: -1, message: `路口信息查询失败: ${e.id}` }; } case "edge": { const t = e.id.split("#"); let s = t[0]; s.startsWith("-") && (s = s.slice(1)); let o = 0; t.length === 2 && (o = Number(t[1])); const i = this.allLaneGraphics.find( (c) => c.getAttribute("roadId") === s && c.getAttribute("sectionIndex") === o ); if (i) { const c = `${s}+${i.getAttribute( "sectionId" )}`, r = `http://${this.openDriveServer}/api/sumo/getSumoEdge`, a = await b.get(r, { params: { id: c, projectName: this.projectName } }); return a.status === 200 ? a.data : { status: -1, message: `路段信息查询失败: ${c}` }; } else return { status: -1, message: "未知类型" }; } default: return { status: -1, message: "未知类型" }; } } /** * 清除OpenDrive内容 */ async clearOpenDrive() { var t, s, o; let e = await this.laneLayer.queryFeatures(); e.features.length > 0 && await this.laneLayer.applyEdits({ deleteFeatures: e.features }), e = await this.roadNameLayer.queryFeatures(), e.features.length > 0 && await this.roadNameLayer.applyEdits({ deleteFeatures: e.features }), this.highlightLayer.removeAll(), this.junctionLayer.removeAll(), this.sectionLayer.removeAll(), this.flashLayer.removeAll(), this.borderLayer.removeAll(), (t = this.mouseMoveHandler) == null || t.remove(), this.mouseMoveHandler = void 0, (s = this.mouseClickHandler) == null || s.remove(), this.mouseClickHandler = void 0, (o = this.scaleWatch) == null || o.remove(), this.scaleWatch = void 0; } /** * 用sumo的id定位车道、基本段、路段 * @param params * @returns */ async findSumo(e) { const { type: t, id: s } = e, o = e.flash === void 0 ? !0 : e.flash; if (t === "junction") return await this.findJunction(s, o); if (t === "edge") { const i = s.split("_"); if (i.length > 2) return { status: -1, message: "id格式错误" }; const c = i.length === 2 ? Number(i[1]) : void 0, r = i[0].split("#"); if (r.length > 2) return { status: -1, message: "id格式错误" }; const a = r[0], n = r.length === 2 ? Number(r[1]) : void 0; return await this.findLane({ roadsectId: a, segmentId: n, laneId: c, flash: o }); } else return { status: -1, message: "未知类型" }; } async findJunction(e, t) { const s = this.junctionLayer.graphics.find( (o) => o.attributes.id === e ); if (!s) return { status: -1, message: "未找到。请检查路口编号" }; if (t) { const o = new g({ geometry: s.geometry, symbol: { type: "simple-marker", style: "circle", size: 30, color: [0, 255, 255, 0.8], outline: { color: [0, 255, 255], width: 1 } } }); this.flashGraphic(o); } return await this.view.goTo(s.geometry, { duration: 1e3 }), { status: 0, message: "ok" }; } /** * 用sumo的id定位车道、基本段、路段 * @param params * @returns */ async findLane(e) { let { roadsectId: t, segmentId: s, laneId: o } = e; t.startsWith("-") && (t = t.slice(1)); let i = this.allLaneGraphics.filter( (a) => a.attributes.roadId === t ); if (i.length === 0) return { status: -1, message: "未找到。请检查路段编号" }; if (s !== void 0) { const a = []; if (i.forEach((n) => { const l = Number(n.attributes.sectionId); a.indexOf(l) === -1 && a.push(l); }), a.sort((n, l) => n - l), s > a.length - 1) return { status: -1, message: "未找到。请检查基本段编号" }; s = a[s], i = i.filter( (n) => Number(n.attributes.sectionId) === s ); } if (o !== void 0) { const a = []; if (i.forEach((n) => { const l = Number(n.attributes.laneId); a.indexOf(l) === -1 && a.push(l); }), a.sort((n, l) => n - l), o > a.length - 1) return { status: -1, message: "未找到。请检查车道编号" }; o = a[o], i = i.filter( (n) => Number(n.attributes.laneId) === o ); } const c = i.map( (a) => a.geometry ), r = S.union(c); if (e.flash) { const a = new g({ geometry: r, symbol: { type: "simple-fill", color: [0, 255, 255, 0.6], style: "solid", outline: { width: 0 } } }); this.flashGraphic(a); } return await this.view.goTo(r, { duration: 1e3 }), { status: 0, message: "ok" }; } /** * graphic渐隐渐显闪烁 * @param flashGraphic */ flashGraphic(e) { this.flashLayer.removeAll(), this.flashLayer.add(e); let t = 0, s = !0; const o = setInterval(() => { s ? (this.flashLayer.opacity -= 0.02, this.flashLayer.opacity <= 0.1 && (s = !1, t++)) : (this.flashLayer.opacity += 0.02, this.flashLayer.opacity >= 1 && (s = !0)), t >= 5 && (this.flashLayer.removeAll(), this.flashLayer.opacity = 1, clearInterval(o)); }, 10); } /** * 通过接口取消选中 * @param params * @returns */ unselectSumo(e) { if ((!e || e.type === "junction") && this.junctionLayer.graphics.forEach((t) => { (!e || !e.id || e.id === "" || e.id === t.getAttribute("id")) && t.getAttribute("selected") && (t.setAttribute("selected", !1), t.symbol = this.getCrossGraphicSymbol( t.attributes, this.view.scale < this.junctionScale ? "picture" : "marker" )); }), !e || e.type === "edge") { let t; !e || !e.id || e.id === "" ? t = this.sectionLayer.graphics.toArray() : t = this.sectionLayer.graphics.filter((s) => s.getAttribute("edgeId") === e.id).toArray(), t.length > 0 && (t.forEach((s) => { const o = s.getAttribute("id"); this.selectedSectionIds = this.selectedSectionIds.filter( (i) => i !== o ); }), this.sectionLayer.removeMany(t)); } return { status: 0, message: "ok" }; } /** * 通过接口选中 * @param params * @returns */ selectSumo(e) { switch (e.type) { case "junction": return this.junctionLayer.graphics.forEach((t) => { if (e.id === t.getAttribute("id")) return t.setAttribute("selected", !0), t.symbol.url = "/GisViewerAssets/Images/point_red.png", this.increasePictureMarkerSize(t, 50), { status: 0, message: "ok" }; }), { status: -1, message: "未找到路口" }; case "edge": { const t = e.id.split("#"); let s = String(t[0]); s.startsWith("-") && (s = s.slice(1)); let o = 0; t.length === 2 && (o = Number(t[1])); let i = []; if (t.length === 1 ? i = this.allLaneGraphics.filter( (c) => c.getAttribute("roadId") === s ) : t.length === 2 && (i = this.allLaneGraphics.filter( (c) => c.getAttribute("roadId") === s && c.getAttribute("sectionIndex") === o )), i.length > 0) { const c = /* @__PURE__ */ new Map(); return i.forEach((r) => { const a = r.getAttribute("roadId") + "+" + r.getAttribute("sectionId"); this.selectedSectionIds.includes(a) || this.selectedSectionIds.push(a); let n = c.get(a); n ? n.push(r.geometry) : (n = [r.geometry], c.set(a, n)); }), c.forEach((r, a) => { const n = S.union(r), l = new g({ geometry: n, symbol: { type: "simple-fill", color: [0, 255, 255, 0.5], style: "solid", outline: { color: [0, 255, 255], width: 1 } }, attributes: { type: "OpenDriveSection", id: a, edgeId: e.id, selected: !0 } }); this.sectionLayer.add(l); }), { status: 0, message: "ok" }; } else return { status: -1, message: "未找到路段" }; } default: return { status: -1, message: "未知类型" }; } } async geometrySearch(e) { const t = new L({ rings: [e] }), s = await this.laneLayer.queryFeatures({ geometry: t, outFields: ["*"] }), o = [], i = []; for (const a of s.features) { const n = a.getAttribute("roadId"), l = a.getAttribute("sectionIndex"), d = `${n}#${l}`; if (o.indexOf(d) === -1) { o.push(d), this.selectSumo({ type: "edge", id: d }); const h = `http://${this.openDriveServer}/api/sumo/getSumoEdge`, f = await b.get(h, { params: { id: `${n}+${a.getAttribute("sectionId")}`, projectName: this.projectName } }); f.status === 200 && f.data.status === 0 && i.push(f.data.result); } } const c = this.junctionLayer.graphics.filter((a) => { const n = a.geometry; return S.contains(t, n); }), r = []; for (const a of c) { const n = a.getAttribute("id"); this.selectSumo({ type: "junction", id: n }); const l = `http://${this.openDriveServer}/api/sumo/getSumoJunction`, d = await b.get(l, { params: { id: n, projectName: this.projectName } }); d.status === 200 && d.data.status === 0 && r.push(d.data.result); } return { status: 0, message: "ok", result: { junctions: r, edges: i } }; } async splitLane(e) { const s = e.id.split("_"); if (s.length !== 2) return { status: -1, message: "车道编号格式错误" }; const o = Number(s[1]), i = s[0].split("#"), c = i.length === 2 ? Number(i[1]) : 0; let r = i[0]; r.startsWith("-") && (r = r.slice(1)); const a = this.allLaneGraphics.filter((I) => I.getAttribute("roadId") === r && I.getAttribute("sectionIndex") === c); if (a.length === 0) return { status: -1, message: "未找到路段" }; const n = a.length - o, l = a.find( (I) => Math.abs(I.getAttribute("laneId")) === n ); if (!l) return { status: -1, message: "未找到车道" }; const d = e.start || 0, h = e.end || 100, f = D.lineString(l.getAttribute("leftLine")), m = x(f, d, h, { units: "meters" }), u = D.lineString(l.getAttribute("rightLine")), p = x(u, d, h, { units: "meters" }), y = m.geometry.coordinates.concat( p.geometry.coordinates.reverse() ); y.push(y[y.length - 1]); const v = new g({ geometry: new L({ rings: [y] }), attributes: { ObjectID: l.getAttribute("ObjectID"), id: l.getAttribute("id"), fromNode: l.getAttribute("fromNode"), toNode: l.getAttribute("toNode"), roadId: l.getAttribute("roadId"), roadName: l.getAttribute("roadName"), sectionId: l.getAttribute("sectionId"), sectionIndex: l.getAttribute("sectionIndex"), laneId: l.getAttribute("laneId"), type: l.getAttribute("type"), sumoId: l.getAttribute("sumoId"), leftLine: m.geometry.coordinates, rightLine: p.geometry.coordinates }, symbol: { type: "simple-fill", color: [255, 0, 0, 0.8], outline: { color: "red" } } }); return this.splitLaneLayer.add(v), this.view.goTo(v), { status: 0, message: "ok", result: { coordinates: y } }; } clearSplitLane() { this.splitLaneLayer.removeAll(); } /** * 更新所有路口的symbol * @param symbolStyle */ updateAllJunctionSymbol(e) { const t = this.junctionLayer.graphics.clone(); this.junctionLayer.removeAll(), t.forEach((s) => { s.getAttribute("selected") || (s.symbol = this.getCrossGraphicSymbol( s.attributes, e )); }), this.junctionLayer.addMany(t.toArray()); } /** * 生成路口点符号。在不同比例尺下,使用不同的符号 * @param attributes * @param symbolType * @returns */ getCrossGraphicSymbol(e, t) { const s = e.crossId !== "" && e.crossId !== void 0 && e.crossId !== null; if (t === "marker") return { type: "picture-marker", url: `/GisViewerAssets/Images/cross/${s ? "gis_xhj_blue" : "gis_lkcz_xz"}.png`, width: "32px", height: "32px" }; if (t === "picture") return s ? { type: "cim", data: { type: "CIMSymbolReference", primitiveOverrides: [ { // 将textGraphic的TextString替换为graphic.attributes.name type: "CIMPrimitiveOverride", primitiveName: "textGraphic", propertyName: "TextString", valueExpressionInfo: { type: "CIMExpressionInfo", title: "Custom", expression: 'Replace($feature.name, "与", "/") + " " + $feature.crossId', returnType: "Default" } } ], symbol: { type: "CIMPointSymbol", symbolLayers: [ // 路口名称 { type: "CIMVectorMarker", size: 32, colorLocked: !0, anchorPointUnits: "Relative", frame: { xmin: -16, ymin: -16, xmax: 16, ymax: 16 }, markerGraphics: [ { type: "CIMMarkerGraphic", primitiveName: "textGraphic", geometry: { x: 0, y: 0 }, symbol: { type: "CIMTextSymbol", height: 12, horizontalAlignment: "Center", offsetX: 0, offsetY: s ? 25 : 15, haloSize: 2, haloSymbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [255, 255, 255, 255] } ] }, symbol: { type: "CIMPolygonSymbol", symbolLayers: [ { type: "CIMSolidFill", enable: !0, color: [0, 0, 0, 255] } ] }, verticalAlignment: "Center" }, textString: "" } ], scaleSymbolsProportionally: !0, respectFrame: !0 }, // 路口图标 { type: "CIMPictureMarker", enable: !0, anchorPoint: { x: 0, y: 0 }, anchorPointUnits: "Relative", size: 32, rotateClockwise: !0, textureFilter: "Picture", url: "/GisViewerAssets/Images/cross/gis_xhj_blue.png" } ] } } } : { type: "picture-marker", url: "/GisViewerAssets/Images/cross/gis_lkcz_xz.png", width: "32px", height: "32px" }; } } export { M as default };