@jorgmoritz/gis-manager 0.1.48 → 0.1.49

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/dist/index.cjs CHANGED
@@ -13,7 +13,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13
13
  // package.json
14
14
  var package_default = {
15
15
  name: "@jorgmoritz/gis-manager",
16
- version: "0.1.47"};
16
+ version: "0.1.48"};
17
17
 
18
18
  // src/utils/version.ts
19
19
  var version = package_default.version;
@@ -4272,7 +4272,7 @@ var VertexLabelManager = class {
4272
4272
  startColor: options?.startColor ?? "#FF6B6B",
4273
4273
  outlineColor: options?.outlineColor ?? "#FFFFFF",
4274
4274
  textColor: options?.textColor ?? "#FFFFFF",
4275
- pixelOffsetY: options?.pixelOffsetY ?? -10
4275
+ pixelOffsetY: options?.pixelOffsetY ?? 0
4276
4276
  };
4277
4277
  }
4278
4278
  /**
@@ -7888,7 +7888,7 @@ function renderFlightPath(CesiumNS, viewer, options) {
7888
7888
  description: entityDescription,
7889
7889
  polyline: {
7890
7890
  positions: positions.slice(),
7891
- width: options.style?.width ?? 3,
7891
+ width: options.style?.width ?? 5,
7892
7892
  material: options.style?.material ?? options.style?.color ?? C.Color.fromCssColorString("#00E676"),
7893
7893
  clampToGround: false
7894
7894
  },
@@ -9159,7 +9159,7 @@ var PolygonEditor = class {
9159
9159
  this.editHandles = positions.map(
9160
9160
  (p, i) => layer.entities.add({
9161
9161
  position: p,
9162
- point: { pixelSize: 7, color: point_color },
9162
+ point: { pixelSize: 7, color: point_color, outlineColor: C.Color.BLACK, outlineWidth: 1 },
9163
9163
  properties: { _vertexIndex: i }
9164
9164
  })
9165
9165
  );
@@ -9241,6 +9241,24 @@ var PolygonEditor = class {
9241
9241
  return void 0;
9242
9242
  }
9243
9243
  };
9244
+ const highlightHandle = (index) => {
9245
+ const handle = this.editHandles[index];
9246
+ if (handle && handle.point) {
9247
+ handle.point.pixelSize = 10;
9248
+ handle.point.color = C.Color.YELLOW;
9249
+ handle.point.outlineColor = C.Color.RED;
9250
+ handle.point.outlineWidth = 2;
9251
+ }
9252
+ };
9253
+ const unhighlightHandle = (index) => {
9254
+ const handle = this.editHandles[index];
9255
+ if (handle && handle.point) {
9256
+ handle.point.pixelSize = 7;
9257
+ handle.point.color = point_color;
9258
+ handle.point.outlineColor = C.Color.BLACK;
9259
+ handle.point.outlineWidth = 1;
9260
+ }
9261
+ };
9244
9262
  this.handler && this.handler.setInputAction(
9245
9263
  (movement) => {
9246
9264
  const picked = this.viewer.scene.pick?.(movement.position);
@@ -9250,6 +9268,7 @@ var PolygonEditor = class {
9250
9268
  if (typeof idx === "number") {
9251
9269
  this.draggingIndex = idx;
9252
9270
  this.originalPositionOnDrag = positions[idx];
9271
+ highlightHandle(idx);
9253
9272
  if (this.segmentHighlight) {
9254
9273
  try {
9255
9274
  layer.entities.remove(this.segmentHighlight);
@@ -9278,7 +9297,7 @@ var PolygonEditor = class {
9278
9297
  positions.splice(insertIndex, 0, insertPoint);
9279
9298
  const newHandle = layer.entities.add({
9280
9299
  position: insertPoint,
9281
- point: { pixelSize: 7, color: point_color },
9300
+ point: { pixelSize: 7, color: point_color, outlineColor: C.Color.BLACK, outlineWidth: 1 },
9282
9301
  properties: { _vertexIndex: insertIndex }
9283
9302
  });
9284
9303
  this.editHandles.splice(insertIndex, 0, newHandle);
@@ -9290,6 +9309,7 @@ var PolygonEditor = class {
9290
9309
  });
9291
9310
  this.draggingIndex = insertIndex;
9292
9311
  this.originalPositionOnDrag = insertPoint;
9312
+ highlightHandle(insertIndex);
9293
9313
  if (this.segmentHighlight) {
9294
9314
  try {
9295
9315
  layer.entities.remove(this.segmentHighlight);
@@ -9306,6 +9326,7 @@ var PolygonEditor = class {
9306
9326
  }
9307
9327
  }
9308
9328
  } else {
9329
+ unhighlightHandle(this.draggingIndex);
9309
9330
  this.draggingIndex = void 0;
9310
9331
  this.originalPositionOnDrag = void 0;
9311
9332
  }
@@ -9443,7 +9464,10 @@ var PolygonEditor = class {
9443
9464
  if (this.draggingIndex !== void 0 && this.originalPositionOnDrag) {
9444
9465
  positions[this.draggingIndex] = this.originalPositionOnDrag;
9445
9466
  const handle = this.editHandles[this.draggingIndex];
9446
- if (handle) handle.position = this.originalPositionOnDrag;
9467
+ if (handle) {
9468
+ handle.position = this.originalPositionOnDrag;
9469
+ unhighlightHandle(this.draggingIndex);
9470
+ }
9447
9471
  this.draggingIndex = void 0;
9448
9472
  this.originalPositionOnDrag = void 0;
9449
9473
  }
@@ -11249,6 +11273,89 @@ var PolygonEditor = class {
11249
11273
  }
11250
11274
  };
11251
11275
 
11276
+ // src/utils/LayerOrderManager.ts
11277
+ function bringDataSourceToTop(viewer, layerName) {
11278
+ const layers = viewer.dataSources.getByName(layerName);
11279
+ if (layers.length === 0) {
11280
+ return false;
11281
+ }
11282
+ const layer = layers[0];
11283
+ const currentIndex = viewer.dataSources.indexOf(layer);
11284
+ const lastIndex = viewer.dataSources.length - 1;
11285
+ if (currentIndex === lastIndex) {
11286
+ return true;
11287
+ }
11288
+ viewer.dataSources.remove(layer, false);
11289
+ viewer.dataSources.add(layer);
11290
+ return true;
11291
+ }
11292
+ function bringPrimitiveCollectionToTop(viewer, collection) {
11293
+ const primitives = viewer.scene.primitives;
11294
+ const targetGuid = collection._guid;
11295
+ let foundIndex = -1;
11296
+ let foundPrimitive = null;
11297
+ const count = primitives.length;
11298
+ for (let i = 0; i < count; i++) {
11299
+ const p = primitives.get(i);
11300
+ if (p === collection || p._guid === targetGuid) {
11301
+ foundIndex = i;
11302
+ foundPrimitive = p;
11303
+ break;
11304
+ }
11305
+ }
11306
+ if (foundIndex < 0) {
11307
+ console.warn("[LayerOrderManager] bringPrimitiveCollectionToTop: collection not found in primitives");
11308
+ return false;
11309
+ }
11310
+ if (foundIndex === count - 1) {
11311
+ return true;
11312
+ }
11313
+ primitives.raiseToTop(foundPrimitive);
11314
+ return true;
11315
+ }
11316
+ function ensureLayerAbove(viewer, topLayerName, bottomLayerName) {
11317
+ const topLayers = viewer.dataSources.getByName(topLayerName);
11318
+ if (topLayers.length === 0) {
11319
+ return;
11320
+ }
11321
+ if (!bottomLayerName) {
11322
+ bringDataSourceToTop(viewer, topLayerName);
11323
+ return;
11324
+ }
11325
+ const bottomLayers = viewer.dataSources.getByName(bottomLayerName);
11326
+ if (bottomLayers.length === 0) {
11327
+ bringDataSourceToTop(viewer, topLayerName);
11328
+ return;
11329
+ }
11330
+ const topLayer = topLayers[0];
11331
+ const bottomLayer = bottomLayers[0];
11332
+ const topIndex = viewer.dataSources.indexOf(topLayer);
11333
+ const bottomIndex = viewer.dataSources.indexOf(bottomLayer);
11334
+ if (topIndex > bottomIndex) {
11335
+ return;
11336
+ }
11337
+ bringDataSourceToTop(viewer, topLayerName);
11338
+ }
11339
+ function getDataSourceIndex(viewer, layerName) {
11340
+ const layers = viewer.dataSources.getByName(layerName);
11341
+ if (layers.length === 0) {
11342
+ return -1;
11343
+ }
11344
+ return viewer.dataSources.indexOf(layers[0]);
11345
+ }
11346
+ function getDataSourceOrder(viewer) {
11347
+ const result = [];
11348
+ const count = viewer.dataSources.length;
11349
+ for (let i = 0; i < count; i++) {
11350
+ const ds = viewer.dataSources.get(i);
11351
+ result.push({
11352
+ name: ds.name,
11353
+ index: i
11354
+ });
11355
+ }
11356
+ return result;
11357
+ }
11358
+
11252
11359
  // src/core/CZMLManager.ts
11253
11360
  var CZMLManager = class {
11254
11361
  constructor(CesiumNS, viewer) {
@@ -11525,16 +11632,7 @@ var CZMLManager = class {
11525
11632
  } else {
11526
11633
  layer = this.viewer.dataSources.getByName("subarray")[0];
11527
11634
  }
11528
- const inverterLayers = this.viewer.dataSources.getByName("inverter");
11529
- if (inverterLayers.length > 0) {
11530
- const inverterLayer = inverterLayers[0];
11531
- const index = this.viewer.dataSources.indexOf(inverterLayer);
11532
- const lastIndex = this.viewer.dataSources.length - 1;
11533
- if (index >= 0 && index < lastIndex) {
11534
- this.viewer.dataSources.remove(inverterLayer, false);
11535
- this.viewer.dataSources.add(inverterLayer);
11536
- }
11537
- }
11635
+ ensureLayerAbove(this.viewer, "inverter", "subarray");
11538
11636
  } else if (type == "inverter") {
11539
11637
  if (this.viewer.dataSources.getByName("inverter").length < 1) {
11540
11638
  const data = new this.CesiumNS.CustomDataSource("inverter");
@@ -11543,14 +11641,7 @@ var CZMLManager = class {
11543
11641
  } else {
11544
11642
  layer = this.viewer.dataSources.getByName("inverter")[0];
11545
11643
  }
11546
- if (layer) {
11547
- const index = this.viewer.dataSources.indexOf(layer);
11548
- const lastIndex = this.viewer.dataSources.length - 1;
11549
- if (index >= 0 && index < lastIndex) {
11550
- this.viewer.dataSources.remove(layer, false);
11551
- this.viewer.dataSources.add(layer);
11552
- }
11553
- }
11644
+ bringDataSourceToTop(this.viewer, "inverter");
11554
11645
  } else {
11555
11646
  if (this.viewer.dataSources.getByName("other").length < 1) {
11556
11647
  const data = new this.CesiumNS.CustomDataSource("other");
@@ -11559,14 +11650,7 @@ var CZMLManager = class {
11559
11650
  } else {
11560
11651
  layer = this.viewer.dataSources.getByName("other")[0];
11561
11652
  }
11562
- if (layer) {
11563
- const index = this.viewer.dataSources.indexOf(layer);
11564
- const lastIndex = this.viewer.dataSources.length - 1;
11565
- if (index >= 0 && index < lastIndex) {
11566
- this.viewer.dataSources.remove(layer, false);
11567
- this.viewer.dataSources.add(layer);
11568
- }
11569
- }
11653
+ bringDataSourceToTop(this.viewer, "other");
11570
11654
  }
11571
11655
  const session = this.polygonEditor.startDrawing(type, layer, (entity) => {
11572
11656
  this.cancelActivePolygonDrawing();
@@ -11671,14 +11755,7 @@ var CZMLManager = class {
11671
11755
  } else {
11672
11756
  layer = this.viewer.dataSources.getByName("other")[0];
11673
11757
  }
11674
- if (layer) {
11675
- const index = this.viewer.dataSources.indexOf(layer);
11676
- const lastIndex = this.viewer.dataSources.length - 1;
11677
- if (index >= 0 && index < lastIndex) {
11678
- this.viewer.dataSources.remove(layer, false);
11679
- this.viewer.dataSources.add(layer);
11680
- }
11681
- }
11758
+ bringDataSourceToTop(this.viewer, "other");
11682
11759
  return this.polygonEditor.startPointDrawing?.(layer, iconSvg, onComplete);
11683
11760
  }
11684
11761
  // New: start editing an existing polygon entity's vertices
@@ -11716,36 +11793,11 @@ var CZMLManager = class {
11716
11793
  const dataSource = this.getEntityDataSource(entity);
11717
11794
  if (!dataSource) return void 0;
11718
11795
  if (dataSource.name === "inverter") {
11719
- const index = this.viewer.dataSources.indexOf(dataSource);
11720
- const lastIndex = this.viewer.dataSources.length - 1;
11721
- if (index >= 0 && index < lastIndex) {
11722
- this.viewer.dataSources.remove(dataSource, false);
11723
- this.viewer.dataSources.add(dataSource);
11724
- }
11725
- }
11726
- if (dataSource.name === "subarray") {
11727
- const inverterLayers = this.viewer.dataSources.getByName("inverter");
11728
- if (inverterLayers.length > 0) {
11729
- const inverterLayer = inverterLayers[0];
11730
- const index = this.viewer.dataSources.indexOf(inverterLayer);
11731
- const lastIndex = this.viewer.dataSources.length - 1;
11732
- if (index >= 0 && index < lastIndex) {
11733
- this.viewer.dataSources.remove(inverterLayer, false);
11734
- this.viewer.dataSources.add(inverterLayer);
11735
- }
11736
- }
11737
- }
11738
- if (dataSource.name === "other") {
11739
- const otherLayers = this.viewer.dataSources.getByName("other");
11740
- if (otherLayers.length > 0) {
11741
- const otherLayer = otherLayers[0];
11742
- const index = this.viewer.dataSources.indexOf(otherLayer);
11743
- const lastIndex = this.viewer.dataSources.length - 1;
11744
- if (index >= 0 && index < lastIndex) {
11745
- this.viewer.dataSources.remove(otherLayer, false);
11746
- this.viewer.dataSources.add(otherLayer);
11747
- }
11748
- }
11796
+ bringDataSourceToTop(this.viewer, "inverter");
11797
+ } else if (dataSource.name === "subarray") {
11798
+ ensureLayerAbove(this.viewer, "inverter", "subarray");
11799
+ } else if (dataSource.name === "other") {
11800
+ bringDataSourceToTop(this.viewer, "other");
11749
11801
  }
11750
11802
  return this.polygonEditor.startEditing(entity, dataSource, onComplete);
11751
11803
  }
@@ -13261,6 +13313,976 @@ var PathSafetyChecker = class {
13261
13313
  }
13262
13314
  };
13263
13315
 
13316
+ // src/core/polygon-manager/MassPolygonManager.ts
13317
+ var MassPolygonManager = class {
13318
+ constructor(CesiumNS, viewer) {
13319
+ __publicField(this, "CesiumNS");
13320
+ __publicField(this, "viewer");
13321
+ // 图层容器
13322
+ __publicField(this, "layerCollection");
13323
+ __publicField(this, "layerName");
13324
+ // Primitives
13325
+ __publicField(this, "primitive");
13326
+ __publicField(this, "outlinePrimitive");
13327
+ __publicField(this, "labelCollection");
13328
+ // 数据存储
13329
+ __publicField(this, "polygonDataMap", /* @__PURE__ */ new Map());
13330
+ __publicField(this, "currentStyle");
13331
+ __publicField(this, "currentOptions", {});
13332
+ __publicField(this, "isClampToGround", false);
13333
+ __publicField(this, "polygonHeight", 0);
13334
+ // 多边形统一高度
13335
+ // 交互配置(内部使用,回调可选)
13336
+ __publicField(this, "interactionOptions");
13337
+ // 事件处理器
13338
+ __publicField(this, "hoverHandler");
13339
+ __publicField(this, "clickHandler");
13340
+ // 悬停状态
13341
+ __publicField(this, "highlightedId");
13342
+ __publicField(this, "originalHighlightFillColor");
13343
+ __publicField(this, "originalHighlightOutlineColor");
13344
+ // 选中状态
13345
+ __publicField(this, "selectedId");
13346
+ __publicField(this, "originalSelectFillColor");
13347
+ __publicField(this, "originalSelectOutlineColor");
13348
+ // 节流相关
13349
+ __publicField(this, "lastPickTime", 0);
13350
+ __publicField(this, "pickThrottleMs", 50);
13351
+ // 悬停标签
13352
+ __publicField(this, "hoverLabel");
13353
+ // ========== 编辑支持方法 ==========
13354
+ // 隐藏的多边形原始颜色存储
13355
+ __publicField(this, "hiddenPolygonColors", /* @__PURE__ */ new Map());
13356
+ this.CesiumNS = CesiumNS;
13357
+ this.viewer = viewer;
13358
+ this.currentStyle = {
13359
+ fillColor: "rgba(0, 150, 255, 0.5)",
13360
+ outlineColor: "rgba(255, 255, 255, 0.8)",
13361
+ outlineWidth: 1
13362
+ };
13363
+ this.interactionOptions = {
13364
+ enableHover: false,
13365
+ enableClick: false,
13366
+ highlightStyle: {
13367
+ fillColor: "rgba(255, 255, 0, 0.7)",
13368
+ outlineColor: "rgba(255, 255, 0, 1)"
13369
+ },
13370
+ selectStyle: {
13371
+ fillColor: "rgba(0, 255, 128, 0.7)",
13372
+ outlineColor: "rgba(0, 255, 128, 1)"
13373
+ },
13374
+ showHoverLabel: true,
13375
+ hoverLabelStyle: {
13376
+ font: "14px sans-serif",
13377
+ fillColor: "#ffffff",
13378
+ outlineColor: "#000000",
13379
+ outlineWidth: 2,
13380
+ backgroundColor: "rgba(0,0,0,0.7)",
13381
+ backgroundPadding: [8, 4],
13382
+ pixelOffset: [0, -20]
13383
+ },
13384
+ onHover: void 0,
13385
+ onClick: void 0
13386
+ };
13387
+ }
13388
+ /**
13389
+ * 获取图层名称
13390
+ */
13391
+ getLayerName() {
13392
+ return this.layerName;
13393
+ }
13394
+ /**
13395
+ * 获取图层容器(PrimitiveCollection)
13396
+ * 用于图层顺序管理
13397
+ */
13398
+ getLayerCollection() {
13399
+ return this.layerCollection;
13400
+ }
13401
+ /**
13402
+ * 批量创建多边形
13403
+ */
13404
+ create(polygons, options) {
13405
+ const C = this.CesiumNS;
13406
+ this.clear();
13407
+ this.currentOptions = options ?? {};
13408
+ this.layerName = options?.layerName;
13409
+ if (options?.style) {
13410
+ this.currentStyle = { ...this.currentStyle, ...options.style };
13411
+ }
13412
+ if (options?.interaction) {
13413
+ const interaction = options.interaction;
13414
+ this.interactionOptions = {
13415
+ enableHover: interaction.enableHover ?? false,
13416
+ enableClick: interaction.enableClick ?? false,
13417
+ highlightStyle: {
13418
+ fillColor: interaction.highlightStyle?.fillColor ?? this.interactionOptions.highlightStyle.fillColor,
13419
+ outlineColor: interaction.highlightStyle?.outlineColor ?? this.interactionOptions.highlightStyle.outlineColor
13420
+ },
13421
+ selectStyle: {
13422
+ fillColor: interaction.selectStyle?.fillColor ?? this.interactionOptions.selectStyle.fillColor,
13423
+ outlineColor: interaction.selectStyle?.outlineColor ?? this.interactionOptions.selectStyle.outlineColor
13424
+ },
13425
+ showHoverLabel: interaction.showHoverLabel ?? true,
13426
+ hoverLabelStyle: {
13427
+ font: interaction.hoverLabelStyle?.font ?? this.interactionOptions.hoverLabelStyle.font,
13428
+ fillColor: interaction.hoverLabelStyle?.fillColor ?? this.interactionOptions.hoverLabelStyle.fillColor,
13429
+ outlineColor: interaction.hoverLabelStyle?.outlineColor ?? this.interactionOptions.hoverLabelStyle.outlineColor,
13430
+ outlineWidth: interaction.hoverLabelStyle?.outlineWidth ?? this.interactionOptions.hoverLabelStyle.outlineWidth,
13431
+ backgroundColor: interaction.hoverLabelStyle?.backgroundColor ?? this.interactionOptions.hoverLabelStyle.backgroundColor,
13432
+ backgroundPadding: interaction.hoverLabelStyle?.backgroundPadding ?? this.interactionOptions.hoverLabelStyle.backgroundPadding,
13433
+ pixelOffset: interaction.hoverLabelStyle?.pixelOffset ?? this.interactionOptions.hoverLabelStyle.pixelOffset
13434
+ },
13435
+ onHover: interaction.onHover,
13436
+ onClick: interaction.onClick
13437
+ };
13438
+ }
13439
+ this.isClampToGround = options?.clampToGround ?? false;
13440
+ const asynchronous = options?.asynchronous ?? true;
13441
+ this.polygonHeight = options?.height ?? 0;
13442
+ if (this.isClampToGround && this.viewer.scene.globe) {
13443
+ this.viewer.scene.globe.depthTestAgainstTerrain = true;
13444
+ }
13445
+ this.layerCollection = new C.PrimitiveCollection();
13446
+ this.viewer.scene.primitives.add(this.layerCollection);
13447
+ this.polygonDataMap.clear();
13448
+ for (const polygon of polygons) {
13449
+ this.polygonDataMap.set(polygon.id, polygon);
13450
+ }
13451
+ const fillInstances = [];
13452
+ const outlineInstances = [];
13453
+ const fillColor = C.Color.fromCssColorString(this.currentStyle.fillColor);
13454
+ const outlineColor = C.Color.fromCssColorString(this.currentStyle.outlineColor);
13455
+ for (const polygon of polygons) {
13456
+ if (polygon.points.length < 3) {
13457
+ console.warn(`[MassPolygonManager] \u591A\u8FB9\u5F62 ${polygon.id} \u9876\u70B9\u6570\u4E0D\u8DB3\uFF0C\u5DF2\u8DF3\u8FC7`);
13458
+ continue;
13459
+ }
13460
+ const positions = this.convertPointsToCartesian(polygon.points);
13461
+ const polygonGeometry = new C.PolygonGeometry({
13462
+ polygonHierarchy: new C.PolygonHierarchy(positions),
13463
+ perPositionHeight: false,
13464
+ height: this.polygonHeight
13465
+ // 使用配置的高度
13466
+ });
13467
+ fillInstances.push(new C.GeometryInstance({
13468
+ geometry: polygonGeometry,
13469
+ id: polygon.id,
13470
+ attributes: {
13471
+ color: C.ColorGeometryInstanceAttribute.fromColor(fillColor),
13472
+ show: new C.ShowGeometryInstanceAttribute(true)
13473
+ }
13474
+ }));
13475
+ const outlinePositionsWithHeight = polygon.points.map(
13476
+ (p) => C.Cartesian3.fromDegrees(p.lon, p.lat, this.polygonHeight)
13477
+ );
13478
+ outlinePositionsWithHeight.push(outlinePositionsWithHeight[0]);
13479
+ const outlineGeometry = new C.PolylineGeometry({
13480
+ positions: outlinePositionsWithHeight,
13481
+ width: this.currentStyle.outlineWidth
13482
+ });
13483
+ outlineInstances.push(new C.GeometryInstance({
13484
+ geometry: outlineGeometry,
13485
+ id: `${polygon.id}-outline`,
13486
+ attributes: {
13487
+ color: C.ColorGeometryInstanceAttribute.fromColor(outlineColor),
13488
+ show: new C.ShowGeometryInstanceAttribute(true)
13489
+ }
13490
+ }));
13491
+ }
13492
+ if (fillInstances.length > 0) {
13493
+ const appearance = new C.PerInstanceColorAppearance({ flat: true, translucent: true });
13494
+ this.primitive = new C.Primitive({ geometryInstances: fillInstances, appearance, asynchronous });
13495
+ this.layerCollection.add(this.primitive);
13496
+ }
13497
+ if (outlineInstances.length > 0) {
13498
+ const appearance = new C.PolylineColorAppearance();
13499
+ this.outlinePrimitive = new C.Primitive({ geometryInstances: outlineInstances, appearance, asynchronous });
13500
+ this.layerCollection.add(this.outlinePrimitive);
13501
+ }
13502
+ this.labelCollection = new C.LabelCollection();
13503
+ this.layerCollection.add(this.labelCollection);
13504
+ if (this.interactionOptions.enableHover) {
13505
+ this.setupHoverHandler();
13506
+ }
13507
+ if (this.interactionOptions.enableClick) {
13508
+ this.setupClickHandler();
13509
+ }
13510
+ this.viewer.scene.requestRender();
13511
+ return {
13512
+ primitive: this.primitive,
13513
+ count: fillInstances.length
13514
+ };
13515
+ }
13516
+ /**
13517
+ * 设置悬停事件处理器
13518
+ */
13519
+ setupHoverHandler() {
13520
+ if (this.hoverHandler) {
13521
+ this.hoverHandler.destroy();
13522
+ }
13523
+ const C = this.CesiumNS;
13524
+ this.hoverHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
13525
+ this.hoverHandler.setInputAction(
13526
+ (movement) => {
13527
+ const now = Date.now();
13528
+ if (now - this.lastPickTime < this.pickThrottleMs) return;
13529
+ this.lastPickTime = now;
13530
+ const pickedObject = this.viewer.scene.pick(movement.endPosition);
13531
+ if (pickedObject?.id && typeof pickedObject.id === "string") {
13532
+ const polygonId = pickedObject.id.endsWith("-outline") ? pickedObject.id.replace("-outline", "") : pickedObject.id;
13533
+ if (this.polygonDataMap.has(polygonId)) {
13534
+ if (this.highlightedId !== polygonId) {
13535
+ this.clearHighlight();
13536
+ this.highlightPolygon(polygonId);
13537
+ const data = this.polygonDataMap.get(polygonId);
13538
+ if (data) this.showLabel(data);
13539
+ this.interactionOptions.onHover?.(polygonId, data ?? null);
13540
+ }
13541
+ } else {
13542
+ this.handleMouseLeave();
13543
+ }
13544
+ } else {
13545
+ this.handleMouseLeave();
13546
+ }
13547
+ },
13548
+ C.ScreenSpaceEventType.MOUSE_MOVE
13549
+ );
13550
+ }
13551
+ /**
13552
+ * 设置点击事件处理器
13553
+ */
13554
+ setupClickHandler() {
13555
+ if (this.clickHandler) {
13556
+ this.clickHandler.destroy();
13557
+ }
13558
+ const C = this.CesiumNS;
13559
+ this.clickHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
13560
+ this.clickHandler.setInputAction(
13561
+ (movement) => {
13562
+ const pickedObject = this.viewer.scene.pick(movement.position);
13563
+ if (pickedObject?.id && typeof pickedObject.id === "string") {
13564
+ const polygonId = pickedObject.id.endsWith("-outline") ? pickedObject.id.replace("-outline", "") : pickedObject.id;
13565
+ if (this.polygonDataMap.has(polygonId)) {
13566
+ if (this.selectedId === polygonId) {
13567
+ this.deselect();
13568
+ this.interactionOptions.onClick?.(null, null);
13569
+ } else {
13570
+ this.select(polygonId);
13571
+ const data = this.polygonDataMap.get(polygonId);
13572
+ this.interactionOptions.onClick?.(polygonId, data ?? null);
13573
+ }
13574
+ } else {
13575
+ if (this.selectedId) {
13576
+ this.deselect();
13577
+ this.interactionOptions.onClick?.(null, null);
13578
+ }
13579
+ }
13580
+ } else {
13581
+ if (this.selectedId) {
13582
+ this.deselect();
13583
+ this.interactionOptions.onClick?.(null, null);
13584
+ }
13585
+ }
13586
+ },
13587
+ C.ScreenSpaceEventType.LEFT_CLICK
13588
+ );
13589
+ }
13590
+ /**
13591
+ * 处理鼠标离开
13592
+ */
13593
+ handleMouseLeave() {
13594
+ if (this.highlightedId) {
13595
+ this.clearHighlight();
13596
+ this.hideLabel();
13597
+ this.interactionOptions.onHover?.(null, null);
13598
+ }
13599
+ }
13600
+ /**
13601
+ * 高亮指定多边形(悬停)
13602
+ */
13603
+ highlightPolygon(id) {
13604
+ if (id === this.selectedId) return;
13605
+ const C = this.CesiumNS;
13606
+ if (!this.primitive) return;
13607
+ try {
13608
+ const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(id);
13609
+ if (fillAttributes?.color) {
13610
+ this.originalHighlightFillColor = new Uint8Array(fillAttributes.color);
13611
+ const highlightColor = C.Color.fromCssColorString(this.interactionOptions.highlightStyle.fillColor);
13612
+ fillAttributes.color = C.ColorGeometryInstanceAttribute.toValue(highlightColor);
13613
+ }
13614
+ if (this.outlinePrimitive) {
13615
+ const outlineAttributes = this.outlinePrimitive.getGeometryInstanceAttributes?.(`${id}-outline`);
13616
+ if (outlineAttributes?.color) {
13617
+ this.originalHighlightOutlineColor = new Uint8Array(outlineAttributes.color);
13618
+ const highlightColor = C.Color.fromCssColorString(this.interactionOptions.highlightStyle.outlineColor);
13619
+ outlineAttributes.color = C.ColorGeometryInstanceAttribute.toValue(highlightColor);
13620
+ }
13621
+ }
13622
+ this.highlightedId = id;
13623
+ this.viewer.scene.requestRender();
13624
+ } catch (e) {
13625
+ }
13626
+ }
13627
+ /**
13628
+ * 清除悬停高亮
13629
+ */
13630
+ clearHighlight() {
13631
+ if (!this.highlightedId) return;
13632
+ try {
13633
+ if (this.primitive && this.originalHighlightFillColor) {
13634
+ const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(this.highlightedId);
13635
+ if (fillAttributes) {
13636
+ fillAttributes.color = this.originalHighlightFillColor;
13637
+ }
13638
+ }
13639
+ if (this.outlinePrimitive && this.originalHighlightOutlineColor) {
13640
+ const outlineAttributes = this.outlinePrimitive.getGeometryInstanceAttributes?.(`${this.highlightedId}-outline`);
13641
+ if (outlineAttributes) {
13642
+ outlineAttributes.color = this.originalHighlightOutlineColor;
13643
+ }
13644
+ }
13645
+ this.highlightedId = void 0;
13646
+ this.originalHighlightFillColor = void 0;
13647
+ this.originalHighlightOutlineColor = void 0;
13648
+ this.viewer.scene.requestRender();
13649
+ } catch (e) {
13650
+ }
13651
+ }
13652
+ /**
13653
+ * 选中指定多边形
13654
+ * @param id 多边形 ID
13655
+ * @returns 是否选中成功
13656
+ */
13657
+ select(id) {
13658
+ if (!this.polygonDataMap.has(id)) return false;
13659
+ if (this.selectedId && this.selectedId !== id) {
13660
+ this.deselect();
13661
+ }
13662
+ if (this.highlightedId === id) {
13663
+ this.clearHighlight();
13664
+ }
13665
+ const C = this.CesiumNS;
13666
+ if (!this.primitive) return false;
13667
+ try {
13668
+ const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(id);
13669
+ if (fillAttributes?.color) {
13670
+ this.originalSelectFillColor = new Uint8Array(fillAttributes.color);
13671
+ const selectColor = C.Color.fromCssColorString(this.interactionOptions.selectStyle.fillColor);
13672
+ fillAttributes.color = C.ColorGeometryInstanceAttribute.toValue(selectColor);
13673
+ }
13674
+ if (this.outlinePrimitive) {
13675
+ const outlineAttributes = this.outlinePrimitive.getGeometryInstanceAttributes?.(`${id}-outline`);
13676
+ if (outlineAttributes?.color) {
13677
+ this.originalSelectOutlineColor = new Uint8Array(outlineAttributes.color);
13678
+ const selectColor = C.Color.fromCssColorString(this.interactionOptions.selectStyle.outlineColor);
13679
+ outlineAttributes.color = C.ColorGeometryInstanceAttribute.toValue(selectColor);
13680
+ }
13681
+ }
13682
+ this.selectedId = id;
13683
+ this.viewer.scene.requestRender();
13684
+ return true;
13685
+ } catch (e) {
13686
+ return false;
13687
+ }
13688
+ }
13689
+ /**
13690
+ * 取消选中
13691
+ */
13692
+ deselect() {
13693
+ if (!this.selectedId) return;
13694
+ try {
13695
+ if (this.primitive && this.originalSelectFillColor) {
13696
+ const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(this.selectedId);
13697
+ if (fillAttributes) {
13698
+ fillAttributes.color = this.originalSelectFillColor;
13699
+ }
13700
+ }
13701
+ if (this.outlinePrimitive && this.originalSelectOutlineColor) {
13702
+ const outlineAttributes = this.outlinePrimitive.getGeometryInstanceAttributes?.(`${this.selectedId}-outline`);
13703
+ if (outlineAttributes) {
13704
+ outlineAttributes.color = this.originalSelectOutlineColor;
13705
+ }
13706
+ }
13707
+ this.selectedId = void 0;
13708
+ this.originalSelectFillColor = void 0;
13709
+ this.originalSelectOutlineColor = void 0;
13710
+ this.viewer.scene.requestRender();
13711
+ } catch (e) {
13712
+ }
13713
+ }
13714
+ /**
13715
+ * 获取当前选中的多边形数据
13716
+ */
13717
+ getSelected() {
13718
+ if (!this.selectedId) return null;
13719
+ return this.polygonDataMap.get(this.selectedId) ?? null;
13720
+ }
13721
+ /**
13722
+ * 获取当前选中的多边形 ID
13723
+ */
13724
+ getSelectedId() {
13725
+ return this.selectedId ?? null;
13726
+ }
13727
+ /**
13728
+ * 计算多边形中心点
13729
+ */
13730
+ calculatePolygonCenter(points) {
13731
+ let sumLon = 0, sumLat = 0, sumHeight = 0;
13732
+ for (const p of points) {
13733
+ sumLon += p.lon;
13734
+ sumLat += p.lat;
13735
+ sumHeight += p.height ?? 0;
13736
+ }
13737
+ return {
13738
+ lon: sumLon / points.length,
13739
+ lat: sumLat / points.length,
13740
+ height: sumHeight / points.length
13741
+ };
13742
+ }
13743
+ /**
13744
+ * 显示悬停标签
13745
+ */
13746
+ showLabel(polygonData) {
13747
+ if (!this.interactionOptions.showHoverLabel || !polygonData.name) return;
13748
+ if (!this.labelCollection) return;
13749
+ const C = this.CesiumNS;
13750
+ const style = this.interactionOptions.hoverLabelStyle;
13751
+ this.hideLabel();
13752
+ const center = this.calculatePolygonCenter(polygonData.points);
13753
+ const position = C.Cartesian3.fromDegrees(center.lon, center.lat, this.polygonHeight);
13754
+ this.hoverLabel = this.labelCollection.add({
13755
+ position,
13756
+ text: polygonData.name,
13757
+ font: style.font,
13758
+ fillColor: C.Color.fromCssColorString(style.fillColor),
13759
+ outlineColor: C.Color.fromCssColorString(style.outlineColor),
13760
+ outlineWidth: style.outlineWidth,
13761
+ style: C.LabelStyle.FILL_AND_OUTLINE,
13762
+ showBackground: true,
13763
+ backgroundColor: C.Color.fromCssColorString(style.backgroundColor),
13764
+ backgroundPadding: new C.Cartesian2(style.backgroundPadding[0], style.backgroundPadding[1]),
13765
+ pixelOffset: new C.Cartesian2(style.pixelOffset[0], style.pixelOffset[1]),
13766
+ verticalOrigin: C.VerticalOrigin.BOTTOM,
13767
+ horizontalOrigin: C.HorizontalOrigin.CENTER,
13768
+ disableDepthTestDistance: Number.POSITIVE_INFINITY
13769
+ });
13770
+ }
13771
+ /**
13772
+ * 隐藏悬停标签
13773
+ */
13774
+ hideLabel() {
13775
+ if (this.hoverLabel && this.labelCollection) {
13776
+ this.labelCollection.remove(this.hoverLabel);
13777
+ this.hoverLabel = void 0;
13778
+ this.viewer.scene.requestRender();
13779
+ }
13780
+ }
13781
+ /**
13782
+ * 根据 ID 获取多边形数据
13783
+ */
13784
+ getById(id) {
13785
+ return this.polygonDataMap.get(id);
13786
+ }
13787
+ /**
13788
+ * 获取所有多边形数据
13789
+ */
13790
+ getAll() {
13791
+ return Array.from(this.polygonDataMap.values());
13792
+ }
13793
+ /**
13794
+ * 获取多边形数量
13795
+ */
13796
+ getCount() {
13797
+ return this.polygonDataMap.size;
13798
+ }
13799
+ /**
13800
+ * 获取所有多边形的边界框
13801
+ */
13802
+ getBounds() {
13803
+ if (this.polygonDataMap.size === 0) return null;
13804
+ const allPoints = [];
13805
+ for (const polygon of this.polygonDataMap.values()) {
13806
+ for (const point of polygon.points) {
13807
+ allPoints.push({ lon: point.lon, lat: point.lat, alt: point.height });
13808
+ }
13809
+ }
13810
+ return calculateGeoBounds(allPoints);
13811
+ }
13812
+ /**
13813
+ * 飞行到所有多边形的范围
13814
+ */
13815
+ flyToBounds(options) {
13816
+ const bounds = this.getBounds();
13817
+ if (!bounds) {
13818
+ console.warn("[MassPolygonManager] \u6CA1\u6709\u591A\u8FB9\u5F62\u6570\u636E\uFF0C\u65E0\u6CD5\u98DE\u884C");
13819
+ return;
13820
+ }
13821
+ const C = this.CesiumNS;
13822
+ const camera = this.viewer.camera;
13823
+ const duration = options?.duration ?? 2;
13824
+ const padding = options?.padding ?? 0.2;
13825
+ const pitch = options?.pitch ?? C.Math.toRadians(-45);
13826
+ const heading = options?.heading ?? 0;
13827
+ const paddedWest = bounds.west - bounds.width * padding;
13828
+ const paddedEast = bounds.east + bounds.width * padding;
13829
+ const paddedSouth = bounds.south - bounds.height * padding;
13830
+ const paddedNorth = bounds.north + bounds.height * padding;
13831
+ const earthRadius = 6371e3;
13832
+ const rectWidth = (paddedEast - paddedWest) * (Math.PI / 180) * earthRadius * Math.cos(bounds.centerLat * Math.PI / 180);
13833
+ const rectHeight = (paddedNorth - paddedSouth) * (Math.PI / 180) * earthRadius;
13834
+ const frustum = camera.frustum;
13835
+ const fovy = frustum.fovy || frustum.fov || C.Math.toRadians(60);
13836
+ const canvas = this.viewer.scene.canvas;
13837
+ const aspectRatio = canvas.width / canvas.height;
13838
+ const fovx = 2 * Math.atan(Math.tan(fovy / 2) * aspectRatio);
13839
+ const absPitch = Math.abs(pitch);
13840
+ const sinPitch = Math.sin(absPitch) || 0.707;
13841
+ const altitudeForHeight = rectHeight / 2 / Math.tan(fovy / 2) / sinPitch;
13842
+ const altitudeForWidth = rectWidth / 2 / Math.tan(fovx / 2) / sinPitch;
13843
+ const altitude = Math.max(altitudeForHeight, altitudeForWidth, 500) * 1.1;
13844
+ const destination = C.Cartesian3.fromDegrees(bounds.centerLon, bounds.centerLat, altitude);
13845
+ const orientation = { heading, pitch, roll: 0 };
13846
+ if (duration > 0) {
13847
+ camera.flyTo({ destination, orientation, duration });
13848
+ } else {
13849
+ camera.setView({ destination, orientation });
13850
+ }
13851
+ console.log(`[MassPolygonManager] \u98DE\u884C\u5230\u8FB9\u754C: \u4E2D\u5FC3(${bounds.centerLon.toFixed(6)}, ${bounds.centerLat.toFixed(6)}), \u9AD8\u5EA6: ${altitude.toFixed(0)}m`);
13852
+ }
13853
+ /**
13854
+ * 设置可见性
13855
+ */
13856
+ setVisibility(visible) {
13857
+ if (this.layerCollection) {
13858
+ this.layerCollection.show = visible;
13859
+ }
13860
+ this.viewer.scene.requestRender();
13861
+ }
13862
+ /**
13863
+ * 更新样式(需要重新创建所有多边形)
13864
+ */
13865
+ updateStyle(style) {
13866
+ this.currentStyle = { ...this.currentStyle, ...style };
13867
+ const polygons = Array.from(this.polygonDataMap.values());
13868
+ if (polygons.length > 0) {
13869
+ this.create(polygons, { ...this.currentOptions, style: this.currentStyle });
13870
+ }
13871
+ }
13872
+ /**
13873
+ * 清除所有多边形
13874
+ */
13875
+ clear() {
13876
+ if (this.hoverHandler) {
13877
+ this.hoverHandler.destroy();
13878
+ this.hoverHandler = void 0;
13879
+ }
13880
+ if (this.clickHandler) {
13881
+ this.clickHandler.destroy();
13882
+ this.clickHandler = void 0;
13883
+ }
13884
+ this.highlightedId = void 0;
13885
+ this.selectedId = void 0;
13886
+ this.originalHighlightFillColor = void 0;
13887
+ this.originalHighlightOutlineColor = void 0;
13888
+ this.originalSelectFillColor = void 0;
13889
+ this.originalSelectOutlineColor = void 0;
13890
+ this.hoverLabel = void 0;
13891
+ if (this.layerCollection) {
13892
+ this.viewer.scene.primitives.remove(this.layerCollection);
13893
+ this.layerCollection = void 0;
13894
+ }
13895
+ this.primitive = void 0;
13896
+ this.outlinePrimitive = void 0;
13897
+ this.labelCollection = void 0;
13898
+ this.polygonDataMap.clear();
13899
+ this.viewer.scene.requestRender();
13900
+ }
13901
+ /**
13902
+ * 销毁并释放资源
13903
+ */
13904
+ destroy() {
13905
+ this.clear();
13906
+ }
13907
+ /**
13908
+ * 将 PolygonPoint 数组转换为 Cartesian3 数组
13909
+ */
13910
+ convertPointsToCartesian(points) {
13911
+ const C = this.CesiumNS;
13912
+ return points.map((p) => C.Cartesian3.fromDegrees(p.lon, p.lat, p.height ?? 0));
13913
+ }
13914
+ /**
13915
+ * 隐藏指定多边形(编辑时使用)
13916
+ * 通过设置 show 属性为 false 实现视觉隐藏,保留数据
13917
+ * @param id 多边形 ID
13918
+ * @returns 是否成功隐藏
13919
+ */
13920
+ hidePolygon(id) {
13921
+ if (!this.polygonDataMap.has(id)) {
13922
+ console.warn(`[MassPolygonManager] hidePolygon: \u591A\u8FB9\u5F62 ${id} \u4E0D\u5B58\u5728`);
13923
+ return false;
13924
+ }
13925
+ const C = this.CesiumNS;
13926
+ if (!this.primitive) return false;
13927
+ if (!this.primitive.ready) {
13928
+ console.warn(`[MassPolygonManager] hidePolygon: Primitive \u5C1A\u672A\u51C6\u5907\u597D\uFF0C\u65E0\u6CD5\u9690\u85CF\u591A\u8FB9\u5F62 ${id}`);
13929
+ return false;
13930
+ }
13931
+ try {
13932
+ const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(id);
13933
+ if (!fillAttributes) {
13934
+ console.warn(`[MassPolygonManager] hidePolygon: \u65E0\u6CD5\u83B7\u53D6\u591A\u8FB9\u5F62 ${id} \u7684\u586B\u5145\u5C5E\u6027`);
13935
+ return false;
13936
+ }
13937
+ const originalFill = fillAttributes.color ? new Uint8Array(fillAttributes.color) : new Uint8Array([255, 255, 255, 255]);
13938
+ let originalOutline = new Uint8Array([255, 255, 255, 255]);
13939
+ if (this.outlinePrimitive && this.outlinePrimitive.ready) {
13940
+ const outlineAttributes = this.outlinePrimitive.getGeometryInstanceAttributes?.(`${id}-outline`);
13941
+ if (outlineAttributes?.color) {
13942
+ originalOutline = new Uint8Array(outlineAttributes.color);
13943
+ }
13944
+ if (outlineAttributes?.show !== void 0) {
13945
+ outlineAttributes.show = C.ShowGeometryInstanceAttribute.toValue(false);
13946
+ }
13947
+ }
13948
+ this.hiddenPolygonColors.set(id, {
13949
+ fill: originalFill,
13950
+ outline: originalOutline
13951
+ });
13952
+ if (fillAttributes.show !== void 0) {
13953
+ fillAttributes.show = C.ShowGeometryInstanceAttribute.toValue(false);
13954
+ this.viewer.scene.requestRender();
13955
+ console.log(`[MassPolygonManager] \u5DF2\u9690\u85CF\u591A\u8FB9\u5F62: ${id}`);
13956
+ return true;
13957
+ }
13958
+ console.warn(`[MassPolygonManager] hidePolygon: \u591A\u8FB9\u5F62 ${id} \u4E0D\u652F\u6301 show \u5C5E\u6027`);
13959
+ return false;
13960
+ } catch (e) {
13961
+ console.error(`[MassPolygonManager] hidePolygon \u5931\u8D25:`, e);
13962
+ return false;
13963
+ }
13964
+ }
13965
+ /**
13966
+ * 异步隐藏指定多边形(等待 Primitive 就绪后再隐藏)
13967
+ * @param id 多边形 ID
13968
+ * @param timeout 超时时间(毫秒),默认 5000ms
13969
+ * @returns Promise<boolean> 是否成功隐藏
13970
+ */
13971
+ async hidePolygonAsync(id, timeout = 5e3) {
13972
+ if (!this.polygonDataMap.has(id)) {
13973
+ console.warn(`[MassPolygonManager] hidePolygonAsync: \u591A\u8FB9\u5F62 ${id} \u4E0D\u5B58\u5728`);
13974
+ return false;
13975
+ }
13976
+ if (!this.primitive) return false;
13977
+ if (this.primitive.ready) {
13978
+ return this.hidePolygon(id);
13979
+ }
13980
+ console.log(`[MassPolygonManager] hidePolygonAsync: \u7B49\u5F85 Primitive \u51C6\u5907\u597D...`);
13981
+ const startTime = Date.now();
13982
+ return new Promise((resolve) => {
13983
+ const checkReady = () => {
13984
+ if (this.primitive?.ready) {
13985
+ console.log(`[MassPolygonManager] hidePolygonAsync: Primitive \u5DF2\u51C6\u5907\u597D`);
13986
+ resolve(this.hidePolygon(id));
13987
+ } else if (Date.now() - startTime > timeout) {
13988
+ console.error(`[MassPolygonManager] hidePolygonAsync: \u7B49\u5F85 Primitive \u8D85\u65F6`);
13989
+ resolve(false);
13990
+ } else {
13991
+ requestAnimationFrame(checkReady);
13992
+ }
13993
+ };
13994
+ checkReady();
13995
+ });
13996
+ }
13997
+ /**
13998
+ * 显示指定多边形(取消编辑或编辑失败时恢复)
13999
+ * 恢复 show 状态为 true
14000
+ * @param id 多边形 ID
14001
+ * @returns 是否成功显示
14002
+ */
14003
+ showPolygon(id) {
14004
+ const savedColors = this.hiddenPolygonColors.get(id);
14005
+ if (!savedColors) {
14006
+ console.warn(`[MassPolygonManager] showPolygon: \u591A\u8FB9\u5F62 ${id} \u672A\u88AB\u9690\u85CF\u6216\u72B6\u6001\u672A\u4FDD\u5B58`);
14007
+ return false;
14008
+ }
14009
+ const C = this.CesiumNS;
14010
+ if (!this.primitive) return false;
14011
+ try {
14012
+ const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(id);
14013
+ if (!fillAttributes) {
14014
+ console.warn(`[MassPolygonManager] showPolygon: \u65E0\u6CD5\u83B7\u53D6\u591A\u8FB9\u5F62 ${id} \u7684\u5C5E\u6027`);
14015
+ return false;
14016
+ }
14017
+ if (fillAttributes.show !== void 0) {
14018
+ fillAttributes.show = C.ShowGeometryInstanceAttribute.toValue(true);
14019
+ }
14020
+ if (this.outlinePrimitive && this.outlinePrimitive.ready) {
14021
+ const outlineAttributes = this.outlinePrimitive.getGeometryInstanceAttributes?.(`${id}-outline`);
14022
+ if (outlineAttributes?.show !== void 0) {
14023
+ outlineAttributes.show = C.ShowGeometryInstanceAttribute.toValue(true);
14024
+ }
14025
+ }
14026
+ this.hiddenPolygonColors.delete(id);
14027
+ this.viewer.scene.requestRender();
14028
+ console.log(`[MassPolygonManager] \u5DF2\u663E\u793A\u591A\u8FB9\u5F62: ${id}`);
14029
+ return true;
14030
+ } catch (e) {
14031
+ console.error(`[MassPolygonManager] showPolygon \u5931\u8D25:`, e);
14032
+ return false;
14033
+ }
14034
+ }
14035
+ /**
14036
+ * 检查多边形是否被隐藏
14037
+ * @param id 多边形 ID
14038
+ * @returns 是否被隐藏
14039
+ */
14040
+ isPolygonHidden(id) {
14041
+ return this.hiddenPolygonColors.has(id);
14042
+ }
14043
+ /**
14044
+ * 更新单个多边形的坐标
14045
+ * 内部实现:更新 polygonDataMap,然后重建整个 Primitive
14046
+ * (Primitive 不支持单个 instance 的几何修改,只能重建)
14047
+ * @param id 多边形 ID
14048
+ * @param newPoints 新的坐标点数组
14049
+ * @returns 是否更新成功
14050
+ */
14051
+ updatePolygon(id, newPoints) {
14052
+ const existingData = this.polygonDataMap.get(id);
14053
+ if (!existingData) {
14054
+ console.warn(`[MassPolygonManager] updatePolygon: \u591A\u8FB9\u5F62 ${id} \u4E0D\u5B58\u5728`);
14055
+ return false;
14056
+ }
14057
+ if (newPoints.length < 3) {
14058
+ console.warn(`[MassPolygonManager] updatePolygon: \u65B0\u5750\u6807\u70B9\u6570\u91CF\u4E0D\u8DB3 (${newPoints.length})`);
14059
+ return false;
14060
+ }
14061
+ existingData.points = newPoints;
14062
+ this.polygonDataMap.set(id, existingData);
14063
+ this.hiddenPolygonColors.delete(id);
14064
+ this.rebuild();
14065
+ console.log(`[MassPolygonManager] \u5DF2\u66F4\u65B0\u591A\u8FB9\u5F62: ${id}, \u65B0\u5750\u6807\u70B9\u6570\u91CF: ${newPoints.length}`);
14066
+ return true;
14067
+ }
14068
+ /**
14069
+ * 更新多边形数据(坐标和/或名称)
14070
+ * @param id 多边形 ID
14071
+ * @param data 要更新的数据
14072
+ * @returns 是否更新成功
14073
+ */
14074
+ updatePolygonData(id, data) {
14075
+ const existingData = this.polygonDataMap.get(id);
14076
+ if (!existingData) {
14077
+ console.warn(`[MassPolygonManager] updatePolygonData: \u591A\u8FB9\u5F62 ${id} \u4E0D\u5B58\u5728`);
14078
+ return false;
14079
+ }
14080
+ if (data.points !== void 0) {
14081
+ if (data.points.length < 3) {
14082
+ console.warn(`[MassPolygonManager] updatePolygonData: \u65B0\u5750\u6807\u70B9\u6570\u91CF\u4E0D\u8DB3`);
14083
+ return false;
14084
+ }
14085
+ existingData.points = data.points;
14086
+ }
14087
+ if (data.name !== void 0) {
14088
+ existingData.name = data.name;
14089
+ }
14090
+ this.polygonDataMap.set(id, existingData);
14091
+ if (data.points !== void 0) {
14092
+ this.hiddenPolygonColors.delete(id);
14093
+ this.rebuild();
14094
+ }
14095
+ return true;
14096
+ }
14097
+ /**
14098
+ * 重建所有 Primitive(保留当前数据和配置)
14099
+ * 用于坐标更新后刷新渲染
14100
+ */
14101
+ rebuild() {
14102
+ const polygons = Array.from(this.polygonDataMap.values());
14103
+ if (polygons.length === 0) {
14104
+ this.clear();
14105
+ return;
14106
+ }
14107
+ const wasSelectedId = this.selectedId;
14108
+ this.create(polygons, this.currentOptions);
14109
+ if (wasSelectedId && this.polygonDataMap.has(wasSelectedId)) {
14110
+ this.select(wasSelectedId);
14111
+ }
14112
+ console.log(`[MassPolygonManager] \u5DF2\u91CD\u5EFA ${polygons.length} \u4E2A\u591A\u8FB9\u5F62`);
14113
+ }
14114
+ /**
14115
+ * 删除指定多边形
14116
+ * @param id 多边形 ID
14117
+ * @returns 是否删除成功
14118
+ */
14119
+ removePolygon(id) {
14120
+ if (!this.polygonDataMap.has(id)) {
14121
+ console.warn(`[MassPolygonManager] removePolygon: \u591A\u8FB9\u5F62 ${id} \u4E0D\u5B58\u5728`);
14122
+ return false;
14123
+ }
14124
+ if (this.selectedId === id) {
14125
+ this.deselect();
14126
+ }
14127
+ this.hiddenPolygonColors.delete(id);
14128
+ this.polygonDataMap.delete(id);
14129
+ this.rebuild();
14130
+ console.log(`[MassPolygonManager] \u5DF2\u5220\u9664\u591A\u8FB9\u5F62: ${id}`);
14131
+ return true;
14132
+ }
14133
+ /**
14134
+ * 添加新多边形
14135
+ * @param polygon 多边形数据
14136
+ * @returns 是否添加成功
14137
+ */
14138
+ addPolygon(polygon) {
14139
+ if (this.polygonDataMap.has(polygon.id)) {
14140
+ console.warn(`[MassPolygonManager] addPolygon: \u591A\u8FB9\u5F62 ${polygon.id} \u5DF2\u5B58\u5728`);
14141
+ return false;
14142
+ }
14143
+ if (polygon.points.length < 3) {
14144
+ console.warn(`[MassPolygonManager] addPolygon: \u5750\u6807\u70B9\u6570\u91CF\u4E0D\u8DB3`);
14145
+ return false;
14146
+ }
14147
+ this.polygonDataMap.set(polygon.id, polygon);
14148
+ this.rebuild();
14149
+ console.log(`[MassPolygonManager] \u5DF2\u6DFB\u52A0\u591A\u8FB9\u5F62: ${polygon.id}`);
14150
+ return true;
14151
+ }
14152
+ };
14153
+
14154
+ // src/utils/LODManager.ts
14155
+ var LODManager = class {
14156
+ constructor(CesiumNS, viewer, config) {
14157
+ __publicField(this, "viewer");
14158
+ __publicField(this, "config");
14159
+ __publicField(this, "targets", /* @__PURE__ */ new Set());
14160
+ __publicField(this, "removeListener");
14161
+ __publicField(this, "lastCheckTime", 0);
14162
+ __publicField(this, "isRunning", false);
14163
+ __publicField(this, "currentVisibility", true);
14164
+ __publicField(this, "onPreRender", () => {
14165
+ if (this.isRunning) {
14166
+ this.checkVisibility();
14167
+ }
14168
+ });
14169
+ this.viewer = viewer;
14170
+ this.config = {
14171
+ minHeight: config?.minHeight ?? 0,
14172
+ maxHeight: config?.maxHeight ?? Infinity,
14173
+ checkInterval: config?.checkInterval ?? 200
14174
+ };
14175
+ }
14176
+ /**
14177
+ * 添加 LOD 控制目标
14178
+ * @param target 具有 show 属性的对象
14179
+ */
14180
+ addTarget(target) {
14181
+ this.targets.add(target);
14182
+ target.show = this.currentVisibility;
14183
+ }
14184
+ /**
14185
+ * 移除 LOD 控制目标
14186
+ * @param target 要移除的目标
14187
+ */
14188
+ removeTarget(target) {
14189
+ this.targets.delete(target);
14190
+ }
14191
+ /**
14192
+ * 清除所有目标
14193
+ */
14194
+ clearTargets() {
14195
+ this.targets.clear();
14196
+ }
14197
+ /**
14198
+ * 获取当前相机高度
14199
+ */
14200
+ getCameraHeight() {
14201
+ const cartographic = this.viewer.camera.positionCartographic;
14202
+ return cartographic?.height ?? 0;
14203
+ }
14204
+ /**
14205
+ * 检查并更新可见性
14206
+ */
14207
+ checkVisibility() {
14208
+ const now = Date.now();
14209
+ if (now - this.lastCheckTime < this.config.checkInterval) {
14210
+ return;
14211
+ }
14212
+ this.lastCheckTime = now;
14213
+ const height = this.getCameraHeight();
14214
+ const shouldShow = height >= this.config.minHeight && height <= this.config.maxHeight;
14215
+ if (shouldShow !== this.currentVisibility) {
14216
+ this.currentVisibility = shouldShow;
14217
+ this.updateTargetsVisibility(shouldShow);
14218
+ }
14219
+ }
14220
+ /**
14221
+ * 更新所有目标的可见性
14222
+ */
14223
+ updateTargetsVisibility(visible) {
14224
+ for (const target of this.targets) {
14225
+ target.show = visible;
14226
+ }
14227
+ this.viewer.scene.requestRender();
14228
+ }
14229
+ /**
14230
+ * 启动 LOD 管理
14231
+ */
14232
+ start() {
14233
+ if (this.isRunning) return;
14234
+ this.isRunning = true;
14235
+ this.lastCheckTime = 0;
14236
+ this.checkVisibility();
14237
+ this.removeListener = this.viewer.camera.changed.addEventListener(() => {
14238
+ this.checkVisibility();
14239
+ });
14240
+ this.viewer.scene.preRender.addEventListener(this.onPreRender);
14241
+ }
14242
+ /**
14243
+ * 停止 LOD 管理
14244
+ */
14245
+ stop() {
14246
+ if (!this.isRunning) return;
14247
+ this.isRunning = false;
14248
+ if (this.removeListener) {
14249
+ this.removeListener();
14250
+ this.removeListener = void 0;
14251
+ }
14252
+ this.viewer.scene.preRender.removeEventListener(this.onPreRender);
14253
+ }
14254
+ /**
14255
+ * 更新配置
14256
+ */
14257
+ updateConfig(config) {
14258
+ if (config.minHeight !== void 0) this.config.minHeight = config.minHeight;
14259
+ if (config.maxHeight !== void 0) this.config.maxHeight = config.maxHeight;
14260
+ if (config.checkInterval !== void 0) this.config.checkInterval = config.checkInterval;
14261
+ this.lastCheckTime = 0;
14262
+ this.checkVisibility();
14263
+ }
14264
+ /**
14265
+ * 强制设置可见性(忽略 LOD 规则)
14266
+ */
14267
+ forceVisibility(visible) {
14268
+ this.currentVisibility = visible;
14269
+ this.updateTargetsVisibility(visible);
14270
+ }
14271
+ /**
14272
+ * 获取当前可见性状态
14273
+ */
14274
+ isVisible() {
14275
+ return this.currentVisibility;
14276
+ }
14277
+ /**
14278
+ * 销毁管理器
14279
+ */
14280
+ destroy() {
14281
+ this.stop();
14282
+ this.clearTargets();
14283
+ }
14284
+ };
14285
+
13264
14286
  // src/index.ts
