gisviewer-vue3-arcgis 1.0.263 → 1.0.265
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/src/gis-map/utils/open-drive-renderer/index.mjs +159 -148
- package/es/src/gis-map/utils/signal-control-area/cross-renderer.d.ts +17 -2
- package/es/src/gis-map/utils/signal-control-area/cross-renderer.mjs +104 -74
- package/es/src/gis-map/utils/signal-control-area/show-area.mjs +11 -11
- package/es/src/types/index.d.ts +1 -0
- package/lib/src/gis-map/utils/open-drive-renderer/index.js +1 -1
- package/lib/src/gis-map/utils/signal-control-area/cross-renderer.d.ts +17 -2
- package/lib/src/gis-map/utils/signal-control-area/cross-renderer.js +1 -1
- package/lib/src/gis-map/utils/signal-control-area/show-area.js +1 -1
- package/lib/src/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,20 +1,29 @@
|
|
|
1
|
+
import { IFindSignalControlAreaParams } from 'packages/components/src/types';
|
|
1
2
|
import DistrictController from './district-controller';
|
|
2
3
|
export default class CrossRenderer {
|
|
3
4
|
private view;
|
|
4
5
|
private crossLayer;
|
|
5
6
|
private crossGraphicSymbol;
|
|
6
7
|
private locations;
|
|
8
|
+
private clusteredLocations;
|
|
9
|
+
private filteredLocations;
|
|
7
10
|
private currentShowMode;
|
|
8
11
|
private zoomWatchHandle;
|
|
9
12
|
private symbolScale;
|
|
10
|
-
private
|
|
13
|
+
private oldScale;
|
|
11
14
|
private readonly clusterRadius;
|
|
12
15
|
private readonly minClusterPoints;
|
|
13
16
|
private readonly maxClusterSymbolSize;
|
|
14
17
|
private readonly minClusterSymbolSize;
|
|
15
18
|
constructor(view: __esri.MapView | __esri.SceneView);
|
|
16
19
|
addCrosses(controllers: DistrictController[]): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* 清除所有路口
|
|
22
|
+
*/
|
|
17
23
|
clearCrosses(): void;
|
|
24
|
+
/**
|
|
25
|
+
* 更新散点符号
|
|
26
|
+
*/
|
|
18
27
|
private updateScatterSymbol;
|
|
19
28
|
/**
|
|
20
29
|
* 将地理位置转换为屏幕坐标
|
|
@@ -29,7 +38,13 @@ export default class CrossRenderer {
|
|
|
29
38
|
*/
|
|
30
39
|
showScatter(): void;
|
|
31
40
|
/**
|
|
32
|
-
*
|
|
41
|
+
* 隐藏路口
|
|
42
|
+
*/
|
|
43
|
+
hideCrosses(): void;
|
|
44
|
+
filter(params: IFindSignalControlAreaParams): void;
|
|
45
|
+
resetFilter(): void;
|
|
46
|
+
/**
|
|
47
|
+
* 根据当前比例尺更新路口符号
|
|
33
48
|
* @param attributes
|
|
34
49
|
* @returns
|
|
35
50
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Point as
|
|
1
|
+
import { Point as h } from "@arcgis/core/geometry";
|
|
2
2
|
import u from "@arcgis/core/Graphic";
|
|
3
|
-
import
|
|
4
|
-
class
|
|
3
|
+
import d from "@arcgis/core/layers/GraphicsLayer";
|
|
4
|
+
class C {
|
|
5
5
|
constructor(e) {
|
|
6
6
|
this.crossGraphicSymbol = {
|
|
7
7
|
type: "cim",
|
|
@@ -85,7 +85,7 @@ class f {
|
|
|
85
85
|
]
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
}, this.locations = [], this.currentShowMode = "scatter", this.symbolScale = 5e3, this.
|
|
88
|
+
}, this.locations = [], this.clusteredLocations = [], this.filteredLocations = [], this.currentShowMode = "scatter", this.symbolScale = 5e3, this.oldScale = 0, this.clusterRadius = 120, this.minClusterPoints = 2, this.maxClusterSymbolSize = 50, this.minClusterSymbolSize = 25, this.view = e, this.crossLayer = new d(), this.view.map.add(this.crossLayer), this.oldScale = e.scale;
|
|
89
89
|
}
|
|
90
90
|
async addCrosses(e) {
|
|
91
91
|
e.forEach((t) => {
|
|
@@ -95,8 +95,13 @@ class f {
|
|
|
95
95
|
x: r.longitude,
|
|
96
96
|
y: r.latitude,
|
|
97
97
|
visited: !1,
|
|
98
|
+
filtered: !1,
|
|
98
99
|
clusterId: void 0,
|
|
99
|
-
properties:
|
|
100
|
+
properties: {
|
|
101
|
+
...r,
|
|
102
|
+
districtId: t.id,
|
|
103
|
+
subDistrictId: ""
|
|
104
|
+
}
|
|
100
105
|
});
|
|
101
106
|
}), t.subDistricts.forEach((r) => {
|
|
102
107
|
r.signals.forEach((s) => {
|
|
@@ -105,31 +110,38 @@ class f {
|
|
|
105
110
|
x: s.longitude,
|
|
106
111
|
y: s.latitude,
|
|
107
112
|
visited: !1,
|
|
113
|
+
filtered: !1,
|
|
108
114
|
clusterId: void 0,
|
|
109
|
-
properties:
|
|
115
|
+
properties: {
|
|
116
|
+
...s,
|
|
117
|
+
districtId: t.id,
|
|
118
|
+
subDistrictId: r.id
|
|
119
|
+
}
|
|
110
120
|
});
|
|
111
121
|
});
|
|
112
122
|
});
|
|
113
|
-
}), this.zoomWatchHandle = this.view.watch(
|
|
114
|
-
|
|
115
|
-
(t, r) => {
|
|
123
|
+
}), this.zoomWatchHandle = this.view.watch("stationary", () => {
|
|
124
|
+
if (this.view.stationary !== !1) {
|
|
116
125
|
if (this.currentShowMode === "scatter")
|
|
117
|
-
(
|
|
118
|
-
else if (this.currentShowMode === "cluster"
|
|
119
|
-
this.
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
this.minClusterPoints
|
|
123
|
-
);
|
|
124
|
-
console.timeEnd("cluster"), this.showClusterResult(s);
|
|
126
|
+
(this.oldScale < this.symbolScale && this.view.scale >= this.symbolScale || this.oldScale >= this.symbolScale && this.view.scale < this.symbolScale) && this.updateScatterSymbol(), this.oldScale = this.view.scale;
|
|
127
|
+
else if (this.currentShowMode === "cluster") {
|
|
128
|
+
this.locationToScreen(), console.time("cluster");
|
|
129
|
+
const t = this.doPixelCluster(this.clusterRadius);
|
|
130
|
+
console.timeEnd("cluster"), this.showClusterResult(t);
|
|
125
131
|
}
|
|
126
132
|
}
|
|
127
|
-
);
|
|
133
|
+
});
|
|
128
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* 清除所有路口
|
|
137
|
+
*/
|
|
129
138
|
clearCrosses() {
|
|
130
139
|
var e;
|
|
131
|
-
console.log("Clearing crosses"), this.crossLayer.removeAll(), this.locations = [], (e = this.zoomWatchHandle) == null || e.remove();
|
|
140
|
+
console.log("Clearing crosses"), this.crossLayer.removeAll(), this.locations = [], this.clusteredLocations = [], (e = this.zoomWatchHandle) == null || e.remove();
|
|
132
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* 更新散点符号
|
|
144
|
+
*/
|
|
133
145
|
updateScatterSymbol() {
|
|
134
146
|
this.crossLayer.graphics.forEach((e) => {
|
|
135
147
|
e.symbol = this.getCrossSymbol(e.attributes);
|
|
@@ -139,11 +151,11 @@ class f {
|
|
|
139
151
|
* 将地理位置转换为屏幕坐标
|
|
140
152
|
*/
|
|
141
153
|
locationToScreen() {
|
|
142
|
-
this.locations.forEach((e) => {
|
|
154
|
+
this.clusteredLocations = [], this.locations.forEach((e) => {
|
|
143
155
|
const t = this.view.toScreen(
|
|
144
|
-
new
|
|
156
|
+
new h({ x: e.x, y: e.y })
|
|
145
157
|
);
|
|
146
|
-
e.properties.screenX = t.x, e.properties.screenY = t.y;
|
|
158
|
+
e.filtered === !1 && t.x > 0 && t.y > 0 && (e.properties.screenX = t.x, e.properties.screenY = t.y, e.visited = !1, e.clusterId = void 0, this.clusteredLocations.push(e));
|
|
147
159
|
});
|
|
148
160
|
}
|
|
149
161
|
/**
|
|
@@ -151,10 +163,7 @@ class f {
|
|
|
151
163
|
*/
|
|
152
164
|
showCluster() {
|
|
153
165
|
this.crossLayer.removeAll(), this.currentShowMode = "cluster", this.locationToScreen();
|
|
154
|
-
const e = this.doPixelCluster(
|
|
155
|
-
this.clusterRadius,
|
|
156
|
-
this.minClusterPoints
|
|
157
|
-
);
|
|
166
|
+
const e = this.doPixelCluster(this.clusterRadius);
|
|
158
167
|
this.showClusterResult(e);
|
|
159
168
|
}
|
|
160
169
|
/**
|
|
@@ -162,19 +171,45 @@ class f {
|
|
|
162
171
|
*/
|
|
163
172
|
showScatter() {
|
|
164
173
|
this.crossLayer.removeAll(), this.currentShowMode = "scatter";
|
|
165
|
-
const e =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
const e = [];
|
|
175
|
+
this.locations.forEach((t) => {
|
|
176
|
+
if (!t.filtered) {
|
|
177
|
+
const r = new u({
|
|
178
|
+
geometry: {
|
|
179
|
+
type: "point",
|
|
180
|
+
longitude: t.x,
|
|
181
|
+
latitude: t.y
|
|
182
|
+
},
|
|
183
|
+
symbol: this.getCrossSymbol(t.properties),
|
|
184
|
+
attributes: t.properties
|
|
185
|
+
});
|
|
186
|
+
e.push(r);
|
|
187
|
+
}
|
|
188
|
+
}), this.crossLayer.addMany(e);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 隐藏路口
|
|
192
|
+
*/
|
|
193
|
+
hideCrosses() {
|
|
194
|
+
this.crossLayer.removeAll();
|
|
195
|
+
}
|
|
196
|
+
filter(e) {
|
|
197
|
+
this.locations.forEach((t) => {
|
|
198
|
+
if (e.type === "district")
|
|
199
|
+
t.filtered = t.properties.districtId === e.id;
|
|
200
|
+
else if (e.type === "subDistrict")
|
|
201
|
+
t.filtered = t.properties.subDistrictId === e.id;
|
|
202
|
+
else if (e.type === "signal" && (t.filtered = t.id === e.id, t.filtered))
|
|
203
|
+
return t.properties;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
resetFilter() {
|
|
207
|
+
this.locations.forEach((e) => {
|
|
208
|
+
e.filtered = !1;
|
|
209
|
+
});
|
|
175
210
|
}
|
|
176
211
|
/**
|
|
177
|
-
*
|
|
212
|
+
* 根据当前比例尺更新路口符号
|
|
178
213
|
* @param attributes
|
|
179
214
|
* @returns
|
|
180
215
|
*/
|
|
@@ -295,7 +330,7 @@ class f {
|
|
|
295
330
|
* @returns
|
|
296
331
|
*/
|
|
297
332
|
getNeighbors(e, t) {
|
|
298
|
-
return this.
|
|
333
|
+
return this.clusteredLocations.filter((r) => r.id === e.id || r.visited ? !1 : this.getDistance(e, r) <= t);
|
|
299
334
|
}
|
|
300
335
|
/**
|
|
301
336
|
* 两点间的像素距离
|
|
@@ -313,30 +348,28 @@ class f {
|
|
|
313
348
|
* @param locations
|
|
314
349
|
* @returns
|
|
315
350
|
*/
|
|
316
|
-
createClusters(
|
|
317
|
-
const
|
|
318
|
-
for (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const s = Object.keys(t).map((i, o) => {
|
|
323
|
-
const a = t[Number(i)], l = a.length, n = a.reduce((c, m) => c + m.x, 0), h = a.reduce((c, m) => c + m.y, 0), p = n / l, d = h / l;
|
|
351
|
+
createClusters() {
|
|
352
|
+
const e = {}, t = [];
|
|
353
|
+
for (const s of this.clusteredLocations)
|
|
354
|
+
s.clusterId === void 0 || s.clusterId === -1 ? t.push(s) : (e[s.clusterId] || (e[s.clusterId] = []), e[s.clusterId].push(s));
|
|
355
|
+
const r = Object.keys(e).map((s, i) => {
|
|
356
|
+
const o = e[Number(s)], a = o.length, l = o.reduce((n, y) => n + y.x, 0), c = o.reduce((n, y) => n + y.y, 0), m = l / a, p = c / a;
|
|
324
357
|
return {
|
|
325
|
-
id: Number(
|
|
326
|
-
items:
|
|
327
|
-
count:
|
|
358
|
+
id: Number(s),
|
|
359
|
+
items: o,
|
|
360
|
+
count: a,
|
|
328
361
|
center: {
|
|
329
|
-
x:
|
|
330
|
-
y:
|
|
362
|
+
x: m,
|
|
363
|
+
y: p
|
|
331
364
|
}
|
|
332
365
|
};
|
|
333
366
|
});
|
|
334
|
-
return
|
|
367
|
+
return t.length > 0 && r.push({
|
|
335
368
|
id: -1,
|
|
336
|
-
items:
|
|
337
|
-
count:
|
|
369
|
+
items: t,
|
|
370
|
+
count: t.length,
|
|
338
371
|
center: null
|
|
339
|
-
}),
|
|
372
|
+
}), r;
|
|
340
373
|
}
|
|
341
374
|
/**
|
|
342
375
|
* 按照像素距离聚类
|
|
@@ -345,22 +378,19 @@ class f {
|
|
|
345
378
|
* @param minPoints
|
|
346
379
|
* @returns
|
|
347
380
|
*/
|
|
348
|
-
doPixelCluster(e
|
|
349
|
-
let
|
|
350
|
-
this.
|
|
351
|
-
s
|
|
352
|
-
|
|
353
|
-
for (let s = 0; s < this.locations.length; s++) {
|
|
354
|
-
const i = this.locations[s];
|
|
355
|
-
if (i.visited)
|
|
381
|
+
doPixelCluster(e) {
|
|
382
|
+
let t = 0;
|
|
383
|
+
for (let r = 0; r < this.clusteredLocations.length; r++) {
|
|
384
|
+
const s = this.clusteredLocations[r];
|
|
385
|
+
if (s.visited)
|
|
356
386
|
continue;
|
|
357
|
-
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}),
|
|
387
|
+
s.visited = !0;
|
|
388
|
+
const i = this.getNeighbors(s, e);
|
|
389
|
+
i.length < this.minClusterPoints ? s.clusterId = -1 : (i.forEach((o) => {
|
|
390
|
+
o.visited = !0, o.clusterId = t;
|
|
391
|
+
}), s.clusterId = t, t++);
|
|
362
392
|
}
|
|
363
|
-
return this.createClusters(
|
|
393
|
+
return this.createClusters();
|
|
364
394
|
}
|
|
365
395
|
showClusterResult(e) {
|
|
366
396
|
this.crossLayer.removeAll();
|
|
@@ -371,8 +401,8 @@ class f {
|
|
|
371
401
|
if (s.id !== -1) {
|
|
372
402
|
let i = r === t ? (this.maxClusterSymbolSize + this.minClusterSymbolSize) / 2 : this.minClusterSymbolSize + (s.count - r) / (t - r) * (this.maxClusterSymbolSize - this.minClusterSymbolSize);
|
|
373
403
|
i *= 0.75;
|
|
374
|
-
const l = (s.count.toString().length * 8 + 6) / 2,
|
|
375
|
-
geometry: new
|
|
404
|
+
const l = (s.count.toString().length * 8 + 6) / 2, c = new u({
|
|
405
|
+
geometry: new h({ x: s.center.x, y: s.center.y }),
|
|
376
406
|
attributes: {
|
|
377
407
|
count: s.count
|
|
378
408
|
},
|
|
@@ -484,11 +514,11 @@ class f {
|
|
|
484
514
|
}
|
|
485
515
|
}
|
|
486
516
|
});
|
|
487
|
-
this.crossLayer.add(
|
|
517
|
+
this.crossLayer.add(c);
|
|
488
518
|
} else
|
|
489
519
|
s.items.forEach((i) => {
|
|
490
520
|
const o = new u({
|
|
491
|
-
geometry: new
|
|
521
|
+
geometry: new h({ x: i.x, y: i.y }),
|
|
492
522
|
attributes: {
|
|
493
523
|
...i,
|
|
494
524
|
...i.properties,
|
|
@@ -503,5 +533,5 @@ class f {
|
|
|
503
533
|
}
|
|
504
534
|
}
|
|
505
535
|
export {
|
|
506
|
-
|
|
536
|
+
C as default
|
|
507
537
|
};
|
|
@@ -18,15 +18,15 @@ class f {
|
|
|
18
18
|
*/
|
|
19
19
|
async showSignalControlArea(t) {
|
|
20
20
|
await this.clearSignalControlArea(), this.districtRenderer.setVisible(!1), this.subDistrictRenderer.setVisible(!1), this.signalRenderer.setClusterVisible(!1), this.signalRenderer.setPointVisible(!1);
|
|
21
|
-
const s = [],
|
|
22
|
-
for (const
|
|
21
|
+
const s = [], e = [];
|
|
22
|
+
for (const i of t.areaList) {
|
|
23
23
|
const n = new r(
|
|
24
|
-
|
|
24
|
+
i,
|
|
25
25
|
t.style || ""
|
|
26
26
|
);
|
|
27
|
-
s.push(n),
|
|
27
|
+
s.push(n), e.push(...n.subDistricts);
|
|
28
28
|
}
|
|
29
|
-
return this.districtRenderer.style = t.style || "", await this.districtRenderer.showDistricts(s), await this.subDistrictRenderer.showSubDistricts(
|
|
29
|
+
return this.districtRenderer.style = t.style || "", await this.districtRenderer.showDistricts(s), await this.subDistrictRenderer.showSubDistricts(e), await this.signalRenderer.showSignals(s), { status: 0, message: "ok" };
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* 显示单个区控
|
|
@@ -81,10 +81,10 @@ class f {
|
|
|
81
81
|
this.subDistrictRenderer.setVisible(t.visible);
|
|
82
82
|
break;
|
|
83
83
|
case "signal":
|
|
84
|
-
this.crossRenderer.showScatter();
|
|
84
|
+
t.visible === !1 ? this.crossRenderer.hideCrosses() : this.crossRenderer.showScatter();
|
|
85
85
|
break;
|
|
86
86
|
case "signalCluster":
|
|
87
|
-
this.crossRenderer.showCluster();
|
|
87
|
+
t.visible === !1 ? this.crossRenderer.hideCrosses() : this.crossRenderer.showCluster();
|
|
88
88
|
break;
|
|
89
89
|
}
|
|
90
90
|
return { status: 0, message: "ok" };
|
|
@@ -116,12 +116,12 @@ class f {
|
|
|
116
116
|
case "district":
|
|
117
117
|
return await this.districtRenderer.highlightDistrict(t) ? (this.subDistrictRenderer.filter(t), this.signalRenderer.filter(t), await this.subDistrictRenderer.showRoads(t), { status: 0, message: "ok" }) : { status: 1, message: "未找到区控" };
|
|
118
118
|
case "subDistrict": {
|
|
119
|
-
const { count: s, parentId:
|
|
120
|
-
return s > 0 ? (this.districtRenderer.filter(
|
|
119
|
+
const { count: s, parentId: e } = await this.subDistrictRenderer.highlightSubDistrict(t);
|
|
120
|
+
return s > 0 ? (this.districtRenderer.filter(e), this.signalRenderer.filter(t), { status: 0, message: "ok" }) : { status: 1, message: "未找到子区" };
|
|
121
121
|
}
|
|
122
122
|
case "signal": {
|
|
123
|
-
const { districtId: s, subDistrictId:
|
|
124
|
-
return
|
|
123
|
+
const { districtId: s, subDistrictId: e, count: i } = await this.signalRenderer.highlightSignal(t.id);
|
|
124
|
+
return i > 0 ? (this.districtRenderer.filter(s), this.subDistrictRenderer.filter(t), { status: 0, message: "ok" }) : { status: 1, message: "未找到信号机" };
|
|
125
125
|
}
|
|
126
126
|
default:
|
|
127
127
|
return { status: 1, message: "未知类型" };
|
package/es/src/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const I=require("@arcgis/core/Graphic"),J=require("@arcgis/core/core/promiseUtils"),E=require("@arcgis/core/core/reactiveUtils.js"),A=require("@arcgis/core/geometry"),q=require("@arcgis/core/geometry/geometryEngine"),x=require("@arcgis/core/layers/FeatureLayer"),v=require("@arcgis/core/layers/GraphicsLayer"),T=require("@turf/helpers"),O=require("@turf/line-slice-along"),w=require("axios"),_=require("fast-xml-parser"),R=require("md5"),M=require("pako"),z=require("vue"),H=require("../../stores/index.js"),N=require("../common-utils.js");function j(S){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(S){for(const t in S)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(S,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:()=>S[t]})}}return e.default=S,Object.freeze(e)}const P=j(J),U=j(E),L=j(q),B=j(T);class C{constructor(e){this.junctionNames=new Map,this.junctionScale=5e3,this.xodrBorder=[],this.projectName="",this.openDriveServer="",this.currentSectionCode="",this.selectedSectionIds=[],this.currentJunctionId="",this.view=e,this.laneLayer=new x({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:[47,79,79,.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 x({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 C(e)),this.instance}async makeMd5FromFile(e){var t;try{const o=await(await fetch(e)).text();let r=(t=new _.XMLParser({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:R(o),border:r}}}catch(s){return{status:-1,message:s.message}}}async showOpenDriveFromFile(e){var d,m,u;this.openDriveClickCallback=e.selectedCallback,this.scaleWatch=U.watch(()=>this.view.scale,(h,p)=>{h>this.junctionScale&&p<=this.junctionScale?this.updateAllJunctionSymbol("marker"):h<=this.junctionScale&&p>this.junctionScale&&this.updateAllJunctionSymbol("picture")});let t=e.file.split("/").pop()||"";t=t.split(".").slice(0,-1).join("."),this.openDriveServer=e.server;const s=`http://${this.openDriveServer}/api/openDrive/uploadXodr`;let o;try{o=await w.post(s,{},{params:{url:e.file,projectName:t}})}catch(h){return{status:-1,message:h.message}}if(o.status!==200)return{status:-1,message:o.statusText};console.time("渲染用时");const i=o.data.result.geoSetting;N.default.setGeoData(i.geoReference,i.offsetX,i.offsetY);let l=o.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 h=await r.arrayBuffer(),p=M.inflate(h,{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,((m=e.options)==null?void 0:m.showRoadName)||!0),((u=e.options)==null?void 0:u.showJunctionPoint)!==!1){const h=o.data.result.junctions;this.showJunction(h)}e.options&&e.options.centerMap!==!1&&await this.view.goTo(this.allLaneGraphics),this.mouseMoveHandler||this.monitorMouseMove(),this.mouseClickHandler||this.monitorMouseClick();const n=H.default.useAppDataStore;return z.watch(()=>n.isSketching,()=>{var h,p;n.isSketching?((h=this.mouseMoveHandler)==null||h.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"}}async showOpenDriveFromServer(e,t){const s=`http://${e}/api/openDrive/analyzeXodr`,o=await w.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 l=await fetch(i);let r;if(i.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"}}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=>{var c;let l=0;this.allLaneGraphics=[],this.allRefLineGraphics=[];const r=[];for(const n of e){if(!t&&n.junction!=="-1")continue;const{id:d,refLine:m}=n;let u=n.name;u.includes("(")&&(u=u.slice(0,u.indexOf("("))),u=u.replace(/(.)/g,"$1 ");const h=new I({geometry:{type:"polyline",paths:[m]},attributes:{ObjectID:l++,roadId:d,roadName:u}});this.allRefLineGraphics.push(h),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],y=Number(g.id);for(const f of g.lanePaths){const b=Number(f.id);if(b===0)continue;const $=f.type,F=[...f.outerPath],k=f.innerPath.concat(F.reverse());if(k.length<=3){console.warn(`lane ${b} has less than 3 points`);continue}k.push(f.innerPath[0]);const D=new A.Polygon({rings:[k]});if(D){const G=new I({geometry:D,attributes:{ObjectID:l++,id:`${d}+${y}+${b}`,fromNode:n.fromNode,toNode:n.toNode,roadId:String(d),roadName:n.name,sectionId:String(y),sectionIndex:p,laneId:b,type:$,sumoId:"",leftLine:f.innerPath,rightLine:f.outerPath,roadsectBaseIds:(c=g.roadsectBaseIds)==null?void 0:c.toString()}});this.allLaneGraphics.push(G),r.push(G)}}}}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)})}showJunction(e){const t=[];let s;this.xodrBorder.length>0&&(s=new A.Polygon({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 A.Point({x:o.coordinates[0],y:o.coordinates[1]});let l=!0;if(s&&(l=L.contains(s,i)),l){const r=new I({geometry:i,attributes:{...o,selected:!1,type:"OpenDriveJunction"},symbol:this.getCrossGraphicSymbol(o,"marker")});t.push(r)}}this.junctionLayer.addMany(t)}monitorMouseMove(){const e=P.debounce(async t=>{var l;const o=(l=(await this.view.hitTest(t,{include:[this.laneLayer,this.junctionLayer]})).results)==null?void 0:l.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")}`,a=this.hitGraphic.getAttribute("roadsectBaseIds");if(this.currentSectionCode===r||this.selectedSectionIds.includes(a)||this.sectionLayer.graphics.findIndex(y=>y.getAttribute("id")===r)>=0)return;this.currentSectionCode=r;const n=this.allLaneGraphics.filter(y=>`${y.attributes.roadId}+${y.attributes.sectionId}`===r),d=L.union(n.map(y=>y.geometry)),m=this.hitGraphic.getAttribute("fromNode"),u=this.hitGraphic.getAttribute("toNode"),h=this.junctionNames.get(m)||m,p=this.junctionNames.get(u)||u,g=new I({geometry:d,symbol:{type:"simple-fill",color:[0,255,255,.5],style:"solid",outline:{color:[0,255,255],width:1}},attributes:{type:"OpenDriveSection",id:r,selected:!1,fromNodeName:h,toNodeName:p,laneCount:n.length,roadsectBaseIds:this.hitGraphic.getAttribute("roadsectBaseIds")},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(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=P.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(c=>c.type==="graphic");if(o.length===0)return;const i=o[0].graphic,l=i.getAttribute("type"),r=i.getAttribute("id");if(l==="OpenDriveJunction")if(i.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}),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 l==="OpenDriveSection"&&(i.layer.id==="OpenDriveHighlight"?(this.highlightLayer.removeAll(),this.sectionLayer.removeAll(),this.selectedSectionIds=[],this.sectionLayer.add(i),i.setAttribute("selected",!0),this.selectedSectionIds.push(r),this.splitLaneLayer.graphics.filter(n=>n.getAttribute("roadsectBaseIds")===i.getAttribute("roadsectBaseIds")).forEach(n=>n.symbol={type:"simple-fill",color:[255,69,0],outline:{color:"red",width:2}})):(this.splitLaneLayer.graphics.filter(n=>n.getAttribute("roadsectBaseIds")===i.getAttribute("roadsectBaseIds")).forEach(n=>n.symbol={type:"simple-fill",color:[255,0,0,.8],outline:{color:"red",width:1}}),this.sectionLayer.remove(i),this.selectedSectionIds=[],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(()=>{})})}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)}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 w.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(l=>l.getAttribute("roadId")===s&&l.getAttribute("sectionIndex")===o);if(i){const l=`${s}+${i.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}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}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 l=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],c=r.length===2?Number(r[1]):void 0;return await this.findLane({roadsectId:a,segmentId:c,laneId:l,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 I({geometry:s.geometry,symbol:{type:"simple-marker",style:"circle",size:30,color:[0,255,255,.8],outline:{color:[0,255,255],width:1}}});this.flashGraphic(o)}return await this.view.goTo(s.geometry,{duration:1e3}),{status:0,message:"ok"}}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(c=>{const n=Number(c.attributes.sectionId);a.indexOf(n)===-1&&a.push(n)}),a.sort((c,n)=>c-n),s>a.length-1)return{status:-1,message:"未找到。请检查基本段编号"};s=a[s],i=i.filter(c=>Number(c.attributes.sectionId)===s)}if(o!==void 0){const a=[];if(i.forEach(c=>{const n=Number(c.attributes.laneId);a.indexOf(n)===-1&&a.push(n)}),a.sort((c,n)=>c-n),o>a.length-1)return{status:-1,message:"未找到。请检查车道编号"};o=a[o],i=i.filter(c=>Number(c.attributes.laneId)===o)}const l=i.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,.6],style:"solid",outline:{width:0}}});this.flashGraphic(a)}return await this.view.goTo(r,{duration:1e3}),{status:0,message:"ok"}}flashGraphic(e){this.flashLayer.removeAll(),this.flashLayer.add(e);let t=0,s=!0;const o=setInterval(()=>{s?(this.flashLayer.opacity-=.02,this.flashLayer.opacity<=.1&&(s=!1,t++)):(this.flashLayer.opacity+=.02,this.flashLayer.opacity>=1&&(s=!0)),t>=5&&(this.flashLayer.removeAll(),this.flashLayer.opacity=1,clearInterval(o))},10)}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"))}):(this.highlightLayer.removeAll(),this.sectionLayer.removeAll(),this.selectedSectionIds=[],this.splitLaneLayer.removeAll()),!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"}}async 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(l=>l.getAttribute("roadId")===s):t.length===2&&(i=this.allLaneGraphics.filter(l=>l.getAttribute("roadId")===s&&l.getAttribute("sectionIndex")===o)),i.length>0){const l=new Map;return i.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,.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 t=new A.Polygon({rings:[e]}),s=await this.laneLayer.queryFeatures({geometry:t,outFields:["*"]}),o=[],i=[];for(const a of s.features){const c=a.getAttribute("roadId"),n=a.getAttribute("sectionIndex"),d=`${c}#${n}`;if(o.indexOf(d)===-1){o.push(d),this.selectSumo({type:"edge",id:d});const m=`http://${this.openDriveServer}/api/sumo/getSumoEdge`,u=await w.get(m,{params:{id:`${c}+${a.getAttribute("sectionId")}`,projectName:this.projectName}});u.status===200&&u.data.status===0&&i.push(u.data.result)}}const l=this.junctionLayer.graphics.filter(a=>{const c=a.geometry;return L.contains(t,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: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("#"),l=i.length===2?Number(i[1]):0;let r=i[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-o,n=a.find(b=>Math.abs(b.getAttribute("laneId"))===c);if(!n)return{status:-1,message:"未找到车道"};const d=e.start||0,m=e.end||100,u=B.lineString(n.getAttribute("leftLine")),h=O.lineSliceAlong(u,d,m,{units:"meters"}),p=B.lineString(n.getAttribute("rightLine")),g=O.lineSliceAlong(p,d,m,{units:"meters"}),y=h.geometry.coordinates.concat(g.geometry.coordinates.reverse());y.push(y[y.length-1]);const f=new I({geometry:new A.Polygon({rings:[y]}),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:h.geometry.coordinates,rightLine:g.geometry.coordinates},symbol:{type:"simple-fill",color:[255,0,0,.8],outline:{color:"red"}}});return this.splitLaneLayer.add(f),N.default.viewGoto(this.view,[f]),{status:0,message:"ok",result:{coordinates:y}}}blockLane(e){const t=this.allLaneGraphics.filter(o=>{var l;let i=String(o.getAttribute("laneId"));return i.startsWith("-")&&(i=i.slice(1)),o.getAttribute("roadId")===e.roadsectId&&((l=o.getAttribute("roadsectBaseIds"))==null?void 0:l.includes(e.roadsectBaseId))&&i===String(e.laneId)}),s=t.map(o=>{const i=o.clone();return console.log(t[0].getAttribute("roadsectBaseIds"),this.selectedSectionIds,this.selectedSectionIds.includes(t[0].getAttribute("roadsectBaseIds"))),i.symbol={type:"simple-fill",color:this.selectedSectionIds.includes(t[0].getAttribute("roadsectBaseIds"))?[255,69,0,.8]:[255,0,0,.8],outline:{color:"red"}},i});this.splitLaneLayer.addMany(s),N.default.viewGoto(this.view,s)}clearSplitLane(){this.splitLaneLayer.removeAll()}selectComputable(e){if(e.type==="roadsectBase"){this.allLaneGraphics.forEach(s=>{s.getAttribute("roadsectBaseIds")||console.log(s.attributes)});const t=this.allLaneGraphics.filter(s=>{var o;return(o=s.getAttribute("roadsectBaseIds"))==null?void 0:o.includes(e.id)});if(t.length>0){const s=L.union(t.map(r=>r.geometry)),o=t[0].getAttribute("roadsectBaseIds"),i=new I({geometry:s,symbol:{type:"simple-fill",color:[0,255,255,.5],style:"solid",outline:{color:[0,255,255],width:1}},attributes:{type:"OpenDriveSection",roadsectBaseIds:o}});this.sectionLayer.removeAll(),this.sectionLayer.add(i),N.default.viewGoto(this.view,[i]),this.selectedSectionIds=[o];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}})}}}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())}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:[{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"}}}exports.default=C;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const I=require("@arcgis/core/Graphic"),J=require("@arcgis/core/core/promiseUtils"),E=require("@arcgis/core/core/reactiveUtils.js"),A=require("@arcgis/core/geometry"),q=require("@arcgis/core/geometry/geometryEngine"),x=require("@arcgis/core/layers/FeatureLayer"),v=require("@arcgis/core/layers/GraphicsLayer"),T=require("@turf/helpers"),O=require("@turf/line-slice-along"),w=require("axios"),_=require("fast-xml-parser"),R=require("md5"),M=require("pako"),z=require("vue"),H=require("../../stores/index.js"),k=require("../common-utils.js");function N(S){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(S){for(const t in S)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(S,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:()=>S[t]})}}return e.default=S,Object.freeze(e)}const P=N(J),U=N(E),L=N(q),B=N(T);class C{constructor(e){this.junctionNames=new Map,this.junctionScale=5e3,this.xodrBorder=[],this.projectName="",this.openDriveServer="",this.currentSectionCode="",this.selectedSectionIds=[],this.currentJunctionId="",this.view=e,this.laneLayer=new x({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:[47,79,79,.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 x({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 C(e)),this.instance}async makeMd5FromFile(e){var t;try{const o=await(await fetch(e)).text();let r=(t=new _.XMLParser({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:R(o),border:r}}}catch(s){return{status:-1,message:s.message}}}async showOpenDriveFromFile(e){var d,m,u;this.openDriveClickCallback=e.selectedCallback,this.scaleWatch=U.watch(()=>this.view.scale,(h,p)=>{h>this.junctionScale&&p<=this.junctionScale?this.updateAllJunctionSymbol("marker"):h<=this.junctionScale&&p>this.junctionScale&&this.updateAllJunctionSymbol("picture")});let t=e.file.split("/").pop()||"";t=t.split(".").slice(0,-1).join("."),this.openDriveServer=e.server;const s=`http://${this.openDriveServer}/api/openDrive/uploadXodr`;let o;try{o=await w.post(s,{},{params:{url:e.file,projectName:t}})}catch(h){return{status:-1,message:h.message}}if(o.status!==200)return{status:-1,message:o.statusText};console.time("渲染用时");const i=o.data.result.geoSetting;k.default.setGeoData(i.geoReference,i.offsetX,i.offsetY);let l=o.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 h=await r.arrayBuffer(),p=M.inflate(h,{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,((m=e.options)==null?void 0:m.showRoadName)||!0),((u=e.options)==null?void 0:u.showJunctionPoint)!==!1){const h=o.data.result.junctions;this.showJunction(h)}e.options&&e.options.centerMap!==!1&&await this.view.goTo(this.allLaneGraphics),this.mouseMoveHandler||this.monitorMouseMove(),this.mouseClickHandler||this.monitorMouseClick();const n=H.default.useAppDataStore;return z.watch(()=>n.isSketching,()=>{var h,p;n.isSketching?((h=this.mouseMoveHandler)==null||h.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"}}async showOpenDriveFromServer(e,t){const s=`http://${e}/api/openDrive/analyzeXodr`,o=await w.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 l=await fetch(i);let r;if(i.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"}}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=>{var c;let l=0;this.allLaneGraphics=[],this.allRefLineGraphics=[];const r=[];for(const n of e){if(!t&&n.junction!=="-1")continue;const{id:d,refLine:m}=n;let u=n.name;u.includes("(")&&(u=u.slice(0,u.indexOf("("))),u=u.replace(/(.)/g,"$1 ");const h=new I({geometry:{type:"polyline",paths:[m]},attributes:{ObjectID:l++,roadId:d,roadName:u}});this.allRefLineGraphics.push(h),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],y=Number(g.id);for(const f of g.lanePaths){const b=Number(f.id);if(b===0)continue;const $=f.type,F=[...f.outerPath],j=f.innerPath.concat(F.reverse());if(j.length<=3){console.warn(`lane ${b} has less than 3 points`);continue}j.push(f.innerPath[0]);const D=new A.Polygon({rings:[j]});if(D){const G=new I({geometry:D,attributes:{ObjectID:l++,id:`${d}+${y}+${b}`,fromNode:n.fromNode,toNode:n.toNode,roadId:String(d),roadName:n.name,sectionId:String(y),sectionIndex:p,laneId:b,type:$,sumoId:"",leftLine:f.innerPath,rightLine:f.outerPath,roadsectBaseIds:(c=g.roadsectBaseIds)==null?void 0:c.toString()}});this.allLaneGraphics.push(G),r.push(G)}}}}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)})}showJunction(e){const t=[];let s;this.xodrBorder.length>0&&(s=new A.Polygon({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 A.Point({x:o.coordinates[0],y:o.coordinates[1]});let l=!0;if(s&&(l=L.contains(s,i)),l){const r=new I({geometry:i,attributes:{...o,selected:!1,type:"OpenDriveJunction"},symbol:this.getCrossGraphicSymbol(o,"marker")});t.push(r)}}this.junctionLayer.addMany(t)}monitorMouseMove(){const e=P.debounce(async t=>{var l;const o=(l=(await this.view.hitTest(t,{include:[this.laneLayer,this.junctionLayer]})).results)==null?void 0:l.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")}`,a=this.hitGraphic.getAttribute("roadsectBaseIds");if(this.currentSectionCode===r||this.selectedSectionIds.includes(a)||this.sectionLayer.graphics.findIndex(y=>y.getAttribute("id")===r)>=0)return;this.currentSectionCode=r;const n=this.allLaneGraphics.filter(y=>`${y.attributes.roadId}+${y.attributes.sectionId}`===r),d=L.union(n.map(y=>y.geometry)),m=this.hitGraphic.getAttribute("fromNode"),u=this.hitGraphic.getAttribute("toNode"),h=this.junctionNames.get(m)||m,p=this.junctionNames.get(u)||u,g=new I({geometry:d,symbol:{type:"simple-fill",color:[0,255,255,.5],style:"solid",outline:{color:[0,255,255],width:1}},attributes:{type:"OpenDriveSection",id:r,selected:!1,fromNodeName:h,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(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=P.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(c=>c.type==="graphic");if(o.length===0)return;const i=o[0].graphic,l=i.getAttribute("type"),r=i.getAttribute("id");if(l==="OpenDriveJunction")if(i.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}),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 l==="OpenDriveSection"&&(i.layer.id==="OpenDriveHighlight"?(this.highlightLayer.removeAll(),this.sectionLayer.removeAll(),this.selectedSectionIds=[],this.sectionLayer.add(i),i.setAttribute("selected",!0),this.selectedSectionIds.push(r),this.splitLaneLayer.graphics.filter(n=>n.getAttribute("roadsectBaseIds")===i.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:i.getAttribute("id"),details:{roadsectId:i.getAttribute("roadId"),roadsectBaseIds:i.getAttribute("roadsectBaseIds")}})):(this.splitLaneLayer.graphics.filter(n=>n.getAttribute("roadsectBaseIds")===i.getAttribute("roadsectBaseIds")).forEach(n=>n.symbol={type:"simple-fill",color:[255,0,0,.8],outline:{color:"red",width:1}}),this.sectionLayer.remove(i),this.selectedSectionIds=[],this.openDriveClickCallback&&this.openDriveClickCallback({type:"CloseOpenDriveSection",id:i.getAttribute("roadsectBaseIds"),details:{roadsectId:i.getAttribute("roadId"),roadsectBaseIds:i.getAttribute("roadsectBaseIds")}})))});this.mouseClickHandler=this.view.on("immediate-click",async t=>{e(t).catch(()=>{})})}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)}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 w.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(l=>l.getAttribute("roadId")===s&&l.getAttribute("sectionIndex")===o);if(i){const l=`${s}+${i.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}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}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 l=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],c=r.length===2?Number(r[1]):void 0;return await this.findLane({roadsectId:a,segmentId:c,laneId:l,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 I({geometry:s.geometry,symbol:{type:"simple-marker",style:"circle",size:30,color:[0,255,255,.8],outline:{color:[0,255,255],width:1}}});this.flashGraphic(o)}return await this.view.goTo(s.geometry,{duration:1e3}),{status:0,message:"ok"}}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(c=>{const n=Number(c.attributes.sectionId);a.indexOf(n)===-1&&a.push(n)}),a.sort((c,n)=>c-n),s>a.length-1)return{status:-1,message:"未找到。请检查基本段编号"};s=a[s],i=i.filter(c=>Number(c.attributes.sectionId)===s)}if(o!==void 0){const a=[];if(i.forEach(c=>{const n=Number(c.attributes.laneId);a.indexOf(n)===-1&&a.push(n)}),a.sort((c,n)=>c-n),o>a.length-1)return{status:-1,message:"未找到。请检查车道编号"};o=a[o],i=i.filter(c=>Number(c.attributes.laneId)===o)}const l=i.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,.6],style:"solid",outline:{width:0}}});this.flashGraphic(a)}return await this.view.goTo(r,{duration:1e3}),{status:0,message:"ok"}}flashGraphic(e){this.flashLayer.removeAll(),this.flashLayer.add(e);let t=0,s=!0;const o=setInterval(()=>{s?(this.flashLayer.opacity-=.02,this.flashLayer.opacity<=.1&&(s=!1,t++)):(this.flashLayer.opacity+=.02,this.flashLayer.opacity>=1&&(s=!0)),t>=5&&(this.flashLayer.removeAll(),this.flashLayer.opacity=1,clearInterval(o))},10)}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"))}):(this.highlightLayer.removeAll(),this.sectionLayer.removeAll(),this.selectedSectionIds=[],this.splitLaneLayer.removeAll()),!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"}}async 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(l=>l.getAttribute("roadId")===s):t.length===2&&(i=this.allLaneGraphics.filter(l=>l.getAttribute("roadId")===s&&l.getAttribute("sectionIndex")===o)),i.length>0){const l=new Map;return i.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,.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 t=new A.Polygon({rings:[e]}),s=await this.laneLayer.queryFeatures({geometry:t,outFields:["*"]}),o=[],i=[];for(const a of s.features){const c=a.getAttribute("roadId"),n=a.getAttribute("sectionIndex"),d=`${c}#${n}`;if(o.indexOf(d)===-1){o.push(d),this.selectSumo({type:"edge",id:d});const m=`http://${this.openDriveServer}/api/sumo/getSumoEdge`,u=await w.get(m,{params:{id:`${c}+${a.getAttribute("sectionId")}`,projectName:this.projectName}});u.status===200&&u.data.status===0&&i.push(u.data.result)}}const l=this.junctionLayer.graphics.filter(a=>{const c=a.geometry;return L.contains(t,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: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("#"),l=i.length===2?Number(i[1]):0;let r=i[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-o,n=a.find(b=>Math.abs(b.getAttribute("laneId"))===c);if(!n)return{status:-1,message:"未找到车道"};const d=e.start||0,m=e.end||100,u=B.lineString(n.getAttribute("leftLine")),h=O.lineSliceAlong(u,d,m,{units:"meters"}),p=B.lineString(n.getAttribute("rightLine")),g=O.lineSliceAlong(p,d,m,{units:"meters"}),y=h.geometry.coordinates.concat(g.geometry.coordinates.reverse());y.push(y[y.length-1]);const f=new I({geometry:new A.Polygon({rings:[y]}),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:h.geometry.coordinates,rightLine:g.geometry.coordinates},symbol:{type:"simple-fill",color:[255,0,0,.8],outline:{color:"red"}}});return this.splitLaneLayer.add(f),k.default.viewGoto(this.view,[f]),{status:0,message:"ok",result:{coordinates:y}}}blockLane(e){const t=this.allLaneGraphics.filter(o=>{var l;let i=String(o.getAttribute("laneId"));return i.startsWith("-")&&(i=i.slice(1)),o.getAttribute("roadId")===e.roadsectId&&((l=o.getAttribute("roadsectBaseIds"))==null?void 0:l.includes(e.roadsectBaseId))&&i===String(e.laneId)}),s=t.map(o=>{const i=o.clone();return console.log(t[0].getAttribute("roadsectBaseIds"),this.selectedSectionIds,this.selectedSectionIds.includes(t[0].getAttribute("roadsectBaseIds"))),i.symbol={type:"simple-fill",color:this.selectedSectionIds.includes(t[0].getAttribute("roadsectBaseIds"))?[255,69,0,.8]:[255,0,0,.8],outline:{color:"red"}},i});this.splitLaneLayer.addMany(s),k.default.viewGoto(this.view,s)}clearSplitLane(){this.splitLaneLayer.removeAll()}selectComputable(e){if(e.type==="roadsectBase"){this.allLaneGraphics.forEach(s=>{s.getAttribute("roadsectBaseIds")||console.log(s.attributes)});const t=this.allLaneGraphics.filter(s=>{var o;return(o=s.getAttribute("roadsectBaseIds"))==null?void 0:o.includes(e.id)});if(t.length>0){const s=L.union(t.map(r=>r.geometry)),o=t[0].getAttribute("roadsectBaseIds"),i=new I({geometry:s,symbol:{type:"simple-fill",color:[0,255,255,.5],style:"solid",outline:{color:[0,255,255],width:1}},attributes:{type:"OpenDriveSection",roadsectBaseIds:o}});this.sectionLayer.removeAll(),this.sectionLayer.add(i),k.default.viewGoto(this.view,[i]),this.selectedSectionIds=[o];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}})}}}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())}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:[{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"}}}exports.default=C;
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
+
import { IFindSignalControlAreaParams } from 'packages/components/src/types';
|
|
1
2
|
import DistrictController from './district-controller';
|
|
2
3
|
export default class CrossRenderer {
|
|
3
4
|
private view;
|
|
4
5
|
private crossLayer;
|
|
5
6
|
private crossGraphicSymbol;
|
|
6
7
|
private locations;
|
|
8
|
+
private clusteredLocations;
|
|
9
|
+
private filteredLocations;
|
|
7
10
|
private currentShowMode;
|
|
8
11
|
private zoomWatchHandle;
|
|
9
12
|
private symbolScale;
|
|
10
|
-
private
|
|
13
|
+
private oldScale;
|
|
11
14
|
private readonly clusterRadius;
|
|
12
15
|
private readonly minClusterPoints;
|
|
13
16
|
private readonly maxClusterSymbolSize;
|
|
14
17
|
private readonly minClusterSymbolSize;
|
|
15
18
|
constructor(view: __esri.MapView | __esri.SceneView);
|
|
16
19
|
addCrosses(controllers: DistrictController[]): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* 清除所有路口
|
|
22
|
+
*/
|
|
17
23
|
clearCrosses(): void;
|
|
24
|
+
/**
|
|
25
|
+
* 更新散点符号
|
|
26
|
+
*/
|
|
18
27
|
private updateScatterSymbol;
|
|
19
28
|
/**
|
|
20
29
|
* 将地理位置转换为屏幕坐标
|
|
@@ -29,7 +38,13 @@ export default class CrossRenderer {
|
|
|
29
38
|
*/
|
|
30
39
|
showScatter(): void;
|
|
31
40
|
/**
|
|
32
|
-
*
|
|
41
|
+
* 隐藏路口
|
|
42
|
+
*/
|
|
43
|
+
hideCrosses(): void;
|
|
44
|
+
filter(params: IFindSignalControlAreaParams): void;
|
|
45
|
+
resetFilter(): void;
|
|
46
|
+
/**
|
|
47
|
+
* 根据当前比例尺更新路口符号
|
|
33
48
|
* @param attributes
|
|
34
49
|
* @returns
|
|
35
50
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const y=require("@arcgis/core/geometry"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const y=require("@arcgis/core/geometry"),h=require("@arcgis/core/Graphic"),p=require("@arcgis/core/layers/GraphicsLayer");class f{constructor(e){this.crossGraphicSymbol={type:"cim",data:{type:"CIMSymbolReference",primitiveOverrides:[{type:"CIMPrimitiveOverride",primitiveName:"textGraphic",propertyName:"TextString",valueExpressionInfo:{type:"CIMExpressionInfo",title:"Custom",expression:'Replace($feature.name, "与", "/") + " " + $feature.signalId',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:18,haloSize:1,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:20,rotateClockwise:!0,textureFilter:"Picture",url:"/GisViewerAssets/Images/cross/gis_xhj_blue.png"}]}}},this.locations=[],this.clusteredLocations=[],this.filteredLocations=[],this.currentShowMode="scatter",this.symbolScale=5e3,this.oldScale=0,this.clusterRadius=120,this.minClusterPoints=2,this.maxClusterSymbolSize=50,this.minClusterSymbolSize=25,this.view=e,this.crossLayer=new p,this.view.map.add(this.crossLayer),this.oldScale=e.scale}async addCrosses(e){e.forEach(t=>{t.signals.forEach(r=>{r.longitude&&r.latitude&&!isNaN(r.longitude)&&!isNaN(r.latitude)&&this.locations.push({id:r.id,x:r.longitude,y:r.latitude,visited:!1,filtered:!1,clusterId:void 0,properties:{...r,districtId:t.id,subDistrictId:""}})}),t.subDistricts.forEach(r=>{r.signals.forEach(s=>{s.longitude&&s.latitude&&!isNaN(s.longitude)&&!isNaN(s.latitude)&&this.locations.push({id:s.id,x:s.longitude,y:s.latitude,visited:!1,filtered:!1,clusterId:void 0,properties:{...s,districtId:t.id,subDistrictId:r.id}})})})}),this.zoomWatchHandle=this.view.watch("stationary",()=>{if(this.view.stationary!==!1){if(this.currentShowMode==="scatter")(this.oldScale<this.symbolScale&&this.view.scale>=this.symbolScale||this.oldScale>=this.symbolScale&&this.view.scale<this.symbolScale)&&this.updateScatterSymbol(),this.oldScale=this.view.scale;else if(this.currentShowMode==="cluster"){this.locationToScreen(),console.time("cluster");const t=this.doPixelCluster(this.clusterRadius);console.timeEnd("cluster"),this.showClusterResult(t)}}})}clearCrosses(){var e;console.log("Clearing crosses"),this.crossLayer.removeAll(),this.locations=[],this.clusteredLocations=[],(e=this.zoomWatchHandle)==null||e.remove()}updateScatterSymbol(){this.crossLayer.graphics.forEach(e=>{e.symbol=this.getCrossSymbol(e.attributes)})}locationToScreen(){this.clusteredLocations=[],this.locations.forEach(e=>{const t=this.view.toScreen(new y.Point({x:e.x,y:e.y}));e.filtered===!1&&t.x>0&&t.y>0&&(e.properties.screenX=t.x,e.properties.screenY=t.y,e.visited=!1,e.clusterId=void 0,this.clusteredLocations.push(e))})}showCluster(){this.crossLayer.removeAll(),this.currentShowMode="cluster",this.locationToScreen();const e=this.doPixelCluster(this.clusterRadius);this.showClusterResult(e)}showScatter(){this.crossLayer.removeAll(),this.currentShowMode="scatter";const e=[];this.locations.forEach(t=>{if(!t.filtered){const r=new h({geometry:{type:"point",longitude:t.x,latitude:t.y},symbol:this.getCrossSymbol(t.properties),attributes:t.properties});e.push(r)}}),this.crossLayer.addMany(e)}hideCrosses(){this.crossLayer.removeAll()}filter(e){this.locations.forEach(t=>{if(e.type==="district")t.filtered=t.properties.districtId===e.id;else if(e.type==="subDistrict")t.filtered=t.properties.subDistrictId===e.id;else if(e.type==="signal"&&(t.filtered=t.id===e.id,t.filtered))return t.properties})}resetFilter(){this.locations.forEach(e=>{e.filtered=!1})}getCrossSymbol(e){if(this.view.scale>this.symbolScale)return e.isKey?{type:"picture-marker",url:"/GisViewerAssets/Images/icon_star.png",width:"20px",height:"20px"}:{type:"simple-marker",style:"circle",color:[5,116,255,.8],size:8,outline:{color:"white",width:0}};{const t=e.isKey?"/GisViewerAssets/Images/cross/gis_gjxklk_orange.png":"/GisViewerAssets/Images/cross/gis_xhj_blue.png";return{type:"cim",data:{type:"CIMSymbolReference",primitiveOverrides:[{type:"CIMPrimitiveOverride",primitiveName:"textGraphic",propertyName:"TextString",valueExpressionInfo:{type:"CIMExpressionInfo",title:"Custom",expression:'Replace($feature.name, "与", "/") + " " + $feature.signalId',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:20,haloSize:1,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:20,rotateClockwise:!0,textureFilter:"Picture",url:t}]}}}}}getNeighbors(e,t){return this.clusteredLocations.filter(r=>r.id===e.id||r.visited?!1:this.getDistance(e,r)<=t)}getDistance(e,t){return Math.sqrt(Math.pow(e.properties.screenX-t.properties.screenX,2)+Math.pow(e.properties.screenY-t.properties.screenY,2))}createClusters(){const e={},t=[];for(const s of this.clusteredLocations)s.clusterId===void 0||s.clusterId===-1?t.push(s):(e[s.clusterId]||(e[s.clusterId]=[]),e[s.clusterId].push(s));const r=Object.keys(e).map((s,i)=>{const o=e[Number(s)],c=o.length,l=o.reduce((n,u)=>n+u.x,0),a=o.reduce((n,u)=>n+u.y,0),m=l/c,d=a/c;return{id:Number(s),items:o,count:c,center:{x:m,y:d}}});return t.length>0&&r.push({id:-1,items:t,count:t.length,center:null}),r}doPixelCluster(e){let t=0;for(let r=0;r<this.clusteredLocations.length;r++){const s=this.clusteredLocations[r];if(s.visited)continue;s.visited=!0;const i=this.getNeighbors(s,e);i.length<this.minClusterPoints?s.clusterId=-1:(i.forEach(o=>{o.visited=!0,o.clusterId=t}),s.clusterId=t,t++)}return this.createClusters()}showClusterResult(e){this.crossLayer.removeAll();let t=Number.MIN_VALUE,r=Number.MAX_VALUE;e.forEach(s=>{s.count>1&&(r=Math.min(r,s.count),t=Math.max(t,s.count))}),e.forEach(s=>{if(s.id!==-1){let i=r===t?(this.maxClusterSymbolSize+this.minClusterSymbolSize)/2:this.minClusterSymbolSize+(s.count-r)/(t-r)*(this.maxClusterSymbolSize-this.minClusterSymbolSize);i*=.75;const l=(s.count.toString().length*8+6)/2,a=new h({geometry:new y.Point({x:s.center.x,y:s.center.y}),attributes:{count:s.count},symbol:{type:"cim",data:{type:"CIMSymbolReference",primitiveOverrides:[{type:"CIMPrimitiveOverride",primitiveName:"textGraphic",propertyName:"TextString",valueExpressionInfo:{type:"CIMExpressionInfo",title:"Custom",expression:"$feature.count",returnType:"Default"}}],symbol:{type:"CIMPointSymbol",symbolLayers:[{type:"CIMVectorMarker",size:i,colorLocked:!0,anchorPointUnits:"Relative",frame:{xmin:-16,ymin:-16,xmax:16,ymax:16},markerGraphics:[{type:"CIMMarkerGraphic",geometry:{rings:[[[-l,40],[l,40],[l,20],[-l,20],[-l,40]]]},symbol:{type:"CIMPolygonSymbol",symbolLayers:[{type:"CIMSolidFill",enable:!0,color:[2,72,200,255]},{type:"CIMSolidStroke",enable:!0,width:5,color:[2,72,200,128]}]}},{type:"CIMMarkerGraphic",primitiveName:"textGraphic",geometry:{x:0,y:0},symbol:{type:"CIMTextSymbol",height:16,horizontalAlignment:"Center",offsetX:0,offsetY:30,symbol:{type:"CIMPolygonSymbol",symbolLayers:[{type:"CIMSolidFill",enable:!0,color:[255,255,255,255]}]},verticalAlignment:"Center"},textString:""}],scaleSymbolsProportionally:!0,respectFrame:!0},{type:"CIMPictureMarker",enable:!0,anchorPoint:{x:0,y:0},anchorPointUnits:"Relative",size:i,rotateClockwise:!0,textureFilter:"Picture",url:"/GisViewerAssets/Images/cross/gis_xhj_blue.png"}]}}}});this.crossLayer.add(a)}else s.items.forEach(i=>{const o=new h({geometry:new y.Point({x:i.x,y:i.y}),attributes:{...i,...i.properties,type:"clusterPoint",id:i.id},symbol:this.crossGraphicSymbol});this.crossLayer.add(o)})})}}exports.default=f;
|