gisviewer-vue3-arcgis 1.0.268 → 1.0.269
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/signal-control-area/signal-cross-controller.d.ts +40 -0
- package/es/src/gis-map/utils/signal-control-area/signal-cross-controller.mjs +250 -46
- package/lib/src/gis-map/utils/signal-control-area/signal-cross-controller.d.ts +40 -0
- package/lib/src/gis-map/utils/signal-control-area/signal-cross-controller.js +1 -1
- package/package.json +1 -1
|
@@ -6,10 +6,20 @@ export default class SignalCrossController {
|
|
|
6
6
|
private view;
|
|
7
7
|
private crossLayer;
|
|
8
8
|
private readonly symbolScale;
|
|
9
|
+
private oldScale;
|
|
9
10
|
private scaleWatchHandle;
|
|
10
11
|
private showName;
|
|
11
12
|
private showStyle;
|
|
13
|
+
private readonly clusterRadius;
|
|
14
|
+
private readonly minClusterPoints;
|
|
15
|
+
private readonly maxClusterSymbolSize;
|
|
16
|
+
private readonly minClusterSymbolSize;
|
|
17
|
+
/** 需要进行聚合的点位,一般为当前屏幕范围内的点位 */
|
|
18
|
+
private clusteredLocations;
|
|
19
|
+
/** 所有路口点位 */
|
|
20
|
+
private locations;
|
|
12
21
|
constructor(view: __esri.MapView | __esri.SceneView);
|
|
22
|
+
private locationToScreen;
|
|
13
23
|
/**
|
|
14
24
|
* 显示信控路口
|
|
15
25
|
* @param params
|
|
@@ -17,6 +27,36 @@ export default class SignalCrossController {
|
|
|
17
27
|
*/
|
|
18
28
|
showSignalCross(params: IShowSignalCrossParams): IResult;
|
|
19
29
|
clearSignalCross(): void;
|
|
30
|
+
/**
|
|
31
|
+
* 按照像素距离聚类
|
|
32
|
+
* @param locations
|
|
33
|
+
* @param eps
|
|
34
|
+
* @param minPoints
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
private doPixelCluster;
|
|
38
|
+
/**
|
|
39
|
+
* 获取邻居点
|
|
40
|
+
* @param locations
|
|
41
|
+
* @param index
|
|
42
|
+
* @param eps
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
private getNeighbors;
|
|
46
|
+
/**
|
|
47
|
+
* 两点间的像素距离
|
|
48
|
+
* @param point1
|
|
49
|
+
* @param point2
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
private getDistance;
|
|
53
|
+
/**
|
|
54
|
+
* 从聚类结果中创建聚类对象
|
|
55
|
+
* @param locations
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
private createClusters;
|
|
59
|
+
private showClusterResult;
|
|
20
60
|
private getBrandLabel;
|
|
21
61
|
private getOnlineLabel;
|
|
22
62
|
private getMalfunctionLabel;
|
|
@@ -1,76 +1,71 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { Point as u } from "@arcgis/core/geometry";
|
|
2
|
+
import y from "@arcgis/core/Graphic";
|
|
3
|
+
import d from "@arcgis/core/layers/GraphicsLayer";
|
|
4
|
+
class C {
|
|
4
5
|
constructor(e) {
|
|
5
|
-
this.symbolScale = 6e3, this.showName = "signalId", this.showStyle = "scatter", this.view = e, this.crossLayer = new
|
|
6
|
+
this.symbolScale = 6e3, this.oldScale = 0, this.showName = "signalId", this.showStyle = "scatter", this.clusterRadius = 120, this.minClusterPoints = 2, this.maxClusterSymbolSize = 50, this.minClusterSymbolSize = 25, this.clusteredLocations = [], this.locations = [], this.view = e, this.crossLayer = new d({
|
|
6
7
|
id: "signal-control-cross-layer",
|
|
7
8
|
title: "信控路口图层"
|
|
8
9
|
}), this.view.map.add(this.crossLayer);
|
|
9
10
|
}
|
|
11
|
+
locationToScreen() {
|
|
12
|
+
this.clusteredLocations = [], this.locations.forEach((e) => {
|
|
13
|
+
const t = this.view.toScreen(
|
|
14
|
+
new u({ x: e.x, y: e.y })
|
|
15
|
+
);
|
|
16
|
+
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));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
10
19
|
/**
|
|
11
20
|
* 显示信控路口
|
|
12
21
|
* @param params
|
|
13
22
|
* @returns
|
|
14
23
|
*/
|
|
15
24
|
showSignalCross(e) {
|
|
16
|
-
if (this.crossLayer.removeAll(), this.showName = e.showName || "signalId", this.showStyle = e.style || "scatter", this.scaleWatchHandle || (this.scaleWatchHandle = this.view.watch("
|
|
17
|
-
(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
if (this.crossLayer.removeAll(), this.showName = e.showName || "signalId", this.showStyle = e.style || "scatter", this.scaleWatchHandle || (this.scaleWatchHandle = this.view.watch("stationary", () => {
|
|
26
|
+
if (this.showStyle === "scatter")
|
|
27
|
+
(this.oldScale < this.symbolScale && this.view.scale >= this.symbolScale || this.oldScale >= this.symbolScale && this.view.scale < this.symbolScale) && this.crossLayer.graphics.forEach((t) => {
|
|
28
|
+
t.symbol = this.getCrossSymbol(t.attributes);
|
|
29
|
+
}), this.oldScale = this.view.scale;
|
|
30
|
+
else {
|
|
31
|
+
this.locationToScreen();
|
|
32
|
+
const t = this.doPixelCluster(this.clusterRadius);
|
|
33
|
+
this.showClusterResult(t);
|
|
34
|
+
}
|
|
21
35
|
})), this.showStyle === "scatter") {
|
|
22
36
|
const t = e.points.map((i) => {
|
|
23
|
-
const
|
|
37
|
+
const s = this.getCrossSymbol(i), r = this.getBrandLabel(i.brand), o = this.getOnlineLabel(i.isOnline), n = this.getMalfunctionLabel(
|
|
24
38
|
i.isMalfunction
|
|
25
39
|
);
|
|
26
|
-
return new
|
|
40
|
+
return new y({
|
|
27
41
|
geometry: {
|
|
28
42
|
type: "point",
|
|
29
43
|
longitude: i.x,
|
|
30
44
|
latitude: i.y
|
|
31
45
|
},
|
|
32
|
-
symbol:
|
|
46
|
+
symbol: s,
|
|
33
47
|
attributes: {
|
|
34
48
|
type: "signal-cross",
|
|
35
49
|
id: i.crossId,
|
|
36
|
-
brandLabel:
|
|
37
|
-
isOnlineLabel:
|
|
38
|
-
isMalfunctionLabel:
|
|
50
|
+
brandLabel: r,
|
|
51
|
+
isOnlineLabel: o,
|
|
52
|
+
isMalfunctionLabel: n,
|
|
39
53
|
...i
|
|
40
|
-
},
|
|
41
|
-
popupTemplate: {
|
|
42
|
-
title: "{name}信号机",
|
|
43
|
-
content: [
|
|
44
|
-
{
|
|
45
|
-
type: "fields",
|
|
46
|
-
fieldInfos: [
|
|
47
|
-
{
|
|
48
|
-
fieldName: "signalId",
|
|
49
|
-
label: "信号机编号"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
fieldName: "crossId",
|
|
53
|
-
label: "路口编号"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
fieldName: "brandLabel",
|
|
57
|
-
label: "品牌"
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
fieldName: "isOnlineLabel",
|
|
61
|
-
label: "是否在线"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
fieldName: "isMalfunctionLabel",
|
|
65
|
-
label: "是否故障"
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
]
|
|
70
54
|
}
|
|
71
55
|
});
|
|
72
56
|
});
|
|
73
57
|
this.crossLayer.addMany(t);
|
|
58
|
+
} else {
|
|
59
|
+
this.locations = e.points.map((i) => ({
|
|
60
|
+
id: i.crossId,
|
|
61
|
+
x: i.x,
|
|
62
|
+
y: i.y,
|
|
63
|
+
visited: !1,
|
|
64
|
+
clusterId: void 0,
|
|
65
|
+
properties: i
|
|
66
|
+
})), this.locationToScreen();
|
|
67
|
+
const t = this.doPixelCluster(this.clusterRadius);
|
|
68
|
+
this.showClusterResult(t);
|
|
74
69
|
}
|
|
75
70
|
return { status: 0, message: "ok" };
|
|
76
71
|
}
|
|
@@ -78,6 +73,215 @@ class b {
|
|
|
78
73
|
var e;
|
|
79
74
|
this.crossLayer.removeAll(), (e = this.scaleWatchHandle) == null || e.remove(), this.scaleWatchHandle = null;
|
|
80
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* 按照像素距离聚类
|
|
78
|
+
* @param locations
|
|
79
|
+
* @param eps
|
|
80
|
+
* @param minPoints
|
|
81
|
+
* @returns
|
|
82
|
+
*/
|
|
83
|
+
doPixelCluster(e) {
|
|
84
|
+
let t = 0;
|
|
85
|
+
for (let i = 0; i < this.clusteredLocations.length; i++) {
|
|
86
|
+
const s = this.clusteredLocations[i];
|
|
87
|
+
if (s.visited)
|
|
88
|
+
continue;
|
|
89
|
+
s.visited = !0;
|
|
90
|
+
const r = this.getNeighbors(s, e);
|
|
91
|
+
r.length < this.minClusterPoints ? s.clusterId = -1 : (r.forEach((o) => {
|
|
92
|
+
o.visited = !0, o.clusterId = t;
|
|
93
|
+
}), s.clusterId = t, t++);
|
|
94
|
+
}
|
|
95
|
+
return this.createClusters();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 获取邻居点
|
|
99
|
+
* @param locations
|
|
100
|
+
* @param index
|
|
101
|
+
* @param eps
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
getNeighbors(e, t) {
|
|
105
|
+
return this.clusteredLocations.filter((i) => i.id === e.id || i.visited ? !1 : this.getDistance(e, i) <= t);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 两点间的像素距离
|
|
109
|
+
* @param point1
|
|
110
|
+
* @param point2
|
|
111
|
+
* @returns
|
|
112
|
+
*/
|
|
113
|
+
getDistance(e, t) {
|
|
114
|
+
return Math.sqrt(
|
|
115
|
+
Math.pow(e.properties.screenX - t.properties.screenX, 2) + Math.pow(e.properties.screenY - t.properties.screenY, 2)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 从聚类结果中创建聚类对象
|
|
120
|
+
* @param locations
|
|
121
|
+
* @returns
|
|
122
|
+
*/
|
|
123
|
+
createClusters() {
|
|
124
|
+
const e = {}, t = [];
|
|
125
|
+
for (const s of this.clusteredLocations)
|
|
126
|
+
s.clusterId === void 0 || s.clusterId === -1 ? t.push(s) : (e[s.clusterId] || (e[s.clusterId] = []), e[s.clusterId].push(s));
|
|
127
|
+
const i = Object.keys(e).map((s, r) => {
|
|
128
|
+
const o = e[Number(s)], n = o.length, l = o.reduce((c, h) => c + h.x, 0), a = o.reduce((c, h) => c + h.y, 0), m = l / n, p = a / n;
|
|
129
|
+
return {
|
|
130
|
+
id: Number(s),
|
|
131
|
+
items: o,
|
|
132
|
+
count: n,
|
|
133
|
+
center: {
|
|
134
|
+
x: m,
|
|
135
|
+
y: p
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
return t.length > 0 && i.push({
|
|
140
|
+
id: -1,
|
|
141
|
+
items: t,
|
|
142
|
+
count: t.length,
|
|
143
|
+
center: null
|
|
144
|
+
}), i;
|
|
145
|
+
}
|
|
146
|
+
showClusterResult(e) {
|
|
147
|
+
this.crossLayer.removeAll();
|
|
148
|
+
let t = Number.MIN_VALUE, i = Number.MAX_VALUE;
|
|
149
|
+
e.forEach((s) => {
|
|
150
|
+
s.count > 1 && (i = Math.min(i, s.count), t = Math.max(t, s.count));
|
|
151
|
+
}), e.forEach((s) => {
|
|
152
|
+
if (s.id !== -1) {
|
|
153
|
+
let r = i === t ? (this.maxClusterSymbolSize + this.minClusterSymbolSize) / 2 : this.minClusterSymbolSize + (s.count - i) / (t - i) * (this.maxClusterSymbolSize - this.minClusterSymbolSize);
|
|
154
|
+
r *= 0.75;
|
|
155
|
+
const l = (s.count.toString().length * 8 + 6) / 2, a = new y({
|
|
156
|
+
geometry: new u({ x: s.center.x, y: s.center.y }),
|
|
157
|
+
attributes: {
|
|
158
|
+
count: s.count
|
|
159
|
+
},
|
|
160
|
+
symbol: {
|
|
161
|
+
type: "cim",
|
|
162
|
+
data: {
|
|
163
|
+
type: "CIMSymbolReference",
|
|
164
|
+
primitiveOverrides: [
|
|
165
|
+
{
|
|
166
|
+
// 将textGraphic的TextString替换为graphic.attributes.name
|
|
167
|
+
type: "CIMPrimitiveOverride",
|
|
168
|
+
primitiveName: "textGraphic",
|
|
169
|
+
propertyName: "TextString",
|
|
170
|
+
valueExpressionInfo: {
|
|
171
|
+
type: "CIMExpressionInfo",
|
|
172
|
+
title: "Custom",
|
|
173
|
+
expression: "$feature.count",
|
|
174
|
+
returnType: "Default"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
symbol: {
|
|
179
|
+
type: "CIMPointSymbol",
|
|
180
|
+
symbolLayers: [
|
|
181
|
+
// 聚合数量
|
|
182
|
+
{
|
|
183
|
+
type: "CIMVectorMarker",
|
|
184
|
+
size: r,
|
|
185
|
+
colorLocked: !0,
|
|
186
|
+
anchorPointUnits: "Relative",
|
|
187
|
+
frame: { xmin: -16, ymin: -16, xmax: 16, ymax: 16 },
|
|
188
|
+
markerGraphics: [
|
|
189
|
+
// 数量文本框
|
|
190
|
+
{
|
|
191
|
+
type: "CIMMarkerGraphic",
|
|
192
|
+
geometry: {
|
|
193
|
+
rings: [
|
|
194
|
+
[
|
|
195
|
+
[-l, 40],
|
|
196
|
+
[l, 40],
|
|
197
|
+
[l, 20],
|
|
198
|
+
[-l, 20],
|
|
199
|
+
[-l, 40]
|
|
200
|
+
]
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
symbol: {
|
|
204
|
+
type: "CIMPolygonSymbol",
|
|
205
|
+
symbolLayers: [
|
|
206
|
+
{
|
|
207
|
+
type: "CIMSolidFill",
|
|
208
|
+
enable: !0,
|
|
209
|
+
color: [2, 72, 200, 255]
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
type: "CIMSolidStroke",
|
|
213
|
+
enable: !0,
|
|
214
|
+
width: 5,
|
|
215
|
+
color: [2, 72, 200, 128]
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
// 数量文字
|
|
221
|
+
{
|
|
222
|
+
type: "CIMMarkerGraphic",
|
|
223
|
+
primitiveName: "textGraphic",
|
|
224
|
+
geometry: { x: 0, y: 0 },
|
|
225
|
+
symbol: {
|
|
226
|
+
type: "CIMTextSymbol",
|
|
227
|
+
height: 16,
|
|
228
|
+
horizontalAlignment: "Center",
|
|
229
|
+
offsetX: 0,
|
|
230
|
+
offsetY: 30,
|
|
231
|
+
symbol: {
|
|
232
|
+
type: "CIMPolygonSymbol",
|
|
233
|
+
symbolLayers: [
|
|
234
|
+
{
|
|
235
|
+
type: "CIMSolidFill",
|
|
236
|
+
enable: !0,
|
|
237
|
+
color: [255, 255, 255, 255]
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
verticalAlignment: "Center"
|
|
242
|
+
},
|
|
243
|
+
textString: ""
|
|
244
|
+
}
|
|
245
|
+
],
|
|
246
|
+
scaleSymbolsProportionally: !0,
|
|
247
|
+
respectFrame: !0
|
|
248
|
+
},
|
|
249
|
+
// 聚合图标
|
|
250
|
+
{
|
|
251
|
+
type: "CIMPictureMarker",
|
|
252
|
+
enable: !0,
|
|
253
|
+
anchorPoint: {
|
|
254
|
+
x: 0,
|
|
255
|
+
y: 0
|
|
256
|
+
},
|
|
257
|
+
anchorPointUnits: "Relative",
|
|
258
|
+
size: r,
|
|
259
|
+
rotateClockwise: !0,
|
|
260
|
+
textureFilter: "Picture",
|
|
261
|
+
url: "/GisViewerAssets/Images/cross/gis_xhj_blue.png"
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
this.crossLayer.add(a);
|
|
269
|
+
} else
|
|
270
|
+
s.items.forEach((r) => {
|
|
271
|
+
const o = new y({
|
|
272
|
+
geometry: new u({ x: r.x, y: r.y }),
|
|
273
|
+
attributes: {
|
|
274
|
+
...r,
|
|
275
|
+
...r.properties,
|
|
276
|
+
type: "signal-cross",
|
|
277
|
+
id: r.id
|
|
278
|
+
},
|
|
279
|
+
symbol: this.getCrossSymbol(r.properties)
|
|
280
|
+
});
|
|
281
|
+
this.crossLayer.add(o);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
}
|
|
81
285
|
getBrandLabel(e) {
|
|
82
286
|
const t = (e ?? "").toLowerCase();
|
|
83
287
|
return t === "scats" ? "SCATS" : t === "gc" ? "国产" : e ?? "";
|
|
@@ -189,5 +393,5 @@ class b {
|
|
|
189
393
|
}
|
|
190
394
|
}
|
|
191
395
|
export {
|
|
192
|
-
|
|
396
|
+
C as default
|
|
193
397
|
};
|
|
@@ -6,10 +6,20 @@ export default class SignalCrossController {
|
|
|
6
6
|
private view;
|
|
7
7
|
private crossLayer;
|
|
8
8
|
private readonly symbolScale;
|
|
9
|
+
private oldScale;
|
|
9
10
|
private scaleWatchHandle;
|
|
10
11
|
private showName;
|
|
11
12
|
private showStyle;
|
|
13
|
+
private readonly clusterRadius;
|
|
14
|
+
private readonly minClusterPoints;
|
|
15
|
+
private readonly maxClusterSymbolSize;
|
|
16
|
+
private readonly minClusterSymbolSize;
|
|
17
|
+
/** 需要进行聚合的点位,一般为当前屏幕范围内的点位 */
|
|
18
|
+
private clusteredLocations;
|
|
19
|
+
/** 所有路口点位 */
|
|
20
|
+
private locations;
|
|
12
21
|
constructor(view: __esri.MapView | __esri.SceneView);
|
|
22
|
+
private locationToScreen;
|
|
13
23
|
/**
|
|
14
24
|
* 显示信控路口
|
|
15
25
|
* @param params
|
|
@@ -17,6 +27,36 @@ export default class SignalCrossController {
|
|
|
17
27
|
*/
|
|
18
28
|
showSignalCross(params: IShowSignalCrossParams): IResult;
|
|
19
29
|
clearSignalCross(): void;
|
|
30
|
+
/**
|
|
31
|
+
* 按照像素距离聚类
|
|
32
|
+
* @param locations
|
|
33
|
+
* @param eps
|
|
34
|
+
* @param minPoints
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
private doPixelCluster;
|
|
38
|
+
/**
|
|
39
|
+
* 获取邻居点
|
|
40
|
+
* @param locations
|
|
41
|
+
* @param index
|
|
42
|
+
* @param eps
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
private getNeighbors;
|
|
46
|
+
/**
|
|
47
|
+
* 两点间的像素距离
|
|
48
|
+
* @param point1
|
|
49
|
+
* @param point2
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
private getDistance;
|
|
53
|
+
/**
|
|
54
|
+
* 从聚类结果中创建聚类对象
|
|
55
|
+
* @param locations
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
private createClusters;
|
|
59
|
+
private showClusterResult;
|
|
20
60
|
private getBrandLabel;
|
|
21
61
|
private getOnlineLabel;
|
|
22
62
|
private getMalfunctionLabel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const h=require("@arcgis/core/geometry"),y=require("@arcgis/core/Graphic"),d=require("@arcgis/core/layers/GraphicsLayer");class b{constructor(e){this.symbolScale=6e3,this.oldScale=0,this.showName="signalId",this.showStyle="scatter",this.clusterRadius=120,this.minClusterPoints=2,this.maxClusterSymbolSize=50,this.minClusterSymbolSize=25,this.clusteredLocations=[],this.locations=[],this.view=e,this.crossLayer=new d({id:"signal-control-cross-layer",title:"信控路口图层"}),this.view.map.add(this.crossLayer)}locationToScreen(){this.clusteredLocations=[],this.locations.forEach(e=>{const t=this.view.toScreen(new h.Point({x:e.x,y:e.y}));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))})}showSignalCross(e){if(this.crossLayer.removeAll(),this.showName=e.showName||"signalId",this.showStyle=e.style||"scatter",this.scaleWatchHandle||(this.scaleWatchHandle=this.view.watch("stationary",()=>{if(this.showStyle==="scatter")(this.oldScale<this.symbolScale&&this.view.scale>=this.symbolScale||this.oldScale>=this.symbolScale&&this.view.scale<this.symbolScale)&&this.crossLayer.graphics.forEach(t=>{t.symbol=this.getCrossSymbol(t.attributes)}),this.oldScale=this.view.scale;else{this.locationToScreen();const t=this.doPixelCluster(this.clusterRadius);this.showClusterResult(t)}})),this.showStyle==="scatter"){const t=e.points.map(i=>{const s=this.getCrossSymbol(i),r=this.getBrandLabel(i.brand),o=this.getOnlineLabel(i.isOnline),n=this.getMalfunctionLabel(i.isMalfunction);return new y({geometry:{type:"point",longitude:i.x,latitude:i.y},symbol:s,attributes:{type:"signal-cross",id:i.crossId,brandLabel:r,isOnlineLabel:o,isMalfunctionLabel:n,...i}})});this.crossLayer.addMany(t)}else{this.locations=e.points.map(i=>({id:i.crossId,x:i.x,y:i.y,visited:!1,clusterId:void 0,properties:i})),this.locationToScreen();const t=this.doPixelCluster(this.clusterRadius);this.showClusterResult(t)}return{status:0,message:"ok"}}clearSignalCross(){var e;this.crossLayer.removeAll(),(e=this.scaleWatchHandle)==null||e.remove(),this.scaleWatchHandle=null}doPixelCluster(e){let t=0;for(let i=0;i<this.clusteredLocations.length;i++){const s=this.clusteredLocations[i];if(s.visited)continue;s.visited=!0;const r=this.getNeighbors(s,e);r.length<this.minClusterPoints?s.clusterId=-1:(r.forEach(o=>{o.visited=!0,o.clusterId=t}),s.clusterId=t,t++)}return this.createClusters()}getNeighbors(e,t){return this.clusteredLocations.filter(i=>i.id===e.id||i.visited?!1:this.getDistance(e,i)<=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 i=Object.keys(e).map((s,r)=>{const o=e[Number(s)],n=o.length,l=o.reduce((c,u)=>c+u.x,0),a=o.reduce((c,u)=>c+u.y,0),m=l/n,p=a/n;return{id:Number(s),items:o,count:n,center:{x:m,y:p}}});return t.length>0&&i.push({id:-1,items:t,count:t.length,center:null}),i}showClusterResult(e){this.crossLayer.removeAll();let t=Number.MIN_VALUE,i=Number.MAX_VALUE;e.forEach(s=>{s.count>1&&(i=Math.min(i,s.count),t=Math.max(t,s.count))}),e.forEach(s=>{if(s.id!==-1){let r=i===t?(this.maxClusterSymbolSize+this.minClusterSymbolSize)/2:this.minClusterSymbolSize+(s.count-i)/(t-i)*(this.maxClusterSymbolSize-this.minClusterSymbolSize);r*=.75;const l=(s.count.toString().length*8+6)/2,a=new y({geometry:new h.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:r,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:r,rotateClockwise:!0,textureFilter:"Picture",url:"/GisViewerAssets/Images/cross/gis_xhj_blue.png"}]}}}});this.crossLayer.add(a)}else s.items.forEach(r=>{const o=new y({geometry:new h.Point({x:r.x,y:r.y}),attributes:{...r,...r.properties,type:"signal-cross",id:r.id},symbol:this.getCrossSymbol(r.properties)});this.crossLayer.add(o)})})}getBrandLabel(e){const t=(e??"").toLowerCase();return t==="scats"?"SCATS":t==="gc"?"国产":e??""}getOnlineLabel(e){return e?"在线":"离线"}getMalfunctionLabel(e){return e?"故障":"正常"}getCrossSymbol(e){if(this.view.scale<=this.symbolScale){let t="/GisViewerAssets/Images/cross/ic_";return t+=e.brand==="scats"?"scats_":"gc_",t+=e.isOnline?"online_":"offline_",t+=e.isMalfunction?"malfunction.png":"normal.png",{type:"cim",data:{type:"CIMSymbolReference",primitiveOverrides:[{type:"CIMPrimitiveOverride",primitiveName:"textGraphic",propertyName:"TextString",valueExpressionInfo:{type:"CIMExpressionInfo",title:"Custom",expression:this.showName==="signalId"?'Replace($feature.name, "与", "/") + " " + $feature.signalId':'Replace($feature.name, "与", "/") + " " + $feature.crossId',returnType:"Default"}}],symbol:{type:"CIMPointSymbol",symbolLayers:[{type:"CIMVectorMarker",size:25,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}]}}}}else{const t={type:"simple-marker",style:"circle",size:6,outline:{width:0}};return e.brand.toLowerCase()==="scats"?(e.isOnline?t.color=[23,169,100]:t.color=[202,202,202],t.outline.color=[23,169,100]):e.isOnline?t.color=[33,240,142]:t.color=[202,202,202],t}}}exports.default=b;
|