13265
14287
  var placeholder = { ready: true };
13266
14288
  var droneModelUrl = wurenji_default;
@@ -13273,7 +14295,9 @@ exports.CameraManager = CameraManager;
13273
14295
  exports.Emitter = Emitter;
13274
14296
  exports.FlightSimulator = FlightSimulator;
13275
14297
  exports.FrustumPyramid = FrustumPyramid;
14298
+ exports.LODManager = LODManager;
13276
14299
  exports.LayerManager = LayerManager;
14300
+ exports.MassPolygonManager = MassPolygonManager;
13277
14301
  exports.PathSafetyChecker = PathSafetyChecker;
13278
14302
  exports.PointCloudPicker = PointCloudPicker;
13279
14303
  exports.PolygonEditor = PolygonEditor;
@@ -13282,6 +14306,8 @@ exports.SceneManager = SceneManager;
13282
14306
  exports.Selector = Selector;
13283
14307
  exports.StateManager = StateManager;
13284
14308
  exports.assertCesiumAssetsConfigured = assertCesiumAssetsConfigured;
14309
+ exports.bringDataSourceToTop = bringDataSourceToTop;
14310
+ exports.bringPrimitiveCollectionToTop = bringPrimitiveCollectionToTop;
13285
14311
  exports.calculateAbsoluteHeight = calculateAbsoluteHeight;
13286
14312
  exports.calculateBoundsDiagonal = calculateBoundsDiagonal;
13287
14313
  exports.calculateDistance = calculateDistance;
@@ -13297,9 +14323,12 @@ exports.convertSinoflyWayline = convertSinoflyWayline;
13297
14323
  exports.convertSinoflyWaylines = convertSinoflyWaylines;
13298
14324
  exports.droneModelUrl = droneModelUrl;
13299
14325
  exports.ensureCesiumIonToken = ensureCesiumIonToken;
14326
+ exports.ensureLayerAbove = ensureLayerAbove;
13300
14327
  exports.expandBounds = expandBounds;
13301
14328
  exports.getCesiumBaseUrl = getCesiumBaseUrl;
13302
14329
  exports.getCesiumIonToken = getCesiumIonToken;
14330
+ exports.getDataSourceIndex = getDataSourceIndex;
14331
+ exports.getDataSourceOrder = getDataSourceOrder;
13303
14332
  exports.globalCameraEventBus = globalCameraEventBus;
13304
14333
  exports.globalState = globalState;
13305
14334
  exports.isPointInBounds = isPointInBounds;