cesium-pocket 0.7.2-alpha → 0.7.4-alpha
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/{CircleDrawer-D2dAuEcD.js → CircleDrawer-CF3y41Db.js} +200 -139
- package/analysis.js +5 -0
- package/czml.d.ts +1 -1
- package/czml.js +319 -0
- package/drawer.js +1 -1
- package/gauger.js +1 -1
- package/index.css +1 -1
- package/index.js +842 -1043
- package/package.json +1 -1
- package/{polygonSolid-DpagI6AO.js → polygonSolid-CiAmYON1.js} +157 -138
- package/src/drawer/CP2dDrawer.d.ts +6 -0
- package/src/drawer/DataCenter.d.ts +12 -0
- package/src/drawer/RectDrawer.d.ts +8 -2
- package/src/gauger/util.d.ts +24 -0
- package/submerger-Bqh-bzY0.js +294 -0
- package/src/drawer/util.d.ts +0 -9
package/analysis.js
ADDED
package/czml.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { PathHeightEditor, PathPoint, PathHeightEditorOptions } from './src/czml/path/pathHeightEditor';
|
|
2
|
-
export { PathHeightEditor, type PathPoint, PathHeightEditorOptions };
|
|
2
|
+
export { PathHeightEditor, type PathPoint, type PathHeightEditorOptions };
|
package/czml.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { Math as g, Cartesian3 as o, Cartographic as T, Ellipsoid as A, CustomDataSource as M, Cartesian2 as d, ScreenSpaceEventHandler as _, PolylineDashMaterialProperty as I, CallbackProperty as c, Color as h, HorizontalOrigin as x, CallbackPositionProperty as O, ScreenSpaceEventType as u } from "cesium";
|
|
2
|
+
const R = 0.05, L = g.toRadians(60), N = "pathHeightNode", F = (s) => `${N}${s}`, k = (s) => ({
|
|
3
|
+
lon: s.lon,
|
|
4
|
+
lat: s.lat,
|
|
5
|
+
height: s.height
|
|
6
|
+
}), v = (s) => {
|
|
7
|
+
const t = T.fromCartesian(s);
|
|
8
|
+
return {
|
|
9
|
+
lon: g.toDegrees(t.longitude),
|
|
10
|
+
lat: g.toDegrees(t.latitude),
|
|
11
|
+
// 椭球面上取到的点高度可能是 NaN,统一兜底为 0
|
|
12
|
+
height: Number.isFinite(t.height) ? t.height : 0
|
|
13
|
+
};
|
|
14
|
+
}, p = (s) => o.fromDegrees(s.lon, s.lat, s.height), E = (s, t) => o.fromDegrees(s.lon, s.lat, t), G = (s, t = 0, e = Number.POSITIVE_INFINITY) => Math.min(e, Math.max(t, s)), $ = (s, t, e) => {
|
|
15
|
+
const i = e == null ? void 0 : e[t];
|
|
16
|
+
return Number.isFinite(i) ? i : s.height;
|
|
17
|
+
}, W = (s, t) => `P${s + 1} · ${t.toFixed(0)} m`, Y = (s) => {
|
|
18
|
+
if (typeof s != "string") return -1;
|
|
19
|
+
const t = new RegExp(`^${N}(\\d+)$`).exec(s);
|
|
20
|
+
return t ? Number(t[1]) : -1;
|
|
21
|
+
}, q = (s, t, e, i) => {
|
|
22
|
+
const n = o.fromDegrees(t.lon, t.lat), r = s.scene.camera.getPickRay(e);
|
|
23
|
+
if (r) {
|
|
24
|
+
const l = A.WGS84.geodeticSurfaceNormal(n, new o()), f = o.subtract(n, r.origin, new o()), m = 1 - o.dot(l, r.direction) ** 2;
|
|
25
|
+
if (m > R) {
|
|
26
|
+
const D = o.dot(l, r.direction), S = o.dot(l, f), H = o.dot(r.direction, f);
|
|
27
|
+
return (D * H - S) / m;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const a = s.scene.camera.frustum, b = "fovy" in a && a.fovy || L, y = s.scene.canvas.clientHeight || 1, C = o.distance(s.scene.camera.positionWC, n), P = 2 * Math.tan(b / 2) * C / y;
|
|
31
|
+
return t.height + (i.y - e.y) * P;
|
|
32
|
+
}, V = "pathHeightGround", z = "pathHeightLine", U = "pathHeightStick", w = 14;
|
|
33
|
+
class j {
|
|
34
|
+
/**
|
|
35
|
+
* 创建编辑器:转换节点数据、注册数据源、生成实体并绑定鼠标事件。
|
|
36
|
+
*
|
|
37
|
+
* @param viewer 三维场景
|
|
38
|
+
* @param positions 折线节点,通常来自绘制工具,直接传 Cartesian3[]
|
|
39
|
+
* @param options 可选配置
|
|
40
|
+
*/
|
|
41
|
+
constructor(t, e, i = {}) {
|
|
42
|
+
this.dataSource = new M("pathHeightEditor"), this.nodeEntities = /* @__PURE__ */ new Map(), this.activeIndex = -1, this.lastScreen = new d(), this.destroyed = !1, this.viewer = t, this.options = i, this.points = e.map(v), this.groundHeights = this.buildGroundHeights(this.points), this.editable = i.editable !== !1, t.dataSources.add(this.dataSource), this.handler = new _(t.scene.canvas), this.build(), this.bindEvents();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 读取当前所有节点。返回的是副本,修改不会影响编辑器内部数据。
|
|
46
|
+
* @returns 节点数组,经纬度为度、高度为米
|
|
47
|
+
*/
|
|
48
|
+
getPoints() {
|
|
49
|
+
return this.points.map(k);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 读取当前所有节点的世界坐标,可直接用于绘制折线或生成 CZML。
|
|
53
|
+
* @returns 每个节点当前空中位置
|
|
54
|
+
*/
|
|
55
|
+
getPositions() {
|
|
56
|
+
return this.points.map((t) => p(t));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 读取当前所有节点的高度。
|
|
60
|
+
* @returns 与节点顺序一致的高度数组(米)
|
|
61
|
+
*/
|
|
62
|
+
getHeights() {
|
|
63
|
+
return this.points.map((t) => t.height);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 查询当前正在拖拽的节点。
|
|
67
|
+
* @returns 节点序号,未在拖拽时返回 -1
|
|
68
|
+
*/
|
|
69
|
+
getActiveIndex() {
|
|
70
|
+
return this.activeIndex;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 运行时开关拖拽。关闭时会立即结束正在进行的拖拽,并恢复相机操作。
|
|
74
|
+
* @param editable 是否允许拖拽
|
|
75
|
+
*/
|
|
76
|
+
setEditable(t) {
|
|
77
|
+
this.editable = t, t || this.endDrag();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 修改单个节点的高度,用于输入框等外部入口。
|
|
81
|
+
* 高度会按 `minHeight` / `maxHeight` 钳制,值未变化时不触发回调。
|
|
82
|
+
* @param index 节点序号
|
|
83
|
+
* @param height 目标高度(米)
|
|
84
|
+
*/
|
|
85
|
+
setHeight(t, e) {
|
|
86
|
+
const i = this.points[t];
|
|
87
|
+
if (!i || !Number.isFinite(e)) return;
|
|
88
|
+
const n = this.clampHeight(e);
|
|
89
|
+
Math.abs(i.height - n) < 1e-6 || (i.height = n, this.notify(t));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 批量修改高度,按数组顺序对应节点;多出的高度或非有限值会被忽略。
|
|
93
|
+
* 有实际变化时以 index = -1 触发一次 `onChange`。
|
|
94
|
+
* @param heights 高度数组(米)
|
|
95
|
+
*/
|
|
96
|
+
setHeights(t) {
|
|
97
|
+
let e = !1;
|
|
98
|
+
const i = Math.min(t.length, this.points.length);
|
|
99
|
+
for (let n = 0; n < i; n++) {
|
|
100
|
+
const r = t[n];
|
|
101
|
+
if (!Number.isFinite(r)) continue;
|
|
102
|
+
const a = this.clampHeight(r);
|
|
103
|
+
Math.abs(this.points[n].height - a) < 1e-6 || (this.points[n].height = a, e = !0);
|
|
104
|
+
}
|
|
105
|
+
e && this.notify(-1);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 用新的折线整体替换当前节点,重建全部实体。
|
|
109
|
+
* 会先结束正在进行的拖拽。
|
|
110
|
+
* @param positions 新的折线节点(世界坐标)
|
|
111
|
+
*/
|
|
112
|
+
setPoints(t) {
|
|
113
|
+
this.endDrag(), this.points = t.map(v), this.groundHeights = this.buildGroundHeights(this.points), this.build(), this.refresh();
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 销毁编辑器:结束拖拽、移除事件句柄、移除数据源及全部实体。
|
|
117
|
+
* 重复调用安全。
|
|
118
|
+
*/
|
|
119
|
+
destroy() {
|
|
120
|
+
this.destroyed || (this.destroyed = !0, this.endDrag(), this.handler.destroy(), this.viewer.isDestroyed() || (this.viewer.scene.canvas.style.cursor = "", this.viewer.dataSources.remove(this.dataSource, !0)), this.nodeEntities.clear());
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 按当前节点数据重建全部实体:地面投影、空中折线、节点与垂线。
|
|
124
|
+
* 节点位置/高度都通过 CallbackProperty 实时读取,改动数据后无需重建即可刷新。
|
|
125
|
+
*/
|
|
126
|
+
build() {
|
|
127
|
+
this.dataSource.entities.removeAll(), this.nodeEntities.clear(), this.activeIndex = -1;
|
|
128
|
+
const t = this.options.showProjection !== !1;
|
|
129
|
+
t && this.dataSource.entities.add({
|
|
130
|
+
id: V,
|
|
131
|
+
polyline: {
|
|
132
|
+
positions: new c(() => this.groundPositions(), !1),
|
|
133
|
+
width: 1.5,
|
|
134
|
+
material: new I({
|
|
135
|
+
color: (this.options.groundLineColor ?? h.WHITE).withAlpha(0.6),
|
|
136
|
+
dashLength: 14
|
|
137
|
+
}),
|
|
138
|
+
clampToGround: !1
|
|
139
|
+
}
|
|
140
|
+
}), this.dataSource.entities.add({
|
|
141
|
+
id: z,
|
|
142
|
+
polyline: {
|
|
143
|
+
positions: new c(() => this.airPositions(), !1),
|
|
144
|
+
width: 4,
|
|
145
|
+
material: this.options.lineColor ?? h.CYAN,
|
|
146
|
+
clampToGround: !1
|
|
147
|
+
}
|
|
148
|
+
}), this.points.forEach((e, i) => this.addNode(i, t));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* 创建单个节点的圆点、标签,以及(可选)垂直投影线。
|
|
152
|
+
* @param index 节点序号
|
|
153
|
+
* @param showProjection 是否同时创建垂线
|
|
154
|
+
*/
|
|
155
|
+
addNode(t, e) {
|
|
156
|
+
const i = this.dataSource.entities.add({
|
|
157
|
+
id: F(t),
|
|
158
|
+
position: new O(() => this.nodePosition(t), !1),
|
|
159
|
+
point: {
|
|
160
|
+
pixelSize: 12,
|
|
161
|
+
color: new c(() => this.nodeColor(t), !1),
|
|
162
|
+
outlineColor: h.WHITE,
|
|
163
|
+
outlineWidth: 2,
|
|
164
|
+
// 始终显示在模型/地形之上,方便点击
|
|
165
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
166
|
+
},
|
|
167
|
+
label: {
|
|
168
|
+
text: new c(() => W(t, this.points[t].height), !1),
|
|
169
|
+
font: "12px sans-serif",
|
|
170
|
+
fillColor: h.WHITE,
|
|
171
|
+
showBackground: !0,
|
|
172
|
+
backgroundColor: h.BLACK.withAlpha(0.5),
|
|
173
|
+
horizontalOrigin: x.CENTER,
|
|
174
|
+
pixelOffset: new d(0, -28),
|
|
175
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
this.nodeEntities.set(i, t), e && this.dataSource.entities.add({
|
|
179
|
+
id: `${U}${t}`,
|
|
180
|
+
polyline: {
|
|
181
|
+
positions: new c(() => this.stickPositions(t), !1),
|
|
182
|
+
width: 1.5,
|
|
183
|
+
material: new I({
|
|
184
|
+
color: (this.options.stickColor ?? h.LIME).withAlpha(0.8)
|
|
185
|
+
}),
|
|
186
|
+
clampToGround: !1
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/** 绑定鼠标按下、移动、抬起三个事件 */
|
|
191
|
+
bindEvents() {
|
|
192
|
+
this.handler.setInputAction(
|
|
193
|
+
(t) => this.onLeftDown(t.position),
|
|
194
|
+
u.LEFT_DOWN
|
|
195
|
+
), this.handler.setInputAction(
|
|
196
|
+
(t) => this.onMouseMove(t.endPosition),
|
|
197
|
+
u.MOUSE_MOVE
|
|
198
|
+
), this.handler.setInputAction(() => this.endDrag(), u.LEFT_UP);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 左键按下:命中节点则进入拖拽状态。
|
|
202
|
+
* 拖拽期间关闭相机操作,否则视角会和节点一起被拖动。
|
|
203
|
+
* @param screenPosition 鼠标位置(画布坐标)
|
|
204
|
+
*/
|
|
205
|
+
onLeftDown(t) {
|
|
206
|
+
var i, n;
|
|
207
|
+
if (!this.editable || this.destroyed) return;
|
|
208
|
+
const e = this.pickNode(t);
|
|
209
|
+
e < 0 || (this.activeIndex = e, this.lastScreen = d.clone(t), this.viewer.scene.screenSpaceCameraController.enableInputs = !1, this.viewer.scene.canvas.style.cursor = "ns-resize", this.requestRender(), (n = (i = this.options).onDragStart) == null || n.call(i, e));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* 鼠标移动:拖拽中则更新高度;未拖拽时只切换悬停光标。
|
|
213
|
+
* @param screenPosition 鼠标位置(画布坐标)
|
|
214
|
+
*/
|
|
215
|
+
onMouseMove(t) {
|
|
216
|
+
if (this.destroyed) return;
|
|
217
|
+
if (this.activeIndex < 0) {
|
|
218
|
+
if (!this.editable) return;
|
|
219
|
+
const n = this.pickNode(t);
|
|
220
|
+
this.viewer.scene.canvas.style.cursor = n >= 0 ? "ns-resize" : "";
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const e = this.points[this.activeIndex], i = q(this.viewer, e, t, this.lastScreen);
|
|
224
|
+
this.lastScreen = d.clone(t), this.setHeight(this.activeIndex, i);
|
|
225
|
+
}
|
|
226
|
+
/** 结束拖拽:复位状态、恢复相机操作与光标,并触发 `onDragEnd` */
|
|
227
|
+
endDrag() {
|
|
228
|
+
var e, i;
|
|
229
|
+
const t = this.activeIndex;
|
|
230
|
+
t < 0 || (this.activeIndex = -1, this.viewer.isDestroyed() || (this.viewer.scene.screenSpaceCameraController.enableInputs = !0, this.viewer.scene.canvas.style.cursor = "", this.requestRender()), (i = (e = this.options).onDragEnd) == null || i.call(e, t));
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* 在鼠标位置拾取节点。
|
|
234
|
+
* 先用 Map 命中,失败再退化为解析实体 id,兼容拾取结果的包装差异。
|
|
235
|
+
* @param screenPosition 鼠标位置(画布坐标)
|
|
236
|
+
* @returns 节点序号,未命中返回 -1
|
|
237
|
+
*/
|
|
238
|
+
pickNode(t) {
|
|
239
|
+
var n;
|
|
240
|
+
const e = this.viewer.scene.pick(t, w, w);
|
|
241
|
+
if (!e || !e.id) return -1;
|
|
242
|
+
const i = this.nodeEntities.get(e.id);
|
|
243
|
+
return i !== void 0 ? i : Y((n = e.id) == null ? void 0 : n.id);
|
|
244
|
+
}
|
|
245
|
+
/** 各节点当前高度位置,用于空中折线 */
|
|
246
|
+
airPositions() {
|
|
247
|
+
return this.points.map((t) => p(t));
|
|
248
|
+
}
|
|
249
|
+
/** 各节点在地面参考高度上的投影,用于地面虚线 */
|
|
250
|
+
groundPositions() {
|
|
251
|
+
return this.points.map((t, e) => E(t, this.groundHeightAt(e)));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 单个节点垂线的两个端点。
|
|
255
|
+
* @param index 节点序号
|
|
256
|
+
*/
|
|
257
|
+
stickPositions(t) {
|
|
258
|
+
return [
|
|
259
|
+
E(this.points[t], this.groundHeightAt(t)),
|
|
260
|
+
this.nodePosition(t)
|
|
261
|
+
];
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* 节点当前位置。
|
|
265
|
+
* @param index 节点序号
|
|
266
|
+
*/
|
|
267
|
+
nodePosition(t) {
|
|
268
|
+
return p(this.points[t]);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* 节点对应的地面参考高度,越界或非法值按 0 处理。
|
|
272
|
+
* @param index 节点序号
|
|
273
|
+
*/
|
|
274
|
+
groundHeightAt(t) {
|
|
275
|
+
const e = this.groundHeights[t];
|
|
276
|
+
return Number.isFinite(e) ? e : 0;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* 节点颜色:拖拽中高亮,否则用配置色(默认橙色)。
|
|
280
|
+
* @param index 节点序号
|
|
281
|
+
*/
|
|
282
|
+
nodeColor(t) {
|
|
283
|
+
return this.activeIndex === t ? this.options.activeColor ?? h.YELLOW : this.options.pointColor ?? h.ORANGE;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* 批量计算地面参考高度,结果与节点顺序一一对应。
|
|
287
|
+
* @param points 节点数组
|
|
288
|
+
*/
|
|
289
|
+
buildGroundHeights(t) {
|
|
290
|
+
return t.map((e, i) => $(e, i, this.options.groundHeights));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* 按配置的上下限钳制高度。
|
|
294
|
+
* @param height 原始高度(米)
|
|
295
|
+
*/
|
|
296
|
+
clampHeight(t) {
|
|
297
|
+
return G(t, this.options.minHeight, this.options.maxHeight);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* 单节点变化:请求重绘并通知调用方。
|
|
301
|
+
* @param index 变化节点的序号
|
|
302
|
+
*/
|
|
303
|
+
notify(t) {
|
|
304
|
+
var e, i;
|
|
305
|
+
this.requestRender(), (i = (e = this.options).onChange) == null || i.call(e, this.getPoints(), t);
|
|
306
|
+
}
|
|
307
|
+
/** 整体变化:请求重绘并以 index = -1 通知调用方 */
|
|
308
|
+
refresh() {
|
|
309
|
+
var t, e;
|
|
310
|
+
this.requestRender(), (e = (t = this.options).onChange) == null || e.call(t, this.getPoints(), -1);
|
|
311
|
+
}
|
|
312
|
+
/** 请求一次重绘,兼容 requestRenderMode 与已销毁的场景 */
|
|
313
|
+
requestRender() {
|
|
314
|
+
this.viewer.isDestroyed() || this.viewer.scene.requestRender();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
export {
|
|
318
|
+
j as PathHeightEditor
|
|
319
|
+
};
|
package/drawer.js
CHANGED
package/gauger.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as g, b as o, H as r, L as s, P as i, a as l, d as c, R as t, c as u } from "./polygonSolid-
|
|
1
|
+
import { C as g, b as o, H as r, L as s, P as i, a as l, d as c, R as t, c as u } from "./polygonSolid-CiAmYON1.js";
|
|
2
2
|
export {
|
|
3
3
|
g as CircleGaguger,
|
|
4
4
|
o as CircleSolid,
|
package/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.cp-porket-compass[data-v-f9d2dfd0]{position:absolute;z-index:1000;width:100px;height:100px;cursor:pointer}.cp-porket-ruler[data-v-b4295ba8]{z-index:1000;width:100px;height:20px;text-align:center;padding-top:2px;font-size:12px;color:#ebebeb}.cp-porket-ruler-line[data-v-b4295ba8]{width:100px;height:5px;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;border-right:2px solid #eeeeee;margin-top:-2px}.cp-porket-coord[data-v-
|
|
1
|
+
.cp-porket-compass[data-v-f9d2dfd0]{position:absolute;z-index:1000;width:100px;height:100px;cursor:pointer}.cp-porket-ruler[data-v-b4295ba8]{z-index:1000;width:100px;height:20px;text-align:center;padding-top:2px;font-size:12px;color:#ebebeb}.cp-porket-ruler-line[data-v-b4295ba8]{width:100px;height:5px;border-bottom:1px solid #eeeeee;border-left:2px solid #eeeeee;border-right:2px solid #eeeeee;margin-top:-2px}.cp-porket-coord[data-v-d4b378fd]{position:relative;z-index:1000;width:200px;height:26px;text-align:center;font-size:12px;display:flex;justify-content:space-around;color:#eee;cursor:pointer;-webkit-user-select:none;user-select:none}.coord-panel[data-v-d4b378fd]{position:absolute;left:0;bottom:calc(100% + 6px);box-sizing:border-box;width:max-content;padding:5px 8px;border:1px solid rgba(120,190,255,.35);border-radius:5px;background:#0f1928e0;box-shadow:0 4px 16px #00000073;text-align:left;cursor:default;-webkit-user-select:auto;user-select:auto;white-space:nowrap}.coord-panel[data-v-d4b378fd]:after{content:"";position:absolute;left:20px;bottom:-4px;width:7px;height:7px;background:#0f1928e0;border-right:1px solid rgba(120,190,255,.35);border-bottom:1px solid rgba(120,190,255,.35);transform:rotate(45deg)}.coord-row[data-v-d4b378fd]{display:flex;align-items:center;gap:4px}.coord-row span[data-v-d4b378fd]{flex:none;color:#9fc4e8}.coord-row span+input[data-v-d4b378fd]{margin-right:2px}.coord-row input[data-v-d4b378fd]{flex:none;width:72px;height:22px;padding:0 4px;box-sizing:border-box;border:1px solid rgba(120,190,255,.35);border-radius:3px;background:#00000059;color:#fff;font-size:12px;outline:none}.coord-row input[data-v-d4b378fd]::placeholder{color:#ffffff59}.coord-row input[data-v-d4b378fd]:focus{border-color:#4ea8ff}.coord-error[data-v-d4b378fd]{position:absolute;left:8px;bottom:100%;margin-bottom:3px;color:#ff6b6b;font-size:11px;line-height:1.2}.coord-fly-btn[data-v-d4b378fd]{flex:none;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;padding:0;margin-left:2px;border:none;border-radius:3px;background:#2b7de9;color:#fff;cursor:pointer}.coord-fly-icon[data-v-d4b378fd]{display:block;pointer-events:none}.coord-fly-btn[data-v-d4b378fd]:hover{background:#3d8df5}.coord-fly-btn[data-v-d4b378fd]:active{background:#1f68c4}.cp-overlay[data-v-8d46cebf]{position:absolute;z-index:100;font-size:12px}.cp-overlay-close[data-v-8d46cebf]{position:absolute;right:0;top:0;z-index:10;width:30px;height:30px;line-height:30px;text-align:center;cursor:pointer}.cp-overlay-close-img[data-v-8d46cebf]{width:30px;height:30px;color:#fff}.leader-layer[data-v-9e9c4b4e]{position:absolute;left:0;top:0;z-index:4;pointer-events:none;overflow:visible}.sign-board[data-v-9e9c4b4e]{position:absolute;z-index:5;display:flex;flex-direction:column;gap:2px;padding:6px 10px;color:#fff;background-color:#000c;border:1px solid #000000;border-radius:4px;font-size:14px;line-height:20px;letter-spacing:.02em;white-space:nowrap;-webkit-user-select:none;user-select:none;box-shadow:0 2px 8px #00000059}.sign-header[data-v-9e9c4b4e]{position:relative;margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid rgba(255,255,255,.35);cursor:grab;touch-action:none}.sign-header[data-v-9e9c4b4e]:active{cursor:grabbing}.sign-title[data-v-9e9c4b4e]{text-align:left;font-weight:600;padding:0 18px}.sign-close[data-v-9e9c4b4e]{position:absolute;top:-2px;right:-4px;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;background:transparent;color:#fff;cursor:pointer}.cesium-html-marker[data-v-0e7fc65f]{pointer-events:auto;z-index:1000}.pin-container[data-v-0e7fc65f]{position:absolute;z-index:20;color:#eee;font-size:12px;text-shadow:-1px -1px 0 #06012c,1px -1px 0 #06012c,-1px 1px 0 #06012c,1px 1px 0 #06012c;margin:0;padding:5px;border-radius:4px}.eagle-eye[data-v-e9ba1f23]{position:relative;box-sizing:border-box;overflow:hidden;cursor:crosshair;background:#071422;border:2px solid rgba(255,255,255,.92);box-shadow:0 0 0 1px #000000a6,0 6px 16px #0006}.eagle-eye[data-v-e9ba1f23] .cesium-viewer,.eagle-eye[data-v-e9ba1f23] .cesium-widget,.eagle-eye[data-v-e9ba1f23] .cesium-widget canvas{width:100%;height:100%}.eagle-eye[data-v-e9ba1f23] .cesium-viewer-bottom,.eagle-eye[data-v-e9ba1f23] .cesium-viewer-toolbar,.eagle-eye[data-v-e9ba1f23] .cesium-viewer-animationContainer,.eagle-eye[data-v-e9ba1f23] .cesium-viewer-timelineContainer{display:none}.cp-layersmap-header[data-v-ace85555]{height:24px;line-height:20px;font-size:12px;background-color:#000c;display:flex;justify-content:space-around;align-items:center}.cp-layersmap-layer[data-v-ace85555]{width:60px;height:60px;position:relative;margin-left:2px;margin-top:2px;margin-bottom:2px;cursor:pointer}.cp-layersmap-main-header[data-v-ace85555]{position:absolute;z-index:1;width:100%;height:16px;line-height:16px;text-align:center;font-size:12px;background-color:#4449}.cp-layersmap-main-footer[data-v-ace85555]{position:absolute;bottom:0;z-index:1;width:100%;display:flex;justify-content:center;align-items:center;height:14px;font-size:10px;background-color:#4449}.cp-layersmap-main-image[data-v-ace85555]{width:60px;height:60px}.cp-layersmap-active[data-v-ace85555]{background-color:#0047e0cc}.cp-layersmap[data-v-ace85555]{position:absolute;z-index:10;color:#eee;background-color:#000c;border:1px solid rgb(61,64,105);border-radius:4px}.cp-layersmap-main[data-v-ace85555]{display:flex;justify-content:space-around;padding-right:2px}.split-bar[data-v-b8f0cd86]{position:absolute;top:0;bottom:0;z-index:20;width:4px;transform:translate(-50%);background:#fff;box-shadow:0 0 8px #00000073;cursor:ew-resize;touch-action:none}.split-handle[data-v-b8f0cd86]{position:absolute;top:50%;left:50%;width:18px;height:42px;transform:translate(-50%,-50%);border-radius:9px;background:#fff;box-shadow:0 0 8px #0006}.split-handle[data-v-b8f0cd86]:before,.split-handle[data-v-b8f0cd86]:after{content:"";position:absolute;top:50%;width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;transform:translateY(-50%)}.split-handle[data-v-b8f0cd86]:before{left:2px;border-right:5px solid #5a6e82}.split-handle[data-v-b8f0cd86]:after{right:2px;border-left:5px solid #5a6e82}.czml-config[data-v-4bb4e701]{position:fixed;left:0;bottom:60px;z-index:100;width:60x;background-color:#0006;border-top:1px solid rgb(60,60,60);border-right:1px solid rgb(60,60,60);border-radius:4px;padding:6px;font-size:12px;color:#ccc}.czml-config-title[data-v-4bb4e701]{padding-bottom:6px;border-bottom:1px solid #222222;font-weight:500;font-size:14px}.czml-config-label[data-v-4bb4e701]{color:#87ceeb;padding:4px 0}.czmlBar[data-v-4bb4e701]{position:fixed;bottom:0;z-index:100;height:60px;width:100%;display:flex;justify-content:space-between;flex-direction:row;background-color:#0006;font-size:12px;color:#ccc}.bar-control[data-v-4bb4e701]{width:220px;-webkit-user-select:none;user-select:none}.control-btns[data-v-4bb4e701]{display:flex;justify-content:space-around;align-items:center;padding-top:8px}.control-btns div[data-v-4bb4e701]{width:22px;height:22px;border-radius:2px;display:flex;justify-content:center;align-items:center;background-color:#ffffff4d}.control-btns img[data-v-4bb4e701]{width:14px}.control-bottom[data-v-4bb4e701]{height:30px;display:flex;justify-content:space-between;align-items:center;padding:0 10px;color:#ff0}.bar-timeline[data-v-4bb4e701]{flex:1 1 auto;padding:10px;position:relative}.timeline-left[data-v-4bb4e701]{position:absolute;top:6px;left:10px}.timeline-right[data-v-4bb4e701]{position:absolute;top:6px;right:10px}.timeline-ruler[data-v-4bb4e701]{position:relative;height:26px;margin-top:20px;margin-left:0;border-bottom:1px;border-bottom-style:solid;border-bottom-color:gray}.ruler-label[data-v-4bb4e701]{position:absolute;top:-30px;transform:translate(-25%)}.tick[data-v-4bb4e701]{position:absolute;bottom:0;width:0;height:6px;border-left:1px solid rgba(170,180,190,.45);font-size:10px}.grabbing[data-v-4bb4e701]{cursor:grabbing}.tick-major[data-v-4bb4e701]{height:12px;border-left:1px solid rgba(170,180,190,.45)}.playhead[data-v-4bb4e701]{position:absolute;top:0;bottom:0;width:0;z-index:5;transform:translate(-50%);pointer-events:none}.playhead__tri[data-v-4bb4e701]{position:absolute;top:0;left:70%;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:8px solid #ffff00;transform:translate(-50%);filter:drop-shadow(0 1px 1px #ffff00)}.playhead__line[data-v-4bb4e701]{position:absolute;top:10px;bottom:0;left:0;width:1px;background:#ff0}@media (max-width: 720px){.czml-config[data-v-4bb4e701]{bottom:120px}.czmlBar[data-v-4bb4e701]{height:120px;flex-direction:column;gap:6px;min-height:0}.bar-control[data-v-4bb4e701]{width:100%;display:flex;justify-content:space-between}.control-btns[data-v-4bb4e701]{width:55%}.control-bottom[data-v-4bb4e701]{flex:1}}
|