gisviewer-vue3-arcgis
Version:
在应用中引入私服的包, 项目根目录下 新建文件 .npmrc 在 .npmrc 中对包源进行配置:
1,310 lines (1,309 loc) • 42.4 kB
JavaScript
import I from "@arcgis/core/Graphic";
import * as j from "@arcgis/core/core/promiseUtils";
import * as $ from "@arcgis/core/core/reactiveUtils.js";
import { Polygon as S, Point as F } from "@arcgis/core/geometry";
import * as L from "@arcgis/core/geometry/geometryEngine";
import D from "@arcgis/core/layers/FeatureLayer";
import v from "@arcgis/core/layers/GraphicsLayer";
import * as G from "@turf/helpers";
import { lineSliceAlong as x } from "@turf/line-slice-along";
import w from "axios";
import { XMLParser as J } from "fast-xml-parser";
import E from "md5";
import M from "pako";
import { watch as R } from "vue";
import T from "../../../stores/index.mjs";
import A from "../common-utils.mjs";
class O {
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 D({
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"
},
{
name: "roadsectBaseIds",
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 D({
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 v({ id: "OpenDriveJunction" }), this.sectionLayer = new v({ id: "OpenDriveSection" }), this.highlightLayer = new v({ id: "OpenDriveHighlight" }), this.flashLayer = new v({ id: "OpenDriveFlash" }), this.drawLayer = new v({ id: "Draw" }), this.splitLaneLayer = new v({ id: "SplitLane" }), this.borderLayer = new v({ 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 O(e)), this.instance;
}
async makeMd5FromFile(e) {
var i;
try {
const s = await (await fetch(e)).text();
let r = (i = new J({
ignoreAttributes: !1,
allowBooleanAttributes: !0
}).parse(s).OpenDRIVE.userData) == null ? void 0 : i.border;
return r ? r = JSON.parse(r) : r = [], { status: 0, message: "ok", result: { md5: E(s), border: r } };
} catch (o) {
return { status: -1, message: o.message };
}
}
/**
* 从本地文件/网络文件显示OpenDrive内容
* @param params
* @returns
*/
async showOpenDriveFromFile(e) {
var d, y, h;
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");
}
);
let i = e.file.split("/").pop() || "";
i = i.split(".").slice(0, -1).join("."), this.openDriveServer = e.server;
const o = `http://${this.openDriveServer}/api/openDrive/uploadXodr`;
let s;
try {
s = await w.post(
o,
{},
{
params: {
url: e.file,
projectName: i
}
}
);
} catch (u) {
return { status: -1, message: u.message };
}
if (s.status !== 200)
return { status: -1, message: s.statusText };
console.time("渲染用时");
const t = s.data.result.geoSetting;
A.setGeoData(
t.geoReference,
t.offsetX,
t.offsetY
);
let l = s.data.result.json;
l.startsWith(window.location.protocol) || (l = `${window.location.protocol}//${e.server}${l}`);
const r = await fetch(l);
let a;
if (l.endsWith("bin")) {
const u = await r.arrayBuffer(), p = M.inflate(u, { to: "string" });
a = JSON.parse(p);
} else
a = await r.json();
if (await this.showAllLanes(
a,
((d = e.options) == null ? void 0 : d.showJunctionLane) || !1,
((y = e.options) == null ? void 0 : y.showRoadName) || !0
), ((h = e.options) == null ? void 0 : h.showJunctionPoint) !== !1) {
const u = s.data.result.junctions;
this.showJunction(u);
}
e.options && e.options.centerMap !== !1 && await this.view.goTo(this.allLaneGraphics), this.mouseMoveHandler || this.monitorMouseMove(), this.mouseClickHandler || this.monitorMouseClick();
const n = T.useAppDataStore;
return R(
() => n.isSketching,
() => {
var u, p;
n.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, i) {
const o = `http://${e}/api/openDrive/analyzeXodr`, s = await w.get(o, {
headers: {
projectName: i
},
params: {
analyze: !1,
compressed: !0
}
});
if (s.status !== 200)
throw new Error(`OpenDriveRenderer: ${s.statusText}`);
let t = s.data.result.json;
t.startsWith(window.location.protocol) || (t = `${window.location.protocol}//${e}${t}`);
const l = await fetch(t);
let r;
if (t.endsWith("bin")) {
const a = await l.arrayBuffer(), c = M.inflate(a, { to: "string" });
r = JSON.parse(c);
} else
r = await l.json();
return await this.showAllLanes(r, !1, !1), { status: 0, message: "ok" };
}
/**
* 显示所有车道
* @param roads 道路列表
* @param showJunctionLane 是否显示路口内车道
* @param showRoadName 是否显示道路名称
* @returns
*/
async showAllLanes(e, i, o) {
const s = await this.laneLayer.queryFeatures();
return s.features.length > 0 && this.laneLayer.applyEdits({
deleteFeatures: s.features
}), this.roadNameLayer.visible = o, new Promise((t) => {
var c;
let l = 0;
this.allLaneGraphics = [], this.allRefLineGraphics = [];
const r = [];
for (const n of e) {
if (!i && n.junction !== "-1")
continue;
const { id: d, refLine: y } = n;
let h = n.name;
h.includes("(") && (h = h.slice(0, h.indexOf("("))), h = h.replace(/(.)/g, "$1 ");
const u = new I({
geometry: {
type: "polyline",
paths: [y]
},
attributes: {
ObjectID: l++,
roadId: d,
roadName: h
}
});
this.allRefLineGraphics.push(u), n.laneSections.sort((p, g) => Number(p.id) - Number(g.id));
for (let p = 0; p < n.laneSections.length; p++) {
const g = n.laneSections[p], m = Number(g.id);
for (const f of g.lanePaths) {
const b = Number(f.id);
if (b === 0)
continue;
const B = f.type, P = [...f.outerPath], k = f.innerPath.concat(
P.reverse()
);
if (k.length <= 3) {
console.warn(`lane ${b} has less than 3 points`);
continue;
}
k.push(f.innerPath[0]);
const N = new S({
rings: [k]
});
if (N) {
const C = new I({
geometry: N,
attributes: {
ObjectID: l++,
id: `${d}+${m}+${b}`,
fromNode: n.fromNode,
toNode: n.toNode,
roadId: String(d),
roadName: n.name,
sectionId: String(m),
sectionIndex: p,
laneId: b,
type: B,
sumoId: "",
// 记录左右边线的起始点,用于按长度高亮车道的一部分
leftLine: f.innerPath,
rightLine: f.outerPath,
// array转为逗号分隔的字符串
roadsectBaseIds: (c = g.roadsectBaseIds) == null ? void 0 : c.toString()
}
});
this.allLaneGraphics.push(C), r.push(C);
}
}
}
}
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), t();
}, 10);
});
}
/**
* 显示路口
* @param params
* @returns
*/
showJunction(e) {
const i = [];
let o;
this.xodrBorder.length > 0 && (o = new S({
rings: [this.xodrBorder]
}));
for (const s of e)
if (s && (this.junctionNames.set(s.id, s.name), s.nodeType = s.type, s.crossId)) {
const t = new F({
x: s.coordinates[0],
y: s.coordinates[1]
});
let l = !0;
if (o && (l = L.contains(o, t)), l) {
const r = new I({
geometry: t,
attributes: {
...s,
selected: !1,
type: "OpenDriveJunction"
},
symbol: this.getCrossGraphicSymbol(s, "marker")
});
i.push(r);
}
}
this.junctionLayer.addMany(i);
}
/**
* 监听鼠标移动事件,高亮显示鼠标所在路段和路口
*/
monitorMouseMove() {
const e = j.debounce(async (i) => {
var l;
const s = (l = (await this.view.hitTest(i, {
include: [this.laneLayer, this.junctionLayer]
})).results) == null ? void 0 : l.filter(
(r) => r.type === "graphic"
);
if (s.length === 0) {
this.currentSectionCode !== "" && (this.currentSectionCode = "", this.highlightLayer.removeAll()), this.currentJunctionId !== "" && (this.currentJunctionId = ""), this.view.closePopup();
return;
}
const t = s[0];
if (this.hitGraphic = t.graphic, t.layer.id === "OpenDriveLane") {
const r = `${this.hitGraphic.getAttribute(
"roadId"
)}+${this.hitGraphic.getAttribute("sectionId")}`, a = this.hitGraphic.getAttribute("roadsectBaseIds");
if (this.currentSectionCode === r || this.selectedSectionIds.includes(a) || this.sectionLayer.graphics.findIndex(
(m) => m.getAttribute("id") === r
) >= 0)
return;
this.currentSectionCode = r;
const n = this.allLaneGraphics.filter(
(m) => `${m.attributes.roadId}+${m.attributes.sectionId}` === r
), d = L.union(
n.map((m) => m.geometry)
), y = this.hitGraphic.getAttribute("fromNode"), h = this.hitGraphic.getAttribute("toNode"), u = this.junctionNames.get(y) || y, p = this.junctionNames.get(h) || h, g = new I({
geometry: d,
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: u,
toNodeName: p,
laneCount: n.length,
roadsectBaseIds: this.hitGraphic.getAttribute("roadsectBaseIds"),
roadId: this.hitGraphic.getAttribute("roadId")
},
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(g);
} else if (t.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 (i) => {
e(i).catch(() => {
});
});
}
/**
* 监听鼠标点击事件,获取高亮要素的拓扑信息
*/
monitorMouseClick() {
const e = j.debounce(async (i) => {
var a;
const s = (a = (await this.view.hitTest(i, {
include: [this.highlightLayer, this.junctionLayer, this.sectionLayer]
})).results) == null ? void 0 : a.filter(
(c) => c.type === "graphic"
);
if (s.length === 0)
return;
const t = s[0].graphic, l = t.getAttribute("type"), r = t.getAttribute("id");
if (l === "OpenDriveJunction")
if (t.getAttribute("selected") === !1) {
const c = `http://${this.openDriveServer}/api/sumo/getSumoJunction`, n = await w.get(c, {
params: {
id: r,
projectName: this.projectName
}
});
n.status === 200 && n.data.status === 0 && (this.openDriveClickCallback && this.openDriveClickCallback({
type: "OpenDriveJunction",
id: r,
details: n.data.result
}), t.setAttribute("selected", !0), t.symbol = {
type: "picture-marker",
url: "/GisViewerAssets/Images/point_red.png",
width: "20px",
height: "20px"
}, this.increasePictureMarkerSize(t, 50));
} else
this.openDriveClickCallback && this.openDriveClickCallback({
type: "OpenDriveJunction",
id: r,
details: void 0
}), t.setAttribute("selected", !1), t.symbol = this.getCrossGraphicSymbol(
t.attributes,
this.view.scale < this.junctionScale ? "picture" : "marker"
);
else
l === "OpenDriveSection" && (t.layer.id === "OpenDriveHighlight" ? (this.highlightLayer.removeAll(), this.sectionLayer.removeAll(), this.selectedSectionIds = [], this.sectionLayer.add(t), t.setAttribute("selected", !0), this.selectedSectionIds.push(r), this.splitLaneLayer.graphics.filter(
(n) => n.getAttribute("roadsectBaseIds") === t.getAttribute("roadsectBaseIds")
).forEach(
(n) => n.symbol = {
type: "simple-fill",
color: [255, 69, 0],
outline: {
color: "red",
width: 2
}
}
), this.openDriveClickCallback && this.openDriveClickCallback({
type: "OpenDriveSection",
id: t.getAttribute("id"),
details: {
roadsectId: t.getAttribute("roadId"),
roadsectBaseIds: t.getAttribute("roadsectBaseIds")
}
})) : (this.splitLaneLayer.graphics.filter(
(n) => n.getAttribute("roadsectBaseIds") === t.getAttribute("roadsectBaseIds")
).forEach(
(n) => n.symbol = {
type: "simple-fill",
color: [255, 0, 0, 0.8],
outline: {
color: "red",
width: 1
}
}
), this.sectionLayer.remove(t), this.selectedSectionIds = [], this.openDriveClickCallback && this.openDriveClickCallback({
type: "CloseOpenDriveSection",
id: t.getAttribute("roadsectBaseIds"),
details: {
roadsectId: t.getAttribute("roadId"),
roadsectBaseIds: t.getAttribute("roadsectBaseIds")
}
})));
});
this.mouseClickHandler = this.view.on("immediate-click", async (i) => {
e(i).catch(() => {
});
});
}
/**
* 图标增大动画
* @param graphic
* @param targetSize
*/
increasePictureMarkerSize(e, i) {
const o = setInterval(() => {
const s = e.symbol, t = s.width;
t < i ? e.symbol = {
type: "picture-marker",
url: s.url,
width: t + 1,
height: t + 1
} : clearInterval(o);
}, 20);
}
/**
* 图标缩小动画
* @param graphic
* @param targetSize
*/
decreasePictureMarkerSize(e, i) {
const o = setInterval(() => {
const s = e.symbol, t = s.width;
t > i ? e.symbol = {
type: "picture-marker",
url: s.url,
width: t - 1,
height: t - 1
} : clearInterval(o);
}, 20);
}
async getSumoInfo(e) {
switch (e.type) {
case "junction": {
const i = `http://${this.openDriveServer}/api/sumo/getSumoJunction`, o = await w.get(i, {
params: {
id: e.id,
projectName: this.projectName
}
});
return o.status === 200 ? o.data : { status: -1, message: `路口信息查询失败: ${e.id}` };
}
case "edge": {
const i = e.id.split("#");
let o = i[0];
o.startsWith("-") && (o = o.slice(1));
let s = 0;
i.length === 2 && (s = Number(i[1]));
const t = this.allLaneGraphics.find(
(l) => l.getAttribute("roadId") === o && l.getAttribute("sectionIndex") === s
);
if (t) {
const l = `${o}+${t.getAttribute(
"sectionId"
)}`, r = `http://${this.openDriveServer}/api/sumo/getSumoEdge`, a = await w.get(r, {
params: {
id: l,
projectName: this.projectName
}
});
return a.status === 200 ? a.data : { status: -1, message: `路段信息查询失败: ${l}` };
} else
return { status: -1, message: "未知类型" };
}
default:
return { status: -1, message: "未知类型" };
}
}
setOpendriveVisibility(e) {
this.laneLayer.visible = e;
}
/**
* 清除OpenDrive内容
*/
async clearOpenDrive() {
var i, o, s;
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(), (i = this.mouseMoveHandler) == null || i.remove(), this.mouseMoveHandler = void 0, (o = this.mouseClickHandler) == null || o.remove(), this.mouseClickHandler = void 0, (s = this.scaleWatch) == null || s.remove(), this.scaleWatch = void 0;
}
/**
* 用sumo的id定位车道、基本段、路段
* @param params
* @returns
*/
async findSumo(e) {
const { type: i, id: o } = e, s = e.flash === void 0 ? !0 : e.flash;
if (i === "junction")
return await this.findJunction(o, s);
if (i === "edge") {
const t = o.split("_");
if (t.length > 2)
return { status: -1, message: "id格式错误" };
const l = t.length === 2 ? Number(t[1]) : void 0, r = t[0].split("#");
if (r.length > 2)
return { status: -1, message: "id格式错误" };
const a = r[0], c = r.length === 2 ? Number(r[1]) : void 0;
return await this.findLane({ roadsectId: a, segmentId: c, laneId: l, flash: s });
} else
return { status: -1, message: "未知类型" };
}
async findJunction(e, i) {
const o = this.junctionLayer.graphics.find(
(s) => s.attributes.id === e
);
if (!o)
return { status: -1, message: "未找到。请检查路口编号" };
if (i) {
const s = new I({
geometry: o.geometry,
symbol: {
type: "simple-marker",
style: "circle",
size: 30,
color: [0, 255, 255, 0.8],
outline: {
color: [0, 255, 255],
width: 1
}
}
});
this.flashGraphic(s);
}
return await this.view.goTo(o.geometry, { duration: 1e3 }), { status: 0, message: "ok" };
}
/**
* 用sumo的id定位车道、基本段、路段
* @param params
* @returns
*/
async findLane(e) {
let { roadsectId: i, segmentId: o, laneId: s } = e;
i.startsWith("-") && (i = i.slice(1));
let t = this.allLaneGraphics.filter(
(a) => a.attributes.roadId === i
);
if (t.length === 0)
return { status: -1, message: "未找到。请检查路段编号" };
if (o !== void 0) {
const a = [];
if (t.forEach((c) => {
const n = Number(c.attributes.sectionId);
a.indexOf(n) === -1 && a.push(n);
}), a.sort((c, n) => c - n), o > a.length - 1)
return { status: -1, message: "未找到。请检查基本段编号" };
o = a[o], t = t.filter(
(c) => Number(c.attributes.sectionId) === o
);
}
if (s !== void 0) {
const a = [];
if (t.forEach((c) => {
const n = Number(c.attributes.laneId);
a.indexOf(n) === -1 && a.push(n);
}), a.sort((c, n) => c - n), s > a.length - 1)
return { status: -1, message: "未找到。请检查车道编号" };
s = a[s], t = t.filter(
(c) => Number(c.attributes.laneId) === s
);
}
const l = t.map(
(a) => a.geometry
), r = L.union(l);
if (e.flash) {
const a = new I({
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 i = 0, o = !0;
const s = setInterval(() => {
o ? (this.flashLayer.opacity -= 0.02, this.flashLayer.opacity <= 0.1 && (o = !1, i++)) : (this.flashLayer.opacity += 0.02, this.flashLayer.opacity >= 1 && (o = !0)), i >= 5 && (this.flashLayer.removeAll(), this.flashLayer.opacity = 1, clearInterval(s));
}, 10);
}
/**
* 通过接口取消选中
* @param params
* @returns
*/
unselectSumo(e) {
if (e ? e.type === "junction" && this.junctionLayer.graphics.forEach((i) => {
(!e || !e.id || e.id === "" || e.id === i.getAttribute("id")) && i.getAttribute("selected") && (i.setAttribute("selected", !1), i.symbol = this.getCrossGraphicSymbol(
i.attributes,
this.view.scale < this.junctionScale ? "picture" : "marker"
));
}) : (this.highlightLayer.removeAll(), this.sectionLayer.removeAll(), this.selectedSectionIds = [], this.splitLaneLayer.removeAll()), !e || e.type === "edge") {
let i;
!e || !e.id || e.id === "" ? i = this.sectionLayer.graphics.toArray() : i = this.sectionLayer.graphics.filter((o) => o.getAttribute("edgeId") === e.id).toArray(), i.length > 0 && (i.forEach((o) => {
const s = o.getAttribute("id");
this.selectedSectionIds = this.selectedSectionIds.filter(
(t) => t !== s
);
}), this.sectionLayer.removeMany(i));
}
return { status: 0, message: "ok" };
}
/**
* 通过接口选中
* @param params
* @returns
*/
async selectSumo(e) {
switch (e.type) {
case "junction":
return this.junctionLayer.graphics.forEach((i) => {
if (e.id === i.getAttribute("id"))
return i.setAttribute("selected", !0), i.symbol.url = "/GisViewerAssets/Images/point_red.png", this.increasePictureMarkerSize(i, 50), { status: 0, message: "ok" };
}), { status: -1, message: "未找到路口" };
case "edge": {
const i = e.id.split("#");
let o = String(i[0]);
o.startsWith("-") && (o = o.slice(1));
let s = 0;
i.length === 2 && (s = Number(i[1]));
let t = [];
if (i.length === 1 ? t = this.allLaneGraphics.filter(
(l) => l.getAttribute("roadId") === o
) : i.length === 2 && (t = this.allLaneGraphics.filter(
(l) => l.getAttribute("roadId") === o && l.getAttribute("sectionIndex") === s
)), t.length > 0) {
const l = /* @__PURE__ */ new Map();
return t.forEach((r) => {
const a = r.getAttribute("roadId") + "+" + r.getAttribute("sectionId");
this.selectedSectionIds.includes(a) || this.selectedSectionIds.push(a);
let c = l.get(a);
c ? c.push(r.geometry) : (c = [r.geometry], l.set(a, c));
}), l.forEach(async (r, a) => {
const c = L.union(r), n = new I({
geometry: c,
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(n), await this.view.goTo(n);
}), { status: 0, message: "ok" };
} else
return { status: -1, message: "未找到路段" };
}
default:
return { status: -1, message: "未知类型" };
}
}
async geometrySearch(e) {
const i = new S({
rings: [e]
}), o = await this.laneLayer.queryFeatures({
geometry: i,
outFields: ["*"]
}), s = [], t = [];
for (const a of o.features) {
const c = a.getAttribute("roadId"), n = a.getAttribute("sectionIndex"), d = `${c}#${n}`;
if (s.indexOf(d) === -1) {
s.push(d), this.selectSumo({
type: "edge",
id: d
});
const y = `http://${this.openDriveServer}/api/sumo/getSumoEdge`, h = await w.get(y, {
params: {
id: `${c}+${a.getAttribute("sectionId")}`,
projectName: this.projectName
}
});
h.status === 200 && h.data.status === 0 && t.push(h.data.result);
}
}
const l = this.junctionLayer.graphics.filter((a) => {
const c = a.geometry;
return L.contains(i, c);
}), r = [];
for (const a of l) {
const c = a.getAttribute("id");
this.selectSumo({
type: "junction",
id: c
});
const n = `http://${this.openDriveServer}/api/sumo/getSumoJunction`, d = await w.get(n, {
params: {
id: c,
projectName: this.projectName
}
});
d.status === 200 && d.data.status === 0 && r.push(d.data.result);
}
return {
status: 0,
message: "ok",
result: {
junctions: r,
edges: t
}
};
}
/**
* 封闭车道,使用sumo的id
* @param params
* @returns
*/
async splitLane(e) {
const o = e.id.split("_");
if (o.length !== 2)
return { status: -1, message: "车道编号格式错误" };
const s = Number(o[1]), t = o[0].split("#"), l = t.length === 2 ? Number(t[1]) : 0;
let r = t[0];
r.startsWith("-") && (r = r.slice(1));
const a = this.allLaneGraphics.filter((b) => b.getAttribute("roadId") === r && b.getAttribute("sectionIndex") === l);
if (a.length === 0)
return { status: -1, message: "未找到路段" };
const c = a.length - s, n = a.find(
(b) => Math.abs(b.getAttribute("laneId")) === c
);
if (!n)
return { status: -1, message: "未找到车道" };
const d = e.start || 0, y = e.end || 100, h = G.lineString(n.getAttribute("leftLine")), u = x(h, d, y, {
units: "meters"
}), p = G.lineString(n.getAttribute("rightLine")), g = x(p, d, y, {
units: "meters"
}), m = u.geometry.coordinates.concat(
g.geometry.coordinates.reverse()
);
m.push(m[m.length - 1]);
const f = new I({
geometry: new S({
rings: [m]
}),
attributes: {
ObjectID: n.getAttribute("ObjectID"),
id: n.getAttribute("id"),
fromNode: n.getAttribute("fromNode"),
toNode: n.getAttribute("toNode"),
roadId: n.getAttribute("roadId"),
roadName: n.getAttribute("roadName"),
sectionId: n.getAttribute("sectionId"),
sectionIndex: n.getAttribute("sectionIndex"),
laneId: n.getAttribute("laneId"),
type: n.getAttribute("type"),
sumoId: n.getAttribute("sumoId"),
leftLine: u.geometry.coordinates,
rightLine: g.geometry.coordinates
},
symbol: {
type: "simple-fill",
color: [255, 0, 0, 0.8],
outline: {
color: "red"
}
}
});
return this.splitLaneLayer.add(f), A.viewGoto(this.view, [f]), { status: 0, message: "ok", result: { coordinates: m } };
}
clearSplitLane() {
this.splitLaneLayer.removeAll();
}
/**
* 封闭车道,使用可计算路网的id
* @param params
*/
blockLane(e) {
const i = this.allLaneGraphics.filter((s) => {
var l;
let t = String(s.getAttribute("laneId"));
return t.startsWith("-") && (t = t.slice(1)), s.getAttribute("roadId") === e.roadsectId && ((l = s.getAttribute("roadsectBaseIds")) == null ? void 0 : l.includes(e.roadsectBaseId)) && t === String(e.laneId);
}), o = i.map((s) => {
const t = s.clone();
return t.symbol = {
type: "simple-fill",
color: this.selectedSectionIds.includes(
i[0].getAttribute("roadsectBaseIds")
) ? [255, 69, 0, 0.8] : [255, 0, 0, 0.8],
outline: {
color: "red"
}
}, t;
});
this.splitLaneLayer.addMany(o), A.viewGoto(this.view, o);
}
/**
* 解除封闭车道,使用可计算路网id
* @param params
*/
clearBlockLane(e) {
const i = this.splitLaneLayer.graphics.filter((o) => {
const s = o.getAttribute("roadId"), t = o.getAttribute("roadsectBaseIds");
let l = String(o.getAttribute("laneId"));
return l.startsWith("-") && (l = l.slice(1)), s === e.roadsectId && (t == null ? void 0 : t.includes(e.roadsectBaseId)) && l === String(e.laneId);
});
this.splitLaneLayer.removeMany(i.toArray());
}
selectComputable(e) {
if (e.type === "roadsectBase") {
const i = this.allLaneGraphics.filter((o) => {
var s;
return (s = o.getAttribute("roadsectBaseIds")) == null ? void 0 : s.includes(e.id);
});
if (i.length > 0) {
const o = L.union(
i.map((r) => r.geometry)
), s = i[0].getAttribute("roadsectBaseIds"), t = new I({
geometry: o,
symbol: {
type: "simple-fill",
color: [0, 255, 255, 0.5],
style: "solid",
outline: {
color: [0, 255, 255],
width: 1
}
},
attributes: {
type: "OpenDriveSection",
roadsectBaseIds: s
}
});
this.sectionLayer.removeAll(), this.sectionLayer.add(t), A.viewGoto(this.view, [t]), this.selectedSectionIds = [s];
const l = this.splitLaneLayer.graphics.filter(
(r) => {
var a;
return (a = r.getAttribute("roadsectBaseIds")) == null ? void 0 : a.includes(e.id);
}
);
l.length > 0 && l.forEach(
(r) => r.symbol = {
type: "simple-fill",
color: [255, 69, 0],
outline: {
color: "red",
width: 2
}
}
);
}
}
}
/**
* 更新所有路口的symbol
* @param symbolStyle
*/
updateAllJunctionSymbol(e) {
const i = this.junctionLayer.graphics.clone();
this.junctionLayer.removeAll(), i.forEach((o) => {
o.getAttribute("selected") || (o.symbol = this.getCrossGraphicSymbol(
o.attributes,
e
));
}), this.junctionLayer.addMany(i.toArray());
}
/**
* 生成路口点符号。在不同比例尺下,使用不同的符号
* @param attributes
* @param symbolType
* @returns
*/
getCrossGraphicSymbol(e, i) {
const o = e.crossId !== "" && e.crossId !== void 0 && e.crossId !== null;
if (i === "marker")
return {
type: "picture-marker",
url: `/GisViewerAssets/Images/cross/${o ? "gis_xhj_blue" : "gis_lkcz_xz"}.png`,
width: "32px",
height: "32px"
};
if (i === "picture")
return o ? {
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: o ? 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 {
O as default
};