leiting-bim 2.1.52 → 2.1.55
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/leiting-bim.es.js +1 -25503
- package/leiting-bim.umd.js +8 -8
- package/leitingbim.css +1 -1
- package/package.json +1 -1
- package/plugins/cesium-core/dist/components/HtmlOverlayLabelPool.d.ts +152 -152
- package/plugins/cesium-core/dist/components/MarkerEvent.d.ts +38 -38
- package/plugins/cesium-core/dist/components/Material/MaterialManager.d.ts +49 -49
- package/plugins/cesium-core/dist/components/Material/help/PolylineFlowMaterialProperty.d.ts +10 -10
- package/plugins/cesium-core/dist/components/Material/help/dynamicImgMaterial.d.ts +16 -16
- package/plugins/cesium-core/dist/components/Material/index.d.ts +3 -3
- package/plugins/cesium-core/dist/components/TooltipManager.d.ts +11 -11
- package/plugins/cesium-core/dist/components/draw/DrawTool.d.ts +10 -10
- package/plugins/cesium-core/dist/components/draw/handlers/CircleDrawer.d.ts +16 -16
- package/plugins/cesium-core/dist/components/draw/handlers/LineDrawer.d.ts +14 -14
- package/plugins/cesium-core/dist/components/draw/handlers/PointDrawer.d.ts +12 -12
- package/plugins/cesium-core/dist/components/draw/handlers/PolygonDrawer.d.ts +14 -14
- package/plugins/cesium-core/dist/components/draw/handlers/RectangleDrawer.d.ts +13 -13
- package/plugins/cesium-core/dist/components/draw/types.d.ts +29 -29
- package/plugins/cesium-core/dist/components/entity/EntityLayer.d.ts +65 -65
- package/plugins/cesium-core/dist/components/gltf/GLTFManage.d.ts +141 -141
- package/plugins/cesium-core/dist/components/gltf/index.d.ts +1 -1
- package/plugins/cesium-core/dist/components/measurement/MeasurementTool.d.ts +34 -34
- package/plugins/cesium-core/dist/components/measurement/handlers/CoordinateMeasure.d.ts +16 -16
- package/plugins/cesium-core/dist/components/measurement/handlers/TerrainHeightMeasure.d.ts +18 -18
- package/plugins/cesium-core/dist/components/measurement/handlers/VerticalMeasure.d.ts +23 -23
- package/plugins/cesium-core/dist/components/measurement/index.d.ts +13 -13
- package/plugins/cesium-core/dist/components/measurement/types.d.ts +42 -42
- package/plugins/cesium-core/dist/components/primitive/PrimitiveManager.d.ts +50 -50
- package/plugins/cesium-core/dist/components/roaming/CameraRoamTool.d.ts +27 -27
- package/plugins/cesium-core/dist/components/roaming/PathRoamTool.d.ts +23 -23
- package/plugins/cesium-core/dist/components/roaming/index.d.ts +3 -3
- package/plugins/cesium-core/dist/components/roaming/types.d.ts +66 -66
- package/plugins/cesium-core/dist/components/utils/convertGeoJsonToEntityData.d.ts +1 -1
- package/plugins/cesium-core/dist/components/utils/uuid.d.ts +1 -1
- package/plugins/cesium-core/dist/index.d.ts +12 -12
- package/plugins/cesium-core/package.json +27 -27
- package/plugins/cesium-vue/dist/HtmlOverlayLabelPool-B1gUt-p1.js +339 -0
- package/plugins/cesium-vue/dist/HtmlOverlayLabelPool-B1gUt-p1.js.map +1 -0
- package/plugins/cesium-vue/dist/components/basic-audio.js.map +1 -1
- package/plugins/cesium-vue/dist/components/basic-video.js.map +1 -1
- package/plugins/cesium-vue/dist/components/card-carousel.js.map +1 -1
- package/plugins/cesium-vue/dist/components/card-content.js +1 -1
- package/plugins/cesium-vue/dist/components/card-content.js.map +1 -1
- package/plugins/cesium-vue/dist/components/card-page.js.map +1 -1
- package/plugins/cesium-vue/dist/components/carousel-img.js.map +1 -1
- package/plugins/cesium-vue/dist/components/echarts-pro.js +1 -1
- package/plugins/cesium-vue/dist/components/marker-bubble.js.map +1 -1
- package/plugins/cesium-vue/dist/components/marker-default.js.map +1 -1
- package/plugins/cesium-vue/dist/components/marker-html.js.map +1 -1
- package/plugins/cesium-vue/dist/components/marker-manage.js +1324 -457
- package/plugins/cesium-vue/dist/components/marker-manage.js.map +1 -1
- package/plugins/cesium-vue/dist/components/marker-text.js.map +1 -1
- package/plugins/cesium-vue/dist/components/measurement.js +2943 -116
- package/plugins/cesium-vue/dist/components/measurement.js.map +1 -1
- package/plugins/cesium-vue/dist/components/position-picker.js.map +1 -1
- package/plugins/cesium-vue/dist/index-CUs_hd1V.js.map +1 -1
- package/plugins/cesium-vue/dist/index-Kdqw0FJN.js +45856 -0
- package/plugins/cesium-vue/dist/index-Kdqw0FJN.js.map +1 -0
- package/plugins/cesium-vue/dist/index.js +1 -1
- package/plugins/cesium-vue/dist/index.js.map +1 -1
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
var h = /* @__PURE__ */ ((r) => (r.Click = "marker:click", r.DoubleClick = "marker:dblclick", r.RightClick = "marker:rightclick", r.MouseEnter = "marker:mouseenter", r.MouseLeave = "marker:mouseleave", r.MouseDown = "marker:mousedown", r.MouseUp = "marker:mouseup", r))(h || {});
|
|
2
|
+
class E {
|
|
3
|
+
listenerMap = /* @__PURE__ */ new Map();
|
|
4
|
+
/**
|
|
5
|
+
* 添加监听器
|
|
6
|
+
* @param key 事件 key
|
|
7
|
+
* @param listener 监听器项
|
|
8
|
+
* @param overwrite 是否覆盖同名监听器
|
|
9
|
+
* @returns 是否成功添加
|
|
10
|
+
*/
|
|
11
|
+
addListener(t, e, s = !1) {
|
|
12
|
+
let n = this.listenerMap.get(t);
|
|
13
|
+
return n || (n = /* @__PURE__ */ new Map(), this.listenerMap.set(t, n)), n.has(e.name) ? s ? (console.warn(
|
|
14
|
+
`[MarkerEventBus] Overwriting listener "${e.name}" for event "${t}".`
|
|
15
|
+
), n.set(e.name, e), !0) : (console.warn(
|
|
16
|
+
`[MarkerEventBus] Listener "${e.name}" for event "${t}" already exists. Use overwrite=true to replace it.`
|
|
17
|
+
), !1) : (n.set(e.name, e), !0);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 移除某个 key 的所有监听器
|
|
21
|
+
*/
|
|
22
|
+
removeListenerByKey(t) {
|
|
23
|
+
const e = this.listenerMap.has(t);
|
|
24
|
+
return this.listenerMap.set(t, /* @__PURE__ */ new Map()), e;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 移除某个 key 下的指定名字的监听器
|
|
28
|
+
*/
|
|
29
|
+
removeListenerByKeyAndName(t, e) {
|
|
30
|
+
const s = this.listenerMap.get(t);
|
|
31
|
+
return s ? s.delete(e) : !1;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 运行监听器
|
|
35
|
+
*/
|
|
36
|
+
runListener(t, e, s) {
|
|
37
|
+
const n = this.listenerMap.get(t);
|
|
38
|
+
if (n)
|
|
39
|
+
for (const [l, a] of n.entries()) {
|
|
40
|
+
try {
|
|
41
|
+
a.fn(e, s);
|
|
42
|
+
} catch (o) {
|
|
43
|
+
console.error(`Error in listener "${l}" for event "${t}":`, o);
|
|
44
|
+
}
|
|
45
|
+
a.once && n.delete(l);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const L = {
|
|
50
|
+
[h.Click]: "click",
|
|
51
|
+
[h.DoubleClick]: "dblclick",
|
|
52
|
+
[h.RightClick]: "contextmenu",
|
|
53
|
+
[h.MouseEnter]: "mouseenter",
|
|
54
|
+
[h.MouseLeave]: "mouseleave",
|
|
55
|
+
[h.MouseDown]: "mousedown",
|
|
56
|
+
[h.MouseUp]: "mouseup"
|
|
57
|
+
};
|
|
58
|
+
class B {
|
|
59
|
+
viewer;
|
|
60
|
+
Cesium;
|
|
61
|
+
container;
|
|
62
|
+
labels = /* @__PURE__ */ new Map();
|
|
63
|
+
activeIds = /* @__PURE__ */ new Set();
|
|
64
|
+
_updateFn;
|
|
65
|
+
themes = {};
|
|
66
|
+
eventBus;
|
|
67
|
+
openWheel = !0;
|
|
68
|
+
/**
|
|
69
|
+
* 构造函数
|
|
70
|
+
* @param Cesium Cesium 命名空间
|
|
71
|
+
* @param viewer Cesium Viewer 实例
|
|
72
|
+
* @param containerId HTML 容器 ID(默认:"html-label-container")
|
|
73
|
+
* @param eventBus 可选:自定义事件总线
|
|
74
|
+
*/
|
|
75
|
+
constructor(t, e, s = "html-label-container", n, l = !0) {
|
|
76
|
+
this.Cesium = t, this.viewer = e, this.container = this._createContainer(s), this._updateFn = this._update.bind(this), this.viewer.scene.postRender.addEventListener(this._updateFn), this.eventBus = n || new E(), this.openWheel = l;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 创建标签容器
|
|
80
|
+
*/
|
|
81
|
+
_createContainer(t) {
|
|
82
|
+
let e = document.getElementById(t);
|
|
83
|
+
return e || (e = document.createElement("div"), e.id = t, Object.assign(e.style, {
|
|
84
|
+
position: "absolute",
|
|
85
|
+
top: "0",
|
|
86
|
+
left: "0",
|
|
87
|
+
pointerEvents: "none",
|
|
88
|
+
width: "100%",
|
|
89
|
+
height: "100%",
|
|
90
|
+
zIndex: "100",
|
|
91
|
+
overflow: "hidden"
|
|
92
|
+
}), document.body.appendChild(e)), e;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 注册标签主题
|
|
96
|
+
*/
|
|
97
|
+
registerTheme(t, e) {
|
|
98
|
+
this.themes[t] = e;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 添加单个标签
|
|
102
|
+
*/
|
|
103
|
+
add(t, e) {
|
|
104
|
+
const {
|
|
105
|
+
id: s,
|
|
106
|
+
lon: n,
|
|
107
|
+
lat: l,
|
|
108
|
+
height: a = 0,
|
|
109
|
+
theme: o,
|
|
110
|
+
show: u = !0,
|
|
111
|
+
notCreateElement: d = !1,
|
|
112
|
+
style: b
|
|
113
|
+
} = e, m = this.themes[o];
|
|
114
|
+
if (!m) {
|
|
115
|
+
console.warn(`Theme "${o}" not registered`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
let i = this.labels.get(s);
|
|
119
|
+
if (i) {
|
|
120
|
+
i.theme = o, i.data = t, i.notCreateElement = d;
|
|
121
|
+
try {
|
|
122
|
+
i.unload = m.createElement(i.el, { id: s, theme: o, data: t }, m), (!d || u) && this.container.appendChild(i.el);
|
|
123
|
+
} catch (c) {
|
|
124
|
+
console.error(`Error updating label element for id "${s}":`, c);
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
const c = document.createElement("div");
|
|
128
|
+
Object.assign(c.style, {
|
|
129
|
+
position: "absolute",
|
|
130
|
+
transform: "translate(0, 0)",
|
|
131
|
+
pointerEvents: "auto",
|
|
132
|
+
...e.style || {}
|
|
133
|
+
});
|
|
134
|
+
for (const [v, g] of Object.entries(L)) {
|
|
135
|
+
c.addEventListener(g, (f) => {
|
|
136
|
+
f.stopPropagation();
|
|
137
|
+
const p = this.labels.get(s);
|
|
138
|
+
this.eventBus.runListener(v, p, f);
|
|
139
|
+
});
|
|
140
|
+
let w = 0;
|
|
141
|
+
c.addEventListener("wheel", (f) => {
|
|
142
|
+
if (!this.openWheel) return;
|
|
143
|
+
const p = f.currentTarget;
|
|
144
|
+
w = Date.now();
|
|
145
|
+
const C = w;
|
|
146
|
+
p.style.pointerEvents = "none", setTimeout(() => {
|
|
147
|
+
w === C && (p.style.pointerEvents = "auto");
|
|
148
|
+
}, 2e3);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
let y = null;
|
|
152
|
+
if (!d || u) {
|
|
153
|
+
try {
|
|
154
|
+
y = m.createElement(c, { id: s, theme: o, data: t }, m) || {};
|
|
155
|
+
} catch (v) {
|
|
156
|
+
console.error(`Error updating label element for id "${s}":`, v);
|
|
157
|
+
}
|
|
158
|
+
this.container.appendChild(c);
|
|
159
|
+
}
|
|
160
|
+
i = { id: s, el: c, theme: o, data: t, notCreateElement: d, unload: y }, this.labels.set(s, i);
|
|
161
|
+
}
|
|
162
|
+
i.el.dataset.lon = String(n), i.el.dataset.lat = String(l), i.el.dataset.height = String(a), i.el.style.zIndex = b?.zIndex || "1", i.el.style.display = u ? "block" : "none", u && this.activeIds.add(s);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 批量添加标签
|
|
166
|
+
*/
|
|
167
|
+
addBatch(t) {
|
|
168
|
+
for (const { data: e, options: s } of t)
|
|
169
|
+
this.add(e, s);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 根据 ID 批量移除标签
|
|
173
|
+
*/
|
|
174
|
+
removeByIds(t) {
|
|
175
|
+
for (const e of t) {
|
|
176
|
+
const s = this.labels.get(e);
|
|
177
|
+
s && (this.unloadByLabel(s), this.labels.delete(e), this.activeIds.delete(e));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
unloadByLabel(t) {
|
|
181
|
+
t.el.remove(), t?.unload && typeof t.unload == "function" && t?.unload(), t.unload = null;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 移除所有标签
|
|
185
|
+
*/
|
|
186
|
+
removeAll() {
|
|
187
|
+
for (const t of this.labels.values())
|
|
188
|
+
this.unloadByLabel(t);
|
|
189
|
+
this.labels.clear(), this.activeIds.clear();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 更新标签的数据并刷新内容
|
|
193
|
+
*/
|
|
194
|
+
update(t, e) {
|
|
195
|
+
const s = this.labels.get(t);
|
|
196
|
+
if (!s) {
|
|
197
|
+
console.warn(`Label with id "${t}" not found for update.`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const n = this.themes[s.theme];
|
|
201
|
+
if (!n) {
|
|
202
|
+
console.warn(`Theme "${s.theme}" not registered.`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
n.createElement(s.el, { id: t, theme: s.theme, data: e }, n);
|
|
207
|
+
} catch (l) {
|
|
208
|
+
console.error(`Failed to update label "${t}":`, l);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* 根据 ID 批量隐藏标签
|
|
213
|
+
*/
|
|
214
|
+
hideByIds(t) {
|
|
215
|
+
for (const e of t) {
|
|
216
|
+
const s = this.labels.get(e);
|
|
217
|
+
s && (s.notCreateElement && this.unloadByLabel(s), s.el.style.display = "none", this.activeIds.delete(e));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 隐藏所有标签
|
|
222
|
+
*/
|
|
223
|
+
hideAll() {
|
|
224
|
+
for (const t of this.labels.values())
|
|
225
|
+
t.notCreateElement && this.unloadByLabel(t), t.el.style.display = "none", this.activeIds.delete(t.id);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* 条件过滤隐藏标签
|
|
229
|
+
*/
|
|
230
|
+
hideFilter(t) {
|
|
231
|
+
for (const e of this.labels.values())
|
|
232
|
+
t(e.data) && (e.notCreateElement && this.unloadByLabel(e), e.el.style.display = "none", this.activeIds.delete(e.id));
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* 根据 ID 显示标签
|
|
236
|
+
*/
|
|
237
|
+
showByIds(t) {
|
|
238
|
+
for (const e of t) {
|
|
239
|
+
const s = this.labels.get(e);
|
|
240
|
+
if (s) {
|
|
241
|
+
if ((s.notCreateElement || !s.el.parentNode) && this.container.appendChild(s.el), !s.unload)
|
|
242
|
+
try {
|
|
243
|
+
const n = this.themes[s.theme];
|
|
244
|
+
if (!n) {
|
|
245
|
+
console.warn(`Theme "${s.theme}" not registered`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
s.unload = n.createElement(
|
|
249
|
+
s.el,
|
|
250
|
+
{ id: e, theme: s.theme, data: s.data },
|
|
251
|
+
n
|
|
252
|
+
) || {};
|
|
253
|
+
} catch (n) {
|
|
254
|
+
console.error(`Error creating label element for theme "${s.theme}":`, n);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
s.el.style.display = "block", this.activeIds.add(e);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* 检查标签是否存在
|
|
263
|
+
*/
|
|
264
|
+
has(t) {
|
|
265
|
+
return this.labels.has(t);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* 清空活跃 ID 列表(不影响 DOM)
|
|
269
|
+
*/
|
|
270
|
+
reset() {
|
|
271
|
+
for (const t of this.activeIds.values()) {
|
|
272
|
+
let e = this.labels.get(t);
|
|
273
|
+
e && this.unloadByLabel(e);
|
|
274
|
+
}
|
|
275
|
+
this.activeIds.clear();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* 清理当前未活跃的标签(隐藏而不移除 DOM)
|
|
279
|
+
*/
|
|
280
|
+
cleanup() {
|
|
281
|
+
for (const [t, e] of this.labels.entries())
|
|
282
|
+
this.activeIds.has(t) || (e.el.style.display = "none");
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* 经纬度 -> 自动地形高度修正 -> Cartesian3 -> 屏幕坐标
|
|
286
|
+
*/
|
|
287
|
+
async toWindowPositionByLonLat(t, e) {
|
|
288
|
+
const s = this.Cesium, n = this.viewer.scene, l = [s.Cartographic.fromDegrees(t, e)];
|
|
289
|
+
let a;
|
|
290
|
+
try {
|
|
291
|
+
a = await n.clampToHeightMostDetailed(l);
|
|
292
|
+
} catch {
|
|
293
|
+
console.warn("clampToHeightMostDetailed failed, fallback to ellipsoid height.");
|
|
294
|
+
}
|
|
295
|
+
let o = 0;
|
|
296
|
+
a && a[0] && a[0].height != null ? o = a[0].height : o = 0;
|
|
297
|
+
const u = s.Cartesian3.fromDegrees(t, e, o);
|
|
298
|
+
return this.toWindowCoordinates(u);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* 坐标转换:经纬度 -> 屏幕像素坐标
|
|
302
|
+
*/
|
|
303
|
+
toWindowCoordinates(t) {
|
|
304
|
+
const e = this.viewer.scene, s = this.Cesium.SceneTransforms;
|
|
305
|
+
if (typeof s?.wgs84ToWindowCoordinates == "function")
|
|
306
|
+
return s.wgs84ToWindowCoordinates(e, t);
|
|
307
|
+
if (typeof s?.worldToWindowCoordinates == "function")
|
|
308
|
+
return s.worldToWindowCoordinates(e, t);
|
|
309
|
+
console.warn("No compatible window coordinate transform function found.");
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 每帧刷新所有活跃标签的位置
|
|
313
|
+
*/
|
|
314
|
+
async _update() {
|
|
315
|
+
this.viewer.scene;
|
|
316
|
+
for (const t of this.activeIds) {
|
|
317
|
+
const e = this.labels.get(t);
|
|
318
|
+
if (!e) continue;
|
|
319
|
+
const s = parseFloat(e.el.dataset.lon), n = parseFloat(e.el.dataset.lat), l = parseFloat(e.el.dataset.height || "0"), a = this.Cesium.Cartesian3.fromDegrees(s, n, l), o = this.toWindowCoordinates(a);
|
|
320
|
+
if (this.Cesium.defined(o)) {
|
|
321
|
+
const d = this.themes[e.theme].options?.offset || {}, b = d.x || 0, m = d.y || 0;
|
|
322
|
+
e.el.style.left = `${o.x}px`, e.el.style.top = `${o.y}px`, e.el.style.transform = `translate(${b}px, ${m}px)`, e.el.style.display = "block";
|
|
323
|
+
} else
|
|
324
|
+
e.el.style.display = "none";
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* 销毁标签池,清理监听器和 DOM
|
|
329
|
+
*/
|
|
330
|
+
destroy() {
|
|
331
|
+
this.viewer.scene.postRender.removeEventListener(this._updateFn), this.labels.clear(), this.activeIds.clear();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
export {
|
|
335
|
+
B as H,
|
|
336
|
+
h as M,
|
|
337
|
+
E as a
|
|
338
|
+
};
|
|
339
|
+
//# sourceMappingURL=HtmlOverlayLabelPool-B1gUt-p1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HtmlOverlayLabelPool-B1gUt-p1.js","sources":["../../cesium-core/src/components/MarkerEvent.ts","../../cesium-core/src/components/HtmlOverlayLabelPool.ts"],"sourcesContent":["export enum MarkerEventKey {\r\n Click = 'marker:click',\r\n DoubleClick = 'marker:dblclick',\r\n RightClick = 'marker:rightclick',\r\n MouseEnter = 'marker:mouseenter',\r\n MouseLeave = 'marker:mouseleave',\r\n MouseDown = 'marker:mousedown',\r\n MouseUp = 'marker:mouseup',\r\n}\r\n\r\ninterface ListenerItem<T = any> {\r\n name: string;\r\n fn: (data: T, event: Event) => void;\r\n once?: boolean;\r\n}\r\n\r\nexport { ListenerItem };\r\n\r\nexport class MarkerEventBus {\r\n private listenerMap = new Map<MarkerEventKey, Map<string, ListenerItem>>();\r\n\r\n /**\r\n * 添加监听器\r\n * @param key 事件 key\r\n * @param listener 监听器项\r\n * @param overwrite 是否覆盖同名监听器\r\n * @returns 是否成功添加\r\n */\r\n addListener(key: MarkerEventKey, listener: ListenerItem, overwrite: boolean = false): boolean {\r\n let map = this.listenerMap.get(key);\r\n if (!map) {\r\n map = new Map();\r\n this.listenerMap.set(key, map);\r\n }\r\n\r\n if (map.has(listener.name)) {\r\n if (overwrite) {\r\n console.warn(\r\n `[MarkerEventBus] Overwriting listener \"${listener.name}\" for event \"${key}\".`,\r\n );\r\n map.set(listener.name, listener);\r\n return true;\r\n } else {\r\n console.warn(\r\n `[MarkerEventBus] Listener \"${listener.name}\" for event \"${key}\" already exists. Use overwrite=true to replace it.`,\r\n );\r\n return false;\r\n }\r\n }\r\n\r\n map.set(listener.name, listener);\r\n return true;\r\n }\r\n\r\n /**\r\n * 移除某个 key 的所有监听器\r\n */\r\n removeListenerByKey(key: MarkerEventKey): boolean {\r\n const existed = this.listenerMap.has(key);\r\n this.listenerMap.set(key, new Map());\r\n return existed;\r\n }\r\n\r\n /**\r\n * 移除某个 key 下的指定名字的监听器\r\n */\r\n removeListenerByKeyAndName(key: MarkerEventKey, name: string): boolean {\r\n const map = this.listenerMap.get(key);\r\n if (!map) return false;\r\n return map.delete(name);\r\n }\r\n\r\n /**\r\n * 运行监听器\r\n */\r\n runListener<T = any>(key: MarkerEventKey, data: T, e: Event) {\r\n const map = this.listenerMap.get(key);\r\n if (!map) return;\r\n\r\n for (const [name, listener] of map.entries()) {\r\n try {\r\n listener.fn(data, e);\r\n } catch (err) {\r\n console.error(`Error in listener \"${name}\" for event \"${key}\":`, err);\r\n }\r\n\r\n if (listener.once) {\r\n map.delete(name);\r\n }\r\n }\r\n }\r\n}\r\n","import { MarkerEventKey, MarkerEventBus } from './MarkerEvent';\r\n\r\n/**\r\n * 单个标签实例\r\n */\r\ninterface LabelInstance {\r\n id: string;\r\n el: HTMLDivElement;\r\n theme: string;\r\n data?: any;\r\n notCreateElement?: boolean;\r\n unload?: any;\r\n}\r\n\r\n/**\r\n * 主题配置项\r\n */\r\ninterface ThemeOptions {\r\n /**\r\n * 创建标签 DOM 内容的方法\r\n */\r\n createElement: (\r\n el: HTMLDivElement,\r\n context: { id: string; theme: string; data: any },\r\n options: ThemeOptions,\r\n ) => any;\r\n\r\n /**\r\n * 可选配置,如偏移量\r\n */\r\n options?: {\r\n offset?: { x?: number; y?: number };\r\n };\r\n}\r\n\r\n/**\r\n * 标签添加时的参数\r\n */\r\ninterface LabelOptions {\r\n id: string;\r\n lon: number;\r\n lat: number;\r\n height?: number;\r\n theme: string;\r\n show?: boolean;\r\n notCreateElement?: boolean;\r\n style?: {\r\n [key: string]: string;\r\n };\r\n}\r\n\r\nexport { LabelOptions, LabelInstance, ThemeOptions };\r\n\r\n/**\r\n * 自定义事件与 DOM 事件的映射\r\n */\r\nexport const DOM_EVENT_MAP: Record<MarkerEventKey, keyof HTMLElementEventMap> = {\r\n [MarkerEventKey.Click]: 'click',\r\n [MarkerEventKey.DoubleClick]: 'dblclick',\r\n [MarkerEventKey.RightClick]: 'contextmenu',\r\n [MarkerEventKey.MouseEnter]: 'mouseenter',\r\n [MarkerEventKey.MouseLeave]: 'mouseleave',\r\n [MarkerEventKey.MouseDown]: 'mousedown',\r\n [MarkerEventKey.MouseUp]: 'mouseup',\r\n};\r\n\r\n/**\r\n * 用于管理 Cesium HTML 标签的池,支持主题渲染、事件分发、动态更新等功能\r\n */\r\nexport class HtmlOverlayLabelPool {\r\n private viewer: any;\r\n private Cesium: any;\r\n private container: HTMLDivElement;\r\n private labels: Map<string, LabelInstance> = new Map();\r\n private activeIds: Set<string> = new Set();\r\n private _updateFn: () => void;\r\n private themes: Record<string, ThemeOptions> = {};\r\n public eventBus: MarkerEventBus;\r\n public openWheel = true;\r\n /**\r\n * 构造函数\r\n * @param Cesium Cesium 命名空间\r\n * @param viewer Cesium Viewer 实例\r\n * @param containerId HTML 容器 ID(默认:\"html-label-container\")\r\n * @param eventBus 可选:自定义事件总线\r\n */\r\n constructor(\r\n Cesium: any,\r\n viewer: any,\r\n containerId: string = 'html-label-container',\r\n eventBus?: MarkerEventBus,\r\n openWheel: boolean = true,\r\n ) {\r\n this.Cesium = Cesium;\r\n this.viewer = viewer;\r\n this.container = this._createContainer(containerId);\r\n this._updateFn = this._update.bind(this);\r\n this.viewer.scene.postRender.addEventListener(this._updateFn);\r\n this.eventBus = eventBus || new MarkerEventBus();\r\n this.openWheel = openWheel;\r\n }\r\n\r\n /**\r\n * 创建标签容器\r\n */\r\n private _createContainer(id: string): HTMLDivElement {\r\n let container = document.getElementById(id) as HTMLDivElement;\r\n if (!container) {\r\n container = document.createElement('div');\r\n container.id = id;\r\n Object.assign(container.style, {\r\n position: 'absolute',\r\n top: '0',\r\n left: '0',\r\n pointerEvents: 'none',\r\n width: '100%',\r\n height: '100%',\r\n zIndex: '100',\r\n overflow: 'hidden',\r\n });\r\n document.body.appendChild(container);\r\n }\r\n return container;\r\n }\r\n\r\n /**\r\n * 注册标签主题\r\n */\r\n registerTheme(themeName: string, options: ThemeOptions) {\r\n this.themes[themeName] = options;\r\n }\r\n\r\n /**\r\n * 添加单个标签\r\n */\r\n add(data: any, options: LabelOptions) {\r\n const {\r\n id,\r\n lon,\r\n lat,\r\n height = 0,\r\n theme,\r\n show = true,\r\n notCreateElement = false,\r\n style,\r\n } = options;\r\n\r\n const themeOptions = this.themes[theme];\r\n if (!themeOptions) {\r\n console.warn(`Theme \"${theme}\" not registered`);\r\n return;\r\n }\r\n\r\n let label = this.labels.get(id);\r\n if (!label) {\r\n const el = document.createElement('div');\r\n Object.assign(el.style, {\r\n position: 'absolute',\r\n transform: 'translate(0, 0)',\r\n pointerEvents: 'auto',\r\n ...(options.style || {}),\r\n });\r\n\r\n // 绑定 DOM 事件到事件总线\r\n for (const [key, domEvent] of Object.entries(DOM_EVENT_MAP)) {\r\n el.addEventListener(domEvent, (e: Event) => {\r\n e.stopPropagation();\r\n const labelData = this.labels.get(id);\r\n this.eventBus.runListener(key as MarkerEventKey, labelData, e);\r\n });\r\n\r\n // 滚轮期间禁止点击\r\n let lastTime = 0;\r\n el.addEventListener('wheel', (event) => {\r\n if (!this.openWheel) return;\r\n const dom = event.currentTarget as HTMLElement;\r\n lastTime = Date.now();\r\n const currTime = lastTime;\r\n dom.style.pointerEvents = 'none';\r\n setTimeout(() => {\r\n if (lastTime === currTime) {\r\n dom.style.pointerEvents = 'auto';\r\n }\r\n }, 2000);\r\n });\r\n }\r\n\r\n let unload = null;\r\n if (!notCreateElement || show) {\r\n try {\r\n unload = themeOptions.createElement(el, { id, theme, data }, themeOptions) || {};\r\n } catch (err) {\r\n console.error(`Error updating label element for id \"${id}\":`, err);\r\n }\r\n this.container.appendChild(el);\r\n }\r\n label = { id, el, theme, data, notCreateElement, unload: unload };\r\n this.labels.set(id, label);\r\n } else {\r\n label.theme = theme;\r\n label.data = data;\r\n label.notCreateElement = notCreateElement;\r\n\r\n // 若已存在,则更新 DOM 内容\r\n try {\r\n label.unload = themeOptions.createElement(label.el, { id, theme, data }, themeOptions);\r\n if (!notCreateElement || show) {\r\n this.container.appendChild(label.el);\r\n }\r\n } catch (err) {\r\n console.error(`Error updating label element for id \"${id}\":`, err);\r\n }\r\n }\r\n\r\n // 存储坐标用于后续位置更新\r\n label.el.dataset.lon = String(lon);\r\n label.el.dataset.lat = String(lat);\r\n label.el.dataset.height = String(height);\r\n\r\n label.el.style.zIndex = style?.zIndex || '1';\r\n label.el.style.display = show ? 'block' : 'none';\r\n if (show) {\r\n this.activeIds.add(id);\r\n }\r\n }\r\n\r\n /**\r\n * 批量添加标签\r\n */\r\n addBatch(items: Array<{ data: any; options: LabelOptions }>) {\r\n for (const { data, options } of items) {\r\n this.add(data, options);\r\n }\r\n }\r\n\r\n /**\r\n * 根据 ID 批量移除标签\r\n */\r\n removeByIds(ids: string[]) {\r\n for (const id of ids) {\r\n const label = this.labels.get(id);\r\n if (label) {\r\n this.unloadByLabel(label);\r\n this.labels.delete(id);\r\n this.activeIds.delete(id);\r\n }\r\n }\r\n }\r\n\r\n unloadByLabel(label: LabelInstance) {\r\n label.el.remove();\r\n if (label?.unload && typeof label.unload === 'function') label?.unload();\r\n label.unload = null;\r\n }\r\n\r\n /**\r\n * 移除所有标签\r\n */\r\n removeAll() {\r\n for (const label of this.labels.values()) {\r\n this.unloadByLabel(label);\r\n }\r\n this.labels.clear();\r\n this.activeIds.clear();\r\n }\r\n\r\n /**\r\n * 更新标签的数据并刷新内容\r\n */\r\n update(id: string, newData: any) {\r\n const label = this.labels.get(id);\r\n if (!label) {\r\n console.warn(`Label with id \"${id}\" not found for update.`);\r\n return;\r\n }\r\n\r\n const theme = this.themes[label.theme];\r\n if (!theme) {\r\n console.warn(`Theme \"${label.theme}\" not registered.`);\r\n return;\r\n }\r\n\r\n try {\r\n theme.createElement(label.el, { id, theme: label.theme, data: newData }, theme);\r\n } catch (err) {\r\n console.error(`Failed to update label \"${id}\":`, err);\r\n }\r\n }\r\n\r\n /**\r\n * 根据 ID 批量隐藏标签\r\n */\r\n hideByIds(ids: string[]) {\r\n for (const id of ids) {\r\n const label = this.labels.get(id);\r\n if (label) {\r\n if (label.notCreateElement) {\r\n this.unloadByLabel(label);\r\n }\r\n label.el.style.display = 'none';\r\n this.activeIds.delete(id);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 隐藏所有标签\r\n */\r\n hideAll() {\r\n for (const label of this.labels.values()) {\r\n if (label.notCreateElement) {\r\n this.unloadByLabel(label);\r\n }\r\n label.el.style.display = 'none';\r\n this.activeIds.delete(label.id);\r\n }\r\n }\r\n\r\n /**\r\n * 条件过滤隐藏标签\r\n */\r\n hideFilter(filter: (data: any) => boolean) {\r\n for (const label of this.labels.values()) {\r\n if (!filter(label.data)) continue;\r\n if (label.notCreateElement) {\r\n this.unloadByLabel(label);\r\n }\r\n label.el.style.display = 'none';\r\n this.activeIds.delete(label.id);\r\n }\r\n }\r\n\r\n /**\r\n * 根据 ID 显示标签\r\n */\r\n showByIds(ids: string[]) {\r\n for (const id of ids) {\r\n const label = this.labels.get(id);\r\n if (label) {\r\n if (label.notCreateElement || !label.el.parentNode) {\r\n this.container.appendChild(label.el);\r\n }\r\n if (!label.unload) {\r\n try {\r\n const themeOptions = this.themes[label.theme];\r\n if (!themeOptions) {\r\n console.warn(`Theme \"${label.theme}\" not registered`);\r\n return;\r\n }\r\n label.unload =\r\n themeOptions.createElement(\r\n label.el,\r\n { id, theme: label.theme, data: label.data },\r\n themeOptions,\r\n ) || {};\r\n } catch (err) {\r\n console.error(`Error creating label element for theme \"${label.theme}\":`, err);\r\n return;\r\n }\r\n }\r\n\r\n label.el.style.display = 'block';\r\n this.activeIds.add(id);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 检查标签是否存在\r\n */\r\n has(id: string): boolean {\r\n return this.labels.has(id);\r\n }\r\n\r\n /**\r\n * 清空活跃 ID 列表(不影响 DOM)\r\n */\r\n reset() {\r\n for (const id of this.activeIds.values()) {\r\n let label = this.labels.get(id);\r\n label && this.unloadByLabel(label);\r\n }\r\n this.activeIds.clear();\r\n }\r\n\r\n /**\r\n * 清理当前未活跃的标签(隐藏而不移除 DOM)\r\n */\r\n cleanup() {\r\n for (const [id, label] of this.labels.entries()) {\r\n if (!this.activeIds.has(id)) {\r\n label.el.style.display = 'none';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 经纬度 -> 自动地形高度修正 -> Cartesian3 -> 屏幕坐标\r\n */\r\n async toWindowPositionByLonLat(lon: number, lat: number): Promise<any> {\r\n const Cesium = this.Cesium;\r\n const scene = this.viewer.scene;\r\n\r\n // 1. 经纬度列表\r\n const positions = [Cesium.Cartographic.fromDegrees(lon, lat)];\r\n\r\n // 2. 使用 clampToHeightMostDetailed 获取真实地形高度\r\n let heightResult;\r\n try {\r\n heightResult = await scene.clampToHeightMostDetailed(positions);\r\n } catch (e) {\r\n console.warn('clampToHeightMostDetailed failed, fallback to ellipsoid height.');\r\n }\r\n\r\n let finalHeight = 0;\r\n if (heightResult && heightResult[0] && heightResult[0].height != null) {\r\n finalHeight = heightResult[0].height; // 用户偏好:height[0].height\r\n } else {\r\n // 如果地形未开启,则 fallback 椭球高度\r\n finalHeight = 0;\r\n }\r\n\r\n // 3. 生成真实位置 Cartesian3\r\n const worldPos = Cesium.Cartesian3.fromDegrees(lon, lat, finalHeight);\r\n\r\n // 4. 转屏幕像素坐标\r\n return this.toWindowCoordinates(worldPos);\r\n }\r\n\r\n /**\r\n * 坐标转换:经纬度 -> 屏幕像素坐标\r\n */\r\n toWindowCoordinates(position: any): any {\r\n const scene = this.viewer.scene;\r\n const st = this.Cesium.SceneTransforms;\r\n if (typeof st?.wgs84ToWindowCoordinates === 'function') {\r\n return st.wgs84ToWindowCoordinates(scene, position);\r\n }\r\n if (typeof st?.worldToWindowCoordinates === 'function') {\r\n return st.worldToWindowCoordinates(scene, position);\r\n }\r\n\r\n console.warn('No compatible window coordinate transform function found.');\r\n return undefined;\r\n }\r\n\r\n /**\r\n * 每帧刷新所有活跃标签的位置\r\n */\r\n private async _update() {\r\n const scene = this.viewer.scene;\r\n\r\n for (const id of this.activeIds) {\r\n const label = this.labels.get(id);\r\n if (!label) continue;\r\n\r\n const lon = parseFloat(label.el.dataset.lon!);\r\n const lat = parseFloat(label.el.dataset.lat!);\r\n const height = parseFloat(label.el.dataset.height || '0');\r\n\r\n const position = this.Cesium.Cartesian3.fromDegrees(lon, lat, height);\r\n const screenPosition = this.toWindowCoordinates(position);\r\n\r\n if (this.Cesium.defined(screenPosition)) {\r\n const theme = this.themes[label.theme];\r\n const offset = theme.options?.offset || {};\r\n const offsetX = offset.x || 0;\r\n const offsetY = offset.y || 0;\r\n\r\n label.el.style.left = `${screenPosition.x}px`;\r\n label.el.style.top = `${screenPosition.y}px`;\r\n label.el.style.transform = `translate(${offsetX}px, ${offsetY}px)`;\r\n label.el.style.display = 'block';\r\n } else {\r\n label.el.style.display = 'none';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * 销毁标签池,清理监听器和 DOM\r\n */\r\n destroy() {\r\n this.viewer.scene.postRender.removeEventListener(this._updateFn);\r\n // this.container.remove();\r\n this.labels.clear();\r\n this.activeIds.clear();\r\n }\r\n}\r\n"],"names":["MarkerEventKey","MarkerEventBus","key","listener","overwrite","map","existed","name","data","e","err","DOM_EVENT_MAP","HtmlOverlayLabelPool","Cesium","viewer","containerId","eventBus","openWheel","id","container","themeName","options","lon","lat","height","theme","show","notCreateElement","style","themeOptions","label","el","domEvent","labelData","lastTime","event","dom","currTime","unload","items","ids","newData","filter","scene","positions","heightResult","finalHeight","worldPos","position","st","screenPosition","offset","offsetX","offsetY"],"mappings":"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"}
|