@hzab/map-combine 0.4.2-alpha.5 → 0.4.2-alpha.6

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/CHANGELOG.md CHANGED
@@ -6,6 +6,7 @@ break: PointAggregation datas 改为数组对象
6
6
  fix: cesium flyTo height 计算
7
7
  feat: map.bussinesses onFrame 事件回调
8
8
  fix: AmapPoint drawPoint 逻辑修复
9
+ feat: Cesium 线 首次加载优化
9
10
 
10
11
  # @hzab/map-combine@0.4.1
11
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/map-combine",
3
- "version": "0.4.2-alpha.5",
3
+ "version": "0.4.2-alpha.6",
4
4
  "description": "地图组件",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -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({
@@ -99,25 +100,180 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
99
100
  },
100
101
  };
101
102
 
102
- let primitive: any;
103
103
  let cache: any[];
104
104
  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,
105
+
106
+ let geometryInstance = null;
107
+ let primitive = null;
108
+ let currentPositions = [];
109
+ let isFirstRender = true;
110
+
111
+ /**
112
+ * 更新或创建线条几何体
113
+ * @param newPositions - 新的顶点数组
114
+ * @param forceRebuild 强制重建
115
+ */
116
+ function updatePrimitiveGeometry(newPositions, forceRebuild: boolean = false) {
117
+ // 验证数据有效性
118
+ if (!newPositions || newPositions.length < 2) {
119
+ if (primitive) {
120
+ viewer.scene.primitives.remove(primitive);
121
+ primitive = null;
122
+ geometryInstance = null;
123
+ }
124
+ currentPositions = [];
125
+ return;
126
+ }
127
+
128
+ // 强制重建,跳过检查
129
+ if (!forceRebuild && !isFirstRender) {
130
+ if (currentPositions.length === newPositions.length) {
131
+ let same = true;
132
+ for (let i = 0; i < newPositions.length; i++) {
133
+ const p1 = currentPositions[i];
134
+ const p2 = newPositions[i];
135
+ if (
136
+ !p1 ||
137
+ !p2 ||
138
+ Math.abs(p1.x - p2.x) > 1e-10 ||
139
+ Math.abs(p1.y - p2.y) > 1e-10 ||
140
+ Math.abs(p1.z - p2.z) > 1e-10
141
+ ) {
142
+ same = false;
143
+ break;
144
+ }
145
+ }
146
+ if (same) return;
147
+ }
148
+ }
149
+
150
+ // 创建新的几何体数据
151
+ let newGeometry: any = null;
152
+ try {
153
+ newGeometry = Cesium.PolylineGeometry.createGeometry(
154
+ new Cesium.PolylineGeometry({
155
+ positions: newPositions,
113
156
  width: polyline.lineWidth,
114
157
  vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
115
158
  }),
159
+ );
160
+ } catch (error) {
161
+ console.error("创建几何体失败:", error);
162
+ return;
163
+ }
164
+
165
+ if (!newGeometry) return;
166
+
167
+ // 复用或创建 Primitive
168
+ if (geometryInstance && primitive && !forceRebuild) {
169
+ // 复用几何体实例
170
+ try {
171
+ geometryInstance.geometry = newGeometry;
172
+ if (primitive._state !== undefined) {
173
+ primitive._state = Cesium.PrimitiveState.NEEDS_REBUILD;
174
+ }
175
+ if (primitive._boundingVolume) {
176
+ primitive._boundingVolume = undefined;
177
+ }
178
+ if (primitive._dirty !== undefined) {
179
+ primitive._dirty = true;
180
+ }
181
+ } catch (error) {
182
+ console.warn("复用 Primitive 失败,降级到重建:", error);
183
+ // 降级:重新创建
184
+ if (primitive) {
185
+ viewer.scene.primitives.remove(primitive);
186
+ primitive = null;
187
+ }
188
+ geometryInstance = new Cesium.GeometryInstance({
189
+ geometry: newGeometry,
190
+ id: _event,
191
+ });
192
+ primitive = new Cesium.Primitive({
193
+ show: polyline.show !== false,
194
+ asynchronous: false,
195
+ geometryInstances: geometryInstance,
196
+ appearance: appearance,
197
+ compressVertices: true,
198
+ releaseGeometryInstances: false,
199
+ });
200
+ viewer.scene.primitives.add(primitive);
201
+ }
202
+ // 复用 Primitive,只更新几何体数据(性能最优)
203
+ try {
204
+ // 直接替换几何体数据
205
+ geometryInstance.geometry = newGeometry;
206
+
207
+ // 关键:标记 Primitive 需要重建
208
+ // 在 Cesium 1.90.1 中,这些内部状态需要手动触发
209
+ if (primitive._state !== undefined) {
210
+ primitive._state = Cesium.PrimitiveState.NEEDS_REBUILD;
211
+ }
212
+
213
+ // 清除缓存的包围盒,强制重新计算
214
+ if (primitive._boundingVolume) {
215
+ primitive._boundingVolume = undefined;
216
+ }
217
+
218
+ // 标记为脏,触发重绘
219
+ if (primitive._dirty !== undefined) {
220
+ primitive._dirty = true;
221
+ }
222
+
223
+ // 对于某些版本,可能需要重新设置 geometryInstances
224
+ // primitive.geometryInstances = geometryInstance;
225
+ } catch (error) {
226
+ // 如果复用失败,降级到重建方案
227
+ console.warn("复用 Primitive 失败,降级到重建:", error);
228
+ forceRebuild = true;
229
+ }
230
+ }
231
+
232
+ // 强制重建或者首次创建,重新创建 Primitive
233
+ if (forceRebuild || !primitive || !geometryInstance) {
234
+ if (primitive) {
235
+ viewer.scene.primitives.remove(primitive);
236
+ primitive = null;
237
+ }
238
+
239
+ geometryInstance = new Cesium.GeometryInstance({
240
+ geometry: newGeometry,
116
241
  id: _event,
117
- }),
118
- appearance,
119
- });
120
- viewer.scene.primitives.add(primitive);
242
+ });
243
+
244
+ primitive = new Cesium.Primitive({
245
+ show: polyline.show !== false,
246
+ asynchronous: false,
247
+ geometryInstances: geometryInstance,
248
+ appearance: appearance,
249
+ compressVertices: true,
250
+ releaseGeometryInstances: false,
251
+ });
252
+
253
+ viewer.scene.primitives.add(primitive);
254
+ isFirstRender = false;
255
+ }
256
+
257
+ currentPositions = newPositions.slice();
258
+ }
259
+
260
+ function cleanupPrimitive() {
261
+ if (primitive) {
262
+ viewer.scene.primitives.remove(primitive);
263
+ primitive = null;
264
+ }
265
+ if (geometryInstance) {
266
+ geometryInstance = null;
267
+ }
268
+ currentPositions = [];
269
+ isFirstRender = true;
270
+ }
271
+
272
+ // 初始加载
273
+ if (polyline.coordinates) {
274
+ status = 2;
275
+ cache = polyline.coordinates.map(geographyTcartesian3);
276
+ updatePrimitiveGeometry(cache, true); // 强制重建
121
277
  }
