gisviewer-vue3-arcgis
Version:
在应用中引入私服的包, 项目根目录下 新建文件 .npmrc 在 .npmrc 中对包源进行配置:
1,204 lines (1,203 loc) • 38.6 kB
JavaScript
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
};