cesium-multi-target-framework 0.1.0
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/README.md +474 -0
- package/dist/assets/renderWorker-118e8f3b.js +1 -0
- package/dist/cesium-multi-target-framework.js +4605 -0
- package/dist/cesium-multi-target-framework.umd.cjs +101 -0
- package/dist/cluster/QuadCluster.d.ts +66 -0
- package/dist/cluster/clusterClient.d.ts +44 -0
- package/dist/cluster/clusterWorker.d.ts +1 -0
- package/dist/config/types.d.ts +266 -0
- package/dist/core/EventEmitter.d.ts +9 -0
- package/dist/core/MultiTargetFramework.d.ts +184 -0
- package/dist/core/MultiTargetScene.d.ts +224 -0
- package/dist/data/types.d.ts +67 -0
- package/dist/events/bus.d.ts +336 -0
- package/dist/index.d.ts +22 -0
- package/dist/render/AirGroundReferenceRenderer.d.ts +20 -0
- package/dist/render/InstancedGltfBatch.d.ts +37 -0
- package/dist/render/InstancedSymbolRenderer.d.ts +65 -0
- package/dist/render/LowModelInstancedRenderer.d.ts +39 -0
- package/dist/render/ModelPoolRenderer.d.ts +43 -0
- package/dist/render/PointCloudRenderer.d.ts +135 -0
- package/dist/render/SelectionOverlayRenderer.d.ts +37 -0
- package/dist/render/targetVisualMetrics.d.ts +9 -0
- package/dist/site/SiteLayer.d.ts +43 -0
- package/dist/site/SiteLowModelRenderer.d.ts +12 -0
- package/dist/site/SiteSpatialIndex.d.ts +10 -0
- package/dist/site/types.d.ts +72 -0
- package/dist/track/TrackHoverPicker.d.ts +26 -0
- package/dist/track/TrackManager.d.ts +42 -0
- package/dist/track/TrackRenderer.d.ts +29 -0
- package/dist/track/types.d.ts +27 -0
- package/dist/worker/protocol.d.ts +182 -0
- package/dist/worker/renderWorker.d.ts +1 -0
- package/doc//345/244/232/347/233/256/346/240/207/344/274/230/345/214/226/344/270/216/351/242/204/346/265/213/346/270/262/346/237/223/350/257/264/346/230/216.md +186 -0
- package/doc//345/244/232/347/273/204/344/273/266/344/272/213/344/273/266/346/226/271/346/241/210.md +410 -0
- package/doc//345/257/271/345/244/226/346/216/245/345/217/243/350/257/264/346/230/216.md +519 -0
- package/doc//345/267/245/344/275/234/350/256/241/345/210/222.md +59 -0
- package/doc//346/270/262/346/237/223/344/270/232/345/212/241/351/200/273/350/276/221.md +202 -0
- package/doc//347/253/231/347/202/271/346/270/262/346/237/223/344/270/216/345/217/263/351/224/256/350/217/234/345/215/225/345/256/236/347/216/260/350/257/264/346/230/216.md +49 -0
- package/doc//350/247/206/345/217/243/351/251/261/345/212/250/346/225/260/346/215/256/346/265/201/347/250/213/344/277/256/346/224/271/350/256/241/345/210/222.md +69 -0
- package/doc//351/241/271/347/233/256/350/257/264/346/230/216/344/271/246.md +729 -0
- package/package.json +51 -0
|
@@ -0,0 +1,4605 @@
|
|
|
1
|
+
var fi = Object.defineProperty;
|
|
2
|
+
var mi = (i, e, t) => e in i ? fi(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
|
|
3
|
+
var a = (i, e, t) => (mi(i, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
+
import * as Re from "cesium";
|
|
5
|
+
import { Color as D, PolylineCollection as Ve, PointPrimitiveCollection as pi, Cartesian3 as f, Material as ae, Cartographic as et, Matrix4 as R, BoundingSphere as Ze, HeadingPitchRoll as Vt, Math as A, Transforms as Ye, Model as gi, ModelAnimationLoop as Le, BillboardCollection as fe, Cartesian2 as J, HorizontalOrigin as vi, VerticalOrigin as yi, SceneTransforms as Ae, ScreenSpaceEventHandler as Wt, ScreenSpaceEventType as N, HeadingPitchRange as wi } from "cesium";
|
|
6
|
+
export * from "cesium";
|
|
7
|
+
const Pe = {
|
|
8
|
+
SURFACE: "surface",
|
|
9
|
+
AIR: "air",
|
|
10
|
+
UNDERWATER: "underwater"
|
|
11
|
+
}, Mi = {
|
|
12
|
+
pointAbove: 15e4,
|
|
13
|
+
animatedBelow: 1e4
|
|
14
|
+
}, Ii = { size: 3e4 }, Si = { size: 64 }, ye = {
|
|
15
|
+
updateFps: 30,
|
|
16
|
+
predictSeconds: 10,
|
|
17
|
+
predictFitSeconds: 2,
|
|
18
|
+
masterHideHeight: 15e4
|
|
19
|
+
};
|
|
20
|
+
function xi(i) {
|
|
21
|
+
var o, r, l, h, c, m, u, v, d, p, g, y, w, M, I, C, k, S, T, z, L, E, B, Z, Q, q, ee, $, X, le, me, pe, ge, x, H, O;
|
|
22
|
+
const e = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const j of i.nodeTypes ?? [])
|
|
24
|
+
e.set(j.type, j);
|
|
25
|
+
const t = Array.from(e.values()).map(Ti), s = ((o = i.pool) == null ? void 0 : o.size) ?? Ii.size, n = ((r = i.frame) == null ? void 0 : r.heatmapAboveHeight) ?? 2e6;
|
|
26
|
+
return {
|
|
27
|
+
nodeTypes: e,
|
|
28
|
+
renderTypes: t,
|
|
29
|
+
lod: i.lod ?? Mi,
|
|
30
|
+
poolSize: s,
|
|
31
|
+
animatedCapacity: ((l = i.animatedPool) == null ? void 0 : l.size) ?? Si.size,
|
|
32
|
+
updateFps: i.updateFps ?? ye.updateFps,
|
|
33
|
+
predictSeconds: i.predictSeconds ?? ye.predictSeconds,
|
|
34
|
+
predictFitSeconds: i.predictFitSeconds ?? ye.predictFitSeconds,
|
|
35
|
+
fadeMs: i.fadeMs ?? 350,
|
|
36
|
+
masterHideHeight: i.masterHideHeight ?? ye.masterHideHeight,
|
|
37
|
+
groundSymbols: i.groundSymbols ?? !1,
|
|
38
|
+
groundSymbolPixelSize: i.groundSymbolPixelSize ?? 30,
|
|
39
|
+
merge: Ai(i.merge, s),
|
|
40
|
+
pick: {
|
|
41
|
+
enabled: ((h = i.pick) == null ? void 0 : h.enabled) ?? !0,
|
|
42
|
+
pixelThreshold: ((c = i.pick) == null ? void 0 : c.pixelThreshold) ?? 20,
|
|
43
|
+
hover: ((m = i.pick) == null ? void 0 : m.hover) ?? !0
|
|
44
|
+
},
|
|
45
|
+
cull: {
|
|
46
|
+
enabled: ((u = i.cull) == null ? void 0 : u.enabled) ?? !0,
|
|
47
|
+
padding: ((v = i.cull) == null ? void 0 : v.padding) ?? 3e4,
|
|
48
|
+
viewportCull: ((d = i.cull) == null ? void 0 : d.viewportCull) ?? !0,
|
|
49
|
+
viewportBufferRatio: ((p = i.cull) == null ? void 0 : p.viewportBufferRatio) ?? 0.15,
|
|
50
|
+
viewportBufferMinMeters: Math.max(0, ((g = i.cull) == null ? void 0 : g.viewportBufferMinMeters) ?? 500)
|
|
51
|
+
},
|
|
52
|
+
horizonCull: {
|
|
53
|
+
enabled: ((y = i.horizonCull) == null ? void 0 : y.enabled) ?? !0,
|
|
54
|
+
pitchThreshold: ((w = i.horizonCull) == null ? void 0 : w.pitchThreshold) ?? -25,
|
|
55
|
+
minDistance: Math.max(0, ((M = i.horizonCull) == null ? void 0 : M.minDistance) ?? 8e3),
|
|
56
|
+
maxDistance: Math.max(0, ((I = i.horizonCull) == null ? void 0 : I.maxDistance) ?? 4e4),
|
|
57
|
+
cameraHeightMultiplier: Math.max(0, ((C = i.horizonCull) == null ? void 0 : C.cameraHeightMultiplier) ?? 6),
|
|
58
|
+
maxCameraHeight: Math.max(0, ((k = i.horizonCull) == null ? void 0 : k.maxCameraHeight) ?? 8e4)
|
|
59
|
+
},
|
|
60
|
+
label: Ke(i.label),
|
|
61
|
+
frame: {
|
|
62
|
+
maxScanPerFrame: ((S = i.frame) == null ? void 0 : S.maxScanPerFrame) ?? 3e4,
|
|
63
|
+
maxScanMs: ((T = i.frame) == null ? void 0 : T.maxScanMs) ?? 4,
|
|
64
|
+
maxIngestPerFrame: ((z = i.frame) == null ? void 0 : z.maxIngestPerFrame) ?? 2e4,
|
|
65
|
+
maxLowModelRenderItems: ((L = i.frame) == null ? void 0 : L.maxLowModelRenderItems) ?? ((E = i.frame) == null ? void 0 : E.maxModelRenderItems) ?? 3e3,
|
|
66
|
+
maxModelRenderItems: ((B = i.frame) == null ? void 0 : B.maxModelRenderItems) ?? 2e3,
|
|
67
|
+
suspendRenderUpdateWhileMoving: ((Z = i.frame) == null ? void 0 : Z.suspendRenderUpdateWhileMoving) ?? !0,
|
|
68
|
+
heatmapAboveHeight: n,
|
|
69
|
+
heatmapBelowHeight: ((Q = i.frame) == null ? void 0 : Q.heatmapBelowHeight) ?? Math.max(0, n * 0.9),
|
|
70
|
+
heatmapSwitchSettleMs: ((q = i.frame) == null ? void 0 : q.heatmapSwitchSettleMs) ?? 300,
|
|
71
|
+
heatmapUpdateIntervalMs: ((ee = i.frame) == null ? void 0 : ee.heatmapUpdateIntervalMs) ?? 6e5
|
|
72
|
+
},
|
|
73
|
+
data: {
|
|
74
|
+
commitIntervalMs: (($ = i.data) == null ? void 0 : $.commitIntervalMs) ?? 2e3,
|
|
75
|
+
leading: ((X = i.data) == null ? void 0 : X.leading) ?? !0,
|
|
76
|
+
worker: ((le = i.data) == null ? void 0 : le.worker) ?? !0
|
|
77
|
+
},
|
|
78
|
+
adaptive: {
|
|
79
|
+
enabled: ((me = i.adaptive) == null ? void 0 : me.enabled) ?? !0,
|
|
80
|
+
dynamic: ((pe = i.adaptive) == null ? void 0 : pe.dynamic) ?? !0,
|
|
81
|
+
minFps: ((ge = i.adaptive) == null ? void 0 : ge.minFps) ?? 25,
|
|
82
|
+
upFps: ((x = i.adaptive) == null ? void 0 : x.upFps) ?? 50,
|
|
83
|
+
windowMs: ((H = i.adaptive) == null ? void 0 : H.windowMs) ?? 2e3,
|
|
84
|
+
baseTier: ((O = i.adaptive) == null ? void 0 : O.baseTier) ?? "high"
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function Ti(i) {
|
|
89
|
+
const e = i.targetDomain ?? Ci(i.type);
|
|
90
|
+
return {
|
|
91
|
+
...i,
|
|
92
|
+
targetDomain: e,
|
|
93
|
+
forceHighModelInLowLod: i.forceHighModelInLowLod ?? e === Pe.AIR,
|
|
94
|
+
iconPath: i.iconPath ?? i.pointIcon ?? bi(i.type),
|
|
95
|
+
defaultColor: i.defaultColor ?? Pi(i.type),
|
|
96
|
+
pointHeadingOffset: i.pointHeadingOffset ?? 0,
|
|
97
|
+
smoothMove: i.smoothMove ?? !1,
|
|
98
|
+
smoothMoveMinCameraHeight: i.smoothMoveMinCameraHeight ?? 25e3,
|
|
99
|
+
smoothMoveDurationMs: i.smoothMoveDurationMs ?? i.moveAnimationDurationMs ?? 400,
|
|
100
|
+
predictMove: i.predictMove ?? !1,
|
|
101
|
+
predictMinCameraHeight: i.predictMinCameraHeight ?? 25e3,
|
|
102
|
+
predictSeconds: i.predictSeconds,
|
|
103
|
+
predictFitSeconds: i.predictFitSeconds
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function Ci(i) {
|
|
107
|
+
return i.startsWith("air") || i.startsWith("uav") || i.includes("bird") || i.includes("aircraft") || i.includes("fpv") ? Pe.AIR : i.startsWith("underwater") || i.startsWith("subsea") ? Pe.UNDERWATER : Pe.SURFACE;
|
|
108
|
+
}
|
|
109
|
+
function bi(i) {
|
|
110
|
+
return i.startsWith("air") || i.startsWith("uav") ? "/icons/target-uav-mask.png" : i.startsWith("person") ? "/icons/target-person-mask.png" : i.startsWith("car") ? "/icons/target-car-mask.png" : "/icons/target-ship-mask.png";
|
|
111
|
+
}
|
|
112
|
+
function Pi(i) {
|
|
113
|
+
return i.startsWith("air") || i.startsWith("uav") ? "#22d2f2" : i.startsWith("person") ? "#ffdc40" : i.startsWith("car") ? "#ff9a2a" : "#25e65c";
|
|
114
|
+
}
|
|
115
|
+
function Xt(i) {
|
|
116
|
+
return {
|
|
117
|
+
key: i.key,
|
|
118
|
+
label: i.label,
|
|
119
|
+
source: i.source ?? "standard",
|
|
120
|
+
fallback: i.fallback,
|
|
121
|
+
minCameraHeight: i.minCameraHeight,
|
|
122
|
+
maxCameraHeight: i.maxCameraHeight
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function tt(i) {
|
|
126
|
+
let e = 0;
|
|
127
|
+
for (const t of i ?? [])
|
|
128
|
+
t.maxCameraHeight != null && t.maxCameraHeight > e && (e = t.maxCameraHeight);
|
|
129
|
+
return e;
|
|
130
|
+
}
|
|
131
|
+
function Ri(i) {
|
|
132
|
+
var e;
|
|
133
|
+
return {
|
|
134
|
+
...i,
|
|
135
|
+
fields: (e = i.fields) == null ? void 0 : e.map(Xt),
|
|
136
|
+
maxCameraHeight: i.maxCameraHeight != null ? Math.max(0, i.maxCameraHeight) : void 0,
|
|
137
|
+
maxCount: i.maxCount != null ? Math.max(0, i.maxCount) : void 0
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function Ke(i) {
|
|
141
|
+
var o;
|
|
142
|
+
const e = Math.max(0, (i == null ? void 0 : i.maxCameraHeight) ?? 5e3), t = (o = i == null ? void 0 : i.fields) != null && o.length ? i.fields.map(Xt) : [{ key: "id" }];
|
|
143
|
+
let s = Math.max(e, tt(t));
|
|
144
|
+
const n = i != null && i.byType ? Object.fromEntries(Object.entries(i.byType).map(([r, l]) => [r, Ri(l)])) : void 0;
|
|
145
|
+
if (n)
|
|
146
|
+
for (const r of Object.values(n))
|
|
147
|
+
s = Math.max(s, r.maxCameraHeight ?? 0, tt(r.fields));
|
|
148
|
+
return {
|
|
149
|
+
enabled: (i == null ? void 0 : i.enabled) ?? !0,
|
|
150
|
+
maxCount: Math.max(0, (i == null ? void 0 : i.maxCount) ?? 200),
|
|
151
|
+
maxCameraHeight: s,
|
|
152
|
+
maxDistance: i == null ? void 0 : i.maxDistance,
|
|
153
|
+
fields: t,
|
|
154
|
+
byType: n,
|
|
155
|
+
resolve: i == null ? void 0 : i.resolve,
|
|
156
|
+
backgroundColor: (i == null ? void 0 : i.backgroundColor) ?? "#0000008c",
|
|
157
|
+
textColor: (i == null ? void 0 : i.textColor) ?? "#ffffff",
|
|
158
|
+
fontSize: Math.max(1, (i == null ? void 0 : i.fontSize) ?? 12),
|
|
159
|
+
fontFamily: (i == null ? void 0 : i.fontFamily) ?? "sans-serif",
|
|
160
|
+
backgroundRadius: Math.max(0, (i == null ? void 0 : i.backgroundRadius) ?? 6),
|
|
161
|
+
overlapThreshold: ki((i == null ? void 0 : i.overlapThreshold) ?? 0.35, 0, 1),
|
|
162
|
+
occlusionGraceMs: Math.max(0, (i == null ? void 0 : i.occlusionGraceMs) ?? 300),
|
|
163
|
+
offsetX: Math.max(0, (i == null ? void 0 : i.offsetX) ?? 18),
|
|
164
|
+
offsetY: Math.max(0, (i == null ? void 0 : i.offsetY) ?? 24),
|
|
165
|
+
connectorColor: (i == null ? void 0 : i.connectorColor) ?? (i == null ? void 0 : i.backgroundColor) ?? "#0000008c",
|
|
166
|
+
connectorWidth: Math.max(0, (i == null ? void 0 : i.connectorWidth) ?? 1.5),
|
|
167
|
+
connectorStemLength: Math.max(0, (i == null ? void 0 : i.connectorStemLength) ?? 50),
|
|
168
|
+
showFieldLabels: (i == null ? void 0 : i.showFieldLabels) ?? !0
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function ki(i, e, t) {
|
|
172
|
+
return Math.max(e, Math.min(t, i));
|
|
173
|
+
}
|
|
174
|
+
function Ai(i, e) {
|
|
175
|
+
if (!i)
|
|
176
|
+
return;
|
|
177
|
+
const t = (i.radii ?? [100, 200, 500, 1e3, 2e3, 5e3, 1e4]).slice().sort((s, n) => s - n);
|
|
178
|
+
return {
|
|
179
|
+
enabled: i.enabled,
|
|
180
|
+
mode: i.mode ?? "global",
|
|
181
|
+
maxVisible: i.maxVisible ?? e,
|
|
182
|
+
globalRootLimit: Math.max(1, i.globalRootLimit ?? 500),
|
|
183
|
+
globalMaxLevels: Math.max(1, i.globalMaxLevels ?? 64),
|
|
184
|
+
globalRebuildIntervalMs: Math.max(0, i.globalRebuildIntervalMs ?? 3e5),
|
|
185
|
+
globalViewportHeight: Math.max(0, i.globalViewportHeight ?? 45e4),
|
|
186
|
+
cameraMergeBaseHeight: Math.max(0, i.cameraMergeBaseHeight ?? 1e5),
|
|
187
|
+
cameraMergeStepHeight: Math.max(1, i.cameraMergeStepHeight ?? 1e4),
|
|
188
|
+
cameraMergeStepRadius: Math.max(1, i.cameraMergeStepRadius ?? 100),
|
|
189
|
+
innerRatio: Math.max(0, Math.min(1, i.innerRatio ?? 0.6)),
|
|
190
|
+
radii: t,
|
|
191
|
+
byType: i.byType ?? !0,
|
|
192
|
+
minSecrecy: i.minSecrecy,
|
|
193
|
+
bucketCellDeg: i.bucketCellDeg ?? 0.02
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
class qe {
|
|
197
|
+
constructor() {
|
|
198
|
+
a(this, "handlers", /* @__PURE__ */ new Map());
|
|
199
|
+
}
|
|
200
|
+
on(e, t) {
|
|
201
|
+
let s = this.handlers.get(e);
|
|
202
|
+
return s || (s = /* @__PURE__ */ new Set(), this.handlers.set(e, s)), s.add(t), () => this.off(e, t);
|
|
203
|
+
}
|
|
204
|
+
off(e, t) {
|
|
205
|
+
var s;
|
|
206
|
+
(s = this.handlers.get(e)) == null || s.delete(t);
|
|
207
|
+
}
|
|
208
|
+
emit(e, t) {
|
|
209
|
+
const s = this.handlers.get(e);
|
|
210
|
+
if (s)
|
|
211
|
+
for (const n of s)
|
|
212
|
+
n(t);
|
|
213
|
+
}
|
|
214
|
+
clear() {
|
|
215
|
+
this.handlers.clear();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const it = new D(0.22, 0.82, 1, 0.68), Li = new D(0.22, 0.82, 1, 0), He = new D(0.12, 0.72, 1, 0.72), De = new D(1, 1, 1, 0.9);
|
|
219
|
+
class Hi {
|
|
220
|
+
constructor(e) {
|
|
221
|
+
a(this, "lineCollection");
|
|
222
|
+
a(this, "pointCollection");
|
|
223
|
+
a(this, "pool", []);
|
|
224
|
+
this.scene = e, this.lineCollection = this.scene.primitives.add(new Ve({ show: !0 })), this.pointCollection = this.scene.primitives.add(new pi({ show: !0 }));
|
|
225
|
+
}
|
|
226
|
+
setTargets(e) {
|
|
227
|
+
this.ensurePool(e.length);
|
|
228
|
+
for (let t = 0; t < e.length; t++)
|
|
229
|
+
this.updateSlot(this.pool[t], e[t]);
|
|
230
|
+
for (let t = e.length; t < this.pool.length; t++)
|
|
231
|
+
this.pool[t].line.show = !1, this.pool[t].point.show = !1;
|
|
232
|
+
}
|
|
233
|
+
clear() {
|
|
234
|
+
for (const e of this.pool)
|
|
235
|
+
e.line.show = !1, e.point.show = !1;
|
|
236
|
+
}
|
|
237
|
+
destroy() {
|
|
238
|
+
this.clear(), this.scene.primitives.remove(this.lineCollection), this.scene.primitives.remove(this.pointCollection);
|
|
239
|
+
}
|
|
240
|
+
ensurePool(e) {
|
|
241
|
+
for (; this.pool.length < e; )
|
|
242
|
+
this.pool.push(this.createSlot());
|
|
243
|
+
}
|
|
244
|
+
createSlot() {
|
|
245
|
+
const e = f.clone(f.ZERO), t = f.clone(f.ZERO), s = [e, t], n = ae.fromType(ae.PolylineDashType, {
|
|
246
|
+
color: D.clone(it),
|
|
247
|
+
gapColor: D.clone(Li),
|
|
248
|
+
dashLength: 14,
|
|
249
|
+
dashPattern: 255
|
|
250
|
+
}), o = this.lineCollection.add({
|
|
251
|
+
show: !1,
|
|
252
|
+
positions: s,
|
|
253
|
+
width: 1.5,
|
|
254
|
+
material: n
|
|
255
|
+
}), r = this.pointCollection.add({
|
|
256
|
+
show: !1,
|
|
257
|
+
position: t,
|
|
258
|
+
pixelSize: 7,
|
|
259
|
+
color: D.clone(He),
|
|
260
|
+
outlineColor: D.clone(De),
|
|
261
|
+
outlineWidth: 1.5,
|
|
262
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
263
|
+
});
|
|
264
|
+
return {
|
|
265
|
+
line: o,
|
|
266
|
+
point: r,
|
|
267
|
+
top: e,
|
|
268
|
+
ground: t,
|
|
269
|
+
positions: s,
|
|
270
|
+
cartographic: new et(),
|
|
271
|
+
lineMaterial: n
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
updateSlot(e, t) {
|
|
275
|
+
f.clone(t.position, e.top);
|
|
276
|
+
const s = et.fromCartesian(t.position, void 0, e.cartographic);
|
|
277
|
+
if (!s) {
|
|
278
|
+
e.line.show = !1, e.point.show = !1;
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
f.fromRadians(s.longitude, s.latitude, 0, void 0, e.ground), e.line.positions = e.positions, e.point.position = e.ground, e.line.id = t.id, e.point.id = t.id;
|
|
282
|
+
const n = Math.max(0, Math.min(1, t.visualScale));
|
|
283
|
+
Di(e.lineMaterial, n * it.alpha), e.point.color = st(He, n * He.alpha, e.point.color), e.point.outlineColor = st(
|
|
284
|
+
De,
|
|
285
|
+
n * De.alpha,
|
|
286
|
+
e.point.outlineColor
|
|
287
|
+
), e.line.show = n > 1e-3, e.point.show = n > 1e-3;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function Di(i, e) {
|
|
291
|
+
const t = i.uniforms;
|
|
292
|
+
!t || !t.color || (t.color.alpha = e);
|
|
293
|
+
}
|
|
294
|
+
function st(i, e, t) {
|
|
295
|
+
const s = t ?? new D();
|
|
296
|
+
return s.red = i.red, s.green = i.green, s.blue = i.blue, s.alpha = e, s;
|
|
297
|
+
}
|
|
298
|
+
const F = Re, ce = F.Buffer, he = F.BufferUsage, Ei = F.VertexArray, nt = F.IndexDatatype, _i = F.ShaderProgram, Oi = F.DrawCommand, Bi = F.RenderState, Ni = F.Pass, Fi = F.PrimitiveType, se = F.ComponentDatatype, zi = F.Texture, Vi = F.Sampler, Wi = {
|
|
299
|
+
5120: Int8Array,
|
|
300
|
+
5121: Uint8Array,
|
|
301
|
+
5122: Int16Array,
|
|
302
|
+
5123: Uint16Array,
|
|
303
|
+
5125: Uint32Array,
|
|
304
|
+
5126: Float32Array
|
|
305
|
+
}, Xi = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4, MAT4: 16 };
|
|
306
|
+
class Ui {
|
|
307
|
+
constructor(e, t, s = 8e3) {
|
|
308
|
+
a(this, "url");
|
|
309
|
+
a(this, "scene");
|
|
310
|
+
a(this, "capacity");
|
|
311
|
+
a(this, "center", new f());
|
|
312
|
+
a(this, "instMatrices", new Float32Array(0));
|
|
313
|
+
// count*16, RTC 相对
|
|
314
|
+
a(this, "count", 0);
|
|
315
|
+
a(this, "dirty", !1);
|
|
316
|
+
a(this, "ready", !1);
|
|
317
|
+
a(this, "show", !0);
|
|
318
|
+
a(this, "groups", []);
|
|
319
|
+
a(this, "segments", []);
|
|
320
|
+
// {cmd, instBufs[4], va, sp, texture}
|
|
321
|
+
a(this, "built", !1);
|
|
322
|
+
a(this, "_mm");
|
|
323
|
+
a(this, "_cols", []);
|
|
324
|
+
this.scene = e, this.url = t, this.capacity = s, this.instMatrices = new Float32Array(s * 16), this.load(t);
|
|
325
|
+
}
|
|
326
|
+
/** matrices: Float32Array(count*16) 列主序,平移已相对 center。 */
|
|
327
|
+
setInstances(e, t, s) {
|
|
328
|
+
this.count = Math.min(t, this.capacity), this.instMatrices.set(e.subarray(0, this.count * 16)), f.clone(s, this.center), this.dirty = !0;
|
|
329
|
+
}
|
|
330
|
+
setVisible(e) {
|
|
331
|
+
this.show = e;
|
|
332
|
+
}
|
|
333
|
+
async load(e) {
|
|
334
|
+
try {
|
|
335
|
+
const s = await (await fetch(e)).json(), n = (s.buffers ?? []).map((o) => Yi(o.uri));
|
|
336
|
+
this.groups = Ji(s, n), this.ready = this.groups.length > 0;
|
|
337
|
+
} catch (t) {
|
|
338
|
+
console.warn("[multi-target] InstancedGltfBatch load failed", e, t);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
update(e) {
|
|
342
|
+
if (!this.show || !this.ready || this.count === 0)
|
|
343
|
+
return;
|
|
344
|
+
const t = e.context;
|
|
345
|
+
this.built || this.build(t), R.fromTranslation(this.center, this._mm ?? (this._mm = new R()));
|
|
346
|
+
for (const s of this.segments) {
|
|
347
|
+
if (this.dirty)
|
|
348
|
+
for (let n = 0; n < 4; n++)
|
|
349
|
+
s.instBufs[n].copyFromArrayView(this.columnView(n), 0);
|
|
350
|
+
R.clone(this._mm, s.cmd.modelMatrix), s.cmd.instanceCount = this.count, e.commandList.push(s.cmd);
|
|
351
|
+
}
|
|
352
|
+
this.dirty = !1;
|
|
353
|
+
}
|
|
354
|
+
// 把 count*16 拆成第 k 列(count*4)
|
|
355
|
+
columnView(e) {
|
|
356
|
+
this._cols[e] || (this._cols[e] = new Float32Array(this.capacity * 4));
|
|
357
|
+
const t = this._cols[e];
|
|
358
|
+
for (let s = 0; s < this.count; s++)
|
|
359
|
+
t[s * 4 + 0] = this.instMatrices[s * 16 + e * 4 + 0], t[s * 4 + 1] = this.instMatrices[s * 16 + e * 4 + 1], t[s * 4 + 2] = this.instMatrices[s * 16 + e * 4 + 2], t[s * 4 + 3] = this.instMatrices[s * 16 + e * 4 + 3];
|
|
360
|
+
return t;
|
|
361
|
+
}
|
|
362
|
+
build(e) {
|
|
363
|
+
this.built = !0;
|
|
364
|
+
for (const t of this.groups) {
|
|
365
|
+
const s = ce.createVertexBuffer({ context: e, typedArray: new Float32Array(t.positions), usage: he.STATIC_DRAW }), n = ce.createVertexBuffer({ context: e, typedArray: new Float32Array(t.normals), usage: he.STATIC_DRAW }), o = ce.createVertexBuffer({ context: e, typedArray: new Float32Array(t.uvs), usage: he.STATIC_DRAW }), r = t.vcount > 65535 ? new Uint32Array(t.indices) : new Uint16Array(t.indices), l = ce.createIndexBuffer({
|
|
366
|
+
context: e,
|
|
367
|
+
typedArray: r,
|
|
368
|
+
usage: he.STATIC_DRAW,
|
|
369
|
+
indexDatatype: t.vcount > 65535 ? nt.UNSIGNED_INT : nt.UNSIGNED_SHORT
|
|
370
|
+
}), h = [0, 1, 2, 3].map(
|
|
371
|
+
() => ce.createVertexBuffer({ context: e, typedArray: new Float32Array(this.capacity * 4), usage: he.DYNAMIC_DRAW })
|
|
372
|
+
), c = new Ei({
|
|
373
|
+
context: e,
|
|
374
|
+
attributes: [
|
|
375
|
+
{ index: 0, vertexBuffer: s, componentsPerAttribute: 3, componentDatatype: se.FLOAT },
|
|
376
|
+
{ index: 1, vertexBuffer: n, componentsPerAttribute: 3, componentDatatype: se.FLOAT },
|
|
377
|
+
{ index: 2, vertexBuffer: o, componentsPerAttribute: 2, componentDatatype: se.FLOAT },
|
|
378
|
+
{ index: 3, vertexBuffer: h[0], componentsPerAttribute: 4, componentDatatype: se.FLOAT, instanceDivisor: 1 },
|
|
379
|
+
{ index: 4, vertexBuffer: h[1], componentsPerAttribute: 4, componentDatatype: se.FLOAT, instanceDivisor: 1 },
|
|
380
|
+
{ index: 5, vertexBuffer: h[2], componentsPerAttribute: 4, componentDatatype: se.FLOAT, instanceDivisor: 1 },
|
|
381
|
+
{ index: 6, vertexBuffer: h[3], componentsPerAttribute: 4, componentDatatype: se.FLOAT, instanceDivisor: 1 }
|
|
382
|
+
],
|
|
383
|
+
indexBuffer: l
|
|
384
|
+
}), m = _i.fromCache({
|
|
385
|
+
context: e,
|
|
386
|
+
vertexShaderSource: Gi,
|
|
387
|
+
fragmentShaderSource: Zi,
|
|
388
|
+
attributeLocations: { a_pos: 0, a_nrm: 1, a_uv: 2, a_m0: 3, a_m1: 4, a_m2: 5, a_m3: 6 }
|
|
389
|
+
}), u = this.makeTexture(e, t.imageUri), v = {
|
|
390
|
+
u_tex: () => u.value ?? e.defaultTexture,
|
|
391
|
+
u_hasTex: () => u.value ? 1 : 0
|
|
392
|
+
}, d = new Oi({
|
|
393
|
+
primitiveType: Fi.TRIANGLES,
|
|
394
|
+
vertexArray: c,
|
|
395
|
+
shaderProgram: m,
|
|
396
|
+
renderState: Bi.fromCache({ depthTest: { enabled: !0 }, depthMask: !0, cull: { enabled: !1 } }),
|
|
397
|
+
pass: Ni.OPAQUE,
|
|
398
|
+
modelMatrix: R.clone(R.IDENTITY, new R()),
|
|
399
|
+
uniformMap: v,
|
|
400
|
+
count: t.indices.length,
|
|
401
|
+
instanceCount: this.count,
|
|
402
|
+
cull: !1,
|
|
403
|
+
boundingVolume: new Ze(f.ZERO, 1e8),
|
|
404
|
+
owner: this
|
|
405
|
+
});
|
|
406
|
+
this.segments.push({ cmd: d, instBufs: h, va: c, sp: m, texture: u });
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
makeTexture(e, t) {
|
|
410
|
+
const s = { value: void 0 };
|
|
411
|
+
if (!t)
|
|
412
|
+
return s;
|
|
413
|
+
const n = new Image();
|
|
414
|
+
return n.onload = () => {
|
|
415
|
+
var o, r;
|
|
416
|
+
s.value = new zi({ context: e, source: n, flipY: !1, sampler: new Vi({}) }), (r = (o = this.scene).requestRender) == null || r.call(o);
|
|
417
|
+
}, n.src = t, s;
|
|
418
|
+
}
|
|
419
|
+
isDestroyed() {
|
|
420
|
+
return !1;
|
|
421
|
+
}
|
|
422
|
+
destroy() {
|
|
423
|
+
for (const e of this.segments)
|
|
424
|
+
e.sp && e.sp.destroy(), e.va && e.va.destroy(), e.texture && e.texture.value && e.texture.value.destroy();
|
|
425
|
+
return this.segments = [], !0;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
const Gi = `
|
|
429
|
+
in vec3 a_pos;
|
|
430
|
+
in vec3 a_nrm;
|
|
431
|
+
in vec2 a_uv;
|
|
432
|
+
in vec4 a_m0;
|
|
433
|
+
in vec4 a_m1;
|
|
434
|
+
in vec4 a_m2;
|
|
435
|
+
in vec4 a_m3;
|
|
436
|
+
out vec2 v_uv;
|
|
437
|
+
out vec3 v_nrm;
|
|
438
|
+
void main() {
|
|
439
|
+
mat4 inst = mat4(a_m0, a_m1, a_m2, a_m3);
|
|
440
|
+
vec4 worldRTC = inst * vec4(a_pos, 1.0);
|
|
441
|
+
v_uv = a_uv;
|
|
442
|
+
v_nrm = normalize(mat3(a_m0.xyz, a_m1.xyz, a_m2.xyz) * a_nrm);
|
|
443
|
+
gl_Position = czm_modelViewProjection * worldRTC;
|
|
444
|
+
czm_vertexLogDepth();
|
|
445
|
+
}
|
|
446
|
+
`, Zi = `
|
|
447
|
+
in vec2 v_uv;
|
|
448
|
+
in vec3 v_nrm;
|
|
449
|
+
uniform sampler2D u_tex;
|
|
450
|
+
uniform float u_hasTex;
|
|
451
|
+
void main() {
|
|
452
|
+
vec3 base = u_hasTex > 0.5 ? texture(u_tex, v_uv).rgb : vec3(0.7);
|
|
453
|
+
float lambert = 0.45 + 0.55 * max(0.0, dot(v_nrm, czm_sunDirectionWC));
|
|
454
|
+
out_FragColor = vec4(base * lambert, 1.0);
|
|
455
|
+
}
|
|
456
|
+
`;
|
|
457
|
+
function Yi(i) {
|
|
458
|
+
const e = i.split(",")[1] ?? "", t = atob(e), s = new Uint8Array(t.length);
|
|
459
|
+
for (let n = 0; n < t.length; n++)
|
|
460
|
+
s[n] = t.charCodeAt(n);
|
|
461
|
+
return s.buffer;
|
|
462
|
+
}
|
|
463
|
+
function we(i, e, t) {
|
|
464
|
+
const s = i.accessors[t], n = i.bufferViews[s.bufferView], o = e[n.buffer], r = Xi[s.type], l = Wi[s.componentType], h = l.BYTES_PER_ELEMENT, c = (n.byteOffset ?? 0) + (s.byteOffset ?? 0), m = n.byteStride, u = new Float32Array(s.count * r);
|
|
465
|
+
if (!m || m === r * h) {
|
|
466
|
+
const v = new l(o, c, s.count * r);
|
|
467
|
+
for (let d = 0; d < u.length; d++)
|
|
468
|
+
u[d] = v[d];
|
|
469
|
+
} else {
|
|
470
|
+
const v = new DataView(o);
|
|
471
|
+
for (let d = 0; d < s.count; d++)
|
|
472
|
+
for (let p = 0; p < r; p++) {
|
|
473
|
+
const g = c + d * m + p * h;
|
|
474
|
+
u[d * r + p] = Ki(v, g, s.componentType);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return u;
|
|
478
|
+
}
|
|
479
|
+
function Ki(i, e, t) {
|
|
480
|
+
switch (t) {
|
|
481
|
+
case 5126:
|
|
482
|
+
return i.getFloat32(e, !0);
|
|
483
|
+
case 5125:
|
|
484
|
+
return i.getUint32(e, !0);
|
|
485
|
+
case 5123:
|
|
486
|
+
return i.getUint16(e, !0);
|
|
487
|
+
case 5122:
|
|
488
|
+
return i.getInt16(e, !0);
|
|
489
|
+
case 5121:
|
|
490
|
+
return i.getUint8(e);
|
|
491
|
+
default:
|
|
492
|
+
return i.getInt8(e);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function qi(i) {
|
|
496
|
+
if (i.matrix)
|
|
497
|
+
return R.fromColumnMajorArray(i.matrix, new R());
|
|
498
|
+
const e = i.translation ? new f(i.translation[0], i.translation[1], i.translation[2]) : f.ZERO, t = i.rotation ? new Re.Quaternion(i.rotation[0], i.rotation[1], i.rotation[2], i.rotation[3]) : Re.Quaternion.IDENTITY, s = i.scale ? new f(i.scale[0], i.scale[1], i.scale[2]) : new f(1, 1, 1);
|
|
499
|
+
return R.fromTranslationQuaternionRotationScale(e, t, s, new R());
|
|
500
|
+
}
|
|
501
|
+
function $i(i, e) {
|
|
502
|
+
var o, r, l, h, c, m, u;
|
|
503
|
+
if (e == null)
|
|
504
|
+
return;
|
|
505
|
+
const t = (o = i.materials) == null ? void 0 : o[e], s = (l = (r = t == null ? void 0 : t.pbrMetallicRoughness) == null ? void 0 : r.baseColorTexture) == null ? void 0 : l.index;
|
|
506
|
+
if (s == null)
|
|
507
|
+
return;
|
|
508
|
+
const n = (c = (h = i.textures) == null ? void 0 : h[s]) == null ? void 0 : c.source;
|
|
509
|
+
if (n != null)
|
|
510
|
+
return (u = (m = i.images) == null ? void 0 : m[n]) == null ? void 0 : u.uri;
|
|
511
|
+
}
|
|
512
|
+
function ji() {
|
|
513
|
+
const i = F.Axis, e = R.clone(i.Y_UP_TO_Z_UP, new R());
|
|
514
|
+
return R.multiplyTransformation(e, i.Z_UP_TO_X_UP, e);
|
|
515
|
+
}
|
|
516
|
+
function Ji(i, e) {
|
|
517
|
+
var l, h;
|
|
518
|
+
const t = /* @__PURE__ */ new Map(), s = ((h = (l = i.scenes) == null ? void 0 : l[i.scene ?? 0]) == null ? void 0 : h.nodes) ?? [], n = ji(), o = new f(), r = (c, m) => {
|
|
519
|
+
const u = i.nodes[c], v = R.multiply(m, qi(u), new R());
|
|
520
|
+
if (u.mesh != null)
|
|
521
|
+
for (const d of i.meshes[u.mesh].primitives) {
|
|
522
|
+
const p = we(i, e, d.attributes.POSITION), g = d.attributes.NORMAL != null ? we(i, e, d.attributes.NORMAL) : null, y = d.attributes.TEXCOORD_0 != null ? we(i, e, d.attributes.TEXCOORD_0) : null, w = d.indices != null ? we(i, e, d.indices) : null, M = $i(i, d.material) ?? "__none__";
|
|
523
|
+
let I = t.get(M);
|
|
524
|
+
I || (I = { positions: [], normals: [], uvs: [], indices: [], vcount: 0, imageUri: M === "__none__" ? void 0 : M }, t.set(M, I));
|
|
525
|
+
const C = I.vcount, k = p.length / 3;
|
|
526
|
+
for (let S = 0; S < k; S++)
|
|
527
|
+
o.x = p[S * 3], o.y = p[S * 3 + 1], o.z = p[S * 3 + 2], R.multiplyByPoint(v, o, o), I.positions.push(o.x, o.y, o.z), g ? (o.x = g[S * 3], o.y = g[S * 3 + 1], o.z = g[S * 3 + 2], R.multiplyByPointAsVector(v, o, o), f.normalize(o, o), I.normals.push(o.x, o.y, o.z)) : I.normals.push(0, 0, 1), y ? I.uvs.push(y[S * 2], y[S * 2 + 1]) : I.uvs.push(0, 0);
|
|
528
|
+
if (w)
|
|
529
|
+
for (let S = 0; S < w.length; S++)
|
|
530
|
+
I.indices.push(C + w[S]);
|
|
531
|
+
else
|
|
532
|
+
for (let S = 0; S < k; S++)
|
|
533
|
+
I.indices.push(C + S);
|
|
534
|
+
I.vcount += k;
|
|
535
|
+
}
|
|
536
|
+
for (const d of u.children ?? [])
|
|
537
|
+
r(d, v);
|
|
538
|
+
};
|
|
539
|
+
for (const c of s)
|
|
540
|
+
r(c, n);
|
|
541
|
+
return Array.from(t.values());
|
|
542
|
+
}
|
|
543
|
+
const Qi = 400, Ee = 8e3;
|
|
544
|
+
class Ut {
|
|
545
|
+
constructor(e, t) {
|
|
546
|
+
a(this, "renderIds", /* @__PURE__ */ new Set());
|
|
547
|
+
a(this, "states", /* @__PURE__ */ new Map());
|
|
548
|
+
a(this, "batches", /* @__PURE__ */ new Map());
|
|
549
|
+
// url -> batch
|
|
550
|
+
a(this, "scratch", /* @__PURE__ */ new Map());
|
|
551
|
+
// url -> mats 缓冲
|
|
552
|
+
a(this, "center", new f());
|
|
553
|
+
this.scene = e, this.fadeMs = t;
|
|
554
|
+
}
|
|
555
|
+
activeTargetIds() {
|
|
556
|
+
return Array.from(this.renderIds);
|
|
557
|
+
}
|
|
558
|
+
setCandidates(e) {
|
|
559
|
+
const t = new Set(e.map((s) => s.id));
|
|
560
|
+
this.renderIds.clear();
|
|
561
|
+
for (const s of e)
|
|
562
|
+
this.renderIds.add(s.id);
|
|
563
|
+
for (const s of e) {
|
|
564
|
+
let n = this.states.get(s.id);
|
|
565
|
+
n || (n = ts(s), this.states.set(s.id, n)), this.applyCandidate(n, s);
|
|
566
|
+
}
|
|
567
|
+
for (const [, s] of this.states)
|
|
568
|
+
t.has(s.id) || (s.active = !1);
|
|
569
|
+
return this.activeTargetIds();
|
|
570
|
+
}
|
|
571
|
+
getTargetFrame(e, t = new f()) {
|
|
572
|
+
const s = this.states.get(e);
|
|
573
|
+
if (!(!s || s.visualScale <= 1e-3))
|
|
574
|
+
return { position: f.clone(s.currentPosition, t), heading: s.currentHeading };
|
|
575
|
+
}
|
|
576
|
+
update(e) {
|
|
577
|
+
const t = ss(e, this.fadeMs);
|
|
578
|
+
for (const [n, o] of Array.from(this.states))
|
|
579
|
+
is(o, e), o.visualScale = ns(o.visualScale, o.active ? 1 : 0, t), o.modelMatrix = Gt(o, o.modelStyle, o.modelMatrix), o.scaledMatrix = R.multiplyByUniformScale(o.modelMatrix, Math.max(1e-3, o.visualScale), o.scaledMatrix), !o.active && o.visualScale <= 1e-3 && (this.states.delete(n), this.renderIds.delete(n));
|
|
580
|
+
f.clone(this.scene.camera.positionWC, this.center);
|
|
581
|
+
const s = /* @__PURE__ */ new Map();
|
|
582
|
+
for (const n of this.states.values()) {
|
|
583
|
+
if (n.visualScale <= 1e-3)
|
|
584
|
+
continue;
|
|
585
|
+
const o = n.url;
|
|
586
|
+
let r = this.batches.get(o);
|
|
587
|
+
r || (r = new Ui(this.scene, o, Ee), this.batches.set(o, r), this.scene.primitives.add(r));
|
|
588
|
+
let l = this.scratch.get(o);
|
|
589
|
+
l || (l = new Float32Array(Ee * 16), this.scratch.set(o, l));
|
|
590
|
+
const h = s.get(o) ?? 0;
|
|
591
|
+
if (h >= Ee)
|
|
592
|
+
continue;
|
|
593
|
+
const c = n.scaledMatrix, m = h * 16;
|
|
594
|
+
for (let u = 0; u < 16; u++)
|
|
595
|
+
l[m + u] = c[u];
|
|
596
|
+
l[m + 12] = c[12] - this.center.x, l[m + 13] = c[13] - this.center.y, l[m + 14] = c[14] - this.center.z, s.set(o, h + 1);
|
|
597
|
+
}
|
|
598
|
+
for (const [n, o] of this.batches) {
|
|
599
|
+
const r = this.scratch.get(n);
|
|
600
|
+
o.setInstances(r ?? es, s.get(n) ?? 0, this.center);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
clear() {
|
|
604
|
+
this.renderIds.clear();
|
|
605
|
+
for (const e of this.states.values())
|
|
606
|
+
e.active = !1;
|
|
607
|
+
}
|
|
608
|
+
suspend() {
|
|
609
|
+
this.renderIds.clear(), this.states.clear();
|
|
610
|
+
for (const e of this.batches.values())
|
|
611
|
+
this.scene.primitives.remove(e);
|
|
612
|
+
this.batches.clear(), this.scratch.clear();
|
|
613
|
+
}
|
|
614
|
+
destroy() {
|
|
615
|
+
this.suspend();
|
|
616
|
+
}
|
|
617
|
+
applyCandidate(e, t) {
|
|
618
|
+
e.active = !0, e.url = t.url, e.modelKey = t.modelKey, e.modelStyle = t.modelStyle, e.position = t.position, e.heading = t.heading, e.smoothMove = t.smoothMove, e.moveDurationMs = t.moveDurationMs, t.smoothMove ? (f.clone(e.currentPosition, e.startPosition), f.clone(t.position, e.targetPosition), e.startHeading = e.currentHeading, e.targetHeading = t.heading, e.moveElapsedSec = 0, e.moveDurationSec = Math.max(16, t.moveDurationMs || Qi) / 1e3) : (f.clone(t.position, e.currentPosition), f.clone(t.position, e.startPosition), f.clone(t.position, e.targetPosition), e.currentHeading = t.heading, e.startHeading = t.heading, e.targetHeading = t.heading, e.moveElapsedSec = 0, e.moveDurationSec = 0);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const es = new Float32Array(0);
|
|
622
|
+
function ts(i) {
|
|
623
|
+
const e = Gt(
|
|
624
|
+
{ ...i, currentPosition: i.position, currentHeading: i.heading },
|
|
625
|
+
i.modelStyle,
|
|
626
|
+
R.clone(R.IDENTITY)
|
|
627
|
+
);
|
|
628
|
+
return {
|
|
629
|
+
...i,
|
|
630
|
+
active: !0,
|
|
631
|
+
currentPosition: f.clone(i.position),
|
|
632
|
+
startPosition: f.clone(i.position),
|
|
633
|
+
targetPosition: f.clone(i.position),
|
|
634
|
+
currentHeading: i.heading,
|
|
635
|
+
startHeading: i.heading,
|
|
636
|
+
targetHeading: i.heading,
|
|
637
|
+
moveElapsedSec: 0,
|
|
638
|
+
moveDurationSec: 0,
|
|
639
|
+
visualScale: 0,
|
|
640
|
+
modelMatrix: e,
|
|
641
|
+
scaledMatrix: R.clone(e)
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
function is(i, e) {
|
|
645
|
+
if (i.moveDurationSec <= 0)
|
|
646
|
+
return;
|
|
647
|
+
i.moveElapsedSec += e;
|
|
648
|
+
const t = os(Math.min(1, i.moveElapsedSec / Math.max(1e-3, i.moveDurationSec)));
|
|
649
|
+
f.lerp(i.startPosition, i.targetPosition, t, i.currentPosition), i.currentHeading = rs(i.startHeading, i.targetHeading, t), t >= 1 && (f.clone(i.targetPosition, i.currentPosition), i.currentHeading = i.targetHeading, i.moveElapsedSec = 0, i.moveDurationSec = 0);
|
|
650
|
+
}
|
|
651
|
+
function Gt(i, e, t) {
|
|
652
|
+
const s = new Vt(
|
|
653
|
+
A.toRadians(i.currentHeading + (e.headingOffset ?? 0)),
|
|
654
|
+
A.toRadians(e.pitchOffset ?? 0),
|
|
655
|
+
A.toRadians(e.rollOffset ?? 0)
|
|
656
|
+
);
|
|
657
|
+
return Ye.headingPitchRollToFixedFrame(i.currentPosition, s, void 0, void 0, t), R.multiplyByUniformScale(t, e.scale ?? 1, t);
|
|
658
|
+
}
|
|
659
|
+
function ss(i, e) {
|
|
660
|
+
return e <= 0 ? 1 : Math.max(0, i * 1e3 / e);
|
|
661
|
+
}
|
|
662
|
+
function ns(i, e, t) {
|
|
663
|
+
return i < e ? Math.min(e, i + t) : i > e ? Math.max(e, i - t) : i;
|
|
664
|
+
}
|
|
665
|
+
function os(i) {
|
|
666
|
+
return i < 0.5 ? 4 * i * i * i : 1 - Math.pow(-2 * i + 2, 3) / 2;
|
|
667
|
+
}
|
|
668
|
+
function rs(i, e, t) {
|
|
669
|
+
const s = ((e - i) % 360 + 540) % 360 - 180;
|
|
670
|
+
return i + s * t;
|
|
671
|
+
}
|
|
672
|
+
const as = 1, ls = 2, cs = 16, hs = 32, ds = 64, Zt = 400, us = 0.75;
|
|
673
|
+
class fs {
|
|
674
|
+
constructor(e, t, s, n, o, r) {
|
|
675
|
+
a(this, "lowModels");
|
|
676
|
+
a(this, "airReferences");
|
|
677
|
+
a(this, "renderIds", /* @__PURE__ */ new Set());
|
|
678
|
+
a(this, "states", /* @__PURE__ */ new Map());
|
|
679
|
+
a(this, "retiring", []);
|
|
680
|
+
a(this, "scene");
|
|
681
|
+
a(this, "animationKeepAliveElapsedSec", 0);
|
|
682
|
+
a(this, "lastLowRenderCount", 0);
|
|
683
|
+
a(this, "lastHighRenderCount", 0);
|
|
684
|
+
this.viewer = e, this.styles = t, this.lowCapacity = s, this.highCapacity = n, this.fadeMs = r, this.scene = e.scene, this.lowModels = new Ut(this.scene, r), this.airReferences = new Hi(this.scene);
|
|
685
|
+
}
|
|
686
|
+
activeTargetIds() {
|
|
687
|
+
return [...this.lowModels.activeTargetIds(), ...Array.from(this.renderIds)];
|
|
688
|
+
}
|
|
689
|
+
renderStats() {
|
|
690
|
+
return { low: this.lastLowRenderCount, high: this.lastHighRenderCount };
|
|
691
|
+
}
|
|
692
|
+
getTargetFrame(e, t = new f()) {
|
|
693
|
+
const s = this.states.get(e);
|
|
694
|
+
return s != null && s.active && s.visualScale > 1e-3 ? {
|
|
695
|
+
position: f.clone(s.currentPosition, t),
|
|
696
|
+
heading: s.currentHeading
|
|
697
|
+
} : this.lowModels.getTargetFrame(e, t);
|
|
698
|
+
}
|
|
699
|
+
setPacket(e) {
|
|
700
|
+
const t = ms(e, this.styles, this.viewer.scene.camera.positionCartographic.height), s = t.filter((h) => h.lodKind === 1).slice(0, this.lowCapacity), n = t.filter((h) => h.lodKind === 2).slice(0, this.highCapacity);
|
|
701
|
+
this.lastLowRenderCount = s.length, this.lastHighRenderCount = n.length, this.lowModels.setCandidates(s);
|
|
702
|
+
const o = n, r = new Set(o.map((h) => h.id));
|
|
703
|
+
for (const h of Array.from(this.renderIds))
|
|
704
|
+
r.has(h) || this.renderIds.delete(h);
|
|
705
|
+
for (const h of o)
|
|
706
|
+
this.renderIds.add(h.id);
|
|
707
|
+
const l = new Map(o.map((h) => [h.id, h]));
|
|
708
|
+
for (const h of this.renderIds) {
|
|
709
|
+
const c = l.get(h);
|
|
710
|
+
if (!c)
|
|
711
|
+
continue;
|
|
712
|
+
let m = this.states.get(h);
|
|
713
|
+
m || (m = ps(c), this.states.set(h, m)), this.applyCandidate(m, c);
|
|
714
|
+
}
|
|
715
|
+
for (const [h, c] of Array.from(this.states))
|
|
716
|
+
this.renderIds.has(h) || (c.active = !1);
|
|
717
|
+
return this.activeTargetIds();
|
|
718
|
+
}
|
|
719
|
+
update(e) {
|
|
720
|
+
this.lowModels.update(e), this.animationKeepAliveElapsedSec += e;
|
|
721
|
+
const t = this.animationKeepAliveElapsedSec >= us;
|
|
722
|
+
let s = !1;
|
|
723
|
+
const n = vs(e, this.fadeMs);
|
|
724
|
+
for (const [o, r] of Array.from(this.states))
|
|
725
|
+
gs(r, e), r.visualScale = ot(r.visualScale, r.active ? 1 : 0, n), r.modelMatrix = We(
|
|
726
|
+
r.currentPosition,
|
|
727
|
+
r.currentHeading,
|
|
728
|
+
r.modelStyle,
|
|
729
|
+
r.modelMatrix
|
|
730
|
+
), r.model && (r.model.modelMatrix = de(r.modelMatrix, r.visualScale, r.transitionMatrix), r.model.show = r.visualScale > 1e-3, r.modelStyle.runAnimations && r.active && (s = !0, t && this.ensureModelAnimations(r.model, r.modelStyle))), !r.active && r.visualScale <= 1e-3 && this.removeState(o, r);
|
|
731
|
+
this.updateAirReferences();
|
|
732
|
+
for (let o = this.retiring.length - 1; o >= 0; o--) {
|
|
733
|
+
const r = this.retiring[o];
|
|
734
|
+
r.visualScale = ot(r.visualScale, 0, n), r.model.modelMatrix = de(r.modelMatrix, r.visualScale, r.transitionMatrix), r.model.show = r.visualScale > 1e-3, r.visualScale <= 1e-3 && (this.scene.primitives.remove(r.model), this.retiring.splice(o, 1));
|
|
735
|
+
}
|
|
736
|
+
s && this.ensureAnimationClock(), t && (this.animationKeepAliveElapsedSec = 0);
|
|
737
|
+
}
|
|
738
|
+
clear() {
|
|
739
|
+
this.lowModels.clear(), this.airReferences.clear(), this.lastLowRenderCount = 0, this.lastHighRenderCount = 0, this.renderIds.clear();
|
|
740
|
+
for (const e of this.states.values())
|
|
741
|
+
e.active = !1;
|
|
742
|
+
}
|
|
743
|
+
suspend() {
|
|
744
|
+
if (this.lowModels.suspend(), this.airReferences.clear(), this.lastLowRenderCount = 0, this.lastHighRenderCount = 0, !(this.renderIds.size === 0 && this.states.size === 0 && this.retiring.length === 0)) {
|
|
745
|
+
this.renderIds.clear();
|
|
746
|
+
for (const e of this.states.values())
|
|
747
|
+
e.model && this.scene.primitives.remove(e.model), e.model = null, e.loading = !1, e.loadToken++;
|
|
748
|
+
this.states.clear();
|
|
749
|
+
for (const e of this.retiring)
|
|
750
|
+
this.scene.primitives.remove(e.model);
|
|
751
|
+
this.retiring.length = 0;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
destroy() {
|
|
755
|
+
this.lowModels.destroy(), this.airReferences.destroy();
|
|
756
|
+
for (const e of this.states.values())
|
|
757
|
+
e.model && this.scene.primitives.remove(e.model), e.model = null, e.loading = !1, e.loadToken++;
|
|
758
|
+
this.states.clear(), this.renderIds.clear();
|
|
759
|
+
for (const e of this.retiring)
|
|
760
|
+
this.scene.primitives.remove(e.model);
|
|
761
|
+
this.retiring.length = 0;
|
|
762
|
+
}
|
|
763
|
+
applyCandidate(e, t) {
|
|
764
|
+
const s = Ms(e, t), n = e.url !== t.url || e.lodKind !== t.lodKind;
|
|
765
|
+
if (n && (this.retireStateModel(e), e.url = t.url, e.modelKey = t.modelKey, e.lodKind = t.lodKind, e.targetDomain = t.targetDomain, e.modelStyle = t.modelStyle, e.visualScale = 0), e.active = !0, e.url = t.url, e.modelKey = t.modelKey, e.modelStyle = t.modelStyle, e.targetDomain = t.targetDomain, e.category = t.category, e.position = t.position, e.heading = t.heading, e.smoothMove = t.smoothMove, e.moveDurationMs = t.moveDurationMs, e.predictMove = t.predictMove, (t.smoothMove || t.predictMove) && e.model && !n && s ? (f.clone(e.currentPosition, e.startPosition), f.clone(t.position, e.targetPosition), e.startHeading = e.currentHeading, e.targetHeading = t.heading, e.moveElapsedSec = 0, e.moveDurationSec = Math.max(16, t.moveDurationMs || Zt) / 1e3) : (f.clone(t.position, e.currentPosition), f.clone(t.position, e.startPosition), f.clone(t.position, e.targetPosition), e.currentHeading = t.heading, e.startHeading = t.heading, e.targetHeading = t.heading, e.moveElapsedSec = 0, e.moveDurationSec = 0), e.modelMatrix = We(
|
|
766
|
+
e.currentPosition,
|
|
767
|
+
e.currentHeading,
|
|
768
|
+
e.modelStyle,
|
|
769
|
+
e.modelMatrix
|
|
770
|
+
), e.model) {
|
|
771
|
+
e.model.id = e.id, e.model.modelMatrix = de(e.modelMatrix, e.visualScale, e.transitionMatrix), e.model.show = !0;
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
e.loading || this.loadModel(e);
|
|
775
|
+
}
|
|
776
|
+
loadModel(e) {
|
|
777
|
+
const t = ++e.loadToken, s = e.url, n = e.id, o = e.lodKind;
|
|
778
|
+
e.loading = !0, gi.fromGltfAsync({
|
|
779
|
+
url: s,
|
|
780
|
+
scene: this.scene,
|
|
781
|
+
modelMatrix: de(e.modelMatrix, e.visualScale, e.transitionMatrix),
|
|
782
|
+
scale: e.modelStyle.scale ?? 1,
|
|
783
|
+
allowPicking: !0,
|
|
784
|
+
id: n
|
|
785
|
+
}).then((r) => {
|
|
786
|
+
if (e.loadToken !== t || e.url !== s || e.id !== n || e.lodKind !== o || !e.active) {
|
|
787
|
+
this.scene.primitives.remove(r);
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
e.model = this.scene.primitives.add(r), e.model.id = e.id, e.model.show = !0, e.model.modelMatrix = de(e.modelMatrix, e.visualScale, e.transitionMatrix), this.ensureModelAnimations(e.model, e.modelStyle), this.scene.requestRender();
|
|
791
|
+
}).catch((r) => {
|
|
792
|
+
console.warn("[multi-target] model load failed", s, r);
|
|
793
|
+
}).finally(() => {
|
|
794
|
+
e.loadToken === t && (e.loading = !1);
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
removeState(e, t) {
|
|
798
|
+
this.retireStateModel(t), t.loadToken++, t.loading = !1, this.states.delete(e);
|
|
799
|
+
}
|
|
800
|
+
retireStateModel(e) {
|
|
801
|
+
e.model && (this.retiring.push({
|
|
802
|
+
model: e.model,
|
|
803
|
+
modelMatrix: R.clone(e.modelMatrix),
|
|
804
|
+
transitionMatrix: R.clone(e.transitionMatrix),
|
|
805
|
+
visualScale: e.visualScale
|
|
806
|
+
}), e.model = null);
|
|
807
|
+
}
|
|
808
|
+
ensureAnimationClock() {
|
|
809
|
+
this.viewer.clock && (this.viewer.clock.shouldAnimate = !0);
|
|
810
|
+
}
|
|
811
|
+
ensureModelAnimations(e, t) {
|
|
812
|
+
if (!t.runAnimations)
|
|
813
|
+
return;
|
|
814
|
+
const s = e;
|
|
815
|
+
if (!s.__multiTargetAnimationUnavailable && (this.ensureAnimationClock(), !Kt(e) && !_e(e, t))) {
|
|
816
|
+
if (s.ready === !0) {
|
|
817
|
+
s.__multiTargetAnimationStarted || (s.__multiTargetAnimationUnavailable = !0);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
if (!s.__multiTargetAnimationReadyHooked) {
|
|
821
|
+
if (s.readyEvent && typeof s.readyEvent.addEventListener == "function") {
|
|
822
|
+
s.__multiTargetAnimationReadyHooked = !0;
|
|
823
|
+
const n = s.readyEvent.addEventListener(() => {
|
|
824
|
+
s.__multiTargetAnimationReadyHooked = !1, _e(e, t), typeof n == "function" && n();
|
|
825
|
+
});
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
s.readyPromise && typeof s.readyPromise.then == "function" && (s.__multiTargetAnimationReadyHooked = !0, s.readyPromise.then(() => {
|
|
829
|
+
s.__multiTargetAnimationReadyHooked = !1, _e(e, t);
|
|
830
|
+
}).catch(() => {
|
|
831
|
+
s.__multiTargetAnimationReadyHooked = !1;
|
|
832
|
+
}));
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
updateAirReferences() {
|
|
837
|
+
const e = [];
|
|
838
|
+
for (const t of this.states.values())
|
|
839
|
+
!t.active || t.targetDomain !== "air" || t.visualScale <= 1e-3 || e.push({
|
|
840
|
+
id: t.id,
|
|
841
|
+
position: t.currentPosition,
|
|
842
|
+
visualScale: t.visualScale
|
|
843
|
+
});
|
|
844
|
+
this.airReferences.setTargets(e);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
function ms(i, e, t) {
|
|
848
|
+
const s = [];
|
|
849
|
+
for (let n = 0; n < i.lon.length; n++) {
|
|
850
|
+
const o = i.flags[n], r = o >> ls & 3;
|
|
851
|
+
if (r === 0 || o & as || !(o & ds))
|
|
852
|
+
continue;
|
|
853
|
+
const l = i.ids[n] ?? "";
|
|
854
|
+
if (!l)
|
|
855
|
+
continue;
|
|
856
|
+
const h = i.category[n], c = e[h], m = Ss(c, r);
|
|
857
|
+
if (!m)
|
|
858
|
+
continue;
|
|
859
|
+
const u = m.url, v = (o & hs) !== 0;
|
|
860
|
+
s.push({
|
|
861
|
+
id: l,
|
|
862
|
+
url: u,
|
|
863
|
+
category: h,
|
|
864
|
+
modelKey: Is(u),
|
|
865
|
+
lodKind: r,
|
|
866
|
+
targetDomain: c == null ? void 0 : c.targetDomain,
|
|
867
|
+
modelStyle: m,
|
|
868
|
+
position: f.fromDegrees(i.lon[n], i.lat[n], i.height[n]),
|
|
869
|
+
heading: i.heading[n] || 0,
|
|
870
|
+
smoothMove: (o & cs) !== 0,
|
|
871
|
+
moveDurationMs: i.moveDurationMs[n] || Zt,
|
|
872
|
+
predictMove: v
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
return s;
|
|
876
|
+
}
|
|
877
|
+
function ps(i) {
|
|
878
|
+
const e = We(i.position, i.heading, void 0, R.clone(R.IDENTITY));
|
|
879
|
+
return {
|
|
880
|
+
...i,
|
|
881
|
+
model: null,
|
|
882
|
+
loading: !1,
|
|
883
|
+
loadToken: 0,
|
|
884
|
+
active: !0,
|
|
885
|
+
visualScale: 0,
|
|
886
|
+
currentPosition: f.clone(i.position),
|
|
887
|
+
startPosition: f.clone(i.position),
|
|
888
|
+
targetPosition: f.clone(i.position),
|
|
889
|
+
currentHeading: i.heading,
|
|
890
|
+
startHeading: i.heading,
|
|
891
|
+
targetHeading: i.heading,
|
|
892
|
+
moveElapsedSec: 0,
|
|
893
|
+
moveDurationSec: 0,
|
|
894
|
+
modelMatrix: e,
|
|
895
|
+
transitionMatrix: R.clone(R.IDENTITY)
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
function gs(i, e) {
|
|
899
|
+
if (i.moveDurationSec <= 0)
|
|
900
|
+
return;
|
|
901
|
+
i.moveElapsedSec += e;
|
|
902
|
+
const t = Math.min(1, i.moveElapsedSec / Math.max(1e-3, i.moveDurationSec)), s = i.predictMove ? t : ys(t);
|
|
903
|
+
f.lerp(i.startPosition, i.targetPosition, s, i.currentPosition), i.currentHeading = ws(i.startHeading, i.targetHeading, s), s >= 1 && (f.clone(i.targetPosition, i.currentPosition), i.currentHeading = i.targetHeading, i.moveElapsedSec = 0, i.moveDurationSec = 0);
|
|
904
|
+
}
|
|
905
|
+
function vs(i, e) {
|
|
906
|
+
return e <= 0 ? 1 : Math.max(0, i * 1e3 / e);
|
|
907
|
+
}
|
|
908
|
+
function ot(i, e, t) {
|
|
909
|
+
return i < e ? Math.min(e, i + t) : i > e ? Math.max(e, i - t) : i;
|
|
910
|
+
}
|
|
911
|
+
function We(i, e, t, s) {
|
|
912
|
+
const n = new Vt(
|
|
913
|
+
A.toRadians(e + ((t == null ? void 0 : t.headingOffset) ?? 0)),
|
|
914
|
+
A.toRadians((t == null ? void 0 : t.pitchOffset) ?? 0),
|
|
915
|
+
A.toRadians((t == null ? void 0 : t.rollOffset) ?? 0)
|
|
916
|
+
);
|
|
917
|
+
return Ye.headingPitchRollToFixedFrame(i, n, void 0, void 0, s);
|
|
918
|
+
}
|
|
919
|
+
function de(i, e, t) {
|
|
920
|
+
return R.multiplyByUniformScale(i, Math.max(1e-3, e), t);
|
|
921
|
+
}
|
|
922
|
+
function ys(i) {
|
|
923
|
+
return i < 0.5 ? 4 * i * i * i : 1 - Math.pow(-2 * i + 2, 3) / 2;
|
|
924
|
+
}
|
|
925
|
+
function ws(i, e, t) {
|
|
926
|
+
const s = Yt(i, e);
|
|
927
|
+
return i + s * t;
|
|
928
|
+
}
|
|
929
|
+
function Yt(i, e) {
|
|
930
|
+
return ((e - i) % 360 + 540) % 360 - 180;
|
|
931
|
+
}
|
|
932
|
+
function Ms(i, e) {
|
|
933
|
+
return f.distanceSquared(i.position, e.position) > 1e-4 || Math.abs(Yt(i.heading, e.heading)) > 1e-3;
|
|
934
|
+
}
|
|
935
|
+
function Is(i) {
|
|
936
|
+
const e = i.split(/[?#]/, 1)[0] ?? i;
|
|
937
|
+
return e.slice(Math.max(e.lastIndexOf("/"), e.lastIndexOf("\\")) + 1).toLowerCase();
|
|
938
|
+
}
|
|
939
|
+
function Ss(i, e) {
|
|
940
|
+
if (!i)
|
|
941
|
+
return;
|
|
942
|
+
const t = e === 1 ? i.lowModel : i.highModel;
|
|
943
|
+
if (t)
|
|
944
|
+
return rt(t, e);
|
|
945
|
+
const s = e === 1 ? i.lowModelUrl : i.highModelUrl;
|
|
946
|
+
if (s)
|
|
947
|
+
return rt({
|
|
948
|
+
url: s,
|
|
949
|
+
scale: i.scale,
|
|
950
|
+
headingOffset: i.modelHeadingOffset,
|
|
951
|
+
pitchOffset: i.modelPitchOffset,
|
|
952
|
+
rollOffset: i.modelRollOffset
|
|
953
|
+
}, e);
|
|
954
|
+
}
|
|
955
|
+
function rt(i, e) {
|
|
956
|
+
return {
|
|
957
|
+
...i,
|
|
958
|
+
runAnimations: i.runAnimations ?? e === 2,
|
|
959
|
+
animationLoop: i.animationLoop ?? "repeat",
|
|
960
|
+
animationMultiplier: i.animationMultiplier ?? 1
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
function _e(i, e) {
|
|
964
|
+
if (!e.runAnimations)
|
|
965
|
+
return !1;
|
|
966
|
+
const t = i, s = t.activeAnimations;
|
|
967
|
+
if (!s || typeof s.addAll != "function")
|
|
968
|
+
return !1;
|
|
969
|
+
try {
|
|
970
|
+
const n = s.addAll({
|
|
971
|
+
loop: xs(e.animationLoop),
|
|
972
|
+
multiplier: e.animationMultiplier ?? 1
|
|
973
|
+
});
|
|
974
|
+
return (Array.isArray(n) ? n.length > 0 : !!n) || Kt(i) ? (t.__multiTargetAnimationStarted = !0, !0) : !1;
|
|
975
|
+
} catch {
|
|
976
|
+
return !1;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
function Kt(i) {
|
|
980
|
+
const e = i.activeAnimations;
|
|
981
|
+
return !!e && typeof e.length == "number" && e.length > 0;
|
|
982
|
+
}
|
|
983
|
+
function xs(i) {
|
|
984
|
+
return i === "none" ? Le.NONE : i === "mirroredRepeat" ? Le.MIRRORED_REPEAT : Le.REPEAT;
|
|
985
|
+
}
|
|
986
|
+
const Ts = 1.75, te = 36;
|
|
987
|
+
function qt(i, e, t = !1) {
|
|
988
|
+
const s = Math.max(8, e + (t ? 4 : 2)) * 2, n = Math.min(s, 64);
|
|
989
|
+
let o = n * 1.35, r = n * 0.9;
|
|
990
|
+
return i.startsWith("ship") ? (o = n * 1.15, r = n * 1.45) : i.startsWith("uav") ? (o = n * 1.35, r = n * 1.35) : i.startsWith("person") && (o = n * 0.9, r = n * 1.2), {
|
|
991
|
+
width: o,
|
|
992
|
+
height: r,
|
|
993
|
+
maxDimension: Math.max(o, r)
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
function $t(i, e, t = !1) {
|
|
997
|
+
const s = qt(i, e, t);
|
|
998
|
+
return Math.max(te, s.maxDimension * Ts);
|
|
999
|
+
}
|
|
1000
|
+
const Cs = [
|
|
1001
|
+
{ type: "ship", iconPath: "/icons/target-ship-mask.png", defaultColor: "#25e65c" },
|
|
1002
|
+
{ type: "uav", iconPath: "/icons/target-uav-mask.png", defaultColor: "#22d2f2" },
|
|
1003
|
+
{ type: "person", iconPath: "/icons/target-person-mask.png", defaultColor: "#ffdc40" },
|
|
1004
|
+
{ type: "car", iconPath: "/icons/target-car-mask.png", defaultColor: "#ff9a2a" }
|
|
1005
|
+
], Oe = 400, bs = 180, at = 100, lt = 1e3, Ps = "target-glow-circle", ct = 3.6, Rs = 0.34, ks = 0.22, As = 64, Y = {
|
|
1006
|
+
enabled: !0,
|
|
1007
|
+
maxCount: 200,
|
|
1008
|
+
maxCameraHeight: 5e3,
|
|
1009
|
+
maxDistance: void 0,
|
|
1010
|
+
fields: [{ key: "id", source: "standard" }],
|
|
1011
|
+
byType: void 0,
|
|
1012
|
+
resolve: void 0,
|
|
1013
|
+
backgroundColor: "#0000008c",
|
|
1014
|
+
textColor: "#ffffff",
|
|
1015
|
+
fontSize: 12,
|
|
1016
|
+
fontFamily: "sans-serif",
|
|
1017
|
+
backgroundRadius: 6,
|
|
1018
|
+
overlapThreshold: 0.35,
|
|
1019
|
+
occlusionGraceMs: 300,
|
|
1020
|
+
offsetX: 18,
|
|
1021
|
+
offsetY: 24,
|
|
1022
|
+
connectorColor: "#eafcffcc",
|
|
1023
|
+
connectorWidth: 1.5,
|
|
1024
|
+
connectorStemLength: 50,
|
|
1025
|
+
showFieldLabels: !0
|
|
1026
|
+
};
|
|
1027
|
+
let Ls = 0;
|
|
1028
|
+
class Hs {
|
|
1029
|
+
constructor(e, t, s = {}) {
|
|
1030
|
+
a(this, "glowCollection");
|
|
1031
|
+
a(this, "collection");
|
|
1032
|
+
a(this, "labelCollection");
|
|
1033
|
+
a(this, "pool", []);
|
|
1034
|
+
a(this, "glowPool", []);
|
|
1035
|
+
a(this, "labelPool", []);
|
|
1036
|
+
a(this, "typeStyles");
|
|
1037
|
+
a(this, "labelConfig");
|
|
1038
|
+
a(this, "labelTextResolver");
|
|
1039
|
+
a(this, "imageIds");
|
|
1040
|
+
a(this, "imageUrls");
|
|
1041
|
+
a(this, "processedImages");
|
|
1042
|
+
a(this, "glowImage");
|
|
1043
|
+
a(this, "labelImageCache", /* @__PURE__ */ new Map());
|
|
1044
|
+
a(this, "glowSourceIndexes", []);
|
|
1045
|
+
a(this, "labelSourceIndexes", []);
|
|
1046
|
+
a(this, "labelIds", []);
|
|
1047
|
+
a(this, "labelSmoothStarts", []);
|
|
1048
|
+
a(this, "labelSmoothTargets", []);
|
|
1049
|
+
a(this, "labelSmoothElapsedSec", []);
|
|
1050
|
+
a(this, "labelSmoothDurationSec", []);
|
|
1051
|
+
a(this, "labelScales", []);
|
|
1052
|
+
a(this, "labelTargetScales", []);
|
|
1053
|
+
a(this, "labelPositionsById", /* @__PURE__ */ new Map());
|
|
1054
|
+
a(this, "labelScalesById", /* @__PURE__ */ new Map());
|
|
1055
|
+
a(this, "labelLastClearVisibleAt", /* @__PURE__ */ new Map());
|
|
1056
|
+
a(this, "labelVisibleIds", /* @__PURE__ */ new Set());
|
|
1057
|
+
a(this, "poolCategories", []);
|
|
1058
|
+
a(this, "poolIds", []);
|
|
1059
|
+
a(this, "poolHeadings", []);
|
|
1060
|
+
a(this, "poolMerged", []);
|
|
1061
|
+
a(this, "colorCache", /* @__PURE__ */ new Map());
|
|
1062
|
+
a(this, "glowColorCache", /* @__PURE__ */ new Map());
|
|
1063
|
+
a(this, "smoothStarts", []);
|
|
1064
|
+
a(this, "smoothTargets", []);
|
|
1065
|
+
a(this, "smoothElapsedSec", []);
|
|
1066
|
+
a(this, "smoothDurationSec", []);
|
|
1067
|
+
a(this, "baseWidths", []);
|
|
1068
|
+
a(this, "baseHeights", []);
|
|
1069
|
+
a(this, "pointScales", /* @__PURE__ */ new Map());
|
|
1070
|
+
a(this, "modelTargetIds", /* @__PURE__ */ new Set());
|
|
1071
|
+
a(this, "modelHandoffEnabled", !1);
|
|
1072
|
+
// 姓名版锚点解析器。相机跟随某目标时用的是 model / 贴地符号(groundSymbols) 的渲染
|
|
1073
|
+
// 位置,而 point billboard 可能被隐藏或走另一条平滑曲线。姓名版必须锚到与相机完全
|
|
1074
|
+
// 相同的位置源,否则相机锁住目标、姓名版却跟着 point 漂移,贴近时剧烈抖动(越近越明显,
|
|
1075
|
+
// 因屏幕像素差∝1/相机距离)。该解析器由 scene 注入,内部即相机用的 getRenderedTargetFrame
|
|
1076
|
+
// 同源链。返回 undefined 时(目标无 model/symbol)回退到本地 point 平滑位置。
|
|
1077
|
+
a(this, "anchorPositionResolver", null);
|
|
1078
|
+
a(this, "anchorPositionScratch", new f());
|
|
1079
|
+
a(this, "directionalExternal", !1);
|
|
1080
|
+
a(this, "targetVisible", !0);
|
|
1081
|
+
a(this, "visibleCount", 0);
|
|
1082
|
+
a(this, "glowActiveCount", 0);
|
|
1083
|
+
a(this, "labelActiveCount", 0);
|
|
1084
|
+
a(this, "glowPhase", 0);
|
|
1085
|
+
// 姓名版 RTC(相对相机中心):贴近时绝对 ECEF 坐标(~6.3e6 米)经 GPU Float32 投影会量化抖动
|
|
1086
|
+
// (~0.3-0.7m,贴近放大成数像素)。把 labelCollection.modelMatrix 设为“相机位置(网格丸)平移”,
|
|
1087
|
+
// billboard.position 只存“锚点 - 参考点”的米级小偏移,GPU 投影不再碰大坐标 → 消除抖动。
|
|
1088
|
+
// 参考点用 100m 网格丸,避免相机微动导致参考点每帧跳、引入新抖源。
|
|
1089
|
+
a(this, "labelRtcRef", new f());
|
|
1090
|
+
a(this, "labelRtcScratch", new f());
|
|
1091
|
+
var n;
|
|
1092
|
+
this.scene = e, this.typeStyles = (n = s.targetTypes) != null && n.length ? s.targetTypes : Cs, this.labelConfig = dt(s.label), this.labelTextResolver = s.labelTextResolver ?? ((o) => Us(o, this.labelConfig)), this.imageIds = this.typeStyles.map((o, r) => `target-${r}-${o.type}`), this.imageUrls = this.typeStyles.map((o) => o.iconPath), this.processedImages = [...this.imageUrls], this.glowImage = Ks(), this.glowCollection = this.scene.primitives.add(new fe({ scene: e })), this.collection = this.scene.primitives.add(new fe({ scene: e })), this.labelCollection = this.scene.primitives.add(new fe({ scene: e })), this.glowCollection.show = !0, this.collection.show = !0, this.labelCollection.show = !0, this.preprocessImages(), this.ensureLabelPool(Math.min(this.labelConfig.maxCount, at));
|
|
1093
|
+
}
|
|
1094
|
+
setPacket(e) {
|
|
1095
|
+
var h;
|
|
1096
|
+
const t = e.lon.length;
|
|
1097
|
+
this.ensurePool(t), this.ensureGlowPool(), this.syncLabelRtcReference();
|
|
1098
|
+
let s = 0, n = 0;
|
|
1099
|
+
const o = /* @__PURE__ */ new Set(), r = this.labelVisibleIds, l = this.selectLabelInfos(e);
|
|
1100
|
+
this.ensureLabelPool(l.size);
|
|
1101
|
+
for (let c = 0; c < t; c++) {
|
|
1102
|
+
const m = this.pool[c], u = (e.flags[c] & 1) === 1;
|
|
1103
|
+
this.poolMerged[c] = u;
|
|
1104
|
+
const v = ht(e.category[c] ?? 0, this.imageIds.length), d = Ds(e.color[c], u, this.colorCache), p = qt(((h = this.typeStyles[v]) == null ? void 0 : h.type) ?? "", e.size[c], u), g = this.poolIds[c] === e.ids[c];
|
|
1105
|
+
this.poolCategories[c] !== v && (m.setImage(this.imageIds[v], this.processedImages[v]), this.poolCategories[c] = v), this.poolIds[c] = e.ids[c];
|
|
1106
|
+
const y = f.fromDegrees(e.lon[c], e.lat[c], e.height[c]), w = (e.flags[c] & 16) !== 0 && g && (m.show || this.directionalExternal);
|
|
1107
|
+
w ? (this.smoothStarts[c] = f.clone(m.position, this.smoothStarts[c] ?? new f()), this.smoothTargets[c] = y, this.smoothElapsedSec[c] = 0, this.smoothDurationSec[c] = Math.max(16, e.moveDurationMs[c] || Oe) / 1e3) : (m.position = y, this.smoothStarts[c] = null, this.smoothTargets[c] = null, this.smoothElapsedSec[c] = 0, this.smoothDurationSec[c] = 0), this.baseWidths[c] = p.width, this.baseHeights[c] = p.height;
|
|
1108
|
+
const M = this.modelHandoffEnabled ? this.pointScales.get(e.ids[c]) ?? (this.modelTargetIds.has(e.ids[c]) ? 0 : 1) : 1;
|
|
1109
|
+
if (m.width = p.width * Math.max(1e-3, M), m.height = p.height * Math.max(1e-3, M), m.rotation = -A.toRadians(e.heading[c] || 0), this.poolHeadings[c] = e.heading[c] || 0, m.color = d, m.id = e.ids[c], m.show = this.slotVisible(c), e.animation[c] === 1 && this.targetVisible && s < lt) {
|
|
1110
|
+
const C = this.glowPool[s];
|
|
1111
|
+
C.position = m.position, C.width = p.width * ct, C.height = p.height * ct, C.color = Es(e.animationColor[c] || e.color[c], this.glowColorCache, this.glowPhase), C.show = !0, this.glowSourceIndexes[s] = c, s++;
|
|
1112
|
+
}
|
|
1113
|
+
const I = l.get(c);
|
|
1114
|
+
if (I) {
|
|
1115
|
+
const C = e.ids[c] ?? "", k = this.labelPool[n], S = this.labelIds[n] !== C;
|
|
1116
|
+
S && (k.show = !1, k.scale = 0), this.setLabelPosition(n, k, C, m.position, w, e.moveDurationMs[c]), k.width = I.width, k.height = I.height, k.pixelOffset = new J(-I.anchorX, I.marginY), k.setImage(I.id, I.image), S && (this.labelScales[n] = C && r.has(C) ? this.labelScalesById.get(C) ?? 1 : 0), this.labelTargetScales[n] = 1, k.scale = this.labelScales[n] || 0, this.labelSourceIndexes[n] = c, this.labelIds[n] = C, this.updateLabelPosition(n), k.show = !0, C && (o.add(C), this.labelScalesById.set(C, this.labelScales[n] ?? 0)), n++;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
this.hideUnusedGlows(s), this.hideUnusedLabels(n, o), this.labelVisibleIds = o, this.glowActiveCount = s, this.labelActiveCount = Math.max(this.labelActiveCount, n), this.hideUnused(t);
|
|
1120
|
+
}
|
|
1121
|
+
clear() {
|
|
1122
|
+
this.hideUnused(0);
|
|
1123
|
+
}
|
|
1124
|
+
getTargetFrame(e, t = new f()) {
|
|
1125
|
+
for (let s = 0; s < this.visibleCount; s++)
|
|
1126
|
+
if (!(this.poolIds[s] !== e || !this.pool[s].show))
|
|
1127
|
+
return {
|
|
1128
|
+
position: f.clone(this.pool[s].position, t),
|
|
1129
|
+
heading: this.poolHeadings[s] || 0
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
update(e) {
|
|
1133
|
+
this.glowPhase = (this.glowPhase + e * 2.8) % (Math.PI * 2), this.collection.show = this.targetVisible, this.glowCollection.show = this.targetVisible, this.labelCollection.show = !0, this.syncLabelRtcReference();
|
|
1134
|
+
for (let s = 0; s < this.visibleCount; s++) {
|
|
1135
|
+
const n = this.smoothStarts[s], o = this.smoothTargets[s];
|
|
1136
|
+
if (!n || !o)
|
|
1137
|
+
continue;
|
|
1138
|
+
this.smoothElapsedSec[s] += e;
|
|
1139
|
+
const r = Math.max(1e-3, this.smoothDurationSec[s] || Oe / 1e3), l = Gs(Math.min(1, this.smoothElapsedSec[s] / r)), h = f.lerp(n, o, l, new f());
|
|
1140
|
+
this.pool[s].position = h, l >= 1 && (this.pool[s].position = o, this.smoothStarts[s] = null, this.smoothTargets[s] = null);
|
|
1141
|
+
}
|
|
1142
|
+
const t = Zs(e, Oe);
|
|
1143
|
+
for (let s = 0; s < this.visibleCount; s++) {
|
|
1144
|
+
const n = this.poolIds[s];
|
|
1145
|
+
if (!n)
|
|
1146
|
+
continue;
|
|
1147
|
+
if (!this.modelHandoffEnabled) {
|
|
1148
|
+
this.pool[s].width = this.baseWidths[s] || 9, this.pool[s].height = this.baseHeights[s] || 9, this.pool[s].show = this.slotVisible(s);
|
|
1149
|
+
continue;
|
|
1150
|
+
}
|
|
1151
|
+
const o = this.modelHandoffEnabled && this.modelTargetIds.has(n) ? 0 : 1, r = this.pointScales.get(n) ?? 1, l = ut(r, o, t);
|
|
1152
|
+
this.pointScales.set(n, l), this.pool[s].width = (this.baseWidths[s] || 9) * Math.max(1e-3, l), this.pool[s].height = (this.baseHeights[s] || 9) * Math.max(1e-3, l), this.pool[s].show = this.slotVisible(s) && l > 1e-3;
|
|
1153
|
+
}
|
|
1154
|
+
if (this.glowActiveCount > 0) {
|
|
1155
|
+
const s = Jt(this.glowPhase);
|
|
1156
|
+
for (let n = 0; n < this.glowActiveCount; n++) {
|
|
1157
|
+
const o = this.glowPool[n], r = this.glowSourceIndexes[n];
|
|
1158
|
+
o.position = this.pool[r].position, o.color = o.color.withAlpha(s);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
for (let s = 0; s < this.labelActiveCount; s++)
|
|
1162
|
+
this.updateLabelScale(s, e), this.labelPool[s].show && this.updateLabelPosition(s);
|
|
1163
|
+
this.trimInactiveLabels();
|
|
1164
|
+
}
|
|
1165
|
+
setPointLayerVisible(e) {
|
|
1166
|
+
this.targetVisible = e, this.collection.show = e, this.glowCollection.show = e;
|
|
1167
|
+
}
|
|
1168
|
+
/** 单目标有向图标是否交由外部(实例化符号层)渲染。开启后本渲染器对 count===1 的条目不显示 billboard,
|
|
1169
|
+
* 仍保留 merged 簇 billboard、glow、姓名版。 */
|
|
1170
|
+
setDirectionalHandledExternally(e) {
|
|
1171
|
+
this.directionalExternal = e;
|
|
1172
|
+
}
|
|
1173
|
+
slotVisible(e) {
|
|
1174
|
+
return !(!this.targetVisible || this.directionalExternal && !this.poolMerged[e]);
|
|
1175
|
+
}
|
|
1176
|
+
setModelTargetIds(e, t = !0) {
|
|
1177
|
+
this.modelHandoffEnabled = t && e.length > 0, this.modelTargetIds = this.modelHandoffEnabled ? new Set(e) : /* @__PURE__ */ new Set(), this.modelHandoffEnabled || this.pointScales.clear();
|
|
1178
|
+
}
|
|
1179
|
+
// 注入姓名版锚点解析器:让姓名版锚到与相机完全相同的渲染位置源(model/symbol),消除
|
|
1180
|
+
// 贴近时姓名版相对相机/目标的抖动。返回 undefined 时回退到 point 位置。
|
|
1181
|
+
setAnchorPositionResolver(e) {
|
|
1182
|
+
this.anchorPositionResolver = e;
|
|
1183
|
+
}
|
|
1184
|
+
syncLabelRtcReference() {
|
|
1185
|
+
const e = this.scene.camera.positionWC;
|
|
1186
|
+
this.labelRtcRef.x = Math.floor(e.x / 100) * 100, this.labelRtcRef.y = Math.floor(e.y / 100) * 100, this.labelRtcRef.z = Math.floor(e.z / 100) * 100, R.fromTranslation(this.labelRtcRef, this.labelCollection.modelMatrix);
|
|
1187
|
+
}
|
|
1188
|
+
updateLabelPosition(e) {
|
|
1189
|
+
const t = this.labelSourceIndexes[e];
|
|
1190
|
+
if (t < 0)
|
|
1191
|
+
return;
|
|
1192
|
+
const s = this.labelIds[e];
|
|
1193
|
+
let n = this.pool[t].position;
|
|
1194
|
+
if (s && this.anchorPositionResolver) {
|
|
1195
|
+
const o = this.anchorPositionResolver(s, this.anchorPositionScratch);
|
|
1196
|
+
o && (n = o);
|
|
1197
|
+
}
|
|
1198
|
+
this.labelPool[e].position = f.subtract(n, this.labelRtcRef, this.labelRtcScratch), s && this.labelPositionsById.set(s, f.clone(n, this.labelPositionsById.get(s) ?? new f()));
|
|
1199
|
+
}
|
|
1200
|
+
setLabelOptions(e, t) {
|
|
1201
|
+
this.labelConfig = dt(e), t && (this.labelTextResolver = t), this.applyLabelStyle(), this.ensureLabelPool(Math.min(this.labelConfig.maxCount, at)), this.scene.requestRender();
|
|
1202
|
+
}
|
|
1203
|
+
get pointLayerVisible() {
|
|
1204
|
+
return this.targetVisible;
|
|
1205
|
+
}
|
|
1206
|
+
get heatmapActive() {
|
|
1207
|
+
return !1;
|
|
1208
|
+
}
|
|
1209
|
+
destroy() {
|
|
1210
|
+
this.scene.primitives.remove(this.glowCollection), this.scene.primitives.remove(this.collection), this.scene.primitives.remove(this.labelCollection);
|
|
1211
|
+
}
|
|
1212
|
+
ensurePool(e) {
|
|
1213
|
+
for (; this.pool.length < e; ) {
|
|
1214
|
+
const t = this.collection.add({
|
|
1215
|
+
position: f.ZERO,
|
|
1216
|
+
show: !1,
|
|
1217
|
+
width: 9,
|
|
1218
|
+
height: 9,
|
|
1219
|
+
color: D.WHITE.withAlpha(0.92),
|
|
1220
|
+
rotation: 0
|
|
1221
|
+
});
|
|
1222
|
+
t.setImage(this.imageIds[0], this.processedImages[0]), this.pool.push(t), this.poolCategories.push(0), this.poolIds.push(""), this.smoothStarts.push(null), this.smoothTargets.push(null), this.smoothElapsedSec.push(0), this.smoothDurationSec.push(0), this.baseWidths.push(9), this.baseHeights.push(9);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
ensureGlowPool() {
|
|
1226
|
+
for (; this.glowPool.length < lt; ) {
|
|
1227
|
+
const e = this.glowCollection.add({
|
|
1228
|
+
position: f.ZERO,
|
|
1229
|
+
show: !1,
|
|
1230
|
+
width: 20,
|
|
1231
|
+
height: 20,
|
|
1232
|
+
color: D.WHITE.withAlpha(0.22),
|
|
1233
|
+
rotation: 0
|
|
1234
|
+
});
|
|
1235
|
+
e.setImage(Ps, this.glowImage), this.glowPool.push(e), this.glowSourceIndexes.push(-1);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
ensureLabelPool(e) {
|
|
1239
|
+
const t = Math.max(0, Math.min(this.labelConfig.maxCount, Math.ceil(e)));
|
|
1240
|
+
for (; this.labelPool.length < t; ) {
|
|
1241
|
+
const s = this.labelCollection.add({
|
|
1242
|
+
position: f.ZERO,
|
|
1243
|
+
show: !1,
|
|
1244
|
+
width: 1,
|
|
1245
|
+
height: 1,
|
|
1246
|
+
color: D.WHITE,
|
|
1247
|
+
horizontalOrigin: vi.LEFT,
|
|
1248
|
+
verticalOrigin: yi.BOTTOM,
|
|
1249
|
+
pixelOffset: J.ZERO,
|
|
1250
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
1251
|
+
});
|
|
1252
|
+
this.labelPool.push(s), this.labelSourceIndexes.push(-1), this.labelIds.push(""), this.labelSmoothStarts.push(null), this.labelSmoothTargets.push(null), this.labelSmoothElapsedSec.push(0), this.labelSmoothDurationSec.push(0), this.labelScales.push(0), this.labelTargetScales.push(0), s.scale = 0;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
applyLabelStyle() {
|
|
1256
|
+
this.labelImageCache.clear();
|
|
1257
|
+
for (const e of this.labelPool)
|
|
1258
|
+
e.show = !1, e.width = 1, e.height = 1, e.scale = 0;
|
|
1259
|
+
for (let e = 0; e < this.labelPool.length; e++)
|
|
1260
|
+
this.labelScales[e] = 0, this.labelTargetScales[e] = 0;
|
|
1261
|
+
this.labelScalesById.clear(), this.labelLastClearVisibleAt.clear(), this.labelActiveCount = 0;
|
|
1262
|
+
}
|
|
1263
|
+
setLabelPosition(e, t, s, n, o, r) {
|
|
1264
|
+
const l = s ? this.labelPositionsById.get(s) : void 0;
|
|
1265
|
+
this.labelSmoothStarts[e] = null, this.labelSmoothTargets[e] = null, this.labelSmoothElapsedSec[e] = 0, this.labelSmoothDurationSec[e] = 0, s && this.labelPositionsById.set(s, f.clone(n, l ?? new f()));
|
|
1266
|
+
}
|
|
1267
|
+
updateLabelScale(e, t) {
|
|
1268
|
+
const s = this.labelPool[e], n = this.labelTargetScales[e] ?? 0, o = this.labelScales[e] ?? 0, r = t * 1e3 / bs, l = ut(o, n, r);
|
|
1269
|
+
this.labelScales[e] = l;
|
|
1270
|
+
const h = this.labelIds[e];
|
|
1271
|
+
if (h && this.labelScalesById.set(h, l), s.scale = l, l <= 1e-3 && n <= 0) {
|
|
1272
|
+
s.show = !1, this.labelSourceIndexes[e] = -1, h && this.labelScalesById.set(h, 0), this.labelIds[e] = "", this.labelScales[e] = 0, h && this.labelLastClearVisibleAt.delete(h);
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
s.show = !0;
|
|
1276
|
+
}
|
|
1277
|
+
trimInactiveLabels() {
|
|
1278
|
+
for (; this.labelActiveCount > 0 && !this.labelPool[this.labelActiveCount - 1].show; )
|
|
1279
|
+
this.labelActiveCount--;
|
|
1280
|
+
}
|
|
1281
|
+
selectLabelInfos(e) {
|
|
1282
|
+
var v, d, p;
|
|
1283
|
+
const t = this.scene.camera.positionCartographic;
|
|
1284
|
+
if (!this.labelConfig.enabled || this.labelConfig.maxCount <= 0 || t.height > this.labelConfig.maxCameraHeight)
|
|
1285
|
+
return /* @__PURE__ */ new Map();
|
|
1286
|
+
const s = this.labelConfig.maxDistance != null && Number.isFinite(this.labelConfig.maxDistance) ? this.labelConfig.maxDistance * this.labelConfig.maxDistance : Number.POSITIVE_INFINITY, n = A.toDegrees(t.longitude), o = A.toDegrees(t.latitude), r = Ys(), l = [], h = this.scene.canvas;
|
|
1287
|
+
for (let g = 0; g < e.lon.length; g++) {
|
|
1288
|
+
if (!(e.flags[g] & As))
|
|
1289
|
+
continue;
|
|
1290
|
+
const y = _s(n, o, t.height, e.lon[g], e.lat[g], e.height[g]);
|
|
1291
|
+
if (y > s)
|
|
1292
|
+
continue;
|
|
1293
|
+
const w = ht(e.category[g] ?? 0, this.typeStyles.length), M = ((v = this.typeStyles[w]) == null ? void 0 : v.type) ?? "", I = this.labelTextResolver({
|
|
1294
|
+
id: e.ids[g] ?? "",
|
|
1295
|
+
type: M,
|
|
1296
|
+
data: void 0,
|
|
1297
|
+
cameraHeight: t.height,
|
|
1298
|
+
distance: Math.sqrt(y),
|
|
1299
|
+
count: e.count[g]
|
|
1300
|
+
});
|
|
1301
|
+
if (!I)
|
|
1302
|
+
continue;
|
|
1303
|
+
const C = typeof I == "string" || Array.isArray(I) ? I : I.text, k = Array.isArray(C) ? C.join(`
|
|
1304
|
+
`) : C;
|
|
1305
|
+
if (!k)
|
|
1306
|
+
continue;
|
|
1307
|
+
const S = typeof I == "object" && !Array.isArray(I) && I.style ? I.style : void 0, T = S ? { ...this.labelConfig, ...S } : this.labelConfig, z = this.labelImageOf(k, T), L = Ae.wgs84ToWindowCoordinates(
|
|
1308
|
+
this.scene,
|
|
1309
|
+
f.fromDegrees(e.lon[g], e.lat[g], e.height[g])
|
|
1310
|
+
);
|
|
1311
|
+
if (!L)
|
|
1312
|
+
continue;
|
|
1313
|
+
const E = Os(L.x, L.y, z.plateWidth, z.plateHeight, T);
|
|
1314
|
+
E.right < 0 || E.bottom < 0 || E.left > h.clientWidth || E.top > h.clientHeight || l.push({ index: g, id: e.ids[g] ?? "", distance2: y, info: z, rect: E, type: M });
|
|
1315
|
+
}
|
|
1316
|
+
l.sort((g, y) => g.distance2 - y.distance2);
|
|
1317
|
+
const c = /* @__PURE__ */ new Map(), m = [], u = /* @__PURE__ */ new Map();
|
|
1318
|
+
for (const g of l) {
|
|
1319
|
+
if (c.size >= this.labelConfig.maxCount)
|
|
1320
|
+
break;
|
|
1321
|
+
const y = (p = (d = this.labelConfig.byType) == null ? void 0 : d[g.type]) == null ? void 0 : p.maxCount;
|
|
1322
|
+
if (y != null && (u.get(g.type) ?? 0) >= y)
|
|
1323
|
+
continue;
|
|
1324
|
+
const w = Bs(g.rect, m, this.labelConfig.overlapThreshold), M = w && this.isLabelWithinOcclusionGrace(g.id, r);
|
|
1325
|
+
w && !M || (!w && g.id && this.labelLastClearVisibleAt.set(g.id, r), c.set(g.index, { index: g.index, ...g.info }), m.push(g.rect), u.set(g.type, (u.get(g.type) ?? 0) + 1));
|
|
1326
|
+
}
|
|
1327
|
+
return c;
|
|
1328
|
+
}
|
|
1329
|
+
labelImageOf(e, t) {
|
|
1330
|
+
const s = t ?? this.labelConfig, n = Fs(e, s), o = this.labelImageCache.get(n);
|
|
1331
|
+
if (o)
|
|
1332
|
+
return o;
|
|
1333
|
+
const r = zs(e, s), l = {
|
|
1334
|
+
id: `nameplate-${Ls++}`,
|
|
1335
|
+
image: r.canvas,
|
|
1336
|
+
width: r.width,
|
|
1337
|
+
height: r.height,
|
|
1338
|
+
plateWidth: r.plateWidth,
|
|
1339
|
+
plateHeight: r.plateHeight,
|
|
1340
|
+
anchorX: r.anchorX,
|
|
1341
|
+
marginY: r.marginY
|
|
1342
|
+
};
|
|
1343
|
+
return this.labelImageCache.set(n, l), l;
|
|
1344
|
+
}
|
|
1345
|
+
isLabelWithinOcclusionGrace(e, t) {
|
|
1346
|
+
if (!e || this.labelConfig.occlusionGraceMs <= 0)
|
|
1347
|
+
return !1;
|
|
1348
|
+
const s = this.labelLastClearVisibleAt.get(e);
|
|
1349
|
+
return s != null && t - s <= this.labelConfig.occlusionGraceMs;
|
|
1350
|
+
}
|
|
1351
|
+
hideUnused(e) {
|
|
1352
|
+
for (let t = e; t < this.visibleCount; t++)
|
|
1353
|
+
this.pool[t].show = !1, this.smoothStarts[t] = null, this.smoothTargets[t] = null, this.smoothElapsedSec[t] = 0, this.smoothDurationSec[t] = 0, this.poolIds[t] = "", this.baseWidths[t] = 0, this.baseHeights[t] = 0;
|
|
1354
|
+
this.visibleCount = e;
|
|
1355
|
+
}
|
|
1356
|
+
hideUnusedGlows(e) {
|
|
1357
|
+
for (let t = e; t < this.glowActiveCount; t++)
|
|
1358
|
+
this.glowPool[t].show = !1, this.glowSourceIndexes[t] = -1;
|
|
1359
|
+
}
|
|
1360
|
+
hideUnusedLabels(e, t) {
|
|
1361
|
+
for (let s = e; s < this.labelActiveCount; s++) {
|
|
1362
|
+
const n = this.labelIds[s];
|
|
1363
|
+
if (n && t.has(n)) {
|
|
1364
|
+
this.labelPool[s].show = !1, this.labelSourceIndexes[s] = -1, this.labelIds[s] = "", this.labelScales[s] = 0, this.labelTargetScales[s] = 0, this.labelSmoothStarts[s] = null, this.labelSmoothTargets[s] = null, this.labelSmoothElapsedSec[s] = 0, this.labelSmoothDurationSec[s] = 0;
|
|
1365
|
+
continue;
|
|
1366
|
+
}
|
|
1367
|
+
this.labelTargetScales[s] = 0, this.labelSourceIndexes[s] = -1, this.labelSmoothStarts[s] = null, this.labelSmoothTargets[s] = null, this.labelSmoothElapsedSec[s] = 0, this.labelSmoothDurationSec[s] = 0;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
preprocessImages() {
|
|
1371
|
+
for (let e = 0; e < this.imageUrls.length; e++) {
|
|
1372
|
+
const t = new Image();
|
|
1373
|
+
t.decoding = "async", t.onload = () => {
|
|
1374
|
+
const s = qs(t, "#ffffff");
|
|
1375
|
+
this.processedImages[e] = s;
|
|
1376
|
+
for (let n = 0; n < this.pool.length; n++)
|
|
1377
|
+
this.poolCategories[n] === e && this.pool[n].setImage(this.imageIds[e], s);
|
|
1378
|
+
this.scene.requestRender();
|
|
1379
|
+
}, t.src = this.imageUrls[e];
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
function ht(i, e) {
|
|
1384
|
+
return i >= 0 && i < e ? i : 0;
|
|
1385
|
+
}
|
|
1386
|
+
function Ds(i, e, t) {
|
|
1387
|
+
const s = (i & 16777215) << 1 | (e ? 1 : 0), n = t.get(s);
|
|
1388
|
+
if (n)
|
|
1389
|
+
return n;
|
|
1390
|
+
const o = jt(i, e ? 1 : 0.92);
|
|
1391
|
+
return t.set(s, o), o;
|
|
1392
|
+
}
|
|
1393
|
+
function Es(i, e, t) {
|
|
1394
|
+
const s = Jt(t), n = (i & 16777215) << 8 | Math.round(s * 255), o = e.get(n);
|
|
1395
|
+
if (o)
|
|
1396
|
+
return o;
|
|
1397
|
+
const r = jt(i, s);
|
|
1398
|
+
return e.set(n, r), r;
|
|
1399
|
+
}
|
|
1400
|
+
function jt(i, e) {
|
|
1401
|
+
return D.fromBytes(i >> 16 & 255, i >> 8 & 255, i & 255, Math.round(e * 255));
|
|
1402
|
+
}
|
|
1403
|
+
function Jt(i) {
|
|
1404
|
+
return Rs + (Math.sin(i) + 1) * ks;
|
|
1405
|
+
}
|
|
1406
|
+
function _s(i, e, t, s, n, o) {
|
|
1407
|
+
const r = A.toRadians((e + n) * 0.5), l = (s - i) * 111320 * Math.cos(r), h = (n - e) * 110540, c = o - t;
|
|
1408
|
+
return l * l + h * h + c * c;
|
|
1409
|
+
}
|
|
1410
|
+
function Os(i, e, t, s, n) {
|
|
1411
|
+
const o = i + (n.offsetX ?? 0), r = e - (n.offsetY ?? 0) - (n.connectorStemLength ?? 0), l = r - s;
|
|
1412
|
+
return {
|
|
1413
|
+
left: o,
|
|
1414
|
+
top: l,
|
|
1415
|
+
right: o + t,
|
|
1416
|
+
bottom: r,
|
|
1417
|
+
area: t * s
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
function Bs(i, e, t) {
|
|
1421
|
+
for (const s of e) {
|
|
1422
|
+
const n = Math.max(i.left, s.left), o = Math.min(i.right, s.right);
|
|
1423
|
+
if (o <= n)
|
|
1424
|
+
continue;
|
|
1425
|
+
const r = Math.max(i.top, s.top), l = Math.min(i.bottom, s.bottom);
|
|
1426
|
+
if (l <= r)
|
|
1427
|
+
continue;
|
|
1428
|
+
if ((o - n) * (l - r) / Math.max(1, Math.min(i.area, s.area)) >= t)
|
|
1429
|
+
return !0;
|
|
1430
|
+
}
|
|
1431
|
+
return !1;
|
|
1432
|
+
}
|
|
1433
|
+
function dt(i) {
|
|
1434
|
+
var e;
|
|
1435
|
+
return Ke({
|
|
1436
|
+
...Y,
|
|
1437
|
+
...i ?? {},
|
|
1438
|
+
fontSize: Math.max(1, (i == null ? void 0 : i.fontSize) ?? Y.fontSize),
|
|
1439
|
+
backgroundRadius: Math.max(0, (i == null ? void 0 : i.backgroundRadius) ?? Y.backgroundRadius),
|
|
1440
|
+
overlapThreshold: Math.max(0, Math.min(1, (i == null ? void 0 : i.overlapThreshold) ?? Y.overlapThreshold)),
|
|
1441
|
+
offsetX: Math.max(0, (i == null ? void 0 : i.offsetX) ?? Y.offsetX),
|
|
1442
|
+
offsetY: Math.max(0, (i == null ? void 0 : i.offsetY) ?? Y.offsetY),
|
|
1443
|
+
connectorColor: (i == null ? void 0 : i.connectorColor) ?? (i == null ? void 0 : i.backgroundColor) ?? Y.connectorColor,
|
|
1444
|
+
connectorWidth: Math.max(0, (i == null ? void 0 : i.connectorWidth) ?? Y.connectorWidth),
|
|
1445
|
+
connectorStemLength: Math.max(0, (i == null ? void 0 : i.connectorStemLength) ?? Y.connectorStemLength),
|
|
1446
|
+
fields: (e = i == null ? void 0 : i.fields) != null && e.length ? i.fields.map((t) => ({
|
|
1447
|
+
key: t.key,
|
|
1448
|
+
label: t.label,
|
|
1449
|
+
source: t.source ?? "standard",
|
|
1450
|
+
fallback: t.fallback,
|
|
1451
|
+
minCameraHeight: t.minCameraHeight,
|
|
1452
|
+
maxCameraHeight: t.maxCameraHeight
|
|
1453
|
+
})) : Y.fields
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1456
|
+
function Ns(i) {
|
|
1457
|
+
return `${Math.max(1, i.fontSize ?? 12)}px ${i.fontFamily || "sans-serif"}`;
|
|
1458
|
+
}
|
|
1459
|
+
function Fs(i, e) {
|
|
1460
|
+
return [
|
|
1461
|
+
i,
|
|
1462
|
+
e.backgroundColor ?? "",
|
|
1463
|
+
e.textColor ?? "",
|
|
1464
|
+
e.fontSize ?? 12,
|
|
1465
|
+
e.fontFamily ?? "sans-serif",
|
|
1466
|
+
e.backgroundRadius ?? 0,
|
|
1467
|
+
e.offsetX ?? 0,
|
|
1468
|
+
e.offsetY ?? 0,
|
|
1469
|
+
e.connectorColor ?? "",
|
|
1470
|
+
e.connectorWidth ?? 0,
|
|
1471
|
+
e.connectorStemLength ?? 0
|
|
1472
|
+
].join("");
|
|
1473
|
+
}
|
|
1474
|
+
function zs(i, e) {
|
|
1475
|
+
const s = i.split(/\r?\n/).filter((L) => L.length > 0), n = Math.max(1, e.fontSize), o = Ns(e), r = Math.ceil(n * 1.35), l = Math.ceil(n * 0.7), h = Math.ceil(n * 0.45), m = document.createElement("canvas").getContext("2d");
|
|
1476
|
+
let u = 1;
|
|
1477
|
+
if (m) {
|
|
1478
|
+
m.font = o;
|
|
1479
|
+
for (const L of s)
|
|
1480
|
+
u = Math.max(u, m.measureText(L).width);
|
|
1481
|
+
} else
|
|
1482
|
+
for (const L of s)
|
|
1483
|
+
u = Math.max(u, L.length * n * 0.6);
|
|
1484
|
+
const v = Math.ceil(u + l * 2), d = Math.ceil(s.length * r + h * 2), p = Math.ceil(e.connectorWidth * 0.5) + 1, g = p + e.offsetX, y = Math.ceil(g + v), w = Math.ceil(e.connectorStemLength + e.offsetY + d), M = y + 2 * 2, I = w + 2 * 2, C = p + 2, k = Math.min(2, Math.max(1, window.devicePixelRatio || 1)), S = document.createElement("canvas");
|
|
1485
|
+
S.width = Math.ceil(M * k), S.height = Math.ceil(I * k), S.style.width = `${M}px`, S.style.height = `${I}px`;
|
|
1486
|
+
const T = S.getContext("2d");
|
|
1487
|
+
if (!T)
|
|
1488
|
+
return { canvas: S, width: M, height: I, plateWidth: v, plateHeight: d, anchorX: C, marginY: 2 };
|
|
1489
|
+
T.scale(k, k), T.clearRect(0, 0, M, I), T.translate(2, 2);
|
|
1490
|
+
const z = Math.min(e.backgroundRadius, d * 0.5, v * 0.5);
|
|
1491
|
+
if (e.connectorWidth > 0) {
|
|
1492
|
+
const L = w - e.connectorStemLength, E = Ws(g, d, z), B = Math.min(10, Math.max(3, e.connectorStemLength * 0.35)), Z = E.x - p, Q = E.y - L, q = Math.max(1e-3, Math.sqrt(Z * Z + Q * Q)), ee = p + Z / q * B, $ = L + Q / q * B;
|
|
1493
|
+
T.lineWidth = e.connectorWidth, T.lineCap = "round", T.lineJoin = "round";
|
|
1494
|
+
const X = T.createLinearGradient(p, L + B, p, w);
|
|
1495
|
+
X.addColorStop(0, e.connectorColor), X.addColorStop(1, Xs(e.connectorColor)), T.beginPath(), T.strokeStyle = X, T.moveTo(p, w), T.lineTo(p, L + B), T.stroke(), T.beginPath(), T.strokeStyle = e.connectorColor, T.moveTo(p, L + B), T.quadraticCurveTo(p, L, ee, $), T.lineTo(E.x, E.y), T.stroke();
|
|
1496
|
+
}
|
|
1497
|
+
T.fillStyle = e.backgroundColor, Vs(T, g, 0, v, d, z), T.fill(), T.font = o, T.fillStyle = e.textColor, T.textAlign = "left", T.textBaseline = "middle";
|
|
1498
|
+
for (let L = 0; L < s.length; L++)
|
|
1499
|
+
T.fillText(s[L], g + l, h + r * L + r * 0.5);
|
|
1500
|
+
return { canvas: S, width: M, height: I, plateWidth: v, plateHeight: d, anchorX: C, marginY: 2 };
|
|
1501
|
+
}
|
|
1502
|
+
function Vs(i, e, t, s, n, o) {
|
|
1503
|
+
i.beginPath(), i.moveTo(e + o, t), i.lineTo(e + s - o, t), i.quadraticCurveTo(e + s, t, e + s, t + o), i.lineTo(e + s, t + n - o), i.quadraticCurveTo(e + s, t + n, e + s - o, t + n), i.lineTo(e + o, t + n), i.quadraticCurveTo(e, t + n, e, t + n - o), i.lineTo(e, t + o), i.quadraticCurveTo(e, t, e + o, t), i.closePath();
|
|
1504
|
+
}
|
|
1505
|
+
function Ws(i, e, t) {
|
|
1506
|
+
return { x: i + t, y: e };
|
|
1507
|
+
}
|
|
1508
|
+
function Xs(i) {
|
|
1509
|
+
const e = i.trim(), t = e.startsWith("#") ? e.slice(1) : "";
|
|
1510
|
+
if (t.length === 3 || t.length === 4) {
|
|
1511
|
+
const n = Number.parseInt(t[0] + t[0], 16), o = Number.parseInt(t[1] + t[1], 16), r = Number.parseInt(t[2] + t[2], 16);
|
|
1512
|
+
if (Number.isFinite(n) && Number.isFinite(o) && Number.isFinite(r))
|
|
1513
|
+
return `rgba(${n}, ${o}, ${r}, 0)`;
|
|
1514
|
+
}
|
|
1515
|
+
if (t.length === 6 || t.length === 8) {
|
|
1516
|
+
const n = Number.parseInt(t.slice(0, 2), 16), o = Number.parseInt(t.slice(2, 4), 16), r = Number.parseInt(t.slice(4, 6), 16);
|
|
1517
|
+
if (Number.isFinite(n) && Number.isFinite(o) && Number.isFinite(r))
|
|
1518
|
+
return `rgba(${n}, ${o}, ${r}, 0)`;
|
|
1519
|
+
}
|
|
1520
|
+
const s = e.match(/^rgba?\(([^)]+)\)$/i);
|
|
1521
|
+
if (s) {
|
|
1522
|
+
const n = s[1].split(",").map((o) => o.trim());
|
|
1523
|
+
if (n.length >= 3)
|
|
1524
|
+
return `rgba(${n[0]}, ${n[1]}, ${n[2]}, 0)`;
|
|
1525
|
+
}
|
|
1526
|
+
return "rgba(255, 255, 255, 0)";
|
|
1527
|
+
}
|
|
1528
|
+
function Us(i, e) {
|
|
1529
|
+
const t = i.count > 1 ? `merged x${i.count}` : i.id;
|
|
1530
|
+
return e.showFieldLabels === !1 ? t : `target: ${t}`;
|
|
1531
|
+
}
|
|
1532
|
+
function Gs(i) {
|
|
1533
|
+
return i < 0.5 ? 4 * i * i * i : 1 - Math.pow(-2 * i + 2, 3) / 2;
|
|
1534
|
+
}
|
|
1535
|
+
function Zs(i, e) {
|
|
1536
|
+
return e <= 0 ? 1 : Math.max(0, i * 1e3 / e);
|
|
1537
|
+
}
|
|
1538
|
+
function ut(i, e, t) {
|
|
1539
|
+
return i < e ? Math.min(e, i + t) : i > e ? Math.max(e, i - t) : i;
|
|
1540
|
+
}
|
|
1541
|
+
function Ys() {
|
|
1542
|
+
return typeof performance < "u" ? performance.now() : Date.now();
|
|
1543
|
+
}
|
|
1544
|
+
function Ks() {
|
|
1545
|
+
const t = document.createElement("canvas");
|
|
1546
|
+
t.width = 160, t.height = 160;
|
|
1547
|
+
const s = t.getContext("2d");
|
|
1548
|
+
if (!s)
|
|
1549
|
+
return t;
|
|
1550
|
+
const n = s.createRadialGradient(80, 80, 0, 80, 80, 80);
|
|
1551
|
+
return n.addColorStop(0, "rgba(255,255,255,1)"), n.addColorStop(0.2, "rgba(255,255,255,1)"), n.addColorStop(0.52, "rgba(255,255,255,0.72)"), n.addColorStop(0.82, "rgba(255,255,255,0.3)"), n.addColorStop(1, "rgba(255,255,255,0)"), s.fillStyle = n, s.fillRect(0, 0, 160, 160), t;
|
|
1552
|
+
}
|
|
1553
|
+
function qs(i, e) {
|
|
1554
|
+
const n = document.createElement("canvas");
|
|
1555
|
+
n.width = 128, n.height = 128;
|
|
1556
|
+
const o = n.getContext("2d");
|
|
1557
|
+
if (!o)
|
|
1558
|
+
return n;
|
|
1559
|
+
o.imageSmoothingEnabled = !0, o.imageSmoothingQuality = "high", o.clearRect(0, 0, 128, 128);
|
|
1560
|
+
const r = document.createElement("canvas");
|
|
1561
|
+
r.width = 128, r.height = 128;
|
|
1562
|
+
const l = r.getContext("2d");
|
|
1563
|
+
return l && (l.imageSmoothingEnabled = !0, l.imageSmoothingQuality = "high", l.drawImage(i, 8, 8, 128 - 8 * 2, 128 - 8 * 2), $s(o, r, e)), n;
|
|
1564
|
+
}
|
|
1565
|
+
function $s(i, e, t) {
|
|
1566
|
+
const s = e.getContext("2d");
|
|
1567
|
+
if (!s)
|
|
1568
|
+
return;
|
|
1569
|
+
const { width: n, height: o } = e, r = s.getImageData(0, 0, n, o), l = i.createImageData(n, o), h = js(t), c = new Float32Array(n * o), m = new Float32Array(n * o);
|
|
1570
|
+
for (let d = 0; d < r.data.length; d += 4) {
|
|
1571
|
+
const p = d / 4, g = r.data[d], y = r.data[d + 1], w = r.data[d + 2], M = r.data[d + 3] / 255, I = (g * 0.2126 + y * 0.7152 + w * 0.0722) / 255;
|
|
1572
|
+
c[p] = I * M, m[p] = (1 - I) * M;
|
|
1573
|
+
}
|
|
1574
|
+
const u = ft(c, n, o, 3), v = ft(m, n, o, 4);
|
|
1575
|
+
for (let d = 0; d < r.data.length; d += 4) {
|
|
1576
|
+
const p = d / 4, g = Math.min(1, Math.max(c[p], u[p] * 0.72)), y = Math.min(0.34, m[p] * 0.24 + v[p] * 0.7), w = y + g * (1 - y);
|
|
1577
|
+
if (w <= 0)
|
|
1578
|
+
continue;
|
|
1579
|
+
const M = g * (1 - y) / w;
|
|
1580
|
+
l.data[d] = Math.round(h.r * M), l.data[d + 1] = Math.round(h.g * M), l.data[d + 2] = Math.round(h.b * M), l.data[d + 3] = Math.round(w * 255);
|
|
1581
|
+
}
|
|
1582
|
+
i.putImageData(l, 0, 0);
|
|
1583
|
+
}
|
|
1584
|
+
function ft(i, e, t, s) {
|
|
1585
|
+
const n = [443e-5, 0.05401, 0.24204, 0.39905, 0.24204, 0.05401, 443e-5], o = 3, r = new Float32Array(i.length);
|
|
1586
|
+
let l = i, h = new Float32Array(i.length);
|
|
1587
|
+
for (let c = 0; c < s; c++) {
|
|
1588
|
+
for (let m = 0; m < t; m++)
|
|
1589
|
+
for (let u = 0; u < e; u++) {
|
|
1590
|
+
let v = 0;
|
|
1591
|
+
for (let d = -o; d <= o; d++) {
|
|
1592
|
+
const p = mt(u + d, 0, e - 1);
|
|
1593
|
+
v += l[m * e + p] * n[d + o];
|
|
1594
|
+
}
|
|
1595
|
+
r[m * e + u] = v;
|
|
1596
|
+
}
|
|
1597
|
+
h = new Float32Array(i.length);
|
|
1598
|
+
for (let m = 0; m < t; m++)
|
|
1599
|
+
for (let u = 0; u < e; u++) {
|
|
1600
|
+
let v = 0;
|
|
1601
|
+
for (let d = -o; d <= o; d++) {
|
|
1602
|
+
const p = mt(m + d, 0, t - 1);
|
|
1603
|
+
v += r[p * e + u] * n[d + o];
|
|
1604
|
+
}
|
|
1605
|
+
h[m * e + u] = v;
|
|
1606
|
+
}
|
|
1607
|
+
l = h;
|
|
1608
|
+
}
|
|
1609
|
+
return h;
|
|
1610
|
+
}
|
|
1611
|
+
function mt(i, e, t) {
|
|
1612
|
+
return Math.max(e, Math.min(t, i));
|
|
1613
|
+
}
|
|
1614
|
+
function js(i) {
|
|
1615
|
+
const e = i.startsWith("#") ? i.slice(1) : i;
|
|
1616
|
+
return {
|
|
1617
|
+
r: Number.parseInt(e.slice(0, 2), 16),
|
|
1618
|
+
g: Number.parseInt(e.slice(2, 4), 16),
|
|
1619
|
+
b: Number.parseInt(e.slice(4, 6), 16)
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
const W = Re, Me = W.Buffer, Ie = W.BufferUsage, Js = W.VertexArray, Qs = W.ShaderProgram, en = W.DrawCommand, tn = W.RenderState, sn = W.BlendingState, nn = W.Pass, on = W.PrimitiveType, Se = W.ComponentDatatype, rn = W.Texture, an = W.Sampler, ln = 1, cn = 2, hn = 64;
|
|
1623
|
+
class Qt {
|
|
1624
|
+
constructor(e, t) {
|
|
1625
|
+
a(this, "scene");
|
|
1626
|
+
a(this, "capacity");
|
|
1627
|
+
a(this, "pixelSize");
|
|
1628
|
+
a(this, "iconCount");
|
|
1629
|
+
a(this, "headingOffsets");
|
|
1630
|
+
a(this, "center", new f());
|
|
1631
|
+
a(this, "pos");
|
|
1632
|
+
// dx,dy,dz,heading
|
|
1633
|
+
a(this, "col");
|
|
1634
|
+
// r,g,b,a
|
|
1635
|
+
a(this, "ico");
|
|
1636
|
+
// iconIndex
|
|
1637
|
+
a(this, "ids");
|
|
1638
|
+
a(this, "count", 0);
|
|
1639
|
+
a(this, "dirty", !1);
|
|
1640
|
+
a(this, "idIndex", /* @__PURE__ */ new Map());
|
|
1641
|
+
a(this, "headingById", /* @__PURE__ */ new Map());
|
|
1642
|
+
a(this, "cmd");
|
|
1643
|
+
a(this, "posBuf");
|
|
1644
|
+
a(this, "colBuf");
|
|
1645
|
+
a(this, "icoBuf");
|
|
1646
|
+
a(this, "texture");
|
|
1647
|
+
a(this, "iconImages");
|
|
1648
|
+
a(this, "iconReady", 0);
|
|
1649
|
+
a(this, "show", !0);
|
|
1650
|
+
this.scene = e, this.capacity = t.capacity ?? 3e4, this.pixelSize = t.pixelSize ?? 30;
|
|
1651
|
+
const s = t.typeStyles;
|
|
1652
|
+
this.iconCount = Math.max(1, s.length), this.headingOffsets = s.map((n) => n.pointHeadingOffset ?? 0), this.pos = new Float32Array(this.capacity * 4), this.col = new Float32Array(this.capacity * 4), this.ico = new Float32Array(this.capacity), this.ids = new Array(this.capacity).fill(""), this.iconImages = new Array(this.iconCount).fill(null), s.forEach((n, o) => {
|
|
1653
|
+
const r = new Image();
|
|
1654
|
+
r.crossOrigin = "anonymous", r.onload = () => {
|
|
1655
|
+
this.iconImages[o] = r, this.iconReady++;
|
|
1656
|
+
}, r.onerror = () => {
|
|
1657
|
+
this.iconReady++;
|
|
1658
|
+
}, r.src = n.iconPath;
|
|
1659
|
+
});
|
|
1660
|
+
}
|
|
1661
|
+
setVisible(e) {
|
|
1662
|
+
this.show = e;
|
|
1663
|
+
}
|
|
1664
|
+
/** 通用实例入口(站点等静态对象用)。color 为 [r,g,b,a] 0~1,可选。 */
|
|
1665
|
+
setInstances(e) {
|
|
1666
|
+
f.clone(this.scene.camera.positionWC, this.center), this.idIndex.clear(), this.headingById.clear();
|
|
1667
|
+
const t = new f();
|
|
1668
|
+
let s = 0;
|
|
1669
|
+
for (let n = 0; n < e.length && s < this.capacity; n++) {
|
|
1670
|
+
const o = e[n];
|
|
1671
|
+
f.fromDegrees(o.lon, o.lat, o.height ?? 0, void 0, t), this.pos[s * 4 + 0] = t.x - this.center.x, this.pos[s * 4 + 1] = t.y - this.center.y, this.pos[s * 4 + 2] = t.z - this.center.z;
|
|
1672
|
+
const r = o.iconIndex ?? 0, l = r < 0 ? 0 : r >= this.iconCount ? this.iconCount - 1 : r, h = this.renderHeadingOf(o.heading ?? 0, l);
|
|
1673
|
+
this.pos[s * 4 + 3] = h;
|
|
1674
|
+
const c = o.color ?? [1, 1, 1, 1];
|
|
1675
|
+
this.col[s * 4 + 0] = c[0], this.col[s * 4 + 1] = c[1], this.col[s * 4 + 2] = c[2], this.col[s * 4 + 3] = c[3], this.ico[s] = l, this.ids[s] = o.id, this.idIndex.set(o.id, s), this.headingById.set(o.id, o.heading ?? 0), s++;
|
|
1676
|
+
}
|
|
1677
|
+
this.clearSlotsFrom(s), this.count = s, this.dirty = !0;
|
|
1678
|
+
}
|
|
1679
|
+
/** 每包重建实例(worker 已做裁剪/合并,packet 即当前应渲染集)。 */
|
|
1680
|
+
setPacket(e) {
|
|
1681
|
+
const t = this.scene.camera.positionWC;
|
|
1682
|
+
f.clone(t, this.center), this.idIndex.clear(), this.headingById.clear();
|
|
1683
|
+
let s = 0;
|
|
1684
|
+
const n = e.lon.length, o = new f();
|
|
1685
|
+
for (let r = 0; r < n && s < this.capacity; r++) {
|
|
1686
|
+
const l = e.flags[r];
|
|
1687
|
+
if (l >> cn & 3 || !(l & hn) || l & ln || e.count[r] !== 1)
|
|
1688
|
+
continue;
|
|
1689
|
+
f.fromDegrees(e.lon[r], e.lat[r], e.height[r], void 0, o), this.pos[s * 4 + 0] = o.x - this.center.x, this.pos[s * 4 + 1] = o.y - this.center.y, this.pos[s * 4 + 2] = o.z - this.center.z;
|
|
1690
|
+
const h = e.heading[r] || 0, c = e.color[r] >>> 0;
|
|
1691
|
+
this.col[s * 4 + 0] = (c >> 16 & 255) / 255, this.col[s * 4 + 1] = (c >> 8 & 255) / 255, this.col[s * 4 + 2] = (c & 255) / 255, this.col[s * 4 + 3] = 1;
|
|
1692
|
+
const m = e.category[r] ?? 0, u = m < 0 ? 0 : m >= this.iconCount ? this.iconCount - 1 : m;
|
|
1693
|
+
this.ico[s] = u;
|
|
1694
|
+
const v = e.ids[r], d = this.renderHeadingOf(h, u);
|
|
1695
|
+
this.ids[s] = v, this.pos[s * 4 + 3] = d, this.idIndex.set(v, s), this.headingById.set(v, h), s++;
|
|
1696
|
+
}
|
|
1697
|
+
this.clearSlotsFrom(s), this.count = s, this.dirty = !0;
|
|
1698
|
+
}
|
|
1699
|
+
getTargetFrame(e, t = new f()) {
|
|
1700
|
+
const s = this.idIndex.get(e);
|
|
1701
|
+
if (s !== void 0)
|
|
1702
|
+
return t.x = this.pos[s * 4 + 0] + this.center.x, t.y = this.pos[s * 4 + 1] + this.center.y, t.z = this.pos[s * 4 + 2] + this.center.z, { position: t, heading: this.headingById.get(e) ?? 0 };
|
|
1703
|
+
}
|
|
1704
|
+
/** Cesium 渲染管线每帧回调(通过 scene.primitives.add 自动调用)。 */
|
|
1705
|
+
update(e) {
|
|
1706
|
+
if (!this.show || this.count === 0)
|
|
1707
|
+
return;
|
|
1708
|
+
const t = e.context;
|
|
1709
|
+
this.cmd || this.build(t), !this.texture && this.iconReady >= this.iconCount && this.buildAtlas(t), this.dirty && (this.posBuf.copyFromArrayView(this.pos, 0), this.colBuf.copyFromArrayView(this.col, 0), this.icoBuf.copyFromArrayView(this.ico, 0), this.dirty = !1), R.fromTranslation(this.center, this.cmd.modelMatrix), this.cmd.instanceCount = this.count, e.commandList.push(this.cmd);
|
|
1710
|
+
}
|
|
1711
|
+
buildAtlas(e) {
|
|
1712
|
+
const s = document.createElement("canvas");
|
|
1713
|
+
s.width = 128 * this.iconCount, s.height = 128;
|
|
1714
|
+
const n = s.getContext("2d");
|
|
1715
|
+
if (n) {
|
|
1716
|
+
for (let o = 0; o < this.iconCount; o++) {
|
|
1717
|
+
const r = this.iconImages[o];
|
|
1718
|
+
r && n.drawImage(r, o * 128, 0, 128, 128);
|
|
1719
|
+
}
|
|
1720
|
+
this.texture = new rn({
|
|
1721
|
+
context: e,
|
|
1722
|
+
source: s,
|
|
1723
|
+
sampler: new an({})
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
build(e) {
|
|
1728
|
+
const t = new Float32Array([
|
|
1729
|
+
-0.5,
|
|
1730
|
+
-0.5,
|
|
1731
|
+
0,
|
|
1732
|
+
1,
|
|
1733
|
+
0.5,
|
|
1734
|
+
-0.5,
|
|
1735
|
+
1,
|
|
1736
|
+
1,
|
|
1737
|
+
0.5,
|
|
1738
|
+
0.5,
|
|
1739
|
+
1,
|
|
1740
|
+
0,
|
|
1741
|
+
-0.5,
|
|
1742
|
+
-0.5,
|
|
1743
|
+
0,
|
|
1744
|
+
1,
|
|
1745
|
+
0.5,
|
|
1746
|
+
0.5,
|
|
1747
|
+
1,
|
|
1748
|
+
0,
|
|
1749
|
+
-0.5,
|
|
1750
|
+
0.5,
|
|
1751
|
+
0,
|
|
1752
|
+
0
|
|
1753
|
+
]), s = Me.createVertexBuffer({ context: e, typedArray: t, usage: Ie.STATIC_DRAW });
|
|
1754
|
+
this.posBuf = Me.createVertexBuffer({ context: e, typedArray: this.pos, usage: Ie.DYNAMIC_DRAW }), this.colBuf = Me.createVertexBuffer({ context: e, typedArray: this.col, usage: Ie.DYNAMIC_DRAW }), this.icoBuf = Me.createVertexBuffer({ context: e, typedArray: this.ico, usage: Ie.DYNAMIC_DRAW });
|
|
1755
|
+
const n = new Js({
|
|
1756
|
+
context: e,
|
|
1757
|
+
attributes: [
|
|
1758
|
+
{ index: 0, vertexBuffer: s, componentsPerAttribute: 4, componentDatatype: Se.FLOAT },
|
|
1759
|
+
{ index: 1, vertexBuffer: this.posBuf, componentsPerAttribute: 4, componentDatatype: Se.FLOAT, instanceDivisor: 1 },
|
|
1760
|
+
{ index: 2, vertexBuffer: this.colBuf, componentsPerAttribute: 4, componentDatatype: Se.FLOAT, instanceDivisor: 1 },
|
|
1761
|
+
{ index: 3, vertexBuffer: this.icoBuf, componentsPerAttribute: 1, componentDatatype: Se.FLOAT, instanceDivisor: 1 }
|
|
1762
|
+
]
|
|
1763
|
+
}), o = `
|
|
1764
|
+
in vec4 a_quad; // xy=corner, zw=uv
|
|
1765
|
+
in vec4 a_inst; // xyz=ECEF相对中心, w=heading(度)
|
|
1766
|
+
in vec4 a_color; // rgba
|
|
1767
|
+
in float a_icon; // 图标索引
|
|
1768
|
+
uniform vec3 u_center;
|
|
1769
|
+
uniform float u_pixelSize;
|
|
1770
|
+
uniform float u_iconCount;
|
|
1771
|
+
out vec2 v_uv;
|
|
1772
|
+
out vec4 v_color;
|
|
1773
|
+
void main() {
|
|
1774
|
+
vec3 pRel = a_inst.xyz;
|
|
1775
|
+
float heading = radians(a_inst.w);
|
|
1776
|
+
vec3 ecefAbs = u_center + pRel;
|
|
1777
|
+
vec3 up = normalize(ecefAbs);
|
|
1778
|
+
vec3 east = normalize(cross(vec3(0.0, 0.0, 1.0), up));
|
|
1779
|
+
vec3 north = cross(up, east);
|
|
1780
|
+
float ch = cos(heading), sh = sin(heading);
|
|
1781
|
+
vec2 r = vec2(ch * a_quad.x - sh * a_quad.y, sh * a_quad.x + ch * a_quad.y);
|
|
1782
|
+
vec4 eye = czm_modelView * vec4(pRel, 1.0);
|
|
1783
|
+
float worldPerPixel = 2.0 * length(eye.xyz) / (czm_viewport.w * czm_projection[1][1]);
|
|
1784
|
+
vec3 offset = (r.x * east + r.y * north) * (u_pixelSize * worldPerPixel);
|
|
1785
|
+
v_uv = vec2((a_icon + a_quad.z) / u_iconCount, a_quad.w);
|
|
1786
|
+
v_color = a_color;
|
|
1787
|
+
gl_Position = czm_modelViewProjection * vec4(pRel + offset, 1.0);
|
|
1788
|
+
czm_vertexLogDepth();
|
|
1789
|
+
}
|
|
1790
|
+
`, r = `
|
|
1791
|
+
in vec2 v_uv;
|
|
1792
|
+
in vec4 v_color;
|
|
1793
|
+
uniform sampler2D u_icon;
|
|
1794
|
+
uniform float u_hasIcon;
|
|
1795
|
+
void main() {
|
|
1796
|
+
vec4 tex = u_hasIcon > 0.5 ? texture(u_icon, v_uv) : vec4(1.0);
|
|
1797
|
+
if (tex.a < 0.05) discard;
|
|
1798
|
+
// 图标 rgb 携带"白色填充 + 深色描边",乘以实例颜色着色(保留描边)。
|
|
1799
|
+
out_FragColor = vec4(v_color.rgb * tex.rgb, v_color.a * tex.a);
|
|
1800
|
+
}
|
|
1801
|
+
`, l = Qs.fromCache({
|
|
1802
|
+
context: e,
|
|
1803
|
+
vertexShaderSource: o,
|
|
1804
|
+
fragmentShaderSource: r,
|
|
1805
|
+
attributeLocations: { a_quad: 0, a_inst: 1, a_color: 2, a_icon: 3 }
|
|
1806
|
+
}), h = {
|
|
1807
|
+
u_center: () => this.center,
|
|
1808
|
+
u_pixelSize: () => this.pixelSize,
|
|
1809
|
+
u_iconCount: () => this.iconCount,
|
|
1810
|
+
u_icon: () => this.texture,
|
|
1811
|
+
u_hasIcon: () => this.texture ? 1 : 0
|
|
1812
|
+
};
|
|
1813
|
+
this.cmd = new en({
|
|
1814
|
+
primitiveType: on.TRIANGLES,
|
|
1815
|
+
vertexArray: n,
|
|
1816
|
+
shaderProgram: l,
|
|
1817
|
+
renderState: tn.fromCache({
|
|
1818
|
+
depthTest: { enabled: !0 },
|
|
1819
|
+
depthMask: !0,
|
|
1820
|
+
blending: sn.ALPHA_BLEND
|
|
1821
|
+
}),
|
|
1822
|
+
pass: nn.TRANSLUCENT,
|
|
1823
|
+
modelMatrix: R.fromTranslation(this.center, new R()),
|
|
1824
|
+
uniformMap: h,
|
|
1825
|
+
count: 6,
|
|
1826
|
+
instanceCount: this.count,
|
|
1827
|
+
cull: !1,
|
|
1828
|
+
boundingVolume: new Ze(f.ZERO, 1e8),
|
|
1829
|
+
owner: this
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
isDestroyed() {
|
|
1833
|
+
return !1;
|
|
1834
|
+
}
|
|
1835
|
+
destroy() {
|
|
1836
|
+
return this.cmd && (this.cmd.shaderProgram && this.cmd.shaderProgram.destroy(), this.cmd.vertexArray && this.cmd.vertexArray.destroy(), this.cmd = void 0), this.texture && (this.texture.destroy(), this.texture = void 0), !0;
|
|
1837
|
+
}
|
|
1838
|
+
renderHeadingOf(e, t) {
|
|
1839
|
+
return dn((this.headingOffsets[t] ?? 0) - e);
|
|
1840
|
+
}
|
|
1841
|
+
clearSlotsFrom(e) {
|
|
1842
|
+
for (let t = e; t < this.count; t++)
|
|
1843
|
+
this.ids[t] = "";
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
function dn(i) {
|
|
1847
|
+
return (i % 360 + 360) % 360;
|
|
1848
|
+
}
|
|
1849
|
+
const un = "target-selection-overlay", fn = "target-hover-overlay", pt = 500, ei = 0.85, mn = 0.42, ti = 1;
|
|
1850
|
+
class pn {
|
|
1851
|
+
constructor(e, t) {
|
|
1852
|
+
a(this, "collection");
|
|
1853
|
+
a(this, "pool", []);
|
|
1854
|
+
a(this, "baseSizes", []);
|
|
1855
|
+
a(this, "selectedIds", /* @__PURE__ */ new Set());
|
|
1856
|
+
a(this, "pulseElapsedById", /* @__PURE__ */ new Map());
|
|
1857
|
+
a(this, "hoveredId", null);
|
|
1858
|
+
a(this, "lastPacket", null);
|
|
1859
|
+
a(this, "activeCount", 0);
|
|
1860
|
+
a(this, "selectionImage");
|
|
1861
|
+
a(this, "hoverImage");
|
|
1862
|
+
a(this, "hoverBillboard");
|
|
1863
|
+
this.scene = e, this.renderTypes = t, this.selectionImage = vt(
|
|
1864
|
+
"rgba(255, 42, 42, 0.98)",
|
|
1865
|
+
"rgba(255, 24, 24, 0.72)",
|
|
1866
|
+
"rgba(255, 190, 190, 0.9)"
|
|
1867
|
+
), this.hoverImage = vt(
|
|
1868
|
+
"rgba(154, 255, 184, 0.98)",
|
|
1869
|
+
"rgba(120, 255, 160, 0.58)",
|
|
1870
|
+
"rgba(222, 255, 231, 0.95)"
|
|
1871
|
+
), this.collection = this.scene.primitives.add(new fe({ scene: e })), this.collection.show = !0, this.hoverBillboard = this.collection.add({
|
|
1872
|
+
position: f.ZERO,
|
|
1873
|
+
show: !1,
|
|
1874
|
+
width: te,
|
|
1875
|
+
height: te,
|
|
1876
|
+
color: D.WHITE,
|
|
1877
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
1878
|
+
}), this.hoverBillboard.setImage(fn, this.hoverImage);
|
|
1879
|
+
}
|
|
1880
|
+
setSelectedIds(e) {
|
|
1881
|
+
const t = new Set(this.selectedIds), s = new Set(e);
|
|
1882
|
+
for (const n of t)
|
|
1883
|
+
s.has(n) || this.pulseElapsedById.delete(n);
|
|
1884
|
+
this.selectedIds.clear();
|
|
1885
|
+
for (const n of e)
|
|
1886
|
+
!t.has(n) && !this.pulseElapsedById.has(n) && this.pulseElapsedById.set(n, 0), this.selectedIds.add(n);
|
|
1887
|
+
this.refresh();
|
|
1888
|
+
}
|
|
1889
|
+
setPacket(e) {
|
|
1890
|
+
this.lastPacket = e, this.refresh();
|
|
1891
|
+
}
|
|
1892
|
+
setHoveredId(e) {
|
|
1893
|
+
this.hoveredId !== e && (this.hoveredId = e, this.refresh());
|
|
1894
|
+
}
|
|
1895
|
+
update(e) {
|
|
1896
|
+
if (this.activeCount === 0 || this.pulseElapsedById.size === 0)
|
|
1897
|
+
return;
|
|
1898
|
+
let t = !1;
|
|
1899
|
+
for (const [s, n] of this.pulseElapsedById) {
|
|
1900
|
+
const o = n + e;
|
|
1901
|
+
if (o >= ei) {
|
|
1902
|
+
this.pulseElapsedById.delete(s), t = !0;
|
|
1903
|
+
continue;
|
|
1904
|
+
}
|
|
1905
|
+
this.pulseElapsedById.set(s, o), t = !0;
|
|
1906
|
+
}
|
|
1907
|
+
for (let s = 0; s < this.activeCount; s++) {
|
|
1908
|
+
const n = this.baseSizes[s] || te, o = gn(this.pool[s]), r = o ? gt(this.pulseElapsedById.get(o)) : ti;
|
|
1909
|
+
this.pool[s].width = n * r, this.pool[s].height = n * r;
|
|
1910
|
+
}
|
|
1911
|
+
t && this.scene.requestRender();
|
|
1912
|
+
}
|
|
1913
|
+
getRenderedTarget(e) {
|
|
1914
|
+
const t = this.lastPacket;
|
|
1915
|
+
if (!(!t || !this.selectedIds.has(e))) {
|
|
1916
|
+
for (let s = 0; s < t.ids.length; s++)
|
|
1917
|
+
if (!(t.ids[s] !== e || t.count[s] !== 1))
|
|
1918
|
+
return {
|
|
1919
|
+
id: e,
|
|
1920
|
+
position: f.fromDegrees(t.lon[s], t.lat[s], t.height[s]),
|
|
1921
|
+
size: this.overlaySizeOf(t, s)
|
|
1922
|
+
};
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
clear() {
|
|
1926
|
+
this.lastPacket = null, this.hoveredId = null, this.pulseElapsedById.clear(), this.hideUnused(0), this.hoverBillboard.show = !1;
|
|
1927
|
+
}
|
|
1928
|
+
destroy() {
|
|
1929
|
+
this.clear(), this.scene.primitives.remove(this.collection);
|
|
1930
|
+
}
|
|
1931
|
+
refresh() {
|
|
1932
|
+
const e = this.lastPacket;
|
|
1933
|
+
if (!e) {
|
|
1934
|
+
this.hideUnused(0), this.hoverBillboard.show = !1;
|
|
1935
|
+
return;
|
|
1936
|
+
}
|
|
1937
|
+
if (this.selectedIds.size === 0) {
|
|
1938
|
+
this.hideUnused(0), this.refreshHover(e), this.scene.requestRender();
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
let t = 0;
|
|
1942
|
+
this.ensurePool(Math.min(this.selectedIds.size, pt));
|
|
1943
|
+
for (let s = 0; s < e.ids.length && !(t >= pt); s++) {
|
|
1944
|
+
const n = e.ids[s];
|
|
1945
|
+
if (!n || e.count[s] !== 1 || !this.selectedIds.has(n))
|
|
1946
|
+
continue;
|
|
1947
|
+
const o = this.pool[t], r = this.overlaySizeOf(e, s);
|
|
1948
|
+
o.position = f.fromDegrees(e.lon[s], e.lat[s], e.height[s]), this.baseSizes[t] = r;
|
|
1949
|
+
const l = gt(this.pulseElapsedById.get(n));
|
|
1950
|
+
o.width = r * l, o.height = r * l, o.rotation = 0, o.id = { targetId: n, selectionOverlay: !0 }, o.show = !0, t++;
|
|
1951
|
+
}
|
|
1952
|
+
this.hideUnused(t), this.refreshHover(e), this.scene.requestRender();
|
|
1953
|
+
}
|
|
1954
|
+
ensurePool(e) {
|
|
1955
|
+
for (; this.pool.length < e; ) {
|
|
1956
|
+
const t = this.collection.add({
|
|
1957
|
+
position: f.ZERO,
|
|
1958
|
+
show: !1,
|
|
1959
|
+
width: te,
|
|
1960
|
+
height: te,
|
|
1961
|
+
color: D.WHITE,
|
|
1962
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
1963
|
+
});
|
|
1964
|
+
t.setImage(un, this.selectionImage), this.pool.push(t), this.baseSizes.push(te);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
hideUnused(e) {
|
|
1968
|
+
for (let t = e; t < this.activeCount; t++)
|
|
1969
|
+
this.pool[t].show = !1, this.baseSizes[t] = te;
|
|
1970
|
+
this.activeCount = e;
|
|
1971
|
+
}
|
|
1972
|
+
refreshHover(e) {
|
|
1973
|
+
const t = this.hoveredId;
|
|
1974
|
+
if (!t) {
|
|
1975
|
+
this.hoverBillboard.show = !1;
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
for (let s = 0; s < e.ids.length; s++) {
|
|
1979
|
+
if (e.ids[s] !== t || e.count[s] !== 1)
|
|
1980
|
+
continue;
|
|
1981
|
+
const n = this.overlaySizeOf(e, s);
|
|
1982
|
+
this.hoverBillboard.position = f.fromDegrees(e.lon[s], e.lat[s], e.height[s]), this.hoverBillboard.width = n, this.hoverBillboard.height = n, this.hoverBillboard.rotation = 0, this.hoverBillboard.id = { targetId: t, hoverOverlay: !0 }, this.hoverBillboard.show = !0;
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
this.hoverBillboard.show = !1;
|
|
1986
|
+
}
|
|
1987
|
+
overlaySizeOf(e, t) {
|
|
1988
|
+
var o;
|
|
1989
|
+
const s = e.category[t] ?? 0, n = ((o = this.renderTypes[s]) == null ? void 0 : o.type) ?? "";
|
|
1990
|
+
return $t(n, e.size[t], e.count[t] > 1);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
function gt(i) {
|
|
1994
|
+
if (i == null)
|
|
1995
|
+
return ti;
|
|
1996
|
+
const e = i / ei;
|
|
1997
|
+
return 1 + (1 - e) * (1 - e) * mn;
|
|
1998
|
+
}
|
|
1999
|
+
function gn(i) {
|
|
2000
|
+
const e = i.id;
|
|
2001
|
+
return e == null ? void 0 : e.targetId;
|
|
2002
|
+
}
|
|
2003
|
+
function vt(i, e, t) {
|
|
2004
|
+
const n = document.createElement("canvas");
|
|
2005
|
+
n.width = 64, n.height = 64;
|
|
2006
|
+
const o = n.getContext("2d");
|
|
2007
|
+
if (!o)
|
|
2008
|
+
return n;
|
|
2009
|
+
o.clearRect(0, 0, 64, 64), o.strokeStyle = i, o.lineWidth = 4.5, o.shadowColor = e, o.shadowBlur = 10;
|
|
2010
|
+
const r = 9, l = 17;
|
|
2011
|
+
return xe(o, r, r, l, 1, 1), xe(o, 64 - r, r, l, -1, 1), xe(o, r, 64 - r, l, 1, -1), xe(o, 64 - r, 64 - r, l, -1, -1), o.shadowBlur = 0, o.strokeStyle = t, o.lineWidth = 1.6, o.beginPath(), o.arc(64 * 0.5, 64 * 0.5, 6, 0, A.TWO_PI), o.stroke(), n;
|
|
2012
|
+
}
|
|
2013
|
+
function xe(i, e, t, s, n, o) {
|
|
2014
|
+
i.beginPath(), i.moveTo(e, t + o * s), i.lineTo(e, t), i.lineTo(e + n * s, t), i.stroke();
|
|
2015
|
+
}
|
|
2016
|
+
const vn = 80, yt = typeof performance < "u" && typeof performance.now == "function" ? () => performance.now() : () => Date.now();
|
|
2017
|
+
class yn {
|
|
2018
|
+
constructor(e, t) {
|
|
2019
|
+
a(this, "points", []);
|
|
2020
|
+
a(this, "index", null);
|
|
2021
|
+
// 索引建立时的相机位姿。屏幕坐标是世界点投影出来的,相机平移/缩放/旋转后
|
|
2022
|
+
// 同一世界点会落到不同屏幕位置,但 canvas 尺寸不变。必须按位姿失效,否则平移
|
|
2023
|
+
// 海图后 hover 命中的是旧屏幕坐标(表现为要在偏移位置才 hover 得到)。
|
|
2024
|
+
a(this, "builtCameraPosition", null);
|
|
2025
|
+
a(this, "builtCameraDirection", null);
|
|
2026
|
+
// 相机连续运动时,每帧 pick 都重投影全部轨迹点是 O(n) 开销。位姿变化后的重建做
|
|
2027
|
+
// 节流:最多每 HOVER_REBUILD_THROTTLE_MS 重建一次,期间复用旧索引(最多 80ms 陈旧,
|
|
2028
|
+
// hover 体感无差)。canvas 尺寸变化与数据变更(setPoints/invalidate)不受节流,立即重建。
|
|
2029
|
+
a(this, "lastBuiltAt", 0);
|
|
2030
|
+
this.scene = e, this.pixelThreshold = t;
|
|
2031
|
+
}
|
|
2032
|
+
setPoints(e) {
|
|
2033
|
+
this.points = e.slice(), this.index = null;
|
|
2034
|
+
}
|
|
2035
|
+
invalidate() {
|
|
2036
|
+
this.index = null;
|
|
2037
|
+
}
|
|
2038
|
+
rebuild() {
|
|
2039
|
+
this.index = null, this.ensureIndex();
|
|
2040
|
+
}
|
|
2041
|
+
pick(e) {
|
|
2042
|
+
const t = this.ensureIndex();
|
|
2043
|
+
if (!t)
|
|
2044
|
+
return null;
|
|
2045
|
+
const s = Math.max(1, this.pixelThreshold), n = s * s, o = Math.floor(e.x / t.cellSize), r = Math.floor(e.y / t.cellSize);
|
|
2046
|
+
let l = null, h = 0, c = 0, m = n;
|
|
2047
|
+
for (let u = r - 1; u <= r + 1; u++)
|
|
2048
|
+
for (let v = o - 1; v <= o + 1; v++) {
|
|
2049
|
+
const d = t.bins.get(wt(v, u));
|
|
2050
|
+
if (d)
|
|
2051
|
+
for (const p of d) {
|
|
2052
|
+
const g = t.screenX[p] - e.x, y = t.screenY[p] - e.y, w = g * g + y * y;
|
|
2053
|
+
w > m || (m = w, l = this.points[p], h = t.screenX[p], c = t.screenY[p]);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
return l ? {
|
|
2057
|
+
targetId: l.targetId,
|
|
2058
|
+
pointIndex: l.pointIndex,
|
|
2059
|
+
point: l.point,
|
|
2060
|
+
screenX: h,
|
|
2061
|
+
screenY: c
|
|
2062
|
+
} : null;
|
|
2063
|
+
}
|
|
2064
|
+
ensureIndex() {
|
|
2065
|
+
const e = this.scene.canvas, t = this.scene.camera, s = !!this.index && this.index.canvasWidth === e.clientWidth && this.index.canvasHeight === e.clientHeight, n = s && !!this.builtCameraPosition && !!this.builtCameraDirection && f.equalsEpsilon(t.positionWC, this.builtCameraPosition, A.EPSILON7) && f.equalsEpsilon(t.directionWC, this.builtCameraDirection, A.EPSILON9);
|
|
2066
|
+
if (this.index && s && n)
|
|
2067
|
+
return this.index;
|
|
2068
|
+
if (this.index && s && !n && yt() - this.lastBuiltAt < vn)
|
|
2069
|
+
return this.index;
|
|
2070
|
+
if (this.index = null, this.builtCameraPosition = f.clone(t.positionWC, this.builtCameraPosition ?? new f()), this.builtCameraDirection = f.clone(t.directionWC, this.builtCameraDirection ?? new f()), this.lastBuiltAt = yt(), this.points.length === 0)
|
|
2071
|
+
return null;
|
|
2072
|
+
const o = Math.max(48, this.pixelThreshold * 2), r = /* @__PURE__ */ new Map(), l = new Float32Array(this.points.length), h = new Float32Array(this.points.length);
|
|
2073
|
+
l.fill(Number.NaN), h.fill(Number.NaN);
|
|
2074
|
+
for (let c = 0; c < this.points.length; c++) {
|
|
2075
|
+
const m = Ae.wgs84ToWindowCoordinates(this.scene, this.points[c].position);
|
|
2076
|
+
if (!m)
|
|
2077
|
+
continue;
|
|
2078
|
+
const u = m.x, v = m.y;
|
|
2079
|
+
if (!Number.isFinite(u) || !Number.isFinite(v) || u < 0 || v < 0 || u > e.clientWidth || v > e.clientHeight)
|
|
2080
|
+
continue;
|
|
2081
|
+
l[c] = u, h[c] = v;
|
|
2082
|
+
const d = wt(Math.floor(u / o), Math.floor(v / o)), p = r.get(d);
|
|
2083
|
+
p ? p.push(c) : r.set(d, [c]);
|
|
2084
|
+
}
|
|
2085
|
+
return this.index = {
|
|
2086
|
+
bins: r,
|
|
2087
|
+
screenX: l,
|
|
2088
|
+
screenY: h,
|
|
2089
|
+
canvasWidth: e.clientWidth,
|
|
2090
|
+
canvasHeight: e.clientHeight,
|
|
2091
|
+
cellSize: o
|
|
2092
|
+
}, this.index;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
function wt(i, e) {
|
|
2096
|
+
return `${i}:${e}`;
|
|
2097
|
+
}
|
|
2098
|
+
const Mt = new D(0.22, 0.82, 1, 0.84), wn = "track-point-overlay", It = 12, Mn = new f(0, 0, -24);
|
|
2099
|
+
class In {
|
|
2100
|
+
constructor(e) {
|
|
2101
|
+
a(this, "historyCollection");
|
|
2102
|
+
a(this, "connectorCollection");
|
|
2103
|
+
a(this, "pointCollection");
|
|
2104
|
+
a(this, "linePool", []);
|
|
2105
|
+
a(this, "pointPool", []);
|
|
2106
|
+
a(this, "lineCount", 0);
|
|
2107
|
+
a(this, "pointImage");
|
|
2108
|
+
this.scene = e, this.historyCollection = this.scene.primitives.add(new Ve({ show: !0 })), this.connectorCollection = this.scene.primitives.add(new Ve({ show: !0 })), this.pointCollection = this.scene.primitives.add(new fe({ show: !0, scene: e })), this.pointImage = Sn();
|
|
2109
|
+
}
|
|
2110
|
+
setTracks(e) {
|
|
2111
|
+
this.ensureLinePool(e.length);
|
|
2112
|
+
let t = 0;
|
|
2113
|
+
for (let s = 0; s < e.length; s++) {
|
|
2114
|
+
const n = e[s], o = this.linePool[s];
|
|
2115
|
+
o.history.positions = n.cartesianPoints, o.history.show = n.cartesianPoints.length >= 2, o.history.id = { targetId: n.targetId, trackHistory: !0 }, St(o, n.cartesianPoints, n.currentPosition);
|
|
2116
|
+
for (let r = 0; r < n.cartesianPoints.length; r++) {
|
|
2117
|
+
const l = this.ensurePoint(t++);
|
|
2118
|
+
l.position = n.cartesianPoints[r], l.id = { targetId: n.targetId, trackPointIndex: r, trackPoint: !0 }, l.show = !0;
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
this.lineCount = e.length, this.hideUnusedLines(e.length), this.hideUnusedPoints(t);
|
|
2122
|
+
}
|
|
2123
|
+
updateConnectors(e) {
|
|
2124
|
+
const t = Math.min(e.length, this.lineCount);
|
|
2125
|
+
for (let s = 0; s < t; s++)
|
|
2126
|
+
St(this.linePool[s], e[s].cartesianPoints, e[s].currentPosition);
|
|
2127
|
+
}
|
|
2128
|
+
clear() {
|
|
2129
|
+
this.hideUnusedLines(0), this.hideUnusedPoints(0), this.lineCount = 0;
|
|
2130
|
+
}
|
|
2131
|
+
destroy() {
|
|
2132
|
+
this.clear(), this.scene.primitives.remove(this.historyCollection), this.scene.primitives.remove(this.connectorCollection), this.scene.primitives.remove(this.pointCollection);
|
|
2133
|
+
}
|
|
2134
|
+
ensureLinePool(e) {
|
|
2135
|
+
for (; this.linePool.length < e; )
|
|
2136
|
+
this.linePool.push(this.createLineSlot());
|
|
2137
|
+
}
|
|
2138
|
+
ensurePoint(e) {
|
|
2139
|
+
for (; this.pointPool.length <= e; ) {
|
|
2140
|
+
const t = this.pointCollection.add({
|
|
2141
|
+
show: !1,
|
|
2142
|
+
position: f.ZERO,
|
|
2143
|
+
width: It,
|
|
2144
|
+
height: It,
|
|
2145
|
+
color: D.WHITE,
|
|
2146
|
+
eyeOffset: f.clone(Mn),
|
|
2147
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
2148
|
+
});
|
|
2149
|
+
t.setImage(wn, this.pointImage), this.pointPool.push(t);
|
|
2150
|
+
}
|
|
2151
|
+
return this.pointPool[e];
|
|
2152
|
+
}
|
|
2153
|
+
createLineSlot() {
|
|
2154
|
+
const e = f.clone(f.ZERO), t = f.clone(f.ZERO), s = [e, t], n = ae.fromType(ae.ColorType, { color: D.clone(Mt) }), o = ae.fromType(ae.ColorType, { color: D.clone(Mt) }), r = this.historyCollection.add({
|
|
2155
|
+
show: !1,
|
|
2156
|
+
positions: [],
|
|
2157
|
+
width: 2.2,
|
|
2158
|
+
material: n
|
|
2159
|
+
}), l = this.connectorCollection.add({
|
|
2160
|
+
show: !1,
|
|
2161
|
+
positions: s,
|
|
2162
|
+
width: 1.5,
|
|
2163
|
+
material: o
|
|
2164
|
+
});
|
|
2165
|
+
return {
|
|
2166
|
+
history: r,
|
|
2167
|
+
connector: l,
|
|
2168
|
+
connectorStart: e,
|
|
2169
|
+
connectorEnd: t,
|
|
2170
|
+
connectorPositions: s,
|
|
2171
|
+
historyMaterial: n,
|
|
2172
|
+
connectorMaterial: o
|
|
2173
|
+
};
|
|
2174
|
+
}
|
|
2175
|
+
hideUnusedLines(e) {
|
|
2176
|
+
for (let t = e; t < this.linePool.length; t++)
|
|
2177
|
+
this.linePool[t].history.show = !1, this.linePool[t].connector.show = !1;
|
|
2178
|
+
}
|
|
2179
|
+
hideUnusedPoints(e) {
|
|
2180
|
+
for (let t = e; t < this.pointPool.length; t++)
|
|
2181
|
+
this.pointPool[t].show = !1;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
function Sn() {
|
|
2185
|
+
const e = document.createElement("canvas");
|
|
2186
|
+
e.width = 48, e.height = 48;
|
|
2187
|
+
const t = e.getContext("2d");
|
|
2188
|
+
if (!t)
|
|
2189
|
+
return e;
|
|
2190
|
+
const s = 48 * 0.5;
|
|
2191
|
+
return t.clearRect(0, 0, 48, 48), t.fillStyle = "rgba(234,252,255,0.98)", t.strokeStyle = "rgba(18,138,184,0.95)", t.lineWidth = 5, t.beginPath(), t.arc(s, s, 11, 0, Math.PI * 2), t.fill(), t.stroke(), t.strokeStyle = "rgba(255,255,255,0.95)", t.lineWidth = 2, t.beginPath(), t.arc(s, s, 15, 0, Math.PI * 2), t.stroke(), e;
|
|
2192
|
+
}
|
|
2193
|
+
function St(i, e, t) {
|
|
2194
|
+
if (e.length === 0 || !t) {
|
|
2195
|
+
i.connector.show = !1;
|
|
2196
|
+
return;
|
|
2197
|
+
}
|
|
2198
|
+
const s = e[e.length - 1];
|
|
2199
|
+
if (f.distance(s, t) < 1) {
|
|
2200
|
+
i.connector.show = !1;
|
|
2201
|
+
return;
|
|
2202
|
+
}
|
|
2203
|
+
f.clone(s, i.connectorStart), f.clone(t, i.connectorEnd), i.connector.positions = i.connectorPositions, i.connector.show = !0;
|
|
2204
|
+
}
|
|
2205
|
+
class xn extends qe {
|
|
2206
|
+
constructor(t, s) {
|
|
2207
|
+
super();
|
|
2208
|
+
a(this, "records", /* @__PURE__ */ new Map());
|
|
2209
|
+
a(this, "renderer");
|
|
2210
|
+
a(this, "hoverPicker");
|
|
2211
|
+
a(this, "lastPacket", null);
|
|
2212
|
+
a(this, "hoverPosition", null);
|
|
2213
|
+
a(this, "lastPointerPosition", null);
|
|
2214
|
+
a(this, "hoverRafId", 0);
|
|
2215
|
+
a(this, "rebuildHoverIndexTimer", 0);
|
|
2216
|
+
a(this, "currentHoverKey", "");
|
|
2217
|
+
a(this, "removeCameraListener");
|
|
2218
|
+
a(this, "onPointerMoveBound");
|
|
2219
|
+
a(this, "onPointerLeaveBound");
|
|
2220
|
+
a(this, "onPointerDownBound");
|
|
2221
|
+
a(this, "onWheelBound");
|
|
2222
|
+
this.viewer = t, this.renderer = new In(this.viewer.scene), this.hoverPicker = new yn(this.viewer.scene, s), this.removeCameraListener = this.viewer.camera.changed.addEventListener(() => {
|
|
2223
|
+
this.hoverPicker.invalidate(), this.clearHover({ keepPointer: !0 }), this.scheduleHoverIndexRebuild();
|
|
2224
|
+
}), this.onPointerMoveBound = (o) => this.onPointerMove(o), this.onPointerLeaveBound = () => this.clearHover(), this.onPointerDownBound = () => this.clearHover(), this.onWheelBound = () => this.clearHover();
|
|
2225
|
+
const n = this.viewer.scene.canvas;
|
|
2226
|
+
n.addEventListener("pointermove", this.onPointerMoveBound), n.addEventListener("pointerleave", this.onPointerLeaveBound), n.addEventListener("pointerdown", this.onPointerDownBound), n.addEventListener("wheel", this.onWheelBound, { passive: !0 });
|
|
2227
|
+
}
|
|
2228
|
+
setTracks(t) {
|
|
2229
|
+
if (t.length !== 0) {
|
|
2230
|
+
for (const s of t) {
|
|
2231
|
+
const n = Tn(s);
|
|
2232
|
+
this.records.set(n.targetId, n);
|
|
2233
|
+
}
|
|
2234
|
+
this.refresh();
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
getTracks(t) {
|
|
2238
|
+
var o;
|
|
2239
|
+
const s = t != null && t.length ? t : Array.from(this.records.keys()), n = [];
|
|
2240
|
+
for (const r of s) {
|
|
2241
|
+
const l = this.records.get(r);
|
|
2242
|
+
l && n.push({
|
|
2243
|
+
targetId: l.targetId,
|
|
2244
|
+
visible: l.visible,
|
|
2245
|
+
pointList: (o = l.pointList) == null ? void 0 : o.map(ii),
|
|
2246
|
+
trackLine: l.trackLine
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
return n;
|
|
2250
|
+
}
|
|
2251
|
+
showTracks(t) {
|
|
2252
|
+
this.setVisible(t, !0);
|
|
2253
|
+
}
|
|
2254
|
+
hideTracks(t) {
|
|
2255
|
+
this.setVisible(t, !1);
|
|
2256
|
+
}
|
|
2257
|
+
removeTracks(t) {
|
|
2258
|
+
if (t.length !== 0) {
|
|
2259
|
+
for (const s of t)
|
|
2260
|
+
this.records.delete(s);
|
|
2261
|
+
this.refresh();
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
clearTracks() {
|
|
2265
|
+
this.records.size !== 0 && (this.records.clear(), this.refresh());
|
|
2266
|
+
}
|
|
2267
|
+
setRenderPacket(t) {
|
|
2268
|
+
this.lastPacket = t;
|
|
2269
|
+
const s = this.getVisibleRecords();
|
|
2270
|
+
if (s.length === 0)
|
|
2271
|
+
return;
|
|
2272
|
+
const n = new Set(s.map((r) => r.targetId)), o = /* @__PURE__ */ new Set();
|
|
2273
|
+
for (let r = 0; r < t.ids.length; r++) {
|
|
2274
|
+
const l = t.ids[r];
|
|
2275
|
+
if (!l || t.count[r] !== 1 || !n.has(l))
|
|
2276
|
+
continue;
|
|
2277
|
+
const h = this.records.get(l);
|
|
2278
|
+
if (!h)
|
|
2279
|
+
continue;
|
|
2280
|
+
const c = f.fromDegrees(t.lon[r], t.lat[r], t.height[r]);
|
|
2281
|
+
h.currentPosition ? (f.clone(h.currentPosition, h.motionFrom), f.clone(c, h.motionTo), h.motionElapsedSec = 0, h.motionDurationSec = Math.max(0, t.moveDurationMs[r] / 1e3)) : (h.currentPosition = f.clone(c), f.clone(c, h.motionFrom), f.clone(c, h.motionTo), h.motionElapsedSec = 0, h.motionDurationSec = 0), o.add(l);
|
|
2282
|
+
}
|
|
2283
|
+
for (const r of s)
|
|
2284
|
+
o.has(r.targetId) || (r.currentPosition = null, r.motionElapsedSec = 0, r.motionDurationSec = 0);
|
|
2285
|
+
this.renderer.updateConnectors(this.toRenderRecords(s));
|
|
2286
|
+
}
|
|
2287
|
+
update(t) {
|
|
2288
|
+
const s = this.getVisibleRecords();
|
|
2289
|
+
if (s.length === 0)
|
|
2290
|
+
return;
|
|
2291
|
+
let n = !1;
|
|
2292
|
+
for (const o of s) {
|
|
2293
|
+
if (!o.currentPosition || o.motionDurationSec <= 0)
|
|
2294
|
+
continue;
|
|
2295
|
+
o.motionElapsedSec = Math.min(o.motionElapsedSec + t, o.motionDurationSec);
|
|
2296
|
+
const r = o.motionDurationSec <= 0 ? 1 : o.motionElapsedSec / o.motionDurationSec;
|
|
2297
|
+
f.lerp(o.motionFrom, o.motionTo, Rn(r), o.currentPosition), o.motionElapsedSec < o.motionDurationSec ? n = !0 : o.motionDurationSec = 0;
|
|
2298
|
+
}
|
|
2299
|
+
n && this.renderer.updateConnectors(this.toRenderRecords(s));
|
|
2300
|
+
}
|
|
2301
|
+
destroy() {
|
|
2302
|
+
this.hoverRafId && cancelAnimationFrame(this.hoverRafId), this.rebuildHoverIndexTimer && window.clearTimeout(this.rebuildHoverIndexTimer), this.clearHover();
|
|
2303
|
+
const t = this.viewer.scene.canvas;
|
|
2304
|
+
t.removeEventListener("pointermove", this.onPointerMoveBound), t.removeEventListener("pointerleave", this.onPointerLeaveBound), t.removeEventListener("pointerdown", this.onPointerDownBound), t.removeEventListener("wheel", this.onWheelBound), this.removeCameraListener(), this.renderer.destroy(), this.clear();
|
|
2305
|
+
}
|
|
2306
|
+
setVisible(t, s) {
|
|
2307
|
+
if (t.length === 0)
|
|
2308
|
+
return;
|
|
2309
|
+
let n = !1;
|
|
2310
|
+
for (const o of t) {
|
|
2311
|
+
const r = this.records.get(o);
|
|
2312
|
+
!r || r.visible === s || (r.visible = s, n = !0);
|
|
2313
|
+
}
|
|
2314
|
+
n && this.refresh();
|
|
2315
|
+
}
|
|
2316
|
+
refresh() {
|
|
2317
|
+
const t = this.getVisibleRecords();
|
|
2318
|
+
this.renderer.setTracks(this.toRenderRecords(t)), this.hoverPicker.setPoints(t.flatMap(
|
|
2319
|
+
(s) => s.cartesianPoints.map((n, o) => ({
|
|
2320
|
+
targetId: s.targetId,
|
|
2321
|
+
pointIndex: o,
|
|
2322
|
+
point: s.normalizedPoints[o],
|
|
2323
|
+
position: n
|
|
2324
|
+
}))
|
|
2325
|
+
)), this.clearHover(), this.lastPacket && this.setRenderPacket(this.lastPacket);
|
|
2326
|
+
}
|
|
2327
|
+
getVisibleRecords() {
|
|
2328
|
+
const t = [];
|
|
2329
|
+
for (const s of this.records.values())
|
|
2330
|
+
s.visible && s.normalizedPoints.length > 0 && t.push(s);
|
|
2331
|
+
return t;
|
|
2332
|
+
}
|
|
2333
|
+
toRenderRecords(t) {
|
|
2334
|
+
return t.map((s) => ({
|
|
2335
|
+
targetId: s.targetId,
|
|
2336
|
+
points: s.normalizedPoints,
|
|
2337
|
+
cartesianPoints: s.cartesianPoints,
|
|
2338
|
+
currentPosition: s.currentPosition
|
|
2339
|
+
}));
|
|
2340
|
+
}
|
|
2341
|
+
onPointerMove(t) {
|
|
2342
|
+
const s = this.viewer.scene.canvas.getBoundingClientRect();
|
|
2343
|
+
this.lastPointerPosition = new J(t.clientX - s.left, t.clientY - s.top), this.scheduleHoverPick(this.lastPointerPosition);
|
|
2344
|
+
}
|
|
2345
|
+
flushHoverPick() {
|
|
2346
|
+
if (this.hoverRafId = 0, !this.hoverPosition)
|
|
2347
|
+
return;
|
|
2348
|
+
const t = this.hoverPicker.pick(this.hoverPosition), s = t ? `${t.targetId}:${t.pointIndex}` : "";
|
|
2349
|
+
s !== this.currentHoverKey && (this.currentHoverKey = s, this.emit("hover", t));
|
|
2350
|
+
}
|
|
2351
|
+
clearHover(t = {}) {
|
|
2352
|
+
this.hoverPosition = null, t.keepPointer || (this.lastPointerPosition = null), this.currentHoverKey && (this.currentHoverKey = "", this.emit("hover", null));
|
|
2353
|
+
}
|
|
2354
|
+
scheduleHoverPick(t) {
|
|
2355
|
+
this.hoverPosition = J.clone(t, this.hoverPosition ?? new J()), !this.hoverRafId && (this.hoverRafId = requestAnimationFrame(() => this.flushHoverPick()));
|
|
2356
|
+
}
|
|
2357
|
+
scheduleHoverPickFromLastPointer() {
|
|
2358
|
+
this.lastPointerPosition && (this.hoverRafId || (this.hoverRafId = requestAnimationFrame(() => {
|
|
2359
|
+
this.hoverRafId = 0, this.lastPointerPosition && this.scheduleHoverPick(this.lastPointerPosition);
|
|
2360
|
+
})));
|
|
2361
|
+
}
|
|
2362
|
+
scheduleHoverIndexRebuild() {
|
|
2363
|
+
this.rebuildHoverIndexTimer && window.clearTimeout(this.rebuildHoverIndexTimer), this.rebuildHoverIndexTimer = window.setTimeout(() => {
|
|
2364
|
+
this.rebuildHoverIndexTimer = 0, this.hoverPicker.rebuild(), this.scheduleHoverPickFromLastPointer();
|
|
2365
|
+
}, 120);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
function Tn(i) {
|
|
2369
|
+
var s;
|
|
2370
|
+
if (!i || typeof i != "object")
|
|
2371
|
+
throw new Error("track must be an object.");
|
|
2372
|
+
if (typeof i.targetId != "string" || i.targetId.length === 0)
|
|
2373
|
+
throw new Error("track.targetId must be a non-empty string.");
|
|
2374
|
+
const e = Cn(i.pointList), t = e.length > 0 ? e : bn(i.trackLine, i.targetId);
|
|
2375
|
+
return {
|
|
2376
|
+
targetId: i.targetId,
|
|
2377
|
+
visible: i.visible ?? !0,
|
|
2378
|
+
pointList: (s = i.pointList) == null ? void 0 : s.map(ii),
|
|
2379
|
+
trackLine: i.trackLine,
|
|
2380
|
+
normalizedPoints: t,
|
|
2381
|
+
cartesianPoints: t.map((n) => f.fromDegrees(n.lon, n.lat, n.height)),
|
|
2382
|
+
currentPosition: null,
|
|
2383
|
+
motionFrom: f.clone(f.ZERO),
|
|
2384
|
+
motionTo: f.clone(f.ZERO),
|
|
2385
|
+
motionElapsedSec: 0,
|
|
2386
|
+
motionDurationSec: 0
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
function Cn(i) {
|
|
2390
|
+
if (!(i != null && i.length))
|
|
2391
|
+
return [];
|
|
2392
|
+
const e = [];
|
|
2393
|
+
for (const t of i) {
|
|
2394
|
+
if (!t || typeof t != "object")
|
|
2395
|
+
continue;
|
|
2396
|
+
const s = Number(t.lon), n = Number(t.lat), o = Number(t.height), r = Pn(t.time);
|
|
2397
|
+
!Number.isFinite(s) || !Number.isFinite(n) || !Number.isFinite(o) || !Number.isFinite(r) || e.push({
|
|
2398
|
+
lon: s,
|
|
2399
|
+
lat: n,
|
|
2400
|
+
height: o,
|
|
2401
|
+
time: r,
|
|
2402
|
+
heading: xt(t.heading),
|
|
2403
|
+
speed: xt(t.speed),
|
|
2404
|
+
source: typeof t.source == "string" && t.source ? t.source : void 0
|
|
2405
|
+
});
|
|
2406
|
+
}
|
|
2407
|
+
return e.sort((t, s) => t.time - s.time), e;
|
|
2408
|
+
}
|
|
2409
|
+
function bn(i, e) {
|
|
2410
|
+
if (!i)
|
|
2411
|
+
return [];
|
|
2412
|
+
const t = /^\s*LINESTRING(?:\s+Z)?\s*\((.+)\)\s*$/i.exec(i);
|
|
2413
|
+
if (!t)
|
|
2414
|
+
return console.warn(`[tracks] ignored invalid LINESTRING for ${e}`), [];
|
|
2415
|
+
const s = [], n = t[1].split(",");
|
|
2416
|
+
for (let o = 0; o < n.length; o++) {
|
|
2417
|
+
const r = n[o].trim().split(/\s+/).map(Number);
|
|
2418
|
+
r.length < 2 || !Number.isFinite(r[0]) || !Number.isFinite(r[1]) || s.push({
|
|
2419
|
+
lon: r[0],
|
|
2420
|
+
lat: r[1],
|
|
2421
|
+
height: Number.isFinite(r[2]) ? r[2] : 0,
|
|
2422
|
+
time: o,
|
|
2423
|
+
source: "trackLine"
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
return s.length === 0 && console.warn(`[tracks] ignored empty LINESTRING for ${e}`), s;
|
|
2427
|
+
}
|
|
2428
|
+
function Pn(i) {
|
|
2429
|
+
if (typeof i == "number")
|
|
2430
|
+
return i;
|
|
2431
|
+
if (typeof i == "string") {
|
|
2432
|
+
const e = Date.parse(i);
|
|
2433
|
+
if (Number.isFinite(e))
|
|
2434
|
+
return e;
|
|
2435
|
+
const t = Number(i);
|
|
2436
|
+
return Number.isFinite(t) ? t : Number.NaN;
|
|
2437
|
+
}
|
|
2438
|
+
return Number.NaN;
|
|
2439
|
+
}
|
|
2440
|
+
function xt(i) {
|
|
2441
|
+
if (i == null)
|
|
2442
|
+
return;
|
|
2443
|
+
const e = Number(i);
|
|
2444
|
+
return Number.isFinite(e) ? e : void 0;
|
|
2445
|
+
}
|
|
2446
|
+
function ii(i) {
|
|
2447
|
+
return {
|
|
2448
|
+
lon: i.lon,
|
|
2449
|
+
lat: i.lat,
|
|
2450
|
+
height: i.height,
|
|
2451
|
+
time: i.time,
|
|
2452
|
+
heading: i.heading,
|
|
2453
|
+
speed: i.speed,
|
|
2454
|
+
source: i.source
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
function Rn(i) {
|
|
2458
|
+
const e = A.clamp(i, 0, 1);
|
|
2459
|
+
return 1 - Math.pow(1 - e, 3);
|
|
2460
|
+
}
|
|
2461
|
+
function kn() {
|
|
2462
|
+
return new Worker("/assets/renderWorker-118e8f3b.js");
|
|
2463
|
+
}
|
|
2464
|
+
const An = 40, Tt = 2, Ct = 1.25, Ln = 0.75, Hn = 0.3, bt = 0.35, Pt = 16, Rt = 200, Dn = 200, kt = 120, En = 512, _n = 48, On = 32, Bn = 64;
|
|
2465
|
+
class Nn extends qe {
|
|
2466
|
+
constructor(t, s) {
|
|
2467
|
+
var n, o, r, l, h, c, m, u, v;
|
|
2468
|
+
super();
|
|
2469
|
+
a(this, "config");
|
|
2470
|
+
a(this, "render");
|
|
2471
|
+
a(this, "models");
|
|
2472
|
+
a(this, "symbols");
|
|
2473
|
+
a(this, "selection");
|
|
2474
|
+
a(this, "tracks");
|
|
2475
|
+
/** 引擎就绪信号:内部 Web Worker 完成 init 握手后 resolve。可在加载依赖底座的其它组件前 await。 */
|
|
2476
|
+
a(this, "ready");
|
|
2477
|
+
a(this, "nodes", {
|
|
2478
|
+
visibleCount: 0,
|
|
2479
|
+
bufferCount: 0,
|
|
2480
|
+
renderedCount: 0,
|
|
2481
|
+
clusterCount: 0,
|
|
2482
|
+
lastMergeRadius: 0,
|
|
2483
|
+
pointRenderCount: 0,
|
|
2484
|
+
mergedPointRenderCount: 0,
|
|
2485
|
+
plainPointRenderCount: 0,
|
|
2486
|
+
lowModelRenderCount: 0,
|
|
2487
|
+
highModelRenderCount: 0,
|
|
2488
|
+
mergedLowModelRenderCount: 0,
|
|
2489
|
+
mergedHighModelRenderCount: 0,
|
|
2490
|
+
forcedPointMode: !1,
|
|
2491
|
+
level: 0,
|
|
2492
|
+
outsideLevel: 0
|
|
2493
|
+
});
|
|
2494
|
+
a(this, "quality", { tier: "high" });
|
|
2495
|
+
a(this, "worker");
|
|
2496
|
+
a(this, "resolveReady");
|
|
2497
|
+
a(this, "readyResolved", !1);
|
|
2498
|
+
a(this, "commitIntervalMs");
|
|
2499
|
+
a(this, "commitTimer", null);
|
|
2500
|
+
a(this, "rafId", 0);
|
|
2501
|
+
a(this, "paused", !1);
|
|
2502
|
+
a(this, "destroyed", !1);
|
|
2503
|
+
a(this, "total", 0);
|
|
2504
|
+
a(this, "commitRequestId", 0);
|
|
2505
|
+
a(this, "viewportRequestId", 0);
|
|
2506
|
+
a(this, "dataRevision", 0);
|
|
2507
|
+
a(this, "viewportRequestRevisions", /* @__PURE__ */ new Map());
|
|
2508
|
+
a(this, "globalViewportRequestIds", /* @__PURE__ */ new Set());
|
|
2509
|
+
a(this, "globalViewportRevision", -1);
|
|
2510
|
+
a(this, "targetQueryRequestId", 0);
|
|
2511
|
+
a(this, "targetQueryResolvers", /* @__PURE__ */ new Map());
|
|
2512
|
+
a(this, "viewportInFlight", !1);
|
|
2513
|
+
a(this, "viewportDirty", !1);
|
|
2514
|
+
a(this, "lastCommitSubmitAt", 0);
|
|
2515
|
+
a(this, "lastFrameAt", _());
|
|
2516
|
+
a(this, "lastPredictionViewportAt", 0);
|
|
2517
|
+
a(this, "lastSymbolsUpdateAt", 0);
|
|
2518
|
+
a(this, "stagedUpserts", 0);
|
|
2519
|
+
a(this, "stagedBatches", 0);
|
|
2520
|
+
a(this, "removeCameraListener");
|
|
2521
|
+
a(this, "inputHandler");
|
|
2522
|
+
a(this, "selectedIds", /* @__PURE__ */ new Set());
|
|
2523
|
+
a(this, "selectedTargets", /* @__PURE__ */ new Map());
|
|
2524
|
+
a(this, "hoverRequestSerial", 0);
|
|
2525
|
+
a(this, "pickRequestSerial", 0);
|
|
2526
|
+
a(this, "contextMenuRequestSerial", 0);
|
|
2527
|
+
a(this, "hoverPickPosition", null);
|
|
2528
|
+
a(this, "hoverPickRafId", 0);
|
|
2529
|
+
a(this, "lastHoverPickAt", 0);
|
|
2530
|
+
a(this, "lastHoverPointerSample", null);
|
|
2531
|
+
a(this, "hoverPointerSpeedPxPerMs", 0);
|
|
2532
|
+
a(this, "pointerButtonsMask", 0);
|
|
2533
|
+
a(this, "wheelSuppressPickUntil", 0);
|
|
2534
|
+
a(this, "cameraMoving", !1);
|
|
2535
|
+
a(this, "cameraMoveTrailingTimer", 0);
|
|
2536
|
+
a(this, "wheelSuppressResetTimer", 0);
|
|
2537
|
+
a(this, "cameraViewportThrottleTimer", 0);
|
|
2538
|
+
a(this, "lastCameraViewportAt", 0);
|
|
2539
|
+
a(this, "lastHoverId", null);
|
|
2540
|
+
a(this, "hoverTargetCache", /* @__PURE__ */ new Map());
|
|
2541
|
+
a(this, "labelDataById", /* @__PURE__ */ new Map());
|
|
2542
|
+
a(this, "latestRenderPacket", null);
|
|
2543
|
+
a(this, "hoverPickIndex", null);
|
|
2544
|
+
a(this, "hoverPickWarmupRafId", 0);
|
|
2545
|
+
a(this, "cameraRevision", 0);
|
|
2546
|
+
a(this, "labelConfig");
|
|
2547
|
+
this.viewer = t, this.config = xi(s), this.labelConfig = this.config.label, this.commitIntervalMs = this.config.data.commitIntervalMs, this.render = new Hs(t.scene, this.config.fadeMs, {
|
|
2548
|
+
targetTypes: this.config.renderTypes.map(Be),
|
|
2549
|
+
label: this.labelConfig,
|
|
2550
|
+
labelTextResolver: (d) => this.nameplateText(d)
|
|
2551
|
+
}), this.selection = new pn(t.scene, this.config.renderTypes), this.tracks = new xn(t, this.config.pick.pixelThreshold), this.config.groundSymbols && (this.symbols = new Qt(t.scene, {
|
|
2552
|
+
typeStyles: this.config.renderTypes.map(Be),
|
|
2553
|
+
capacity: this.config.poolSize,
|
|
2554
|
+
pixelSize: this.config.groundSymbolPixelSize
|
|
2555
|
+
}), t.scene.primitives.add(this.symbols), this.render.setDirectionalHandledExternally(!0)), this.models = new fs(
|
|
2556
|
+
t,
|
|
2557
|
+
this.config.renderTypes.map(Be),
|
|
2558
|
+
this.config.frame.maxLowModelRenderItems,
|
|
2559
|
+
Math.max(this.config.animatedCapacity, this.config.frame.maxModelRenderItems),
|
|
2560
|
+
this.config.animatedCapacity,
|
|
2561
|
+
this.config.fadeMs
|
|
2562
|
+
), this.render.setAnchorPositionResolver((d, p) => {
|
|
2563
|
+
var g;
|
|
2564
|
+
return (g = this.getRenderedTargetFrame(d, p)) == null ? void 0 : g.position;
|
|
2565
|
+
}), this.ready = new Promise((d) => {
|
|
2566
|
+
this.resolveReady = d;
|
|
2567
|
+
}), this.worker = new kn(), this.worker.onmessage = (d) => this.handleWorkerMessage(d.data), this.worker.postMessage({
|
|
2568
|
+
type: "init",
|
|
2569
|
+
config: {
|
|
2570
|
+
maxVisible: ((n = this.config.merge) == null ? void 0 : n.maxVisible) ?? this.config.poolSize,
|
|
2571
|
+
rootLimit: ((o = this.config.merge) == null ? void 0 : o.globalRootLimit) ?? 500,
|
|
2572
|
+
maxLevels: ((r = this.config.merge) == null ? void 0 : r.globalMaxLevels) ?? 64,
|
|
2573
|
+
cameraMergeBaseHeight: ((l = this.config.merge) == null ? void 0 : l.cameraMergeBaseHeight) ?? 1e5,
|
|
2574
|
+
cameraMergeStepHeight: ((h = this.config.merge) == null ? void 0 : h.cameraMergeStepHeight) ?? 1e4,
|
|
2575
|
+
cameraMergeStepRadius: ((c = this.config.merge) == null ? void 0 : c.cameraMergeStepRadius) ?? 100,
|
|
2576
|
+
globalViewportHeight: ((m = this.config.merge) == null ? void 0 : m.globalViewportHeight) ?? 45e4,
|
|
2577
|
+
globalCacheIntervalMs: ((u = this.config.merge) == null ? void 0 : u.globalRebuildIntervalMs) ?? 3e5,
|
|
2578
|
+
innerRatio: ((v = this.config.merge) == null ? void 0 : v.innerRatio) ?? 0.6,
|
|
2579
|
+
viewportBufferRatio: this.config.cull.viewportBufferRatio,
|
|
2580
|
+
viewportBufferMinMeters: this.config.cull.viewportBufferMinMeters,
|
|
2581
|
+
pointAbove: this.config.lod.pointAbove,
|
|
2582
|
+
animatedBelow: this.config.lod.animatedBelow,
|
|
2583
|
+
predictSeconds: this.config.predictSeconds,
|
|
2584
|
+
predictFitSeconds: this.config.predictFitSeconds,
|
|
2585
|
+
targetTypes: this.config.renderTypes.map((d, p) => ({
|
|
2586
|
+
type: d.type,
|
|
2587
|
+
category: p,
|
|
2588
|
+
targetDomain: d.targetDomain,
|
|
2589
|
+
forceHighModelInLowLod: d.forceHighModelInLowLod,
|
|
2590
|
+
iconPath: d.iconPath,
|
|
2591
|
+
defaultColor: Xn(d.defaultColor),
|
|
2592
|
+
smoothMove: d.smoothMove,
|
|
2593
|
+
smoothMoveMinCameraHeight: d.smoothMoveMinCameraHeight,
|
|
2594
|
+
smoothMoveDurationMs: d.smoothMoveDurationMs,
|
|
2595
|
+
predictMove: d.predictMove,
|
|
2596
|
+
predictMinCameraHeight: d.predictMinCameraHeight,
|
|
2597
|
+
predictSeconds: d.predictSeconds,
|
|
2598
|
+
predictFitSeconds: d.predictFitSeconds
|
|
2599
|
+
}))
|
|
2600
|
+
}
|
|
2601
|
+
}), this.removeCameraListener = this.viewer.camera.changed.addEventListener(() => {
|
|
2602
|
+
this.requestViewportThrottled(), this.noteCameraMovement();
|
|
2603
|
+
}), this.inputHandler = new Wt(this.viewer.scene.canvas), this.inputHandler.setInputAction((d) => {
|
|
2604
|
+
this.handleContextMenuAt(d.position);
|
|
2605
|
+
}, N.RIGHT_CLICK), this.config.pick.enabled && (this.inputHandler.setInputAction((d) => {
|
|
2606
|
+
this.handlePickAt(d.position);
|
|
2607
|
+
}, N.LEFT_CLICK), this.config.pick.hover && (this.bindHoverSuppressionInput(), this.inputHandler.setInputAction((d) => {
|
|
2608
|
+
this.scheduleHoverPick(d.endPosition);
|
|
2609
|
+
}, N.MOUSE_MOVE))), this.startCommitLoop(), this.startRenderLoop();
|
|
2610
|
+
}
|
|
2611
|
+
get targetCount() {
|
|
2612
|
+
return this.total;
|
|
2613
|
+
}
|
|
2614
|
+
setData(t) {
|
|
2615
|
+
if (this.destroyed)
|
|
2616
|
+
return;
|
|
2617
|
+
this.replaceLabelData(t);
|
|
2618
|
+
const s = this.postWithTiming({ type: "set-data", targets: t });
|
|
2619
|
+
this.stagedUpserts = t.length, this.stagedBatches = 1, this.emit("perf", { phase: "worker-submit", full: t.length, batches: 1, upserts: t.length, submitMs: s }), this.config.data.leading && this.commitNow();
|
|
2620
|
+
}
|
|
2621
|
+
applyIncremental(t) {
|
|
2622
|
+
var r, l;
|
|
2623
|
+
if (this.destroyed)
|
|
2624
|
+
return;
|
|
2625
|
+
this.applyLabelIncremental(t);
|
|
2626
|
+
const s = ((r = t.upserts) == null ? void 0 : r.length) ?? 0, n = ((l = t.removes) == null ? void 0 : l.length) ?? 0, o = this.postWithTiming({ type: "incremental", payload: t });
|
|
2627
|
+
this.stagedUpserts += s, this.stagedBatches++, this.emit("perf", { phase: "worker-submit", full: this.total, batches: this.stagedBatches, upserts: s, submitMs: o }), this.config.data.leading && this.total === 0 && this.commitNow(), (s || n) && this.emit("dirty", {
|
|
2628
|
+
added: t.upserts ?? [],
|
|
2629
|
+
updated: [],
|
|
2630
|
+
removed: t.removes ?? []
|
|
2631
|
+
});
|
|
2632
|
+
}
|
|
2633
|
+
applyRealtimeUpsert(t) {
|
|
2634
|
+
this.destroyed || t.length === 0 || (this.upsertLabelData(t), this.worker.postMessage({ type: "realtime-upsert", targets: t }));
|
|
2635
|
+
}
|
|
2636
|
+
applyRealtimeRemove(t) {
|
|
2637
|
+
this.destroyed || t.length === 0 || (this.removeLabelData(t), this.worker.postMessage({ type: "realtime-remove", ids: t.slice() }));
|
|
2638
|
+
}
|
|
2639
|
+
applyPacked(t) {
|
|
2640
|
+
var r;
|
|
2641
|
+
if (this.destroyed)
|
|
2642
|
+
return;
|
|
2643
|
+
t.replacePending && this.labelDataById.clear();
|
|
2644
|
+
const s = Fn(t), n = this.postWithTiming({ type: "stage-packed", payload: t }, s), o = ((r = t.ids) == null ? void 0 : r.length) ?? t.lon.length;
|
|
2645
|
+
this.stagedUpserts = t.replacePending ? o : this.stagedUpserts + o, this.stagedBatches = t.replacePending ? 1 : this.stagedBatches + 1, this.emit("perf", { phase: "worker-submit", full: this.total, batches: this.stagedBatches, upserts: o, submitMs: n }), this.config.data.leading && this.total === 0 && this.commitNow();
|
|
2646
|
+
}
|
|
2647
|
+
applyTargetStyle(t) {
|
|
2648
|
+
this.destroyed || t.length === 0 || this.worker.postMessage({ type: "style-patch", patches: t });
|
|
2649
|
+
}
|
|
2650
|
+
setBoxedTargetIds(t) {
|
|
2651
|
+
this.setSelectedTargetIds(t), this.viewer.scene.requestRender();
|
|
2652
|
+
}
|
|
2653
|
+
setLabelConfig(t) {
|
|
2654
|
+
this.labelConfig = Ke({ ...this.labelConfig, ...t }), this.render.setLabelOptions(this.labelConfig, (s) => this.nameplateText(s));
|
|
2655
|
+
}
|
|
2656
|
+
async selectTarget(t, s = !0) {
|
|
2657
|
+
s && this.clearSelection(!1), this.selectedIds.add(t), this.selection.setSelectedIds(Array.from(this.selectedIds));
|
|
2658
|
+
const n = await this.getPickedNode(t);
|
|
2659
|
+
return n && this.selectedTargets.set(t, n), this.emitSelection(), n;
|
|
2660
|
+
}
|
|
2661
|
+
async selectTargets(t, s = !0) {
|
|
2662
|
+
s && this.clearSelection(!1);
|
|
2663
|
+
for (const o of t)
|
|
2664
|
+
this.selectedIds.add(o);
|
|
2665
|
+
this.selection.setSelectedIds(Array.from(this.selectedIds));
|
|
2666
|
+
const n = await Promise.all(t.map((o) => this.getPickedNode(o)));
|
|
2667
|
+
for (const o of n)
|
|
2668
|
+
o && this.selectedTargets.set(o.id, o);
|
|
2669
|
+
return this.emitSelection(), n.filter((o) => o != null);
|
|
2670
|
+
}
|
|
2671
|
+
unselectTarget(t) {
|
|
2672
|
+
this.selectedIds.delete(t), this.selectedTargets.delete(t), this.selection.setSelectedIds(Array.from(this.selectedIds)), this.emitSelection();
|
|
2673
|
+
}
|
|
2674
|
+
clearSelection(t = !0) {
|
|
2675
|
+
this.selectedIds.clear(), this.selectedTargets.clear(), this.selection.setSelectedIds([]), t && this.emitSelection();
|
|
2676
|
+
}
|
|
2677
|
+
flushNow() {
|
|
2678
|
+
this.commitNow();
|
|
2679
|
+
}
|
|
2680
|
+
getTargetSnapshot(t) {
|
|
2681
|
+
if (this.destroyed)
|
|
2682
|
+
return Promise.resolve(null);
|
|
2683
|
+
const s = ++this.targetQueryRequestId;
|
|
2684
|
+
return new Promise((n) => {
|
|
2685
|
+
this.targetQueryResolvers.set(s, n), this.worker.postMessage({ type: "target-query", requestId: s, id: t });
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2688
|
+
pause() {
|
|
2689
|
+
this.paused = !0;
|
|
2690
|
+
}
|
|
2691
|
+
resume() {
|
|
2692
|
+
this.paused = !1, this.requestViewport("resume");
|
|
2693
|
+
}
|
|
2694
|
+
destroy() {
|
|
2695
|
+
var t, s;
|
|
2696
|
+
this.destroyed || (this.destroyed = !0, this.readyResolved || (this.readyResolved = !0, this.resolveReady()), this.commitTimer != null && window.clearInterval(this.commitTimer), this.rafId && cancelAnimationFrame(this.rafId), this.hoverPickWarmupRafId && cancelAnimationFrame(this.hoverPickWarmupRafId), this.cancelPendingHoverPick(), this.cameraMoveTrailingTimer && window.clearTimeout(this.cameraMoveTrailingTimer), this.wheelSuppressResetTimer && window.clearTimeout(this.wheelSuppressResetTimer), this.cameraViewportThrottleTimer && window.clearTimeout(this.cameraViewportThrottleTimer), (t = this.removeCameraListener) == null || t.call(this), this.worker.postMessage({ type: "destroy" }), this.worker.terminate(), this.models.destroy(), this.tracks.destroy(), this.selection.destroy(), this.render.destroy(), this.symbols && this.viewer.scene.primitives.remove(this.symbols), (s = this.inputHandler) == null || s.destroy(), this.clear());
|
|
2697
|
+
}
|
|
2698
|
+
startCommitLoop() {
|
|
2699
|
+
this.commitIntervalMs <= 0 || (this.commitTimer = window.setInterval(() => this.commitNow(), this.commitIntervalMs));
|
|
2700
|
+
}
|
|
2701
|
+
startRenderLoop() {
|
|
2702
|
+
const t = (s) => {
|
|
2703
|
+
if (this.destroyed)
|
|
2704
|
+
return;
|
|
2705
|
+
const n = Math.max(0, (s - this.lastFrameAt) / 1e3);
|
|
2706
|
+
this.lastFrameAt = s;
|
|
2707
|
+
const o = _();
|
|
2708
|
+
this.isModelRenderActive() && this.models.update(n), this.render.update(n), this.selection.update(n), this.tracks.update(n);
|
|
2709
|
+
const r = _() - o;
|
|
2710
|
+
r >= 16 && this.emit("perf", {
|
|
2711
|
+
phase: "tick-slow",
|
|
2712
|
+
at: _(),
|
|
2713
|
+
totalMs: r,
|
|
2714
|
+
flushMs: 0,
|
|
2715
|
+
ingestMs: 0,
|
|
2716
|
+
scanMs: 0,
|
|
2717
|
+
visualMs: 0,
|
|
2718
|
+
motionMs: 0,
|
|
2719
|
+
renderMs: r,
|
|
2720
|
+
rendered: this.nodes.renderedCount
|
|
2721
|
+
}), this.viewportDirty && !this.viewportInFlight ? (this.viewportDirty = !1, this.requestViewport("dirty-frame")) : this.shouldRefreshPredictionViewport(s) && this.requestViewport("predict-frame"), this.rafId = requestAnimationFrame(t);
|
|
2722
|
+
};
|
|
2723
|
+
this.rafId = requestAnimationFrame(t);
|
|
2724
|
+
}
|
|
2725
|
+
commitNow() {
|
|
2726
|
+
this.destroyed || this.paused || (this.lastCommitSubmitAt = _(), this.worker.postMessage({ type: "commit", requestId: ++this.commitRequestId }));
|
|
2727
|
+
}
|
|
2728
|
+
// 相机移动触发的视口裁剪做 leading+trailing 节流:立即响应一次,期间的连续
|
|
2729
|
+
// 事件合并,停止/间隔满足后再补一次 trailing,确保最终画面与相机一致。
|
|
2730
|
+
requestViewportThrottled() {
|
|
2731
|
+
if (this.destroyed || this.paused)
|
|
2732
|
+
return;
|
|
2733
|
+
const t = _(), s = t - this.lastCameraViewportAt;
|
|
2734
|
+
if (s >= kt) {
|
|
2735
|
+
this.lastCameraViewportAt = t, this.requestViewport("camera");
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
this.cameraViewportThrottleTimer || (this.cameraViewportThrottleTimer = window.setTimeout(() => {
|
|
2739
|
+
this.cameraViewportThrottleTimer = 0, this.lastCameraViewportAt = _(), this.requestViewport("camera-trailing");
|
|
2740
|
+
}, kt - s));
|
|
2741
|
+
}
|
|
2742
|
+
requestViewport(t) {
|
|
2743
|
+
var v, d;
|
|
2744
|
+
if (this.destroyed || this.paused)
|
|
2745
|
+
return;
|
|
2746
|
+
const s = this.viewer.scene.camera.positionCartographic, n = s.height, o = A.toDegrees(s.longitude), r = A.toDegrees(s.latitude), l = A.toDegrees(this.viewer.camera.pitch), h = n >= (((v = this.config.merge) == null ? void 0 : v.globalViewportHeight) ?? 45e4);
|
|
2747
|
+
if (h && this.globalViewportRevision === this.dataRevision && !this.viewportInFlight)
|
|
2748
|
+
return;
|
|
2749
|
+
if (this.viewportInFlight) {
|
|
2750
|
+
this.viewportDirty = !0;
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
this.viewportInFlight = !0;
|
|
2754
|
+
const c = ++this.viewportRequestId;
|
|
2755
|
+
this.viewportRequestRevisions.set(c, this.dataRevision), h && this.globalViewportRequestIds.add(c);
|
|
2756
|
+
const m = h ? { west: -180, east: 180, south: -85, north: 85 } : this.currentBounds(), u = h ? void 0 : Vn(this.config.horizonCull, n, l);
|
|
2757
|
+
this.worker.postMessage({
|
|
2758
|
+
type: "viewport",
|
|
2759
|
+
requestId: c,
|
|
2760
|
+
bounds: m,
|
|
2761
|
+
global: h,
|
|
2762
|
+
cameraHeight: n,
|
|
2763
|
+
cameraLon: o,
|
|
2764
|
+
cameraLat: r,
|
|
2765
|
+
cameraPitch: l,
|
|
2766
|
+
horizonCullDistance: u,
|
|
2767
|
+
maxRender: ((d = this.config.merge) == null ? void 0 : d.maxVisible) ?? this.config.poolSize
|
|
2768
|
+
});
|
|
2769
|
+
}
|
|
2770
|
+
handleWorkerMessage(t) {
|
|
2771
|
+
if (this.destroyed)
|
|
2772
|
+
return;
|
|
2773
|
+
if (t.type === "ready") {
|
|
2774
|
+
this.readyResolved || (this.readyResolved = !0, this.resolveReady()), this.requestViewport("ready");
|
|
2775
|
+
return;
|
|
2776
|
+
}
|
|
2777
|
+
if (t.type === "input") {
|
|
2778
|
+
this.emit("perf", {
|
|
2779
|
+
phase: "input",
|
|
2780
|
+
kind: t.kind,
|
|
2781
|
+
upserts: t.upserts,
|
|
2782
|
+
removes: t.removes,
|
|
2783
|
+
pendingBatches: t.pendingBatches
|
|
2784
|
+
});
|
|
2785
|
+
return;
|
|
2786
|
+
}
|
|
2787
|
+
if (t.type === "commit-done") {
|
|
2788
|
+
this.total = t.size, this.stagedBatches = 0, this.stagedUpserts = 0, (t.added || t.updated || t.removed) && this.dataRevision++, this.emit("perf", {
|
|
2789
|
+
phase: "worker-done",
|
|
2790
|
+
added: t.added,
|
|
2791
|
+
updated: t.updated,
|
|
2792
|
+
removed: t.removed,
|
|
2793
|
+
size: t.size,
|
|
2794
|
+
computeMs: t.computeMs,
|
|
2795
|
+
roundTripMs: _() - this.lastCommitSubmitAt
|
|
2796
|
+
}), this.emit("packedDirty", {
|
|
2797
|
+
added: void 0,
|
|
2798
|
+
updated: void 0,
|
|
2799
|
+
removed: []
|
|
2800
|
+
}), this.requestViewport("commit");
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
if (t.type === "realtime-done") {
|
|
2804
|
+
this.total = t.size, this.dataRevision++, this.emit("perf", {
|
|
2805
|
+
phase: "worker-done",
|
|
2806
|
+
added: t.upserts,
|
|
2807
|
+
updated: 0,
|
|
2808
|
+
removed: t.removes,
|
|
2809
|
+
size: t.size,
|
|
2810
|
+
computeMs: t.computeMs,
|
|
2811
|
+
roundTripMs: 0
|
|
2812
|
+
}), this.requestViewport("realtime");
|
|
2813
|
+
return;
|
|
2814
|
+
}
|
|
2815
|
+
if (t.type === "style-done") {
|
|
2816
|
+
t.updated > 0 && (this.dataRevision++, this.requestViewport("style"));
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
if (t.type === "target-info") {
|
|
2820
|
+
const o = this.targetQueryResolvers.get(t.requestId);
|
|
2821
|
+
o && (this.targetQueryResolvers.delete(t.requestId), o(t.target));
|
|
2822
|
+
return;
|
|
2823
|
+
}
|
|
2824
|
+
if (t.type === "viewport-cache-ready") {
|
|
2825
|
+
this.globalViewportRevision = -1, this.requestViewport("cache-ready");
|
|
2826
|
+
return;
|
|
2827
|
+
}
|
|
2828
|
+
this.viewportInFlight = !1;
|
|
2829
|
+
const s = this.viewportRequestRevisions.get(t.packet.requestId);
|
|
2830
|
+
this.viewportRequestRevisions.delete(t.packet.requestId);
|
|
2831
|
+
const n = this.globalViewportRequestIds.delete(t.packet.requestId);
|
|
2832
|
+
if (t.packet.requestId < this.viewportRequestId || s !== this.dataRevision) {
|
|
2833
|
+
this.viewportDirty = !1, this.requestViewport("stale-data");
|
|
2834
|
+
return;
|
|
2835
|
+
}
|
|
2836
|
+
n && s != null && (this.globalViewportRevision = s), this.applyRenderPacket(t.packet), this.viewportDirty && (this.viewportDirty = !1, this.requestViewport("queued"));
|
|
2837
|
+
}
|
|
2838
|
+
applyRenderPacket(t) {
|
|
2839
|
+
const s = _();
|
|
2840
|
+
this.latestRenderPacket = t, this.hoverPickIndex = null;
|
|
2841
|
+
const n = this.isModelRenderActive(), o = n ? this.models.setPacket(t) : [];
|
|
2842
|
+
n || this.models.suspend(), this.render.setModelTargetIds(o, n), this.render.setPacket(t), this.updateSymbolsThrottled(t), this.selection.setPacket(t), this.tracks.setRenderPacket(t), this.scheduleHoverPickIndexWarmup(), this.applyStats(t.stats), this.applyActualRenderStats(t, this.models.renderStats()), this.viewer.scene.requestRender();
|
|
2843
|
+
const r = _() - s;
|
|
2844
|
+
(r >= 12 || t.computeMs >= 16) && this.emit("perf", {
|
|
2845
|
+
phase: "tick-slow",
|
|
2846
|
+
at: _(),
|
|
2847
|
+
totalMs: r + t.computeMs,
|
|
2848
|
+
flushMs: 0,
|
|
2849
|
+
ingestMs: 0,
|
|
2850
|
+
scanMs: t.computeMs,
|
|
2851
|
+
visualMs: 0,
|
|
2852
|
+
motionMs: 0,
|
|
2853
|
+
renderMs: r,
|
|
2854
|
+
rendered: t.stats.rendered
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
updateSymbolsThrottled(t) {
|
|
2858
|
+
if (!this.symbols)
|
|
2859
|
+
return;
|
|
2860
|
+
const s = _();
|
|
2861
|
+
this.lastSymbolsUpdateAt > 0 && s - this.lastSymbolsUpdateAt < 1e3 || (this.lastSymbolsUpdateAt = s, this.symbols.setPacket(t));
|
|
2862
|
+
}
|
|
2863
|
+
applyStats(t) {
|
|
2864
|
+
this.nodes.visibleCount = t.rawInView, this.nodes.bufferCount = Math.max(0, t.rawInBuffer - t.rawInView), this.nodes.renderedCount = t.rendered, this.nodes.clusterCount = t.clusters, this.nodes.lastMergeRadius = t.lastMergeRadius, this.nodes.pointRenderCount = t.pointCount, this.nodes.lowModelRenderCount = t.lowModelCount, this.nodes.highModelRenderCount = t.highModelCount, this.nodes.plainPointRenderCount = t.plainPointCount, this.nodes.mergedPointRenderCount = t.mergedPointCount, this.nodes.mergedLowModelRenderCount = t.mergedLowModelCount, this.nodes.mergedHighModelRenderCount = t.mergedHighModelCount, this.nodes.forcedPointMode = t.forcedPointMode, this.nodes.level = t.level, this.nodes.outsideLevel = t.outsideLevel;
|
|
2865
|
+
}
|
|
2866
|
+
applyActualRenderStats(t, s) {
|
|
2867
|
+
const n = s.low + s.high, o = Math.max(0, t.ids.length - n), r = t.stats.clusters;
|
|
2868
|
+
this.nodes.lowModelRenderCount = s.low, this.nodes.highModelRenderCount = s.high, this.nodes.pointRenderCount = o, this.nodes.mergedPointRenderCount = Math.min(o, r), this.nodes.plainPointRenderCount = Math.max(0, o - this.nodes.mergedPointRenderCount), this.nodes.mergedLowModelRenderCount = 0, this.nodes.mergedHighModelRenderCount = 0;
|
|
2869
|
+
}
|
|
2870
|
+
shouldRefreshPredictionViewport(t) {
|
|
2871
|
+
if (this.viewportInFlight || this.paused || this.destroyed || !this.isModelRenderActive() || !this.latestRenderPacket || !zn(this.latestRenderPacket))
|
|
2872
|
+
return !1;
|
|
2873
|
+
const s = 1e3 / Math.max(1, this.config.updateFps);
|
|
2874
|
+
return t - this.lastPredictionViewportAt < s ? !1 : (this.lastPredictionViewportAt = t, !0);
|
|
2875
|
+
}
|
|
2876
|
+
async handlePickAt(t) {
|
|
2877
|
+
const s = this.pickTargetId(t, Pt), n = ++this.pickRequestSerial;
|
|
2878
|
+
if (!s) {
|
|
2879
|
+
this.clearSelection(), this.emit("pick", null);
|
|
2880
|
+
return;
|
|
2881
|
+
}
|
|
2882
|
+
const o = await this.selectTarget(s, !0);
|
|
2883
|
+
n === this.pickRequestSerial && this.emit("pick", o);
|
|
2884
|
+
}
|
|
2885
|
+
async handleContextMenuAt(t) {
|
|
2886
|
+
const s = ++this.contextMenuRequestSerial, n = this.pickTargetId(t, Pt), o = this.pickGroundCartesian(t, new f());
|
|
2887
|
+
let r = null;
|
|
2888
|
+
if (n && (r = this.hoverTargetCache.get(n) ?? await this.getPickedNode(n)), s !== this.contextMenuRequestSerial)
|
|
2889
|
+
return;
|
|
2890
|
+
if (r) {
|
|
2891
|
+
const c = this.getRenderedTargetPosition(r.id, new f()) ?? f.fromDegrees(r.data.lon, r.data.lat, r.data.height, void 0, new f());
|
|
2892
|
+
this.emit("contextmenu", {
|
|
2893
|
+
kind: "target",
|
|
2894
|
+
target: r,
|
|
2895
|
+
screenX: t.x,
|
|
2896
|
+
screenY: t.y,
|
|
2897
|
+
cartesian: c,
|
|
2898
|
+
lon: r.data.lon,
|
|
2899
|
+
lat: r.data.lat,
|
|
2900
|
+
height: r.data.height
|
|
2901
|
+
});
|
|
2902
|
+
return;
|
|
2903
|
+
}
|
|
2904
|
+
if (!o) {
|
|
2905
|
+
this.emit("contextmenu", null);
|
|
2906
|
+
return;
|
|
2907
|
+
}
|
|
2908
|
+
const l = A.toDegrees, h = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(o);
|
|
2909
|
+
this.emit("contextmenu", {
|
|
2910
|
+
kind: "ground",
|
|
2911
|
+
target: null,
|
|
2912
|
+
screenX: t.x,
|
|
2913
|
+
screenY: t.y,
|
|
2914
|
+
cartesian: f.clone(o, new f()),
|
|
2915
|
+
lon: l(h.longitude),
|
|
2916
|
+
lat: l(h.latitude),
|
|
2917
|
+
height: h.height
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
bindHoverSuppressionInput() {
|
|
2921
|
+
var t, s, n, o, r, l, h;
|
|
2922
|
+
(t = this.inputHandler) == null || t.setInputAction(() => {
|
|
2923
|
+
this.pointerButtonsMask |= 1, this.onViewManipulationStart();
|
|
2924
|
+
}, N.LEFT_DOWN), (s = this.inputHandler) == null || s.setInputAction(() => {
|
|
2925
|
+
this.pointerButtonsMask &= -2;
|
|
2926
|
+
}, N.LEFT_UP), (n = this.inputHandler) == null || n.setInputAction(() => {
|
|
2927
|
+
this.pointerButtonsMask |= 2, this.onViewManipulationStart();
|
|
2928
|
+
}, N.RIGHT_DOWN), (o = this.inputHandler) == null || o.setInputAction(() => {
|
|
2929
|
+
this.pointerButtonsMask &= -3;
|
|
2930
|
+
}, N.RIGHT_UP), (r = this.inputHandler) == null || r.setInputAction(() => {
|
|
2931
|
+
this.pointerButtonsMask |= 4, this.onViewManipulationStart();
|
|
2932
|
+
}, N.MIDDLE_DOWN), (l = this.inputHandler) == null || l.setInputAction(() => {
|
|
2933
|
+
this.pointerButtonsMask &= -5;
|
|
2934
|
+
}, N.MIDDLE_UP), (h = this.inputHandler) == null || h.setInputAction(() => {
|
|
2935
|
+
this.noteWheelInteraction();
|
|
2936
|
+
}, N.WHEEL);
|
|
2937
|
+
}
|
|
2938
|
+
scheduleHoverPick(t) {
|
|
2939
|
+
if (!(this.destroyed || !this.config.pick.hover)) {
|
|
2940
|
+
if (this.noteHoverPointerSample(t), this.hoverPickPosition) {
|
|
2941
|
+
const s = Math.abs(t.x - this.hoverPickPosition.x), n = Math.abs(t.y - this.hoverPickPosition.y);
|
|
2942
|
+
if (s < Tt && n < Tt)
|
|
2943
|
+
return;
|
|
2944
|
+
J.clone(t, this.hoverPickPosition);
|
|
2945
|
+
} else
|
|
2946
|
+
this.hoverPickPosition = J.clone(t);
|
|
2947
|
+
this.shouldSkipHoverPick() || this.hoverPickRafId || (this.hoverPickRafId = requestAnimationFrame(() => this.flushHoverPick()));
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
flushHoverPick() {
|
|
2951
|
+
if (this.hoverPickRafId = 0, this.destroyed || !this.hoverPickPosition || this.shouldSkipHoverPick())
|
|
2952
|
+
return;
|
|
2953
|
+
const t = _();
|
|
2954
|
+
if (t - this.lastHoverPickAt < An) {
|
|
2955
|
+
this.hoverPickRafId = requestAnimationFrame(() => this.flushHoverPick());
|
|
2956
|
+
return;
|
|
2957
|
+
}
|
|
2958
|
+
this.lastHoverPickAt = t, this.handleHoverAt(this.hoverPickPosition);
|
|
2959
|
+
}
|
|
2960
|
+
async handleHoverAt(t) {
|
|
2961
|
+
if (this.hoverPointerSpeedPxPerMs > Hn) {
|
|
2962
|
+
this.lastHoverId != null && (this.lastHoverId = null, this.hoverRequestSerial++, this.selection.setHoveredId(null), this.emit("hover", null));
|
|
2963
|
+
return;
|
|
2964
|
+
}
|
|
2965
|
+
const s = this.pickIndexedTargetId(t, 1);
|
|
2966
|
+
if (s === this.lastHoverId)
|
|
2967
|
+
return;
|
|
2968
|
+
this.lastHoverId = s;
|
|
2969
|
+
const n = ++this.hoverRequestSerial;
|
|
2970
|
+
if (!s) {
|
|
2971
|
+
this.selection.setHoveredId(null), this.emit("hover", null);
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
this.selection.setHoveredId(s);
|
|
2975
|
+
const o = this.hoverTargetCache.get(s);
|
|
2976
|
+
if (o) {
|
|
2977
|
+
this.emit("hover", o);
|
|
2978
|
+
return;
|
|
2979
|
+
}
|
|
2980
|
+
const r = await this.getPickedNode(s);
|
|
2981
|
+
n === this.hoverRequestSerial && (r && this.cacheHoverTarget(r), this.selection.setHoveredId((r == null ? void 0 : r.id) ?? null), this.emit("hover", r));
|
|
2982
|
+
}
|
|
2983
|
+
pickIndexedTargetId(t, s) {
|
|
2984
|
+
const n = this.ensureHoverPickIndex();
|
|
2985
|
+
if (!n)
|
|
2986
|
+
return null;
|
|
2987
|
+
const o = Math.floor(t.x / n.cellSize), r = Math.floor(t.y / n.cellSize);
|
|
2988
|
+
let l = null, h = Number.POSITIVE_INFINITY;
|
|
2989
|
+
for (let c = r - 1; c <= r + 1; c++)
|
|
2990
|
+
for (let m = o - 1; m <= o + 1; m++) {
|
|
2991
|
+
const u = n.bins.get(At(m, c));
|
|
2992
|
+
if (u)
|
|
2993
|
+
for (const v of u) {
|
|
2994
|
+
const d = Math.max(1, s, n.hitRadius[v]), p = d * d, g = n.windowX[v] - t.x, y = n.windowY[v] - t.y, w = g * g + y * y;
|
|
2995
|
+
if (w > p || w > h)
|
|
2996
|
+
continue;
|
|
2997
|
+
const M = n.ids[v];
|
|
2998
|
+
!M || M.startsWith("cluster:") || (h = w, l = M);
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
return l;
|
|
3002
|
+
}
|
|
3003
|
+
ensureHoverPickIndex() {
|
|
3004
|
+
var m;
|
|
3005
|
+
const t = this.latestRenderPacket;
|
|
3006
|
+
if (!t || t.ids.length === 0)
|
|
3007
|
+
return null;
|
|
3008
|
+
const s = this.viewer.scene.canvas;
|
|
3009
|
+
if (this.hoverPickIndex && this.hoverPickIndex.requestId === t.requestId && this.hoverPickIndex.cameraRevision === this.cameraRevision && this.hoverPickIndex.canvasWidth === s.clientWidth && this.hoverPickIndex.canvasHeight === s.clientHeight)
|
|
3010
|
+
return this.hoverPickIndex;
|
|
3011
|
+
const n = new Float32Array(t.ids.length), o = new Float32Array(t.ids.length), r = new Float32Array(t.ids.length);
|
|
3012
|
+
let l = this.config.pick.pixelThreshold * Ct;
|
|
3013
|
+
o.fill(Number.NaN), r.fill(Number.NaN);
|
|
3014
|
+
for (let u = 0; u < t.ids.length; u++) {
|
|
3015
|
+
if (!(t.flags[u] & Bn) || t.count[u] !== 1)
|
|
3016
|
+
continue;
|
|
3017
|
+
const v = Ae.wgs84ToWindowCoordinates(
|
|
3018
|
+
this.viewer.scene,
|
|
3019
|
+
f.fromDegrees(t.lon[u], t.lat[u], t.height[u])
|
|
3020
|
+
);
|
|
3021
|
+
if (!v)
|
|
3022
|
+
continue;
|
|
3023
|
+
const d = v.x, p = v.y;
|
|
3024
|
+
if (!Number.isFinite(d) || !Number.isFinite(p) || d < 0 || p < 0 || d > s.clientWidth || p > s.clientHeight)
|
|
3025
|
+
continue;
|
|
3026
|
+
const g = t.category[u] ?? 0, y = ((m = this.config.renderTypes[g]) == null ? void 0 : m.type) ?? "", w = $t(y, t.size[u], t.count[u] > 1), M = Math.max(1, w * 0.5 * Ln);
|
|
3027
|
+
n[u] = M, l = Math.max(l, M), o[u] = d, r[u] = p;
|
|
3028
|
+
}
|
|
3029
|
+
const h = Math.max(_n, l * 2), c = /* @__PURE__ */ new Map();
|
|
3030
|
+
for (let u = 0; u < t.ids.length; u++) {
|
|
3031
|
+
const v = o[u], d = r[u];
|
|
3032
|
+
if (!Number.isFinite(v) || !Number.isFinite(d))
|
|
3033
|
+
continue;
|
|
3034
|
+
const p = At(Math.floor(v / h), Math.floor(d / h)), g = c.get(p);
|
|
3035
|
+
g ? g.push(u) : c.set(p, [u]);
|
|
3036
|
+
}
|
|
3037
|
+
return this.hoverPickIndex = {
|
|
3038
|
+
requestId: t.requestId,
|
|
3039
|
+
ids: t.ids.slice(),
|
|
3040
|
+
cameraRevision: this.cameraRevision,
|
|
3041
|
+
canvasWidth: s.clientWidth,
|
|
3042
|
+
canvasHeight: s.clientHeight,
|
|
3043
|
+
cellSize: h,
|
|
3044
|
+
bins: c,
|
|
3045
|
+
windowX: o,
|
|
3046
|
+
windowY: r,
|
|
3047
|
+
hitRadius: n
|
|
3048
|
+
}, this.hoverPickIndex;
|
|
3049
|
+
}
|
|
3050
|
+
pickTargetId(t, s) {
|
|
3051
|
+
const n = this.pickIndexedTargetId(
|
|
3052
|
+
t,
|
|
3053
|
+
Math.max(18, this.config.pick.pixelThreshold * 1.25) * Ct
|
|
3054
|
+
);
|
|
3055
|
+
if (n)
|
|
3056
|
+
return n;
|
|
3057
|
+
const o = this.viewer.scene.pick(t, 1, 1), r = Lt(o);
|
|
3058
|
+
if (r || s <= 0)
|
|
3059
|
+
return r;
|
|
3060
|
+
const l = this.viewer.scene.drillPick(t, s, 1, 1) ?? [];
|
|
3061
|
+
for (const h of l) {
|
|
3062
|
+
const c = Lt(h);
|
|
3063
|
+
if (c)
|
|
3064
|
+
return c;
|
|
3065
|
+
}
|
|
3066
|
+
return null;
|
|
3067
|
+
}
|
|
3068
|
+
getRenderedTargetFrame(t, s = new f()) {
|
|
3069
|
+
var n;
|
|
3070
|
+
return this.models.getTargetFrame(t, s) ?? this.render.getTargetFrame(t, s) ?? ((n = this.symbols) == null ? void 0 : n.getTargetFrame(t, s));
|
|
3071
|
+
}
|
|
3072
|
+
getRenderedTargetPosition(t, s = new f()) {
|
|
3073
|
+
const n = this.latestRenderPacket;
|
|
3074
|
+
if (!n)
|
|
3075
|
+
return null;
|
|
3076
|
+
const o = n.ids.indexOf(t);
|
|
3077
|
+
return o < 0 || n.count[o] !== 1 ? null : f.fromDegrees(n.lon[o], n.lat[o], n.height[o], void 0, s);
|
|
3078
|
+
}
|
|
3079
|
+
pickGroundCartesian(t, s) {
|
|
3080
|
+
const n = this.viewer.scene;
|
|
3081
|
+
if (n.pickPositionSupported && typeof n.pickPosition == "function") {
|
|
3082
|
+
const h = n.pickPosition(t);
|
|
3083
|
+
if (h)
|
|
3084
|
+
return f.clone(h, s);
|
|
3085
|
+
}
|
|
3086
|
+
const r = this.viewer.camera.getPickRay(t);
|
|
3087
|
+
if (!r)
|
|
3088
|
+
return null;
|
|
3089
|
+
const l = n.globe.pick(r, n);
|
|
3090
|
+
return l ? f.clone(l, s) : null;
|
|
3091
|
+
}
|
|
3092
|
+
shouldSkipHoverPick() {
|
|
3093
|
+
return this.pointerButtonsMask !== 0 || this.cameraMoving || _() < this.wheelSuppressPickUntil;
|
|
3094
|
+
}
|
|
3095
|
+
noteHoverPointerSample(t) {
|
|
3096
|
+
const s = _(), n = this.lastHoverPointerSample;
|
|
3097
|
+
if (!n) {
|
|
3098
|
+
this.lastHoverPointerSample = { x: t.x, y: t.y, at: s }, this.hoverPointerSpeedPxPerMs = 0;
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
const o = Math.max(1, s - n.at), r = t.x - n.x, l = t.y - n.y, h = Math.sqrt(r * r + l * l) / o;
|
|
3102
|
+
this.hoverPointerSpeedPxPerMs = h * bt + this.hoverPointerSpeedPxPerMs * (1 - bt), n.x = t.x, n.y = t.y, n.at = s;
|
|
3103
|
+
}
|
|
3104
|
+
cancelPendingHoverPick() {
|
|
3105
|
+
this.hoverPickRafId && (cancelAnimationFrame(this.hoverPickRafId), this.hoverPickRafId = 0);
|
|
3106
|
+
}
|
|
3107
|
+
onViewManipulationStart() {
|
|
3108
|
+
this.cancelPendingHoverPick(), this.lastHoverPointerSample = null, this.hoverPointerSpeedPxPerMs = 0, this.lastHoverId != null && (this.lastHoverId = null, this.hoverRequestSerial++, this.selection.setHoveredId(null), this.emit("hover", null));
|
|
3109
|
+
}
|
|
3110
|
+
noteWheelInteraction() {
|
|
3111
|
+
this.lastHoverPointerSample = null, this.hoverPointerSpeedPxPerMs = 0, this.wheelSuppressPickUntil = _() + Rt, this.wheelSuppressResetTimer && window.clearTimeout(this.wheelSuppressResetTimer), this.wheelSuppressResetTimer = window.setTimeout(() => {
|
|
3112
|
+
this.wheelSuppressResetTimer = 0, this.wheelSuppressPickUntil = 0;
|
|
3113
|
+
}, Rt), this.onViewManipulationStart();
|
|
3114
|
+
}
|
|
3115
|
+
noteCameraMovement() {
|
|
3116
|
+
this.config.pick.hover && (this.cameraRevision++, this.hoverPickIndex = null, this.cameraMoving = !0, this.lastHoverPointerSample = null, this.hoverPointerSpeedPxPerMs = 0, this.onViewManipulationStart(), this.cameraMoveTrailingTimer && window.clearTimeout(this.cameraMoveTrailingTimer), this.cameraMoveTrailingTimer = window.setTimeout(() => {
|
|
3117
|
+
this.cameraMoveTrailingTimer = 0, this.cameraMoving = !1, this.scheduleHoverPickIndexWarmup();
|
|
3118
|
+
}, Dn));
|
|
3119
|
+
}
|
|
3120
|
+
scheduleHoverPickIndexWarmup() {
|
|
3121
|
+
this.destroyed || !this.config.pick.hover || this.hoverPickWarmupRafId || this.hoverPickIndex || !this.latestRenderPacket || (this.hoverPickWarmupRafId = requestAnimationFrame(() => {
|
|
3122
|
+
this.hoverPickWarmupRafId = 0, !(this.destroyed || this.cameraMoving || !this.latestRenderPacket || this.hoverPickIndex) && this.ensureHoverPickIndex();
|
|
3123
|
+
}));
|
|
3124
|
+
}
|
|
3125
|
+
cacheHoverTarget(t) {
|
|
3126
|
+
if (this.hoverTargetCache.set(t.id, t), this.hoverTargetCache.size <= En)
|
|
3127
|
+
return;
|
|
3128
|
+
const s = this.hoverTargetCache.keys().next().value;
|
|
3129
|
+
s && this.hoverTargetCache.delete(s);
|
|
3130
|
+
}
|
|
3131
|
+
async getPickedNode(t) {
|
|
3132
|
+
const s = await this.getTargetSnapshot(t);
|
|
3133
|
+
if (!s)
|
|
3134
|
+
return null;
|
|
3135
|
+
const n = Gn(s), o = this.labelDataById.get(t);
|
|
3136
|
+
return o ? {
|
|
3137
|
+
...n,
|
|
3138
|
+
data: {
|
|
3139
|
+
...n.data,
|
|
3140
|
+
nationality: o.nationality,
|
|
3141
|
+
customInfo: o.customInfo
|
|
3142
|
+
}
|
|
3143
|
+
} : n;
|
|
3144
|
+
}
|
|
3145
|
+
replaceLabelData(t) {
|
|
3146
|
+
this.labelDataById.clear(), this.upsertLabelData(t);
|
|
3147
|
+
}
|
|
3148
|
+
applyLabelIncremental(t) {
|
|
3149
|
+
var s, n;
|
|
3150
|
+
(s = t.removes) != null && s.length && this.removeLabelData(t.removes), (n = t.upserts) != null && n.length && this.upsertLabelData(t.upserts);
|
|
3151
|
+
}
|
|
3152
|
+
upsertLabelData(t) {
|
|
3153
|
+
for (const s of t)
|
|
3154
|
+
this.labelDataById.set(s.id, s);
|
|
3155
|
+
this.hoverTargetCache.clear();
|
|
3156
|
+
}
|
|
3157
|
+
removeLabelData(t) {
|
|
3158
|
+
for (const s of t)
|
|
3159
|
+
this.labelDataById.delete(s);
|
|
3160
|
+
this.hoverTargetCache.clear();
|
|
3161
|
+
}
|
|
3162
|
+
nameplateText(t) {
|
|
3163
|
+
var c, m, u, v;
|
|
3164
|
+
const s = t.data ?? this.labelDataById.get(t.id), n = s && s !== t.data ? { ...t, data: s, type: s.type ?? t.type } : t, o = (m = (c = this.labelConfig).resolve) == null ? void 0 : m.call(c, n);
|
|
3165
|
+
if (o !== void 0)
|
|
3166
|
+
return o;
|
|
3167
|
+
if (n.count > 1)
|
|
3168
|
+
return `merged x${n.count}`;
|
|
3169
|
+
if (!s)
|
|
3170
|
+
return t.id;
|
|
3171
|
+
const r = (u = this.labelConfig.byType) == null ? void 0 : u[n.type];
|
|
3172
|
+
if ((r == null ? void 0 : r.maxCameraHeight) != null && n.cameraHeight > r.maxCameraHeight)
|
|
3173
|
+
return null;
|
|
3174
|
+
const l = (r == null ? void 0 : r.fields) ?? this.labelConfig.fields, h = [];
|
|
3175
|
+
for (const d of l) {
|
|
3176
|
+
if (!Yn(d, n.cameraHeight))
|
|
3177
|
+
continue;
|
|
3178
|
+
const p = d.source === "custom" ? (v = s.customInfo) == null ? void 0 : v[d.key] : s[d.key], g = Zn(p, d.fallback);
|
|
3179
|
+
g && h.push(this.labelConfig.showFieldLabels === !1 || !d.label ? g : `${d.label}: ${g}`);
|
|
3180
|
+
}
|
|
3181
|
+
return h.length ? h : null;
|
|
3182
|
+
}
|
|
3183
|
+
setSelectedTargetIds(t) {
|
|
3184
|
+
this.selectedIds.clear();
|
|
3185
|
+
for (const s of t)
|
|
3186
|
+
this.selectedIds.add(s);
|
|
3187
|
+
this.selection.setSelectedIds(Array.from(this.selectedIds)), Promise.all(t.map((s) => this.getPickedNode(s))).then((s) => {
|
|
3188
|
+
this.selectedTargets.clear();
|
|
3189
|
+
for (const n of s)
|
|
3190
|
+
n && this.selectedTargets.set(n.id, n);
|
|
3191
|
+
this.emitSelection();
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
emitSelection() {
|
|
3195
|
+
const t = [];
|
|
3196
|
+
for (const s of this.selectedIds) {
|
|
3197
|
+
const n = this.selectedTargets.get(s);
|
|
3198
|
+
n && t.push(n);
|
|
3199
|
+
}
|
|
3200
|
+
this.emit("selection", t);
|
|
3201
|
+
}
|
|
3202
|
+
isModelRenderActive() {
|
|
3203
|
+
return this.viewer.scene.camera.positionCartographic.height <= this.config.lod.pointAbove;
|
|
3204
|
+
}
|
|
3205
|
+
currentBounds() {
|
|
3206
|
+
const t = this.viewer.camera.computeViewRectangle();
|
|
3207
|
+
if (!t)
|
|
3208
|
+
return { west: -180, east: 180, south: -85, north: 85 };
|
|
3209
|
+
const s = A.toDegrees(t.west), n = A.toDegrees(t.east), o = A.toDegrees(t.south), r = A.toDegrees(t.north);
|
|
3210
|
+
return !Number.isFinite(s) || !Number.isFinite(n) || n <= s ? { west: -180, east: 180, south: -85, north: 85 } : { west: s, east: n, south: o, north: r };
|
|
3211
|
+
}
|
|
3212
|
+
postWithTiming(t, s) {
|
|
3213
|
+
const n = _();
|
|
3214
|
+
return this.worker.postMessage(t, s ?? []), _() - n;
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3217
|
+
function Fn(i) {
|
|
3218
|
+
const e = [];
|
|
3219
|
+
return K(e, i.lon), K(e, i.lat), K(e, i.height), K(e, i.speedH), K(e, i.speedV), K(e, i.heading), K(e, i.secrecy), K(e, i.renderColor), K(e, i.animate), K(e, i.animateColor), e;
|
|
3220
|
+
}
|
|
3221
|
+
function K(i, e) {
|
|
3222
|
+
e && e.buffer instanceof ArrayBuffer && !i.includes(e.buffer) && i.push(e.buffer);
|
|
3223
|
+
}
|
|
3224
|
+
function zn(i) {
|
|
3225
|
+
for (let e = 0; e < i.flags.length; e++)
|
|
3226
|
+
if (i.flags[e] & On)
|
|
3227
|
+
return !0;
|
|
3228
|
+
return !1;
|
|
3229
|
+
}
|
|
3230
|
+
function _() {
|
|
3231
|
+
return typeof performance < "u" ? performance.now() : Date.now();
|
|
3232
|
+
}
|
|
3233
|
+
function At(i, e) {
|
|
3234
|
+
return `${i}:${e}`;
|
|
3235
|
+
}
|
|
3236
|
+
function Vn(i, e, t) {
|
|
3237
|
+
if (i.enabled && !(e > i.maxCameraHeight) && !(t < i.pitchThreshold))
|
|
3238
|
+
return Wn(
|
|
3239
|
+
e * i.cameraHeightMultiplier,
|
|
3240
|
+
i.minDistance,
|
|
3241
|
+
i.maxDistance
|
|
3242
|
+
);
|
|
3243
|
+
}
|
|
3244
|
+
function Wn(i, e, t) {
|
|
3245
|
+
return Math.max(e, Math.min(t, i));
|
|
3246
|
+
}
|
|
3247
|
+
function Be(i) {
|
|
3248
|
+
return {
|
|
3249
|
+
type: i.type,
|
|
3250
|
+
targetDomain: i.targetDomain,
|
|
3251
|
+
iconPath: i.iconPath,
|
|
3252
|
+
defaultColor: i.defaultColor,
|
|
3253
|
+
pointHeadingOffset: i.pointHeadingOffset,
|
|
3254
|
+
lowModel: i.lowModel,
|
|
3255
|
+
highModel: i.highModel,
|
|
3256
|
+
lowModelUrl: i.lowModelUrl,
|
|
3257
|
+
highModelUrl: i.highModelUrl,
|
|
3258
|
+
scale: i.scale,
|
|
3259
|
+
modelHeadingOffset: i.modelHeadingOffset,
|
|
3260
|
+
modelPitchOffset: i.modelPitchOffset,
|
|
3261
|
+
modelRollOffset: i.modelRollOffset,
|
|
3262
|
+
predictMove: i.predictMove,
|
|
3263
|
+
predictMinCameraHeight: i.predictMinCameraHeight,
|
|
3264
|
+
predictSeconds: i.predictSeconds,
|
|
3265
|
+
predictFitSeconds: i.predictFitSeconds
|
|
3266
|
+
};
|
|
3267
|
+
}
|
|
3268
|
+
function Xn(i) {
|
|
3269
|
+
const e = i.startsWith("#") ? i.slice(1) : i;
|
|
3270
|
+
if (e.length !== 6 && e.length !== 8)
|
|
3271
|
+
return 16777215;
|
|
3272
|
+
const t = e.length === 8 ? e.slice(0, 6) : e, s = Number.parseInt(t, 16);
|
|
3273
|
+
return Number.isFinite(s) ? s : 16777215;
|
|
3274
|
+
}
|
|
3275
|
+
function Lt(i) {
|
|
3276
|
+
var t, s, n;
|
|
3277
|
+
if (!i)
|
|
3278
|
+
return null;
|
|
3279
|
+
const e = [i.id, (t = i.primitive) == null ? void 0 : t.id, (s = i.collection) == null ? void 0 : s.id, (n = i.id) == null ? void 0 : n.id];
|
|
3280
|
+
for (const o of e) {
|
|
3281
|
+
const r = Un(o);
|
|
3282
|
+
if (r)
|
|
3283
|
+
return r;
|
|
3284
|
+
}
|
|
3285
|
+
return null;
|
|
3286
|
+
}
|
|
3287
|
+
function Un(i) {
|
|
3288
|
+
if (typeof i == "string")
|
|
3289
|
+
return i;
|
|
3290
|
+
if (!i || typeof i != "object")
|
|
3291
|
+
return null;
|
|
3292
|
+
const e = i;
|
|
3293
|
+
return typeof e.targetId == "string" ? e.targetId : typeof e.id == "string" ? e.id : null;
|
|
3294
|
+
}
|
|
3295
|
+
function Gn(i) {
|
|
3296
|
+
return {
|
|
3297
|
+
id: i.id,
|
|
3298
|
+
type: i.type,
|
|
3299
|
+
data: {
|
|
3300
|
+
id: i.id,
|
|
3301
|
+
type: i.type,
|
|
3302
|
+
lon: i.lon,
|
|
3303
|
+
lat: i.lat,
|
|
3304
|
+
height: i.height,
|
|
3305
|
+
speedH: i.speedH,
|
|
3306
|
+
speedV: 0,
|
|
3307
|
+
heading: i.heading,
|
|
3308
|
+
renderColor: i.renderColor,
|
|
3309
|
+
openAnimate: i.openAnimate,
|
|
3310
|
+
animateColor: i.animateColor,
|
|
3311
|
+
nationality: i.nationality,
|
|
3312
|
+
customInfo: i.customInfo,
|
|
3313
|
+
extra: i.hidden ? { hidden: !0 } : void 0
|
|
3314
|
+
}
|
|
3315
|
+
};
|
|
3316
|
+
}
|
|
3317
|
+
function Zn(i, e) {
|
|
3318
|
+
if (i == null || i === "")
|
|
3319
|
+
return e ?? "";
|
|
3320
|
+
if (typeof i == "string")
|
|
3321
|
+
return i;
|
|
3322
|
+
if (typeof i == "number" || typeof i == "boolean" || typeof i == "bigint")
|
|
3323
|
+
return String(i);
|
|
3324
|
+
if (i instanceof Date)
|
|
3325
|
+
return i.toISOString();
|
|
3326
|
+
try {
|
|
3327
|
+
return JSON.stringify(i);
|
|
3328
|
+
} catch {
|
|
3329
|
+
return e ?? "";
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
function Yn(i, e) {
|
|
3333
|
+
return !(i.minCameraHeight != null && e < i.minCameraHeight || i.maxCameraHeight != null && e > i.maxCameraHeight);
|
|
3334
|
+
}
|
|
3335
|
+
function si() {
|
|
3336
|
+
const i = /* @__PURE__ */ new Map(), e = /* @__PURE__ */ new Map(), t = {
|
|
3337
|
+
register(s, n, o) {
|
|
3338
|
+
if (i.has(s))
|
|
3339
|
+
throw new Error(`[web-event-bus] Action "${s}" is already registered.`);
|
|
3340
|
+
i.set(s, {
|
|
3341
|
+
action: s,
|
|
3342
|
+
handler: n,
|
|
3343
|
+
owner: o == null ? void 0 : o.owner,
|
|
3344
|
+
description: o == null ? void 0 : o.description
|
|
3345
|
+
});
|
|
3346
|
+
},
|
|
3347
|
+
unregister(s) {
|
|
3348
|
+
i.delete(s);
|
|
3349
|
+
},
|
|
3350
|
+
unregisterAll(s) {
|
|
3351
|
+
for (const [n, o] of i)
|
|
3352
|
+
o.owner === s && i.delete(n);
|
|
3353
|
+
},
|
|
3354
|
+
emit(s, n) {
|
|
3355
|
+
const o = e.get(s);
|
|
3356
|
+
if (o)
|
|
3357
|
+
for (const r of o)
|
|
3358
|
+
try {
|
|
3359
|
+
r(n);
|
|
3360
|
+
} catch (l) {
|
|
3361
|
+
console.error(`[web-event-bus] Listener error on "${s}":`, l);
|
|
3362
|
+
}
|
|
3363
|
+
},
|
|
3364
|
+
on(s, n) {
|
|
3365
|
+
return e.has(s) || e.set(s, /* @__PURE__ */ new Set()), e.get(s).add(n), () => {
|
|
3366
|
+
t.off(s, n);
|
|
3367
|
+
};
|
|
3368
|
+
},
|
|
3369
|
+
off(s, n) {
|
|
3370
|
+
const o = e.get(s);
|
|
3371
|
+
o && (o.delete(n), o.size === 0 && e.delete(s));
|
|
3372
|
+
},
|
|
3373
|
+
async invoke(s, n) {
|
|
3374
|
+
const o = i.get(s);
|
|
3375
|
+
if (!o)
|
|
3376
|
+
throw new Error(`[web-event-bus] Action "${s}" is not registered. Cannot invoke.`);
|
|
3377
|
+
return await o.handler(n);
|
|
3378
|
+
},
|
|
3379
|
+
has(s) {
|
|
3380
|
+
return i.has(s);
|
|
3381
|
+
},
|
|
3382
|
+
inspect() {
|
|
3383
|
+
return Array.from(i.values()).map(({ handler: s, ...n }) => n);
|
|
3384
|
+
}
|
|
3385
|
+
};
|
|
3386
|
+
return t;
|
|
3387
|
+
}
|
|
3388
|
+
var Ne = "__WEB_EVENT_BUS__";
|
|
3389
|
+
function Kn() {
|
|
3390
|
+
if (typeof window > "u")
|
|
3391
|
+
throw new Error("[web-event-bus] getGlobalBus() requires a browser environment (window).");
|
|
3392
|
+
return window[Ne] || (window[Ne] = si()), window[Ne];
|
|
3393
|
+
}
|
|
3394
|
+
const U = {
|
|
3395
|
+
scene: {
|
|
3396
|
+
perf: "mtf.scene.perf",
|
|
3397
|
+
dirty: "mtf.scene.dirty",
|
|
3398
|
+
packedDirty: "mtf.scene.packedDirty",
|
|
3399
|
+
pick: "mtf.scene.pick",
|
|
3400
|
+
hover: "mtf.scene.hover",
|
|
3401
|
+
selection: "mtf.scene.selection",
|
|
3402
|
+
contextmenu: "mtf.scene.contextmenu"
|
|
3403
|
+
},
|
|
3404
|
+
track: {
|
|
3405
|
+
hover: "mtf.track.hover"
|
|
3406
|
+
},
|
|
3407
|
+
site: {
|
|
3408
|
+
contextmenu: "mtf.site.contextmenu",
|
|
3409
|
+
pick: "mtf.site.pick",
|
|
3410
|
+
hover: "mtf.site.hover"
|
|
3411
|
+
}
|
|
3412
|
+
}, b = {
|
|
3413
|
+
framework: {
|
|
3414
|
+
addTarget: "mtf.framework.addTarget",
|
|
3415
|
+
updateTarget: "mtf.framework.updateTarget",
|
|
3416
|
+
setTargetData: "mtf.framework.setTargetData",
|
|
3417
|
+
upsertTargetData: "mtf.framework.upsertTargetData",
|
|
3418
|
+
removeTargetData: "mtf.framework.removeTargetData",
|
|
3419
|
+
applyTargetIncremental: "mtf.framework.applyTargetIncremental",
|
|
3420
|
+
setTargetColor: "mtf.framework.setTargetColor",
|
|
3421
|
+
setTargetGlow: "mtf.framework.setTargetGlow",
|
|
3422
|
+
hideTarget: "mtf.framework.hideTarget",
|
|
3423
|
+
showTarget: "mtf.framework.showTarget",
|
|
3424
|
+
disappearTarget: "mtf.framework.disappearTarget",
|
|
3425
|
+
appearTarget: "mtf.framework.appearTarget",
|
|
3426
|
+
setNameplateConfig: "mtf.framework.setNameplateConfig",
|
|
3427
|
+
selectTarget: "mtf.framework.selectTarget",
|
|
3428
|
+
selectTargets: "mtf.framework.selectTargets",
|
|
3429
|
+
unselectTarget: "mtf.framework.unselectTarget",
|
|
3430
|
+
clearSelection: "mtf.framework.clearSelection",
|
|
3431
|
+
boxTarget: "mtf.framework.boxTarget",
|
|
3432
|
+
unboxTarget: "mtf.framework.unboxTarget",
|
|
3433
|
+
locateTarget: "mtf.framework.locateTarget",
|
|
3434
|
+
registerContextMenuItem: "mtf.framework.registerContextMenuItem",
|
|
3435
|
+
showContextMenu: "mtf.framework.showContextMenu",
|
|
3436
|
+
closeContextMenu: "mtf.framework.closeContextMenu",
|
|
3437
|
+
destroy: "mtf.framework.destroy"
|
|
3438
|
+
},
|
|
3439
|
+
tracks: {
|
|
3440
|
+
setTracks: "mtf.tracks.setTracks",
|
|
3441
|
+
getTracks: "mtf.tracks.getTracks",
|
|
3442
|
+
showTracks: "mtf.tracks.showTracks",
|
|
3443
|
+
hideTracks: "mtf.tracks.hideTracks",
|
|
3444
|
+
removeTracks: "mtf.tracks.removeTracks",
|
|
3445
|
+
clearTracks: "mtf.tracks.clearTracks"
|
|
3446
|
+
},
|
|
3447
|
+
site: {
|
|
3448
|
+
setData: "mtf.site.setData",
|
|
3449
|
+
clear: "mtf.site.clear",
|
|
3450
|
+
pickAt: "mtf.site.pickAt",
|
|
3451
|
+
destroy: "mtf.site.destroy"
|
|
3452
|
+
}
|
|
3453
|
+
}, qn = "cesium-multi-target-framework";
|
|
3454
|
+
let Ht = 0;
|
|
3455
|
+
function $n() {
|
|
3456
|
+
return Kn();
|
|
3457
|
+
}
|
|
3458
|
+
function ni() {
|
|
3459
|
+
try {
|
|
3460
|
+
return $n();
|
|
3461
|
+
} catch {
|
|
3462
|
+
return null;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
function Ho() {
|
|
3466
|
+
return si();
|
|
3467
|
+
}
|
|
3468
|
+
function jn(i, e = {}) {
|
|
3469
|
+
const t = e.bus ?? ni(), s = e.owner ?? ai("framework");
|
|
3470
|
+
if (!t)
|
|
3471
|
+
return ri(s);
|
|
3472
|
+
const n = [], o = [];
|
|
3473
|
+
return e.registerActions !== !1 && Qn(t, i, s, e.replaceExisting === !0, o), e.bridgeEvents !== !1 && n.push(...to(t, i)), oi(t, s, n, o);
|
|
3474
|
+
}
|
|
3475
|
+
function Jn(i, e = {}) {
|
|
3476
|
+
const t = e.bus ?? ni(), s = e.owner ?? ai("site");
|
|
3477
|
+
if (!t)
|
|
3478
|
+
return ri(s);
|
|
3479
|
+
const n = [], o = [];
|
|
3480
|
+
return e.registerActions !== !1 && eo(t, i, s, e.replaceExisting === !0, o), e.bridgeEvents !== !1 && n.push(...io(t, i)), oi(t, s, n, o);
|
|
3481
|
+
}
|
|
3482
|
+
function Qn(i, e, t, s, n) {
|
|
3483
|
+
P(i, b.framework.addTarget, ({ target: o }) => e.addTarget(o), t, s, n), P(i, b.framework.updateTarget, ({ target: o }) => e.updateTarget(o), t, s, n), P(i, b.framework.setTargetData, ({ targets: o }) => e.setTargetData(o), t, s, n), P(i, b.framework.upsertTargetData, ({ targets: o }) => e.upsertTargetData(o), t, s, n), P(i, b.framework.removeTargetData, ({ ids: o }) => e.removeTargetData(o), t, s, n), P(i, b.framework.applyTargetIncremental, ({ payload: o }) => e.applyTargetIncremental(o), t, s, n), P(i, b.framework.setTargetColor, ({ id: o, color: r, options: l }) => e.setTargetColor(o, r, l), t, s, n), P(i, b.framework.setTargetGlow, ({ id: o, enabled: r, color: l, options: h }) => e.setTargetGlow(o, r, l, h), t, s, n), P(i, b.framework.hideTarget, ({ id: o, options: r }) => e.hideTarget(o, r), t, s, n), P(i, b.framework.showTarget, ({ id: o, options: r }) => e.showTarget(o, r), t, s, n), P(i, b.framework.disappearTarget, ({ id: o, options: r }) => e.disappearTarget(o, r), t, s, n), P(i, b.framework.appearTarget, ({ id: o, options: r }) => e.appearTarget(o, r), t, s, n), P(i, b.framework.setNameplateConfig, ({ config: o }) => e.setNameplateConfig(o), t, s, n), P(i, b.framework.selectTarget, ({ id: o, options: r }) => e.selectTarget(o, r), t, s, n), P(i, b.framework.selectTargets, ({ ids: o, options: r }) => e.selectTargets(o, r), t, s, n), P(i, b.framework.unselectTarget, ({ id: o }) => e.unselectTarget(o), t, s, n), P(i, b.framework.clearSelection, () => e.clearSelection(), t, s, n), P(i, b.framework.boxTarget, ({ id: o, enabled: r, options: l }) => e.boxTarget(o, r, l), t, s, n), P(i, b.framework.unboxTarget, ({ id: o, options: r }) => e.unboxTarget(o, r), t, s, n), P(i, b.framework.locateTarget, ({ id: o, options: r }) => e.locateTarget(o, r), t, s, n), P(i, b.framework.registerContextMenuItem, ({ item: o }) => e.registerContextMenuItem(o), t, s, n), P(i, b.framework.showContextMenu, ({ context: o }) => e.showContextMenu(o), t, s, n), P(i, b.framework.closeContextMenu, () => e.closeContextMenu(), t, s, n), P(i, b.framework.destroy, () => e.destroy(), t, s, n), P(i, b.tracks.setTracks, ({ tracks: o }) => e.tracks.setTracks(o), t, s, n), P(i, b.tracks.getTracks, (o) => e.tracks.getTracks(o == null ? void 0 : o.targetIds), t, s, n), P(i, b.tracks.showTracks, ({ targetIds: o }) => e.tracks.showTracks(o), t, s, n), P(i, b.tracks.hideTracks, ({ targetIds: o }) => e.tracks.hideTracks(o), t, s, n), P(i, b.tracks.removeTracks, ({ targetIds: o }) => e.tracks.removeTracks(o), t, s, n), P(i, b.tracks.clearTracks, () => e.tracks.clearTracks(), t, s, n);
|
|
3484
|
+
}
|
|
3485
|
+
function eo(i, e, t, s, n) {
|
|
3486
|
+
P(i, b.site.setData, ({ sites: o }) => e.setData(o), t, s, n), P(i, b.site.clear, () => e.clear(), t, s, n), P(i, b.site.pickAt, ({ position: o, thresholdPx: r }) => e.pickAt(o, r), t, s, n), P(i, b.site.destroy, () => e.destroy(), t, s, n);
|
|
3487
|
+
}
|
|
3488
|
+
function to(i, e) {
|
|
3489
|
+
return [
|
|
3490
|
+
e.scene.on("perf", (t) => G(i, U.scene.perf, t)),
|
|
3491
|
+
e.scene.on("dirty", (t) => G(i, U.scene.dirty, t)),
|
|
3492
|
+
e.scene.on("packedDirty", (t) => G(i, U.scene.packedDirty, t)),
|
|
3493
|
+
e.scene.on("pick", (t) => G(i, U.scene.pick, t)),
|
|
3494
|
+
e.scene.on("hover", (t) => G(i, U.scene.hover, t)),
|
|
3495
|
+
e.scene.on("selection", (t) => G(i, U.scene.selection, t)),
|
|
3496
|
+
e.scene.on("contextmenu", (t) => G(i, U.scene.contextmenu, t)),
|
|
3497
|
+
e.tracks.on("hover", (t) => G(i, U.track.hover, t))
|
|
3498
|
+
];
|
|
3499
|
+
}
|
|
3500
|
+
function io(i, e) {
|
|
3501
|
+
return [
|
|
3502
|
+
e.on("contextmenu", (t) => G(i, U.site.contextmenu, t)),
|
|
3503
|
+
e.on("pick", (t) => G(i, U.site.pick, t)),
|
|
3504
|
+
e.on("hover", (t) => G(i, U.site.hover, t))
|
|
3505
|
+
];
|
|
3506
|
+
}
|
|
3507
|
+
function P(i, e, t, s, n, o) {
|
|
3508
|
+
if (i.has(e)) {
|
|
3509
|
+
if (!n)
|
|
3510
|
+
return;
|
|
3511
|
+
i.unregister(e);
|
|
3512
|
+
}
|
|
3513
|
+
i.register(e, t, { owner: s }), o.push(e);
|
|
3514
|
+
}
|
|
3515
|
+
function G(i, e, t) {
|
|
3516
|
+
try {
|
|
3517
|
+
i.emit(e, t);
|
|
3518
|
+
} catch {
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
function oi(i, e, t, s) {
|
|
3522
|
+
let n = !1;
|
|
3523
|
+
return {
|
|
3524
|
+
active: !0,
|
|
3525
|
+
owner: e,
|
|
3526
|
+
dispose() {
|
|
3527
|
+
if (!n) {
|
|
3528
|
+
n = !0;
|
|
3529
|
+
for (const o of t.splice(0))
|
|
3530
|
+
o();
|
|
3531
|
+
for (const o of s.splice(0))
|
|
3532
|
+
so(i, o, e) && i.unregister(o);
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
};
|
|
3536
|
+
}
|
|
3537
|
+
function ri(i) {
|
|
3538
|
+
return {
|
|
3539
|
+
active: !1,
|
|
3540
|
+
owner: i,
|
|
3541
|
+
dispose() {
|
|
3542
|
+
}
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
function ai(i) {
|
|
3546
|
+
return Ht++, `${qn}:${i}:${Ht}`;
|
|
3547
|
+
}
|
|
3548
|
+
function so(i, e, t) {
|
|
3549
|
+
try {
|
|
3550
|
+
return i.inspect().some((s) => s.action === e && s.owner === t);
|
|
3551
|
+
} catch {
|
|
3552
|
+
return !1;
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
class $e {
|
|
3556
|
+
constructor(e, t) {
|
|
3557
|
+
a(this, "scene");
|
|
3558
|
+
a(this, "viewer");
|
|
3559
|
+
a(this, "tracks");
|
|
3560
|
+
/** 引擎就绪信号(转发自 scene.ready):可在加载依赖底座的其它组件前 await。 */
|
|
3561
|
+
a(this, "ready");
|
|
3562
|
+
a(this, "boxedTargetIds", /* @__PURE__ */ new Set());
|
|
3563
|
+
a(this, "contextMenuItems", /* @__PURE__ */ new Map());
|
|
3564
|
+
a(this, "contextMenuRoot");
|
|
3565
|
+
a(this, "contextMenuList");
|
|
3566
|
+
a(this, "removeSceneContextMenuListener");
|
|
3567
|
+
a(this, "eventBusBinding");
|
|
3568
|
+
a(this, "handleDocumentPointerDownBound");
|
|
3569
|
+
a(this, "handleKeyDownBound");
|
|
3570
|
+
a(this, "activeContextMenuContext", null);
|
|
3571
|
+
const s = no(t);
|
|
3572
|
+
this.viewer = e, this.scene = new Nn(e, s), this.ready = this.scene.ready, this.tracks = this.scene.tracks, this.contextMenuRoot = ho(), this.contextMenuList = document.createElement("div"), this.contextMenuList.className = "mtf-context-menu-list", this.contextMenuRoot.appendChild(this.contextMenuList), document.body.appendChild(this.contextMenuRoot), this.removeSceneContextMenuListener = this.scene.on("contextmenu", (n) => {
|
|
3573
|
+
this.handleSceneContextMenu(n);
|
|
3574
|
+
}), this.handleDocumentPointerDownBound = (n) => this.handleDocumentPointerDown(n), this.handleKeyDownBound = (n) => this.handleDocumentKeyDown(n), document.addEventListener("pointerdown", this.handleDocumentPointerDownBound, !0), document.addEventListener("keydown", this.handleKeyDownBound), this.eventBusBinding = jn(this, { replaceExisting: !0 });
|
|
3575
|
+
}
|
|
3576
|
+
setData(e) {
|
|
3577
|
+
this.setTargetData(e);
|
|
3578
|
+
}
|
|
3579
|
+
upsert(e) {
|
|
3580
|
+
this.upsertTargetData(e);
|
|
3581
|
+
}
|
|
3582
|
+
remove(e) {
|
|
3583
|
+
this.removeTargetData(e);
|
|
3584
|
+
}
|
|
3585
|
+
addTarget(e) {
|
|
3586
|
+
return this.updateTarget(e);
|
|
3587
|
+
}
|
|
3588
|
+
updateTarget(e) {
|
|
3589
|
+
const [t] = Te([e], this.scene.config.nodeTypes);
|
|
3590
|
+
return this.scene.applyRealtimeUpsert([t]), t;
|
|
3591
|
+
}
|
|
3592
|
+
setTargetData(e) {
|
|
3593
|
+
this.scene.setData(Te(e, this.scene.config.nodeTypes));
|
|
3594
|
+
}
|
|
3595
|
+
upsertTargetData(e) {
|
|
3596
|
+
this.scene.applyIncremental({ upserts: Te(e, this.scene.config.nodeTypes) });
|
|
3597
|
+
}
|
|
3598
|
+
removeTargetData(e) {
|
|
3599
|
+
this.scene.applyRealtimeRemove(e);
|
|
3600
|
+
}
|
|
3601
|
+
applyTargetIncremental(e) {
|
|
3602
|
+
var t;
|
|
3603
|
+
this.scene.applyIncremental({
|
|
3604
|
+
upserts: e.upserts ? Te(e.upserts, this.scene.config.nodeTypes) : void 0,
|
|
3605
|
+
removes: (t = e.removes) == null ? void 0 : t.slice()
|
|
3606
|
+
});
|
|
3607
|
+
}
|
|
3608
|
+
setTargetColor(e, t, s) {
|
|
3609
|
+
const n = oe(e);
|
|
3610
|
+
ke(t, "color");
|
|
3611
|
+
const o = ne(s);
|
|
3612
|
+
this.scene.applyTargetStyle(n.map((r, l) => ({
|
|
3613
|
+
id: r,
|
|
3614
|
+
styleKind: "color",
|
|
3615
|
+
clearBefore: o && l === 0,
|
|
3616
|
+
renderColor: t
|
|
3617
|
+
})));
|
|
3618
|
+
}
|
|
3619
|
+
setTargetGlow(e, t = !0, s, n) {
|
|
3620
|
+
const o = oe(e);
|
|
3621
|
+
s && ke(s, "color");
|
|
3622
|
+
const r = ne(n);
|
|
3623
|
+
this.scene.applyTargetStyle(o.map((l, h) => ({
|
|
3624
|
+
id: l,
|
|
3625
|
+
styleKind: "glow",
|
|
3626
|
+
clearBefore: r && h === 0,
|
|
3627
|
+
openAnimate: t,
|
|
3628
|
+
animateType: t ? "发光" : void 0,
|
|
3629
|
+
animateColor: s
|
|
3630
|
+
})));
|
|
3631
|
+
}
|
|
3632
|
+
hideTarget(e, t) {
|
|
3633
|
+
const s = oe(e), n = ne(t);
|
|
3634
|
+
this.scene.applyTargetStyle(s.map((o, r) => ({
|
|
3635
|
+
id: o,
|
|
3636
|
+
styleKind: "hidden",
|
|
3637
|
+
clearBefore: n && r === 0,
|
|
3638
|
+
hidden: !0
|
|
3639
|
+
})));
|
|
3640
|
+
}
|
|
3641
|
+
showTarget(e, t) {
|
|
3642
|
+
const s = oe(e), n = ne(t);
|
|
3643
|
+
this.scene.applyTargetStyle(s.map((o, r) => ({
|
|
3644
|
+
id: o,
|
|
3645
|
+
styleKind: "hidden",
|
|
3646
|
+
clearBefore: n && r === 0,
|
|
3647
|
+
hidden: !1
|
|
3648
|
+
})));
|
|
3649
|
+
}
|
|
3650
|
+
disappearTarget(e, t) {
|
|
3651
|
+
this.hideTarget(e, t);
|
|
3652
|
+
}
|
|
3653
|
+
appearTarget(e, t) {
|
|
3654
|
+
this.showTarget(e, t);
|
|
3655
|
+
}
|
|
3656
|
+
setNameplateConfig(e) {
|
|
3657
|
+
this.scene.setLabelConfig(e);
|
|
3658
|
+
}
|
|
3659
|
+
async selectTarget(e, t) {
|
|
3660
|
+
ie(e, "id");
|
|
3661
|
+
const s = await this.scene.selectTarget(e, ne(t));
|
|
3662
|
+
return s ? Dt(s) : null;
|
|
3663
|
+
}
|
|
3664
|
+
async selectTargets(e, t) {
|
|
3665
|
+
const s = oe(e);
|
|
3666
|
+
return (await this.scene.selectTargets(s, ne(t))).map(Dt);
|
|
3667
|
+
}
|
|
3668
|
+
unselectTarget(e) {
|
|
3669
|
+
ie(e, "id"), this.boxedTargetIds.delete(e), this.scene.unselectTarget(e);
|
|
3670
|
+
}
|
|
3671
|
+
clearSelection() {
|
|
3672
|
+
this.boxedTargetIds.clear(), this.scene.clearSelection();
|
|
3673
|
+
}
|
|
3674
|
+
boxTarget(e, t = !0, s) {
|
|
3675
|
+
const n = oe(e);
|
|
3676
|
+
ne(s) && this.boxedTargetIds.clear();
|
|
3677
|
+
for (const o of n)
|
|
3678
|
+
t ? this.boxedTargetIds.add(o) : this.boxedTargetIds.delete(o);
|
|
3679
|
+
this.scene.setBoxedTargetIds(Array.from(this.boxedTargetIds));
|
|
3680
|
+
}
|
|
3681
|
+
unboxTarget(e, t) {
|
|
3682
|
+
this.boxTarget(e, !1, t);
|
|
3683
|
+
}
|
|
3684
|
+
async locateTarget(e, t = {}) {
|
|
3685
|
+
ie(e, "id");
|
|
3686
|
+
const s = await this.scene.getTargetSnapshot(e);
|
|
3687
|
+
if (!s)
|
|
3688
|
+
return null;
|
|
3689
|
+
const n = t.range ?? t.height ?? 18e3, o = f.fromDegrees(s.lon, s.lat, s.height), r = Ye.eastNorthUpToFixedFrame(o), l = new wi(
|
|
3690
|
+
A.toRadians(t.heading ?? 0),
|
|
3691
|
+
A.toRadians(t.pitch ?? -65),
|
|
3692
|
+
n
|
|
3693
|
+
);
|
|
3694
|
+
return this.viewer.camera.flyToBoundingSphere(
|
|
3695
|
+
new Ze(o, 1),
|
|
3696
|
+
{
|
|
3697
|
+
duration: t.duration ?? 0.8,
|
|
3698
|
+
offset: l,
|
|
3699
|
+
complete: () => {
|
|
3700
|
+
this.viewer.camera.lookAtTransform(r, l), this.viewer.camera.lookAtTransform(R.IDENTITY);
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
), s;
|
|
3704
|
+
}
|
|
3705
|
+
registerContextMenuItem(e) {
|
|
3706
|
+
var s;
|
|
3707
|
+
if (ie(e.key, "context menu item key"), ie(e.label, "context menu item label"), typeof e.onClick != "function")
|
|
3708
|
+
throw new Error("context menu item onClick must be a function.");
|
|
3709
|
+
const t = {
|
|
3710
|
+
...e,
|
|
3711
|
+
targetKinds: (s = e.targetKinds) != null && s.length ? [...e.targetKinds] : ["target"],
|
|
3712
|
+
order: e.order ?? 0
|
|
3713
|
+
};
|
|
3714
|
+
return this.contextMenuItems.set(t.key, t), () => {
|
|
3715
|
+
this.contextMenuItems.get(t.key) === t && (this.contextMenuItems.delete(t.key), this.activeContextMenuContext && this.renderContextMenu(this.activeContextMenuContext));
|
|
3716
|
+
};
|
|
3717
|
+
}
|
|
3718
|
+
async showContextMenu(e) {
|
|
3719
|
+
await this.renderContextMenu(e);
|
|
3720
|
+
}
|
|
3721
|
+
closeContextMenu() {
|
|
3722
|
+
this.activeContextMenuContext = null, this.contextMenuRoot.style.display = "none", this.contextMenuRoot.style.left = "-9999px", this.contextMenuRoot.style.top = "-9999px", this.contextMenuList.innerHTML = "";
|
|
3723
|
+
}
|
|
3724
|
+
destroy() {
|
|
3725
|
+
this.eventBusBinding.dispose(), this.closeContextMenu(), this.removeSceneContextMenuListener(), document.removeEventListener("pointerdown", this.handleDocumentPointerDownBound, !0), document.removeEventListener("keydown", this.handleKeyDownBound), this.contextMenuRoot.remove(), this.scene.destroy();
|
|
3726
|
+
}
|
|
3727
|
+
/**
|
|
3728
|
+
* 异步工厂:构造实例并等待引擎就绪后再 resolve。
|
|
3729
|
+
* 适合「初始化完成后再加载依赖底座的其它组件」的接入方:`const mt = await MultiTargetFramework.create(viewer, options);`
|
|
3730
|
+
* 若需在就绪前挂事件/调方法,请改用同步 `new MultiTargetFramework(...)` 再 `await mt.ready`。
|
|
3731
|
+
*/
|
|
3732
|
+
static async create(e, t) {
|
|
3733
|
+
const s = new $e(e, t);
|
|
3734
|
+
return await s.ready, s;
|
|
3735
|
+
}
|
|
3736
|
+
async handleSceneContextMenu(e) {
|
|
3737
|
+
if (!e) {
|
|
3738
|
+
this.closeContextMenu();
|
|
3739
|
+
return;
|
|
3740
|
+
}
|
|
3741
|
+
const t = await this.toContextMenuContext(e);
|
|
3742
|
+
if (!t) {
|
|
3743
|
+
this.closeContextMenu();
|
|
3744
|
+
return;
|
|
3745
|
+
}
|
|
3746
|
+
await this.renderContextMenu(t);
|
|
3747
|
+
}
|
|
3748
|
+
async toContextMenuContext(e) {
|
|
3749
|
+
if (e.kind === "target" && e.target) {
|
|
3750
|
+
const t = await this.scene.getTargetSnapshot(e.target.id);
|
|
3751
|
+
return t ? {
|
|
3752
|
+
screenX: e.screenX,
|
|
3753
|
+
screenY: e.screenY,
|
|
3754
|
+
cartesian: e.cartesian ? f.clone(e.cartesian, new f()) : void 0,
|
|
3755
|
+
target: {
|
|
3756
|
+
kind: "target",
|
|
3757
|
+
id: t.id,
|
|
3758
|
+
type: t.type,
|
|
3759
|
+
data: t
|
|
3760
|
+
},
|
|
3761
|
+
viewer: this.viewer,
|
|
3762
|
+
scene: this.scene,
|
|
3763
|
+
framework: this
|
|
3764
|
+
} : null;
|
|
3765
|
+
}
|
|
3766
|
+
return e.kind === "ground" && e.lon != null && e.lat != null && e.height != null ? {
|
|
3767
|
+
screenX: e.screenX,
|
|
3768
|
+
screenY: e.screenY,
|
|
3769
|
+
cartesian: e.cartesian ? f.clone(e.cartesian, new f()) : void 0,
|
|
3770
|
+
target: {
|
|
3771
|
+
kind: "ground",
|
|
3772
|
+
lon: e.lon,
|
|
3773
|
+
lat: e.lat,
|
|
3774
|
+
height: e.height
|
|
3775
|
+
},
|
|
3776
|
+
viewer: this.viewer,
|
|
3777
|
+
scene: this.scene,
|
|
3778
|
+
framework: this
|
|
3779
|
+
} : null;
|
|
3780
|
+
}
|
|
3781
|
+
async renderContextMenu(e) {
|
|
3782
|
+
const t = this.resolveVisibleContextMenuItems(e);
|
|
3783
|
+
if (t.length === 0) {
|
|
3784
|
+
this.closeContextMenu();
|
|
3785
|
+
return;
|
|
3786
|
+
}
|
|
3787
|
+
this.activeContextMenuContext = e, this.contextMenuList.innerHTML = "";
|
|
3788
|
+
for (const s of t) {
|
|
3789
|
+
const n = document.createElement("button");
|
|
3790
|
+
n.type = "button", n.className = "mtf-context-menu-item", n.textContent = s.label, n.addEventListener("click", () => {
|
|
3791
|
+
this.closeContextMenu(), s.onClick(e);
|
|
3792
|
+
}), this.contextMenuList.appendChild(n);
|
|
3793
|
+
}
|
|
3794
|
+
this.contextMenuRoot.style.display = "block", this.contextMenuRoot.style.left = `${e.screenX}px`, this.contextMenuRoot.style.top = `${e.screenY}px`, requestAnimationFrame(() => this.repositionContextMenu());
|
|
3795
|
+
}
|
|
3796
|
+
resolveVisibleContextMenuItems(e) {
|
|
3797
|
+
const t = Array.from(this.contextMenuItems.values());
|
|
3798
|
+
return t.sort((s, n) => (s.order ?? 0) - (n.order ?? 0) || s.label.localeCompare(n.label, "zh-CN")), t.filter((s) => s.targetKinds.includes(e.target.kind) ? s.visible ? s.visible(e) !== !1 : !0 : !1);
|
|
3799
|
+
}
|
|
3800
|
+
repositionContextMenu() {
|
|
3801
|
+
if (this.contextMenuRoot.style.display === "none")
|
|
3802
|
+
return;
|
|
3803
|
+
const e = 8, t = this.contextMenuRoot.offsetWidth, s = this.contextMenuRoot.offsetHeight, n = Math.max(e, window.innerWidth - t - e), o = Math.max(e, window.innerHeight - s - e), r = Number.parseFloat(this.contextMenuRoot.style.left || "0"), l = Number.parseFloat(this.contextMenuRoot.style.top || "0"), h = Math.min(Math.max(e, r), n), c = Math.min(Math.max(e, l), o);
|
|
3804
|
+
this.contextMenuRoot.style.left = `${h}px`, this.contextMenuRoot.style.top = `${c}px`;
|
|
3805
|
+
}
|
|
3806
|
+
handleDocumentPointerDown(e) {
|
|
3807
|
+
if (this.contextMenuRoot.style.display === "none")
|
|
3808
|
+
return;
|
|
3809
|
+
const t = e.target;
|
|
3810
|
+
t instanceof Node && this.contextMenuRoot.contains(t) || this.closeContextMenu();
|
|
3811
|
+
}
|
|
3812
|
+
handleDocumentKeyDown(e) {
|
|
3813
|
+
e.key === "Escape" && this.closeContextMenu();
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
function Do(i, e) {
|
|
3817
|
+
return $e.create(i, e);
|
|
3818
|
+
}
|
|
3819
|
+
function no(i) {
|
|
3820
|
+
if (!i.targetTypes.length)
|
|
3821
|
+
throw new Error("MultiTargetFramework requires at least one target type config.");
|
|
3822
|
+
return {
|
|
3823
|
+
...i.scene ?? {},
|
|
3824
|
+
nodeTypes: i.targetTypes.map(oo)
|
|
3825
|
+
};
|
|
3826
|
+
}
|
|
3827
|
+
function oo(i) {
|
|
3828
|
+
return {
|
|
3829
|
+
name: i.name ?? i.type,
|
|
3830
|
+
type: i.type,
|
|
3831
|
+
targetDomain: i.targetDomain,
|
|
3832
|
+
forceHighModelInLowLod: i.forceHighModelInLowLod,
|
|
3833
|
+
iconPath: i.iconPath,
|
|
3834
|
+
defaultColor: i.defaultColor,
|
|
3835
|
+
highModel: i.highModel,
|
|
3836
|
+
lowModel: i.lowModel,
|
|
3837
|
+
highModelUrl: i.highModelUrl,
|
|
3838
|
+
lowModelUrl: i.lowModelUrl,
|
|
3839
|
+
pointPixelSize: i.pointPixelSize,
|
|
3840
|
+
pointHeadingOffset: i.pointHeadingOffset,
|
|
3841
|
+
scale: i.scale,
|
|
3842
|
+
modelHeadingOffset: i.modelHeadingOffset,
|
|
3843
|
+
modelPitchOffset: i.modelPitchOffset,
|
|
3844
|
+
modelRollOffset: i.modelRollOffset,
|
|
3845
|
+
smoothMove: i.smoothMove ?? !1,
|
|
3846
|
+
smoothMoveMinCameraHeight: i.smoothMoveMinCameraHeight ?? 25e3,
|
|
3847
|
+
smoothMoveDurationMs: i.smoothMoveDurationMs ?? i.moveAnimationDurationMs ?? 400,
|
|
3848
|
+
predictMove: i.predictMove ?? i.predict ?? !1,
|
|
3849
|
+
predictMinCameraHeight: i.predictMinCameraHeight ?? 25e3,
|
|
3850
|
+
predictSeconds: i.predictSeconds,
|
|
3851
|
+
predictFitSeconds: i.predictFitSeconds
|
|
3852
|
+
};
|
|
3853
|
+
}
|
|
3854
|
+
function Te(i, e) {
|
|
3855
|
+
return i.map((t, s) => {
|
|
3856
|
+
if (!t || typeof t != "object")
|
|
3857
|
+
throw new Error(`Invalid target at index ${s}.`);
|
|
3858
|
+
if (ao(t, `targets[${s}]`), ie(t.id, `targets[${s}].id`), ie(t.type, `targets[${s}].type`), !e.has(t.type))
|
|
3859
|
+
throw new Error(`Unknown target type "${t.type}" at index ${s}.`);
|
|
3860
|
+
return re(t.lon, `targets[${s}].lon`), re(t.lat, `targets[${s}].lat`), re(t.height, `targets[${s}].height`), re(t.speedH, `targets[${s}].speedH`), re(t.speedV, `targets[${s}].speedV`), re(t.heading, `targets[${s}].heading`), t.renderColor && ke(t.renderColor, `targets[${s}].renderColor`), t.animateColor && ke(t.animateColor, `targets[${s}].animateColor`), t.nationality != null && lo(t.nationality, `targets[${s}].nationality`), t.customInfo != null && co(t.customInfo, `targets[${s}].customInfo`), { ...t };
|
|
3861
|
+
});
|
|
3862
|
+
}
|
|
3863
|
+
const ro = /* @__PURE__ */ new Set([
|
|
3864
|
+
"id",
|
|
3865
|
+
"type",
|
|
3866
|
+
"lon",
|
|
3867
|
+
"lat",
|
|
3868
|
+
"height",
|
|
3869
|
+
"speedH",
|
|
3870
|
+
"speedV",
|
|
3871
|
+
"heading",
|
|
3872
|
+
"renderColor",
|
|
3873
|
+
"openAnimate",
|
|
3874
|
+
"animateType",
|
|
3875
|
+
"animateColor",
|
|
3876
|
+
"nationality",
|
|
3877
|
+
"customInfo",
|
|
3878
|
+
"track",
|
|
3879
|
+
"secrecy",
|
|
3880
|
+
"extra"
|
|
3881
|
+
]);
|
|
3882
|
+
function ao(i, e) {
|
|
3883
|
+
for (const t of Object.keys(i))
|
|
3884
|
+
if (!ro.has(t))
|
|
3885
|
+
throw new Error(`${e}.${t} is not part of StandardTargetData.`);
|
|
3886
|
+
}
|
|
3887
|
+
function oe(i) {
|
|
3888
|
+
const e = typeof i == "string" ? [i] : i.slice();
|
|
3889
|
+
if (e.length === 0)
|
|
3890
|
+
throw new Error("target id list must not be empty.");
|
|
3891
|
+
for (let t = 0; t < e.length; t++)
|
|
3892
|
+
ie(e[t], `ids[${t}]`);
|
|
3893
|
+
return e;
|
|
3894
|
+
}
|
|
3895
|
+
function ne(i) {
|
|
3896
|
+
return (i == null ? void 0 : i.clearBefore) ?? (i == null ? void 0 : i.clearBefor) ?? !0;
|
|
3897
|
+
}
|
|
3898
|
+
function Dt(i) {
|
|
3899
|
+
var e;
|
|
3900
|
+
return {
|
|
3901
|
+
id: i.id,
|
|
3902
|
+
type: i.type,
|
|
3903
|
+
lon: i.data.lon,
|
|
3904
|
+
lat: i.data.lat,
|
|
3905
|
+
height: i.data.height,
|
|
3906
|
+
heading: i.data.heading,
|
|
3907
|
+
speedH: i.data.speedH,
|
|
3908
|
+
renderColor: i.data.renderColor ?? "",
|
|
3909
|
+
openAnimate: i.data.openAnimate ?? !1,
|
|
3910
|
+
animateColor: i.data.animateColor ?? "",
|
|
3911
|
+
hidden: ((e = i.data.extra) == null ? void 0 : e.hidden) === !0,
|
|
3912
|
+
nationality: i.data.nationality,
|
|
3913
|
+
customInfo: i.data.customInfo
|
|
3914
|
+
};
|
|
3915
|
+
}
|
|
3916
|
+
function ie(i, e) {
|
|
3917
|
+
if (typeof i != "string" || i.length === 0)
|
|
3918
|
+
throw new Error(`${e} must be a non-empty string.`);
|
|
3919
|
+
}
|
|
3920
|
+
function lo(i, e) {
|
|
3921
|
+
if (typeof i != "string")
|
|
3922
|
+
throw new Error(`${e} must be a string.`);
|
|
3923
|
+
}
|
|
3924
|
+
function re(i, e) {
|
|
3925
|
+
if (typeof i != "number" || !Number.isFinite(i))
|
|
3926
|
+
throw new Error(`${e} must be a finite number.`);
|
|
3927
|
+
}
|
|
3928
|
+
function ke(i, e) {
|
|
3929
|
+
if (!/^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(i))
|
|
3930
|
+
throw new Error(`${e} must be #RRGGBB or #RRGGBBAA.`);
|
|
3931
|
+
}
|
|
3932
|
+
function co(i, e) {
|
|
3933
|
+
if (!i || typeof i != "object" || Array.isArray(i))
|
|
3934
|
+
throw new Error(`${e} must be an object.`);
|
|
3935
|
+
}
|
|
3936
|
+
function ho() {
|
|
3937
|
+
uo();
|
|
3938
|
+
const i = document.createElement("div");
|
|
3939
|
+
return i.className = "mtf-context-menu", i.style.display = "none", i.style.left = "-9999px", i.style.top = "-9999px", i;
|
|
3940
|
+
}
|
|
3941
|
+
let Et = !1;
|
|
3942
|
+
function uo() {
|
|
3943
|
+
if (Et)
|
|
3944
|
+
return;
|
|
3945
|
+
Et = !0;
|
|
3946
|
+
const i = document.createElement("style");
|
|
3947
|
+
i.dataset.mtfContextMenu = "true", i.textContent = `
|
|
3948
|
+
.mtf-context-menu {
|
|
3949
|
+
position: fixed;
|
|
3950
|
+
z-index: 9999;
|
|
3951
|
+
min-width: 144px;
|
|
3952
|
+
background: #ffffff;
|
|
3953
|
+
color: #111111;
|
|
3954
|
+
border: 1px solid rgba(15, 23, 42, 0.14);
|
|
3955
|
+
border-radius: 8px;
|
|
3956
|
+
box-shadow: 0 10px 28px rgba(15, 23, 42, 0.18);
|
|
3957
|
+
padding: 6px;
|
|
3958
|
+
box-sizing: border-box;
|
|
3959
|
+
}
|
|
3960
|
+
.mtf-context-menu-list {
|
|
3961
|
+
display: grid;
|
|
3962
|
+
gap: 2px;
|
|
3963
|
+
}
|
|
3964
|
+
.mtf-context-menu-item {
|
|
3965
|
+
appearance: none;
|
|
3966
|
+
width: 100%;
|
|
3967
|
+
min-height: 34px;
|
|
3968
|
+
padding: 8px 12px;
|
|
3969
|
+
border: 0;
|
|
3970
|
+
border-radius: 6px;
|
|
3971
|
+
background: transparent;
|
|
3972
|
+
color: #111111;
|
|
3973
|
+
text-align: left;
|
|
3974
|
+
cursor: pointer;
|
|
3975
|
+
font: 500 13px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
3976
|
+
}
|
|
3977
|
+
.mtf-context-menu-item:hover {
|
|
3978
|
+
background: rgba(15, 23, 42, 0.08);
|
|
3979
|
+
}
|
|
3980
|
+
`, document.head.appendChild(i);
|
|
3981
|
+
}
|
|
3982
|
+
class fo {
|
|
3983
|
+
constructor(e, t, s) {
|
|
3984
|
+
a(this, "renderer");
|
|
3985
|
+
a(this, "typeByName", /* @__PURE__ */ new Map());
|
|
3986
|
+
this.renderer = new Ut(e, s);
|
|
3987
|
+
for (const n of t)
|
|
3988
|
+
this.typeByName.set(n.type, n);
|
|
3989
|
+
}
|
|
3990
|
+
setSites(e) {
|
|
3991
|
+
const t = [];
|
|
3992
|
+
for (const s of e) {
|
|
3993
|
+
const n = this.typeByName.get(s.type), o = n == null ? void 0 : n.lowModel;
|
|
3994
|
+
!n || !(o != null && o.url) || t.push({
|
|
3995
|
+
id: s.id,
|
|
3996
|
+
url: o.url,
|
|
3997
|
+
modelKey: mo(n),
|
|
3998
|
+
modelStyle: {
|
|
3999
|
+
url: o.url,
|
|
4000
|
+
scale: o.scale,
|
|
4001
|
+
headingOffset: o.headingOffset,
|
|
4002
|
+
pitchOffset: o.pitchOffset,
|
|
4003
|
+
rollOffset: o.rollOffset
|
|
4004
|
+
},
|
|
4005
|
+
position: f.fromDegrees(s.lon, s.lat, s.height),
|
|
4006
|
+
heading: s.heading ?? 0,
|
|
4007
|
+
smoothMove: !1,
|
|
4008
|
+
moveDurationMs: 0
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
this.renderer.setCandidates(t);
|
|
4012
|
+
}
|
|
4013
|
+
clear() {
|
|
4014
|
+
this.renderer.clear();
|
|
4015
|
+
}
|
|
4016
|
+
update(e) {
|
|
4017
|
+
this.renderer.update(e);
|
|
4018
|
+
}
|
|
4019
|
+
destroy() {
|
|
4020
|
+
this.renderer.destroy();
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
function mo(i) {
|
|
4024
|
+
const e = i.lowModel;
|
|
4025
|
+
return [
|
|
4026
|
+
i.type,
|
|
4027
|
+
(e == null ? void 0 : e.url) ?? "",
|
|
4028
|
+
(e == null ? void 0 : e.scale) ?? 1,
|
|
4029
|
+
(e == null ? void 0 : e.headingOffset) ?? 0,
|
|
4030
|
+
(e == null ? void 0 : e.pitchOffset) ?? 0,
|
|
4031
|
+
(e == null ? void 0 : e.rollOffset) ?? 0
|
|
4032
|
+
].join("|");
|
|
4033
|
+
}
|
|
4034
|
+
class po {
|
|
4035
|
+
constructor(e) {
|
|
4036
|
+
a(this, "buckets", /* @__PURE__ */ new Map());
|
|
4037
|
+
a(this, "sites", []);
|
|
4038
|
+
this.cellDeg = e;
|
|
4039
|
+
}
|
|
4040
|
+
build(e) {
|
|
4041
|
+
this.sites = e, this.buckets.clear();
|
|
4042
|
+
for (let t = 0; t < e.length; t++) {
|
|
4043
|
+
const s = e[t], n = yo(s.lon, s.lat, this.cellDeg);
|
|
4044
|
+
let o = this.buckets.get(n);
|
|
4045
|
+
o || (o = [], this.buckets.set(n, o)), o.push(t);
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
query(e) {
|
|
4049
|
+
if (this.sites.length === 0)
|
|
4050
|
+
return [];
|
|
4051
|
+
const t = [], s = /* @__PURE__ */ new Set(), n = go(e);
|
|
4052
|
+
for (const o of n) {
|
|
4053
|
+
const r = Xe(o.west, this.cellDeg), l = Xe(o.east, this.cellDeg), h = Ue(o.south, this.cellDeg), c = Ue(o.north, this.cellDeg);
|
|
4054
|
+
for (let m = h; m <= c; m++)
|
|
4055
|
+
for (let u = r; u <= l; u++) {
|
|
4056
|
+
const v = this.buckets.get(`${u}:${m}`);
|
|
4057
|
+
if (v)
|
|
4058
|
+
for (const d of v) {
|
|
4059
|
+
if (s.has(d))
|
|
4060
|
+
continue;
|
|
4061
|
+
const p = this.sites[d];
|
|
4062
|
+
vo(e, p.lon, p.lat) && (s.add(d), t.push(d));
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
return t;
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
4069
|
+
function go(i) {
|
|
4070
|
+
return i.east >= i.west ? [i] : [
|
|
4071
|
+
{ west: i.west, east: 180, south: i.south, north: i.north },
|
|
4072
|
+
{ west: -180, east: i.east, south: i.south, north: i.north }
|
|
4073
|
+
];
|
|
4074
|
+
}
|
|
4075
|
+
function vo(i, e, t) {
|
|
4076
|
+
return t >= i.south && t <= i.north ? i.east >= i.west ? e >= i.west && e <= i.east : e >= i.west || e <= i.east : !1;
|
|
4077
|
+
}
|
|
4078
|
+
function yo(i, e, t) {
|
|
4079
|
+
return `${Xe(i, t)}:${Ue(e, t)}`;
|
|
4080
|
+
}
|
|
4081
|
+
function Xe(i, e) {
|
|
4082
|
+
return Math.floor((wo(i) + 180) / e);
|
|
4083
|
+
}
|
|
4084
|
+
function Ue(i, e) {
|
|
4085
|
+
return Math.floor((Mo(i, -90, 90) + 90) / e);
|
|
4086
|
+
}
|
|
4087
|
+
function wo(i) {
|
|
4088
|
+
let e = i;
|
|
4089
|
+
for (; e < -180; )
|
|
4090
|
+
e += 360;
|
|
4091
|
+
for (; e > 180; )
|
|
4092
|
+
e -= 360;
|
|
4093
|
+
return e;
|
|
4094
|
+
}
|
|
4095
|
+
function Mo(i, e, t) {
|
|
4096
|
+
return Math.min(t, Math.max(e, i));
|
|
4097
|
+
}
|
|
4098
|
+
const Fe = 22, _t = 2, Io = 48;
|
|
4099
|
+
class Eo extends qe {
|
|
4100
|
+
constructor(t, s) {
|
|
4101
|
+
super();
|
|
4102
|
+
a(this, "options");
|
|
4103
|
+
a(this, "stats", {
|
|
4104
|
+
total: 0,
|
|
4105
|
+
inView: 0,
|
|
4106
|
+
iconCount: 0,
|
|
4107
|
+
lowModelCount: 0,
|
|
4108
|
+
lowModelEligibleCount: 0,
|
|
4109
|
+
mode: "icon"
|
|
4110
|
+
});
|
|
4111
|
+
a(this, "iconRenderer");
|
|
4112
|
+
a(this, "lowModelRenderer");
|
|
4113
|
+
a(this, "spatialIndex");
|
|
4114
|
+
a(this, "typeIndex", /* @__PURE__ */ new Map());
|
|
4115
|
+
a(this, "typeColor", []);
|
|
4116
|
+
a(this, "visibleSites", []);
|
|
4117
|
+
a(this, "sites", []);
|
|
4118
|
+
a(this, "screenPickIndex", null);
|
|
4119
|
+
a(this, "hoverPosition", null);
|
|
4120
|
+
a(this, "hoverRafId", 0);
|
|
4121
|
+
a(this, "lastHoverSiteId", null);
|
|
4122
|
+
a(this, "destroyed", !1);
|
|
4123
|
+
a(this, "lastUpdateAt", 0);
|
|
4124
|
+
a(this, "lastFrameAt", ze());
|
|
4125
|
+
a(this, "rafId", 0);
|
|
4126
|
+
a(this, "removeCameraListener");
|
|
4127
|
+
a(this, "inputHandler");
|
|
4128
|
+
a(this, "eventBusBinding");
|
|
4129
|
+
this.viewer = t, this.options = So(s);
|
|
4130
|
+
const n = this.options.siteTypes;
|
|
4131
|
+
n.forEach((r, l) => {
|
|
4132
|
+
this.typeIndex.set(r.type, l);
|
|
4133
|
+
const h = D.fromCssColorString(r.defaultColor);
|
|
4134
|
+
this.typeColor.push([h.red, h.green, h.blue, h.alpha]);
|
|
4135
|
+
});
|
|
4136
|
+
const o = Math.max(16, ...n.map((r) => r.pointPixelSize * 2));
|
|
4137
|
+
this.iconRenderer = new Qt(t.scene, {
|
|
4138
|
+
typeStyles: n.map((r) => ({ type: r.type, iconPath: r.iconPath, defaultColor: r.defaultColor })),
|
|
4139
|
+
pixelSize: o
|
|
4140
|
+
}), t.scene.primitives.add(this.iconRenderer), this.lowModelRenderer = new fo(t.scene, this.options.siteTypes, this.options.fadeMs), this.spatialIndex = new po(this.options.indexCellDeg), this.removeCameraListener = this.viewer.camera.changed.addEventListener(() => this.scheduleRefresh()), this.inputHandler = new Wt(this.viewer.scene.canvas), this.inputHandler.setInputAction((r) => {
|
|
4141
|
+
this.handleContextMenuAt(r.position);
|
|
4142
|
+
}, N.RIGHT_CLICK), this.inputHandler.setInputAction((r) => {
|
|
4143
|
+
this.emit("pick", this.pickAt(r.position));
|
|
4144
|
+
}, N.LEFT_CLICK), this.inputHandler.setInputAction((r) => {
|
|
4145
|
+
this.scheduleHoverAt(r.endPosition);
|
|
4146
|
+
}, N.MOUSE_MOVE), this.rafId = requestAnimationFrame((r) => this.tick(r)), this.eventBusBinding = Jn(this, { replaceExisting: !0 });
|
|
4147
|
+
}
|
|
4148
|
+
/** 屏幕坐标拾取最近站点(实例化符号/低模无法 drillPick,按位置最近命中)。 */
|
|
4149
|
+
pickAt(t, s = 22) {
|
|
4150
|
+
return this.nearestSiteAtScreen(t, s);
|
|
4151
|
+
}
|
|
4152
|
+
setData(t) {
|
|
4153
|
+
this.destroyed || (this.sites = To(t, this.options.siteTypesByType), this.spatialIndex.build(this.sites), this.stats.total = this.sites.length, this.refresh(!0));
|
|
4154
|
+
}
|
|
4155
|
+
clear() {
|
|
4156
|
+
this.sites = [], this.spatialIndex.build(this.sites), this.iconRenderer.setInstances([]), this.lowModelRenderer.clear(), this.visibleSites = [], this.screenPickIndex = null, this.clearHover(), this.stats.total = 0, this.stats.inView = 0, this.stats.iconCount = 0, this.stats.lowModelCount = 0, this.stats.lowModelEligibleCount = 0;
|
|
4157
|
+
}
|
|
4158
|
+
destroy() {
|
|
4159
|
+
var t;
|
|
4160
|
+
this.destroyed || (this.destroyed = !0, this.eventBusBinding.dispose(), this.rafId && cancelAnimationFrame(this.rafId), (t = this.removeCameraListener) == null || t.call(this), this.inputHandler.destroy(), this.clearHover(), this.viewer.scene.primitives.remove(this.iconRenderer), this.lowModelRenderer.destroy(), this.clear());
|
|
4161
|
+
}
|
|
4162
|
+
tick(t) {
|
|
4163
|
+
if (this.destroyed)
|
|
4164
|
+
return;
|
|
4165
|
+
const s = Math.max(0, (t - this.lastFrameAt) / 1e3);
|
|
4166
|
+
this.lastFrameAt = t, this.lowModelRenderer.update(s), this.rafId = requestAnimationFrame((n) => this.tick(n));
|
|
4167
|
+
}
|
|
4168
|
+
scheduleRefresh() {
|
|
4169
|
+
ze() - this.lastUpdateAt < this.options.updateThrottleMs || this.refresh(!1);
|
|
4170
|
+
}
|
|
4171
|
+
refresh(t) {
|
|
4172
|
+
if (this.destroyed)
|
|
4173
|
+
return;
|
|
4174
|
+
const s = ze();
|
|
4175
|
+
if (!t && s - this.lastUpdateAt < this.options.updateThrottleMs)
|
|
4176
|
+
return;
|
|
4177
|
+
if (this.lastUpdateAt = s, this.sites.length === 0) {
|
|
4178
|
+
this.iconRenderer.setInstances([]), this.lowModelRenderer.clear(), this.visibleSites = [], this.screenPickIndex = null, this.clearHover(), this.stats.inView = 0, this.stats.iconCount = 0, this.stats.lowModelCount = 0, this.stats.lowModelEligibleCount = 0;
|
|
4179
|
+
return;
|
|
4180
|
+
}
|
|
4181
|
+
const n = Co(this.viewer), r = this.spatialIndex.query(n).map((d) => this.sites[d]), h = this.viewer.scene.camera.positionCartographic.height <= this.options.modelSwitchHeight, c = r.filter((d) => {
|
|
4182
|
+
var g;
|
|
4183
|
+
const p = this.options.siteTypesByType.get(d.type);
|
|
4184
|
+
return !!((g = p == null ? void 0 : p.lowModel) != null && g.url);
|
|
4185
|
+
}), m = h ? c.slice(0, this.options.maxVisibleLowModels) : [], u = new Set(m.map((d) => d.id)), v = h ? r.filter((d) => !u.has(d.id)) : r;
|
|
4186
|
+
this.iconRenderer.setInstances(
|
|
4187
|
+
v.map((d) => {
|
|
4188
|
+
const p = this.typeIndex.get(d.type) ?? 0;
|
|
4189
|
+
return { id: d.id, lon: d.lon, lat: d.lat, height: d.height, heading: d.heading, color: this.typeColor[p], iconIndex: p };
|
|
4190
|
+
})
|
|
4191
|
+
), this.lowModelRenderer.setSites(m), this.visibleSites = r, this.screenPickIndex = this.buildScreenPickIndex(r), this.repickHover(), this.stats.inView = r.length, this.stats.lowModelEligibleCount = c.length, this.stats.lowModelCount = m.length, this.stats.iconCount = v.length, this.stats.mode = h ? "low-model" : "icon";
|
|
4192
|
+
}
|
|
4193
|
+
handleContextMenuAt(t) {
|
|
4194
|
+
const s = this.nearestSiteAtScreen(t, Fe);
|
|
4195
|
+
s && this.emit("contextmenu", {
|
|
4196
|
+
site: s,
|
|
4197
|
+
screenX: t.x,
|
|
4198
|
+
screenY: t.y,
|
|
4199
|
+
cartesian: f.fromDegrees(s.lon, s.lat, s.height)
|
|
4200
|
+
});
|
|
4201
|
+
}
|
|
4202
|
+
scheduleHoverAt(t) {
|
|
4203
|
+
if (!this.destroyed) {
|
|
4204
|
+
if (this.hoverPosition) {
|
|
4205
|
+
const s = Math.abs(t.x - this.hoverPosition.x), n = Math.abs(t.y - this.hoverPosition.y);
|
|
4206
|
+
if (s < _t && n < _t)
|
|
4207
|
+
return;
|
|
4208
|
+
J.clone(t, this.hoverPosition);
|
|
4209
|
+
} else
|
|
4210
|
+
this.hoverPosition = J.clone(t);
|
|
4211
|
+
this.hoverRafId || (this.hoverRafId = requestAnimationFrame(() => this.flushHover()));
|
|
4212
|
+
}
|
|
4213
|
+
}
|
|
4214
|
+
flushHover() {
|
|
4215
|
+
if (this.hoverRafId = 0, this.destroyed || !this.hoverPosition)
|
|
4216
|
+
return;
|
|
4217
|
+
const t = this.nearestSiteAtScreen(this.hoverPosition, Fe), s = (t == null ? void 0 : t.id) ?? null;
|
|
4218
|
+
s !== this.lastHoverSiteId && (this.lastHoverSiteId = s, this.emit("hover", t));
|
|
4219
|
+
}
|
|
4220
|
+
repickHover() {
|
|
4221
|
+
this.hoverPosition && (this.hoverRafId || (this.hoverRafId = requestAnimationFrame(() => this.flushHover())));
|
|
4222
|
+
}
|
|
4223
|
+
clearHover() {
|
|
4224
|
+
this.hoverRafId && (cancelAnimationFrame(this.hoverRafId), this.hoverRafId = 0), this.hoverPosition = null, this.lastHoverSiteId !== null && (this.lastHoverSiteId = null, this.emit("hover", null));
|
|
4225
|
+
}
|
|
4226
|
+
buildScreenPickIndex(t) {
|
|
4227
|
+
const s = this.viewer.scene.canvas;
|
|
4228
|
+
if (t.length === 0 || s.clientWidth <= 0 || s.clientHeight <= 0)
|
|
4229
|
+
return null;
|
|
4230
|
+
const n = new Float32Array(t.length), o = new Float32Array(t.length);
|
|
4231
|
+
n.fill(Number.NaN), o.fill(Number.NaN);
|
|
4232
|
+
const r = new f();
|
|
4233
|
+
for (let c = 0; c < t.length; c++) {
|
|
4234
|
+
const m = t[c];
|
|
4235
|
+
f.fromDegrees(m.lon, m.lat, m.height, void 0, r);
|
|
4236
|
+
const u = Ae.wgs84ToWindowCoordinates(this.viewer.scene, r);
|
|
4237
|
+
u && (!Number.isFinite(u.x) || !Number.isFinite(u.y) || u.x < 0 || u.y < 0 || u.x > s.clientWidth || u.y > s.clientHeight || (n[c] = u.x, o[c] = u.y));
|
|
4238
|
+
}
|
|
4239
|
+
const l = Math.max(Io, Fe * 2), h = /* @__PURE__ */ new Map();
|
|
4240
|
+
for (let c = 0; c < t.length; c++) {
|
|
4241
|
+
const m = n[c], u = o[c];
|
|
4242
|
+
if (!Number.isFinite(m) || !Number.isFinite(u))
|
|
4243
|
+
continue;
|
|
4244
|
+
const v = Ot(Math.floor(m / l), Math.floor(u / l)), d = h.get(v);
|
|
4245
|
+
d ? d.push(c) : h.set(v, [c]);
|
|
4246
|
+
}
|
|
4247
|
+
return {
|
|
4248
|
+
canvasWidth: s.clientWidth,
|
|
4249
|
+
canvasHeight: s.clientHeight,
|
|
4250
|
+
cellSize: l,
|
|
4251
|
+
bins: h,
|
|
4252
|
+
windowX: n,
|
|
4253
|
+
windowY: o
|
|
4254
|
+
};
|
|
4255
|
+
}
|
|
4256
|
+
// 实例化符号/低模无法 drillPick,改用屏幕索引命中(refresh/相机节流时重建)。
|
|
4257
|
+
nearestSiteAtScreen(t, s) {
|
|
4258
|
+
const n = this.screenPickIndex;
|
|
4259
|
+
if (!n)
|
|
4260
|
+
return null;
|
|
4261
|
+
const o = this.viewer.scene.canvas;
|
|
4262
|
+
if (n.canvasWidth !== o.clientWidth || n.canvasHeight !== o.clientHeight)
|
|
4263
|
+
return this.screenPickIndex = this.buildScreenPickIndex(this.visibleSites), this.nearestSiteAtScreen(t, s);
|
|
4264
|
+
let r = null, l = s * s;
|
|
4265
|
+
const h = Math.floor(t.x / n.cellSize), c = Math.floor(t.y / n.cellSize);
|
|
4266
|
+
for (let m = c - 1; m <= c + 1; m++)
|
|
4267
|
+
for (let u = h - 1; u <= h + 1; u++) {
|
|
4268
|
+
const v = n.bins.get(Ot(u, m));
|
|
4269
|
+
if (v)
|
|
4270
|
+
for (const d of v) {
|
|
4271
|
+
const p = n.windowX[d] - t.x, g = n.windowY[d] - t.y, y = p * p + g * g;
|
|
4272
|
+
y <= l && (l = y, r = this.visibleSites[d] ?? null);
|
|
4273
|
+
}
|
|
4274
|
+
}
|
|
4275
|
+
return r;
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
function Ot(i, e) {
|
|
4279
|
+
return `${i}:${e}`;
|
|
4280
|
+
}
|
|
4281
|
+
function So(i) {
|
|
4282
|
+
var s;
|
|
4283
|
+
if (!((s = i.siteTypes) != null && s.length))
|
|
4284
|
+
throw new Error("SiteLayer requires at least one site type.");
|
|
4285
|
+
if (!Number.isFinite(i.modelSwitchHeight) || i.modelSwitchHeight <= 0)
|
|
4286
|
+
throw new Error("SiteLayer modelSwitchHeight must be a positive number.");
|
|
4287
|
+
const e = i.siteTypes.map(xo), t = /* @__PURE__ */ new Map();
|
|
4288
|
+
for (const n of e)
|
|
4289
|
+
t.set(n.type, n);
|
|
4290
|
+
return {
|
|
4291
|
+
siteTypes: e,
|
|
4292
|
+
siteTypesByType: t,
|
|
4293
|
+
modelSwitchHeight: i.modelSwitchHeight,
|
|
4294
|
+
maxVisibleLowModels: Math.max(0, i.maxVisibleLowModels ?? 3e3),
|
|
4295
|
+
updateThrottleMs: Math.max(16, i.updateThrottleMs ?? 100),
|
|
4296
|
+
indexCellDeg: bo(i.indexCellDeg ?? 0.25, 0.02, 10),
|
|
4297
|
+
fadeMs: Math.max(0, i.fadeMs ?? 250)
|
|
4298
|
+
};
|
|
4299
|
+
}
|
|
4300
|
+
function xo(i) {
|
|
4301
|
+
if (!i || typeof i != "object")
|
|
4302
|
+
throw new Error("Invalid site type config.");
|
|
4303
|
+
if (typeof i.type != "string" || i.type.length === 0)
|
|
4304
|
+
throw new Error("site type must be a non-empty string.");
|
|
4305
|
+
if (typeof i.iconPath != "string" || i.iconPath.length === 0)
|
|
4306
|
+
throw new Error(`site type "${i.type}" iconPath is required.`);
|
|
4307
|
+
return {
|
|
4308
|
+
...i,
|
|
4309
|
+
name: i.name ?? i.type,
|
|
4310
|
+
defaultColor: i.defaultColor ?? "#ffffff",
|
|
4311
|
+
pointPixelSize: Math.max(6, i.pointPixelSize ?? 12)
|
|
4312
|
+
};
|
|
4313
|
+
}
|
|
4314
|
+
function To(i, e) {
|
|
4315
|
+
return i.map((t, s) => {
|
|
4316
|
+
if (!t || typeof t != "object")
|
|
4317
|
+
throw new Error(`Invalid site at index ${s}.`);
|
|
4318
|
+
if (typeof t.id != "string" || t.id.length === 0)
|
|
4319
|
+
throw new Error(`sites[${s}].id must be a non-empty string.`);
|
|
4320
|
+
if (typeof t.type != "string" || !e.has(t.type))
|
|
4321
|
+
throw new Error(`sites[${s}].type "${t.type}" is not registered.`);
|
|
4322
|
+
return Ce(t.lon, `sites[${s}].lon`), Ce(t.lat, `sites[${s}].lat`), Ce(t.height, `sites[${s}].height`), t.heading != null && Ce(t.heading, `sites[${s}].heading`), { ...t };
|
|
4323
|
+
});
|
|
4324
|
+
}
|
|
4325
|
+
function Co(i) {
|
|
4326
|
+
const e = i.camera.computeViewRectangle();
|
|
4327
|
+
return e ? {
|
|
4328
|
+
west: A.toDegrees(e.west),
|
|
4329
|
+
east: A.toDegrees(e.east),
|
|
4330
|
+
south: A.toDegrees(e.south),
|
|
4331
|
+
north: A.toDegrees(e.north)
|
|
4332
|
+
} : { west: -180, east: 180, south: -85, north: 85 };
|
|
4333
|
+
}
|
|
4334
|
+
function Ce(i, e) {
|
|
4335
|
+
if (typeof i != "number" || !Number.isFinite(i))
|
|
4336
|
+
throw new Error(`${e} must be a finite number.`);
|
|
4337
|
+
}
|
|
4338
|
+
function bo(i, e, t) {
|
|
4339
|
+
return Math.min(t, Math.max(e, i));
|
|
4340
|
+
}
|
|
4341
|
+
function ze() {
|
|
4342
|
+
return typeof performance < "u" ? performance.now() : Date.now();
|
|
4343
|
+
}
|
|
4344
|
+
const li = "KGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIHEoZSxyLHMsbixvKXtsZXQgdT1uLGY9bztpZih1PT1udWxsfHxmPT1udWxsKXtsZXQgYz0wLHg9MDtmb3IobGV0IGE9MDthPHM7YSsrKWMrPWVbYV0seCs9clthXTt1PWMvcyxmPXgvc31jb25zdCBBPTExMTMyMCpNYXRoLmNvcyhmKk1hdGguUEkvMTgwKSxkPW5ldyBGbG9hdDY0QXJyYXkocyksST1uZXcgRmxvYXQ2NEFycmF5KHMpO2ZvcihsZXQgYz0wO2M8cztjKyspZFtjXT0oZVtjXS11KSpBLElbY109KHJbY10tZikqMTExMzIwO3JldHVybnt4czpkLHlzOkksbG9uMDp1LGxhdDA6Zn19ZnVuY3Rpb24gWChlKXtyZXR1cm4gZSY9NjU1MzUsZT0oZXxlPDw4KSYxNjcxMTkzNSxlPShlfGU8PDQpJjI1MjY0NTEzNSxlPShlfGU8PDIpJjg1ODk5MzQ1OSxlPShlfGU8PDEpJjE0MzE2NTU3NjUsZX1mdW5jdGlvbiBKKGUscil7cmV0dXJuKFgoZSl8WChyKTw8MSk+Pj4wfWNvbnN0IGI9MTEscD0xPDxiLEY9cC0xLHo9bmV3IEludDMyQXJyYXkocCksQz1uZXcgSW50MzJBcnJheSgxNik7ZnVuY3Rpb24gTihlKXtyZXR1cm57Y2FwOmUsa2V5czpuZXcgVWludDMyQXJyYXkoZSksaWR4QTpuZXcgSW50MzJBcnJheShlKSxpZHhCOm5ldyBJbnQzMkFycmF5KGUpLHNvcnRlZEtleXM6bmV3IFVpbnQzMkFycmF5KGUpLGNsdXN0ZXJPZjpuZXcgSW50MzJBcnJheShlKSxoZWFkczpuZXcgSW50MzJBcnJheShlKSxzaXplczpuZXcgSW50MzJBcnJheShlKX19ZnVuY3Rpb24gVihlLHIpe2lmKHI8PWUuY2FwKXJldHVybjtjb25zdCBzPU1hdGgubWF4KHIsZS5jYXAqMik7ZS5jYXA9cyxlLmtleXM9bmV3IFVpbnQzMkFycmF5KHMpLGUuaWR4QT1uZXcgSW50MzJBcnJheShzKSxlLmlkeEI9bmV3IEludDMyQXJyYXkocyksZS5zb3J0ZWRLZXlzPW5ldyBVaW50MzJBcnJheShzKSxlLmNsdXN0ZXJPZj1uZXcgSW50MzJBcnJheShzKSxlLmhlYWRzPW5ldyBJbnQzMkFycmF5KHMpLGUuc2l6ZXM9bmV3IEludDMyQXJyYXkocyl9Y29uc3QgVz0oZSxyKT0+KHtjb3VudDpyLGxldmVsOjAsY2VsbE1ldGVyczplLGNsdXN0ZXJDb3VudDowLGNsdXN0ZXJPZjpuZXcgSW50MzJBcnJheSgwKSxoZWFkSW5kZXg6bmV3IEludDMyQXJyYXkoMCksY2x1c3RlclNpemU6bmV3IEludDMyQXJyYXkoMCksbGV2ZWxzOltdfSk7ZnVuY3Rpb24gJChlLHIscyxuLG8sdSxmLG0pe2xldCBBPTEvMCxkPTEvMCxJPS0xLzAsYz0tMS8wO2ZvcihsZXQgdD0wO3Q8bjt0Kyspe2NvbnN0IGw9clt0XSxpPXNbdF07bDxBJiYoQT1sKSxpPGQmJihkPWkpLGw+SSYmKEk9bCksaT5jJiYoYz1pKX1jb25zdCB4PTEvbztsZXQgYT1vLEU9TWF0aC5tYXgoKEktQSkqeCwoYy1kKSp4KTtmb3IoO0U+PTY1NTM1OylhKj0yLEUvPTI7Y29uc3QgTz0xL2EsaD1lLmtleXM7bGV0IHc9MDtmb3IobGV0IHQ9MDt0PG47dCsrKXtjb25zdCBsPShyW3RdLUEpKk98MCxpPShzW3RdLWQpKk98MCxMPUoobCxpKTtoW3RdPUwsTD53JiYodz1MKX1jb25zdCBUPXc+MD8zMi1NYXRoLmNsejMyKHcpOjEsRz1NYXRoLm1heCgxLE1hdGguY2VpbChUL2IpKTtsZXQgdj1lLmlkeEEsZz1lLmlkeEI7Zm9yKGxldCB0PTA7dDxuO3QrKyl2W3RdPXQ7Y29uc3QgUz1lLnNvcnRlZEtleXM7Zm9yKGxldCB0PTA7dDxHO3QrKyl7Y29uc3QgbD10KmIsaT10PT09Ry0xO3ouZmlsbCgwKTtmb3IobGV0IHk9MDt5PG47eSsrKXpbaFt2W3ldXT4+PmwmRl0rKztsZXQgTD0wO2ZvcihsZXQgeT0wO3k8cDt5Kyspe2NvbnN0IF89elt5XTt6W3ldPUwsTCs9X31mb3IobGV0IHk9MDt5PG47eSsrKXtjb25zdCBfPXZbeV0sUT1oW19dLFo9eltRPj4+bCZGXSsrO2dbWl09XyxpJiYoU1taXT1RKX1jb25zdCBhZT12O3Y9ZyxnPWFlfWNvbnN0IHNlPXY7Qy5maWxsKDApO2xldCBZPVNbMF07Zm9yKGxldCB0PTE7dDxuO3QrKyl7Y29uc3QgbD1TW3RdLGk9bF5ZO1k9bCxpIT09MCYmQ1szMS1NYXRoLmNsejMyKGkpPj4xXSsrfWNvbnN0IEg9W107bGV0IEI9MCxNPW4sRD0wO2ZvcihsZXQgdD0xNTt0Pj0wO3QtLSlEKz1DW3RdO2ZvcihsZXQgdD0wO3Q8Zjt0Kyspe2NvbnN0IGw9MStEO2lmKEgucHVzaCh7bGV2ZWw6dCxjZWxsTWV0ZXJzOmEqKDE8PHQpLGNsdXN0ZXJzOmx9KSxCPXQsTT1sLGw8PXUpYnJlYWs7dDwxNiYmKEQtPUNbdF0pfWNvbnN0IHJlPTIqQixQPWUuY2x1c3Rlck9mLFU9ZS5oZWFkcyxrPWUuc2l6ZXM7ay5maWxsKDAsMCxNKTtsZXQgUj0tMSxqPS0xO2ZvcihsZXQgdD0wO3Q8bjt0Kyspe2NvbnN0IGw9c2VbdF0saT1TW3RdPj4+cmU7KHQ9PT0wfHxpIT09aikmJihSKyssVVtSXT1sLGo9aSksUFtsXT1SLGtbUl0rK31jb25zdCBuZT1tP1Auc3ViYXJyYXkoMCxuKTpQLnNsaWNlKDAsbiksbGU9bT9VLnN1YmFycmF5KDAsTSk6VS5zbGljZSgwLE0pLG9lPW0/ay5zdWJhcnJheSgwLE0pOmsuc2xpY2UoMCxNKTtyZXR1cm57Y291bnQ6bixsZXZlbDpCLGNlbGxNZXRlcnM6YSooMTw8QiksY2x1c3RlckNvdW50Ok0sY2x1c3Rlck9mOm5lLGhlYWRJbmRleDpsZSxjbHVzdGVyU2l6ZTpvZSxsZXZlbHM6SH19ZnVuY3Rpb24gZWUoZT0wKXtjb25zdCByPU4oTWF0aC5tYXgoMSxlKSk7cmV0dXJuKHMsbixvLHU9e30pPT57Y29uc3QgZj11LmJhc2VDZWxsTWV0ZXJzPz8yMDA7cmV0dXJuIG88PTA/VyhmLG8pOihWKHIsbyksJChyLHMsbixvLGYsdS5tYXhDbHVzdGVycz8/M2U0LHUubWF4TGV2ZWxzPz8yMCwhMCkpfX1jb25zdCB0ZT1lZSgpO2Z1bmN0aW9uIEsoZSxyKXtyZXR1cm4gZSYmZS5ieXRlTGVuZ3RoPj1yKjQ/bmV3IEludDMyQXJyYXkoZSwwLHIpOm5ldyBJbnQzMkFycmF5KHIpfXNlbGYub25tZXNzYWdlPWU9Pntjb25zdHtqb2JJZDpyLGxvbkJ1ZjpzLGxhdEJ1ZjpuLGNvdW50Om8sYmFzZTp1LG1heDpmLGxvbjA6bSxsYXQwOkF9PWUuZGF0YSxkPW5ldyBGbG9hdDY0QXJyYXkocywwLG8pLEk9bmV3IEZsb2F0NjRBcnJheShuLDAsbyksYz1wZXJmb3JtYW5jZS5ub3coKSx4PXEoZCxJLG8sbSxBKSxhPXRlKHgueHMseC55cyxvLHtiYXNlQ2VsbE1ldGVyczp1LG1heENsdXN0ZXJzOmZ9KSxFPWEuY2x1c3RlckNvdW50LE89SyhlLmRhdGEucmV0Q2x1c3Rlck9mLG8pO08uc2V0KGEuY2x1c3Rlck9mLnN1YmFycmF5KDAsbykpO2NvbnN0IGg9SyhlLmRhdGEucmV0SGVhZCxmKTtoLnNldChhLmhlYWRJbmRleC5zdWJhcnJheSgwLEUpKTtjb25zdCB3PUsoZS5kYXRhLnJldFNpemUsZik7dy5zZXQoYS5jbHVzdGVyU2l6ZS5zdWJhcnJheSgwLEUpKTtjb25zdCBUPXBlcmZvcm1hbmNlLm5vdygpLWM7c2VsZi5wb3N0TWVzc2FnZSh7am9iSWQ6cixsb25CdWY6cyxsYXRCdWY6bixjbHVzdGVyT2Y6Ty5idWZmZXIsaGVhZDpoLmJ1ZmZlcixzaXplOncuYnVmZmVyLGNsdXN0ZXJDb3VudDpFLGxldmVsOmEubGV2ZWwsY2VsbE1ldGVyczphLmNlbGxNZXRlcnMsY29tcHV0ZU1zOlR9LFtzLG4sTy5idWZmZXIsaC5idWZmZXIsdy5idWZmZXJdKX19KSgpOwo=", Bt = typeof window < "u" && window.Blob && new Blob([atob(li)], { type: "text/javascript;charset=utf-8" });
|
|
4345
|
+
function Po() {
|
|
4346
|
+
let i;
|
|
4347
|
+
try {
|
|
4348
|
+
if (i = Bt && (window.URL || window.webkitURL).createObjectURL(Bt), !i)
|
|
4349
|
+
throw "";
|
|
4350
|
+
return new Worker(i);
|
|
4351
|
+
} catch {
|
|
4352
|
+
return new Worker("data:application/javascript;base64," + li);
|
|
4353
|
+
} finally {
|
|
4354
|
+
i && (window.URL || window.webkitURL).revokeObjectURL(i);
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4357
|
+
function _o() {
|
|
4358
|
+
const i = new Po();
|
|
4359
|
+
let e = 1, t = !1, s = new Float64Array(0), n = new Float64Array(0), o = null, r = null, l = null, h = null, c = new Float64Array(0), m = new Float64Array(0), u = null;
|
|
4360
|
+
function v(p) {
|
|
4361
|
+
s.length < p && (s = new Float64Array(p), n = new Float64Array(p));
|
|
4362
|
+
}
|
|
4363
|
+
function d(p, g, y, w, M) {
|
|
4364
|
+
v(p), M && (s.set(M.lons.subarray(0, p)), n.set(M.lats.subarray(0, p)));
|
|
4365
|
+
const I = s.buffer, C = n.buffer, k = e++;
|
|
4366
|
+
t = !0, h = { resolve: y, startMs: w };
|
|
4367
|
+
const S = {
|
|
4368
|
+
jobId: k,
|
|
4369
|
+
lonBuf: I,
|
|
4370
|
+
latBuf: C,
|
|
4371
|
+
count: p,
|
|
4372
|
+
base: g.baseCellMeters ?? 200,
|
|
4373
|
+
max: g.maxClusters ?? 3e4,
|
|
4374
|
+
lon0: g.lon0 ?? 0,
|
|
4375
|
+
lat0: g.lat0 ?? 0
|
|
4376
|
+
}, T = [I, C];
|
|
4377
|
+
o && (S.retClusterOf = o, T.push(o)), r && (S.retHead = r, T.push(r)), l && (S.retSize = l, T.push(l)), o = r = l = null, i.postMessage(S, T);
|
|
4378
|
+
}
|
|
4379
|
+
return i.onmessage = (p) => {
|
|
4380
|
+
const g = p.data;
|
|
4381
|
+
t = !1, s = new Float64Array(g.lonBuf), n = new Float64Array(g.latBuf);
|
|
4382
|
+
const y = h;
|
|
4383
|
+
h = null;
|
|
4384
|
+
const w = g.clusterCount;
|
|
4385
|
+
if (o = g.clusterOf, r = g.head, l = g.size, y == null || y.resolve({
|
|
4386
|
+
clusterOf: new Int32Array(g.clusterOf),
|
|
4387
|
+
headIndex: new Int32Array(g.head, 0, w),
|
|
4388
|
+
clusterSize: new Int32Array(g.size, 0, w),
|
|
4389
|
+
clusterCount: w,
|
|
4390
|
+
level: g.level,
|
|
4391
|
+
cellMeters: g.cellMeters,
|
|
4392
|
+
computeMs: g.computeMs,
|
|
4393
|
+
roundTripMs: performance.now() - ((y == null ? void 0 : y.startMs) ?? performance.now())
|
|
4394
|
+
}), u) {
|
|
4395
|
+
const M = u;
|
|
4396
|
+
u = null, d(M.count, M.options, M.resolve, M.startMs, { lons: c, lats: m });
|
|
4397
|
+
}
|
|
4398
|
+
}, {
|
|
4399
|
+
run(p, g, y, w = {}) {
|
|
4400
|
+
return new Promise((M) => {
|
|
4401
|
+
if (!t) {
|
|
4402
|
+
d(y, w, M, performance.now(), { lons: p, lats: g });
|
|
4403
|
+
return;
|
|
4404
|
+
}
|
|
4405
|
+
u && u.resolve(null), c.length < y && (c = new Float64Array(y), m = new Float64Array(y)), c.set(p.subarray(0, y)), m.set(g.subarray(0, y)), u = { count: y, options: w, resolve: M, startMs: performance.now() };
|
|
4406
|
+
});
|
|
4407
|
+
},
|
|
4408
|
+
inputBuffers(p) {
|
|
4409
|
+
if (t)
|
|
4410
|
+
throw new Error("inputBuffers 只能在 Worker 空闲时调用(输入缓冲此刻已被 transfer)");
|
|
4411
|
+
return v(p), { lons: s.subarray(0, p), lats: n.subarray(0, p) };
|
|
4412
|
+
},
|
|
4413
|
+
runReusing(p, g = {}) {
|
|
4414
|
+
return new Promise((y) => {
|
|
4415
|
+
if (t)
|
|
4416
|
+
throw new Error("runReusing 仅限串行使用:上一次任务尚未返回");
|
|
4417
|
+
d(p, g, y, performance.now(), null);
|
|
4418
|
+
});
|
|
4419
|
+
},
|
|
4420
|
+
terminate() {
|
|
4421
|
+
i.terminate(), h = null, u = null, o = r = l = null;
|
|
4422
|
+
}
|
|
4423
|
+
};
|
|
4424
|
+
}
|
|
4425
|
+
const Nt = 111320;
|
|
4426
|
+
function Oo(i, e, t, s, n) {
|
|
4427
|
+
let o = s, r = n;
|
|
4428
|
+
if (o == null || r == null) {
|
|
4429
|
+
let u = 0, v = 0;
|
|
4430
|
+
for (let d = 0; d < t; d++)
|
|
4431
|
+
u += i[d], v += e[d];
|
|
4432
|
+
o = u / t, r = v / t;
|
|
4433
|
+
}
|
|
4434
|
+
const l = Math.cos(r * Math.PI / 180), h = Nt * l, c = new Float64Array(t), m = new Float64Array(t);
|
|
4435
|
+
for (let u = 0; u < t; u++)
|
|
4436
|
+
c[u] = (i[u] - o) * h, m[u] = (e[u] - r) * Nt;
|
|
4437
|
+
return { xs: c, ys: m, lon0: o, lat0: r };
|
|
4438
|
+
}
|
|
4439
|
+
function Ft(i) {
|
|
4440
|
+
return i &= 65535, i = (i | i << 8) & 16711935, i = (i | i << 4) & 252645135, i = (i | i << 2) & 858993459, i = (i | i << 1) & 1431655765, i;
|
|
4441
|
+
}
|
|
4442
|
+
function Ro(i, e) {
|
|
4443
|
+
return (Ft(i) | Ft(e) << 1) >>> 0;
|
|
4444
|
+
}
|
|
4445
|
+
const Ge = 11, je = 1 << Ge, zt = je - 1, ue = new Int32Array(je), be = new Int32Array(16);
|
|
4446
|
+
function ci(i) {
|
|
4447
|
+
return {
|
|
4448
|
+
cap: i,
|
|
4449
|
+
keys: new Uint32Array(i),
|
|
4450
|
+
idxA: new Int32Array(i),
|
|
4451
|
+
idxB: new Int32Array(i),
|
|
4452
|
+
sortedKeys: new Uint32Array(i),
|
|
4453
|
+
clusterOf: new Int32Array(i),
|
|
4454
|
+
heads: new Int32Array(i),
|
|
4455
|
+
sizes: new Int32Array(i)
|
|
4456
|
+
};
|
|
4457
|
+
}
|
|
4458
|
+
function ko(i, e) {
|
|
4459
|
+
if (e <= i.cap)
|
|
4460
|
+
return;
|
|
4461
|
+
const t = Math.max(e, i.cap * 2);
|
|
4462
|
+
i.cap = t, i.keys = new Uint32Array(t), i.idxA = new Int32Array(t), i.idxB = new Int32Array(t), i.sortedKeys = new Uint32Array(t), i.clusterOf = new Int32Array(t), i.heads = new Int32Array(t), i.sizes = new Int32Array(t);
|
|
4463
|
+
}
|
|
4464
|
+
const hi = (i, e) => ({
|
|
4465
|
+
count: e,
|
|
4466
|
+
level: 0,
|
|
4467
|
+
cellMeters: i,
|
|
4468
|
+
clusterCount: 0,
|
|
4469
|
+
clusterOf: new Int32Array(0),
|
|
4470
|
+
headIndex: new Int32Array(0),
|
|
4471
|
+
clusterSize: new Int32Array(0),
|
|
4472
|
+
levels: []
|
|
4473
|
+
});
|
|
4474
|
+
function di(i, e, t, s, n, o, r, l) {
|
|
4475
|
+
let h = 1 / 0, c = 1 / 0, m = -1 / 0, u = -1 / 0;
|
|
4476
|
+
for (let x = 0; x < s; x++) {
|
|
4477
|
+
const H = e[x], O = t[x];
|
|
4478
|
+
H < h && (h = H), O < c && (c = O), H > m && (m = H), O > u && (u = O);
|
|
4479
|
+
}
|
|
4480
|
+
const v = 1 / n;
|
|
4481
|
+
let d = n, p = Math.max((m - h) * v, (u - c) * v);
|
|
4482
|
+
for (; p >= 65535; )
|
|
4483
|
+
d *= 2, p /= 2;
|
|
4484
|
+
const g = 1 / d, y = i.keys;
|
|
4485
|
+
let w = 0;
|
|
4486
|
+
for (let x = 0; x < s; x++) {
|
|
4487
|
+
const H = (e[x] - h) * g | 0, O = (t[x] - c) * g | 0, j = Ro(H, O);
|
|
4488
|
+
y[x] = j, j > w && (w = j);
|
|
4489
|
+
}
|
|
4490
|
+
const M = w > 0 ? 32 - Math.clz32(w) : 1, I = Math.max(1, Math.ceil(M / Ge));
|
|
4491
|
+
let C = i.idxA, k = i.idxB;
|
|
4492
|
+
for (let x = 0; x < s; x++)
|
|
4493
|
+
C[x] = x;
|
|
4494
|
+
const S = i.sortedKeys;
|
|
4495
|
+
for (let x = 0; x < I; x++) {
|
|
4496
|
+
const H = x * Ge, O = x === I - 1;
|
|
4497
|
+
ue.fill(0);
|
|
4498
|
+
for (let V = 0; V < s; V++)
|
|
4499
|
+
ue[y[C[V]] >>> H & zt]++;
|
|
4500
|
+
let j = 0;
|
|
4501
|
+
for (let V = 0; V < je; V++) {
|
|
4502
|
+
const ve = ue[V];
|
|
4503
|
+
ue[V] = j, j += ve;
|
|
4504
|
+
}
|
|
4505
|
+
for (let V = 0; V < s; V++) {
|
|
4506
|
+
const ve = C[V], Je = y[ve], Qe = ue[Je >>> H & zt]++;
|
|
4507
|
+
k[Qe] = ve, O && (S[Qe] = Je);
|
|
4508
|
+
}
|
|
4509
|
+
const ui = C;
|
|
4510
|
+
C = k, k = ui;
|
|
4511
|
+
}
|
|
4512
|
+
const T = C;
|
|
4513
|
+
be.fill(0);
|
|
4514
|
+
let z = S[0];
|
|
4515
|
+
for (let x = 1; x < s; x++) {
|
|
4516
|
+
const H = S[x], O = H ^ z;
|
|
4517
|
+
z = H, O !== 0 && be[31 - Math.clz32(O) >> 1]++;
|
|
4518
|
+
}
|
|
4519
|
+
const L = [];
|
|
4520
|
+
let E = 0, B = s, Z = 0;
|
|
4521
|
+
for (let x = 15; x >= 0; x--)
|
|
4522
|
+
Z += be[x];
|
|
4523
|
+
for (let x = 0; x < r; x++) {
|
|
4524
|
+
const H = 1 + Z;
|
|
4525
|
+
if (L.push({ level: x, cellMeters: d * (1 << x), clusters: H }), E = x, B = H, H <= o)
|
|
4526
|
+
break;
|
|
4527
|
+
x < 16 && (Z -= be[x]);
|
|
4528
|
+
}
|
|
4529
|
+
const Q = 2 * E, q = i.clusterOf, ee = i.heads, $ = i.sizes;
|
|
4530
|
+
$.fill(0, 0, B);
|
|
4531
|
+
let X = -1, le = -1;
|
|
4532
|
+
for (let x = 0; x < s; x++) {
|
|
4533
|
+
const H = T[x], O = S[x] >>> Q;
|
|
4534
|
+
(x === 0 || O !== le) && (X++, ee[X] = H, le = O), q[H] = X, $[X]++;
|
|
4535
|
+
}
|
|
4536
|
+
const me = l ? q.subarray(0, s) : q.slice(0, s), pe = l ? ee.subarray(0, B) : ee.slice(0, B), ge = l ? $.subarray(0, B) : $.slice(0, B);
|
|
4537
|
+
return {
|
|
4538
|
+
count: s,
|
|
4539
|
+
level: E,
|
|
4540
|
+
cellMeters: d * (1 << E),
|
|
4541
|
+
clusterCount: B,
|
|
4542
|
+
clusterOf: me,
|
|
4543
|
+
headIndex: pe,
|
|
4544
|
+
clusterSize: ge,
|
|
4545
|
+
levels: L
|
|
4546
|
+
};
|
|
4547
|
+
}
|
|
4548
|
+
function Bo(i = 0) {
|
|
4549
|
+
const e = ci(Math.max(1, i));
|
|
4550
|
+
return (t, s, n, o = {}) => {
|
|
4551
|
+
const r = o.baseCellMeters ?? 200;
|
|
4552
|
+
return n <= 0 ? hi(r, n) : (ko(e, n), di(
|
|
4553
|
+
e,
|
|
4554
|
+
t,
|
|
4555
|
+
s,
|
|
4556
|
+
n,
|
|
4557
|
+
r,
|
|
4558
|
+
o.maxClusters ?? 3e4,
|
|
4559
|
+
o.maxLevels ?? 20,
|
|
4560
|
+
!0
|
|
4561
|
+
));
|
|
4562
|
+
};
|
|
4563
|
+
}
|
|
4564
|
+
function No(i, e, t, s = {}) {
|
|
4565
|
+
const n = s.baseCellMeters ?? 200;
|
|
4566
|
+
if (t <= 0)
|
|
4567
|
+
return hi(n, t);
|
|
4568
|
+
const o = ci(t);
|
|
4569
|
+
return di(
|
|
4570
|
+
o,
|
|
4571
|
+
i,
|
|
4572
|
+
e,
|
|
4573
|
+
t,
|
|
4574
|
+
n,
|
|
4575
|
+
s.maxClusters ?? 3e4,
|
|
4576
|
+
s.maxLevels ?? 20,
|
|
4577
|
+
!1
|
|
4578
|
+
);
|
|
4579
|
+
}
|
|
4580
|
+
const Fo = "0.2.0";
|
|
4581
|
+
export {
|
|
4582
|
+
Si as DEFAULT_ANIMATED_POOL,
|
|
4583
|
+
Mi as DEFAULT_LOD,
|
|
4584
|
+
Ii as DEFAULT_POOL,
|
|
4585
|
+
ye as DEFAULT_SCENE,
|
|
4586
|
+
qe as EventEmitter,
|
|
4587
|
+
b as MTF_ACTION_NAMES,
|
|
4588
|
+
U as MTF_EVENT_NAMES,
|
|
4589
|
+
$e as MultiTargetFramework,
|
|
4590
|
+
Nn as MultiTargetScene,
|
|
4591
|
+
Eo as SiteLayer,
|
|
4592
|
+
Pe as TARGET_DOMAINS,
|
|
4593
|
+
xn as TrackManager,
|
|
4594
|
+
Fo as VERSION,
|
|
4595
|
+
jn as bindFrameworkEventBus,
|
|
4596
|
+
Jn as bindSiteLayerEventBus,
|
|
4597
|
+
No as clusterProgressive,
|
|
4598
|
+
_o as createClusterWorkerClient,
|
|
4599
|
+
Ho as createFrameworkEventBus,
|
|
4600
|
+
Do as createMultiTargetFramework,
|
|
4601
|
+
Bo as createQuadClusterer,
|
|
4602
|
+
$n as getFrameworkEventBus,
|
|
4603
|
+
Oo as lonLatToLocalPlane,
|
|
4604
|
+
ni as tryGetFrameworkEventBus
|
|
4605
|
+
};
|