122
278
 
123
279
  const editor = new PolylineEditor<any, any>();
@@ -180,8 +336,10 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
180
336
  markers.remove(n.shape);
181
337
  });
182
338
  editor.on("empty", () => {
183
- // markers.removeAll()
184
- viewer.scene.primitives.remove(primitive);
339
+ if (primitive) {
340
+ viewer.scene.primitives.remove(primitive);
341
+ primitive = null;
342
+ }
185
343
  status = 0;
186
344
  });
187
345
 
@@ -218,7 +376,6 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
218
376
  break;
219
377
  case "dash":
220
378
  keys.add("Material");
221
-
222
379
  break;
223
380
  default:
224
381
  throw new Error(`${key} 还不支持修改`);
@@ -229,14 +386,13 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
229
386
  case "Primitive":
230
387
  if (polyline.coordinates) {
231
388
  cache = polyline.coordinates.map((e) => geographyTcartesian3(e));
389
+ updatePrimitiveGeometry(cache, true); // 强制重建
232
390
  } else {
233
391
  cache = [];
234
392
  markers.removeAll();
235
393
  status = 0;
236
394
  }
237
-
238
395
  initPrimitive();
239
-
240
396
  break;
241
397
  case "Material":
242
398
  material = createLineMaterial(polyline);
@@ -254,6 +410,7 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
254
410
  break;
255
411
  }
256
412
  };
413
+
257
414
  let temp: any;
258
415
  const onMouseMove = () => {
259
416
  const e = event.geography;
@@ -262,13 +419,13 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
262
419
  case 1:
263
420
  cache.pop();
264
421
  cache.push(geographyTcartesian3(e));
265
- initPrimitive();
422
+ updatePrimitiveGeometry(cache); // 普通更新
266
423
  break;
267
424
  case 4:
268
425
  temp = geographyTcartesian3(e);
269
426
  activeNode.update([temp.x, temp.y, temp.z]);
270
427
  cache = editor.getCoordinates().map((e) => new Cesium.Cartesian3(...e));
271
- initPrimitive();
428
+ updatePrimitiveGeometry(cache, true); // 强制重建
272
429
  break;
273
430
  }
274
431
  };
@@ -284,38 +441,16 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
284
441
  break;
285
442
  case 1:
286
443
  cache.push(cache[cache.length - 1]);
287
- // geometry.setCoordinates(cache)
288
444
  initPrimitive();
289
445
  break;
290
446
  }
291
447
  };
292
448
 
293
449
  const initPrimitive = () => {
294
- primitive && viewer.scene.primitives.remove(primitive);
295
450
  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
- }
451
+ updatePrimitiveGeometry(cache, true); // 强制重建
317
452
  } else {
318
- primitive = undefined;
453
+ cleanupPrimitive();
319
454
  }
320
455
  };
321
456
 
@@ -326,7 +461,6 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
326
461
  skip++;
327
462
  cache.pop();
328
463
  cache.pop();
329
- // geometry.setCoordinates(cache)
330
464
  polyline.coordinates = cache.map((e) => cartesian3Tgeography(e));
331
465
  polyline.event.trigger("data-loaded");
332
466
  polyline.event.trigger("pointer-in");
@@ -348,8 +482,10 @@ export function drawPolyline(map: CesiumMap, polyline: Polyline<unknown>) {
348
482
  };
349
483
 
350
484
  const onDestroy = () => {
351
- primitive && viewer.scene.primitives.remove(primitive);
352
- viewer.scene.primitives.remove(markers);
485
+ cleanupPrimitive();
486
+ if (markers) {
487
+ viewer.scene.primitives.remove(markers);
488
+ }
353
489
  event.off("pointer-move", onMouseMove);
354
490
  event.off("left-click", onClick);
355
491
  event.off("double-click", onDbClick);