@hzab/map-combine 0.4.2-alpha.1 → 0.4.2-alpha.11

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.
@@ -0,0 +1,64 @@
1
+ import { BasicModel, type BasicModelOption } from "../basic/BasicModel";
2
+ import { objHasKeys } from "../utils";
3
+ import { type CesiumMap } from "./CesiumMap";
4
+
5
+ export class CesiumModel extends BasicModel {
6
+ private readonly _map: CesiumMap;
7
+ private _shape: any;
8
+ constructor(map: CesiumMap, option?: Partial<BasicModelOption>) {
9
+ super(option);
10
+ this._map = map;
11
+
12
+ this._shape = map.viewer.scene.primitives.add(
13
+ Cesium.Model.fromGltf({
14
+ id: {
15
+ name: option.name,
16
+ target: this,
17
+ },
18
+ show: this.option.show,
19
+ url: this.option.model,
20
+ modelMatrix: this._initMatrix(),
21
+ scale: this.option.scale,
22
+ allowPicking: !this.option.silent,
23
+ minimumPixelSize: this.option.minSize,
24
+ }),
25
+ );
26
+ }
27
+
28
+ private _initMatrix() {
29
+ const { lon, lat, alt, heading, pitch, roll } = this.option;
30
+ const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
31
+ const origin = Cesium.Cartesian3.fromDegrees(lon, lat, alt);
32
+ const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, hpr);
33
+ return modelMatrix;
34
+ }
35
+
36
+ protected _onUpdate(option: Partial<BasicModelOption>): void {
37
+ const { _shape } = this;
38
+ if (objHasKeys(option, ["model"])) {
39
+ this._map.viewer.scene.primitives.remove(this._shape, true);
40
+ this._shape = this._map.viewer.scene.primitives.add(
41
+ Cesium.Model.fromGltf({
42
+ url: this.option.model,
43
+ modelMatrix: this._initMatrix(),
44
+ scale: this.option.scale,
45
+ minimumPixelSize: this.option.minSize,
46
+ }),
47
+ );
48
+ } else {
49
+ if (objHasKeys(option, ["show"])) {
50
+ _shape.show = option.show;
51
+ }
52
+ if (objHasKeys(option, ["lon", "lat", "alt", "heading", "pitch", "roll"])) {
53
+ this._shape.modelMatrix = this._initMatrix();
54
+ }
55
+ if (objHasKeys(option, ["scale"])) {
56
+ this._shape.scale = option.scale;
57
+ }
58
+ }
59
+ }
60
+
61
+ destroy(): void {
62
+ this._map.viewer.scene.primitives.remove(this._shape, true);
63
+ }
64
+ }
@@ -18,7 +18,10 @@ export function drawPoint(map: CesiumMap, point: Point<unknown>) {
18
18
  height: size[1],
19
19
  image: point.src,
20
20
  rotation: point.rotation,
21
+ allowPicking: !point.silent,
21
22
  id: {
23
+ name: point.name,
24
+ target: point,
22
25
  cursor: point.cursor,
23
26
  silent: point.silent,
24
27
  onPointerIn() {
@@ -67,6 +67,8 @@ export function drawPolygon(map: CesiumMap, polygon: Polygon<unknown>) {
67
67
  );
68
68
 
69
69
  const _event = {
70
+ name: polygon.name,
71
+ target: polygon,
70
72
  cursor: polygon.cursor,
71
73
  silent: polygon.silent,
72
74
  onPointerIn() {
@@ -14,6 +14,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput){
14
14
  material.alpha = colorImage.a * color.a;
15
15
  return material;
16
16
  }`;
17
+
17
18
  function createLineMaterial(e: Polyline<unknown>) {
18
19
  if (e.icon || e.flow) {
19
20
  const material = new Cesium.Material({
@@ -73,6 +74,8 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
73
74
  );
74
75
 
75
76
  const _event = {
77
+ name: polyline.name,
78
+ target: polyline,
76
79
  cursor: polyline.cursor,
77
80
  silent: polyline.silent,
78
81
  onPointerIn() {
@@ -99,25 +102,180 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
99
102
  },
100
103
  };
101
104
 
102
- let primitive: any;
103
105
  let cache: any[];
104
106
  let activeNode: ChainNode<any, any>;
105
- if (polyline.coordinates) {
106
- status = 2;
107
- cache = polyline.coordinates.map(geographyTcartesian3);
108
- primitive = new Cesium.Primitive({
109
- show: polyline.show,
110
- geometryInstances: new Cesium.GeometryInstance({
111
- geometry: new Cesium.PolylineGeometry({
112
- positions: cache,
107
+
108
+ let geometryInstance = null;
109
+ let primitive = null;
110
+ let currentPositions = [];
111
+ let isFirstRender = true;
112
+
113
+ /**
114
+ * 更新或创建线条几何体
115
+ * @param newPositions - 新的顶点数组
116
+ * @param forceRebuild 强制重建
117
+ */
118
+ function updatePrimitiveGeometry(newPositions, forceRebuild: boolean = false) {
119
+ // 验证数据有效性
120
+ if (!newPositions || newPositions.length < 2) {
121
+ if (primitive) {
122
+ viewer.scene.primitives.remove(primitive);
123
+ primitive = null;
124
+ geometryInstance = null;
125
+ }
126
+ currentPositions = [];
127
+ return;
128
+ }
129
+
130
+ // 强制重建,跳过检查
131
+ if (!forceRebuild && !isFirstRender) {
132
+ if (currentPositions.length === newPositions.length) {
133
+ let same = true;
134
+ for (let i = 0; i < newPositions.length; i++) {
135
+ const p1 = currentPositions[i];
136
+ const p2 = newPositions[i];
137
+ if (
138
+ !p1 ||
139
+ !p2 ||
140
+ Math.abs(p1.x - p2.x) > 1e-10 ||
141
+ Math.abs(p1.y - p2.y) > 1e-10 ||
142
+ Math.abs(p1.z - p2.z) > 1e-10
143
+ ) {
144
+ same = false;
145
+ break;
146
+ }
147
+ }
148
+ if (same) return;
149
+ }
150
+ }
151
+
152
+ // 创建新的几何体数据
153
+ let newGeometry: any = null;
154
+ try {
155
+ newGeometry = Cesium.PolylineGeometry.createGeometry(
156
+ new Cesium.PolylineGeometry({
157
+ positions: newPositions,
113
158
  width: polyline.lineWidth,
114
159
  vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
115
160
  }),
161
+ );
162
+ } catch (error) {
163
+ console.error("创建几何体失败:", error);
164
+ return;
165
+ }
166
+
167
+ if (!newGeometry) return;
168
+
169
+ // 复用或创建 Primitive
170
+ if (geometryInstance && primitive && !forceRebuild) {
171
+ // 复用几何体实例
172
+ try {
173
+ geometryInstance.geometry = newGeometry;
174
+ if (primitive._state !== undefined) {
175
+ primitive._state = Cesium.PrimitiveState.NEEDS_REBUILD;
176
+ }
177
+ if (primitive._boundingVolume) {
178
+ primitive._boundingVolume = undefined;
179
+ }
180
+ if (primitive._dirty !== undefined) {
181
+ primitive._dirty = true;
182
+ }
183
+ } catch (error) {
184
+ console.warn("复用 Primitive 失败,降级到重建:", error);
185
+ // 降级:重新创建
186
+ if (primitive) {
187
+ viewer.scene.primitives.remove(primitive);
188
+ primitive = null;
189
+ }
190
+ geometryInstance = new Cesium.GeometryInstance({
191
+ geometry: newGeometry,
192
+ id: _event,
193
+ });
194
+ primitive = new Cesium.Primitive({
195
+ show: polyline.show !== false,
196
+ asynchronous: false,
197
+ geometryInstances: geometryInstance,
198
+ appearance: appearance,
199
+ compressVertices: true,
200
+ releaseGeometryInstances: false,
201
+ });
202
+ viewer.scene.primitives.add(primitive);
203
+ }
204
+ // 复用 Primitive,只更新几何体数据(性能最优)
205
+ try {
206
+ // 直接替换几何体数据
207
+ geometryInstance.geometry = newGeometry;
208
+
209
+ // 关键:标记 Primitive 需要重建
210
+ // 在 Cesium 1.90.1 中,这些内部状态需要手动触发
211
+ if (primitive._state !== undefined) {
212
+ primitive._state = Cesium.PrimitiveState.NEEDS_REBUILD;
213
+ }
214
+
215
+ // 清除缓存的包围盒,强制重新计算
216
+ if (primitive._boundingVolume) {
217
+ primitive._boundingVolume = undefined;
218
+ }
219
+
220
+ // 标记为脏,触发重绘
221
+ if (primitive._dirty !== undefined) {
222
+ primitive._dirty = true;
223
+ }
224
+
225
+ // 对于某些版本,可能需要重新设置 geometryInstances
226
+ // primitive.geometryInstances = geometryInstance;
227
+ } catch (error) {
228
+ // 如果复用失败,降级到重建方案
229
+ console.warn("复用 Primitive 失败,降级到重建:", error);
230
+ forceRebuild = true;
231
+ }
232
+ }
233
+
234
+ // 强制重建或者首次创建,重新创建 Primitive
235
+ if (forceRebuild || !primitive || !geometryInstance) {
236
+ if (primitive) {
237
+ viewer.scene.primitives.remove(primitive);
238
+ primitive = null;
239
+ }
240
+
241
+ geometryInstance = new Cesium.GeometryInstance({
242
+ geometry: newGeometry,
116
243
  id: _event,
117
- }),
118
- appearance,
119
- });
120
- viewer.scene.primitives.add(primitive);
244
+ });
245
+
246
+ primitive = new Cesium.Primitive({
247
+ show: polyline.show !== false,
248
+ asynchronous: false,
249
+ geometryInstances: geometryInstance,
250
+ appearance: appearance,
251
+ compressVertices: true,
252
+ releaseGeometryInstances: false,
253
+ });
254
+
255
+ viewer.scene.primitives.add(primitive);
256
+ isFirstRender = false;
257
+ }
258
+
259
+ currentPositions = newPositions.slice();
260
+ }
261
+
262
+ function cleanupPrimitive() {
263
+ if (primitive) {
264
+ viewer.scene.primitives.remove(primitive);
265
+ primitive = null;
266
+ }
267
+ if (geometryInstance) {
268
+ geometryInstance = null;
269
+ }
270
+ currentPositions = [];
271
+ isFirstRender = true;
272
+ }
273
+
274
+ // 初始加载
275
+ if (polyline.coordinates) {
276
+ status = 2;
277
+ cache = polyline.coordinates.map(geographyTcartesian3);
278
+ updatePrimitiveGeometry(cache, true); // 强制重建
121
279
  }
122
280
 
123
281
  const editor = new PolylineEditor<any, any>();
@@ -180,8 +338,10 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
180
338
  markers.remove(n.shape);
181
339
  });
182
340
  editor.on("empty", () => {
183
- // markers.removeAll()
184
- viewer.scene.primitives.remove(primitive);
341
+ if (primitive) {
342
+ viewer.scene.primitives.remove(primitive);
343
+ primitive = null;
344
+ }
185
345
  status = 0;
186
346
  });
187
347
 
@@ -218,7 +378,6 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
218
378
  break;
219
379
  case "dash":
220
380
  keys.add("Material");
221
-
222
381
  break;
223
382
  default:
224
383
  throw new Error(`${key} 还不支持修改`);
@@ -229,14 +388,13 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
229
388
  case "Primitive":
230
389
  if (polyline.coordinates) {
231
390
  cache = polyline.coordinates.map((e) => geographyTcartesian3(e));
391
+ updatePrimitiveGeometry(cache, true); // 强制重建
232
392
  } else {
233
393
  cache = [];
234
394
  markers.removeAll();
235
395
  status = 0;
236
396
  }
237
-
238
397
  initPrimitive();
239
-
240
398
  break;
241
399
  case "Material":
242
400
  material = createLineMaterial(polyline);
@@ -254,6 +412,7 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
254
412
  break;
255
413
  }
256
414
  };
415
+
257
416
  let temp: any;
258
417
  const onMouseMove = () => {
259
418
  const e = event.geography;
@@ -262,13 +421,13 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
262
421
  case 1:
263
422
  cache.pop();
264
423
  cache.push(geographyTcartesian3(e));
265
- initPrimitive();
424
+ updatePrimitiveGeometry(cache); // 普通更新
266
425
  break;
267
426
  case 4:
268
427
  temp = geographyTcartesian3(e);
269
428
  activeNode.update([temp.x, temp.y, temp.z]);
270
429
  cache = editor.getCoordinates().map((e) => new Cesium.Cartesian3(...e));
271
- initPrimitive();
430
+ updatePrimitiveGeometry(cache, true); // 强制重建
272
431
  break;
273
432
  }
274
433
  };
@@ -284,38 +443,16 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
284
443
  break;
285
444
  case 1:
286
445
  cache.push(cache[cache.length - 1]);
287
- // geometry.setCoordinates(cache)
288
446
  initPrimitive();
289
447
  break;
290
448
  }
291
449
  };
292
450
 
293
451
  const initPrimitive = () => {
294
- primitive && viewer.scene.primitives.remove(primitive);
295
452
  if (cache.length > 1) {
296
- const geometry = Cesium.PolylineGeometry.createGeometry(
297
- new Cesium.PolylineGeometry({
298
- positions: cache,
299
- width: polyline.lineWidth,
300
- vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
301
- }),
302
- );
303
- if (geometry) {
304
- primitive = new Cesium.Primitive({
305
- show: polyline.show,
306
- asynchronous: false,
307
- geometryInstances: new Cesium.GeometryInstance({
308
- geometry,
309
- id: _event,
310
- }),
311
- appearance,
312
- });
313
- viewer.scene.primitives.add(primitive);
314
- } else {
315
- primitive = undefined;
316
- }
453
+ updatePrimitiveGeometry(cache, true); // 强制重建
317
454
  } else {
318
- primitive = undefined;
455
+ cleanupPrimitive();
319
456
  }
320
457
  };
321
458
 
@@ -326,7 +463,6 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
326
463
  skip++;
327
464
  cache.pop();
328
465
  cache.pop();
329
- // geometry.setCoordinates(cache)
330
466
  polyline.coordinates = cache.map((e) => cartesian3Tgeography(e));
331
467
  polyline.event.trigger("data-loaded");
332
468
  polyline.event.trigger("pointer-in");
@@ -348,8 +484,10 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
348
484
  };
349
485
 
350
486
  const onDestroy = () => {
351
- primitive && viewer.scene.primitives.remove(primitive);
352
- viewer.scene.primitives.remove(markers);
487
+ cleanupPrimitive();
488
+ if (markers) {
489
+ viewer.scene.primitives.remove(markers);
490
+ }
353
491
  event.off("pointer-move", onMouseMove);
354
492
  event.off("left-click", onClick);
355
493
  event.off("double-click", onDbClick);