@jorgmoritz/gis-manager 0.1.53 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.53"};
16
+ version: "0.1.54"};
17
17
 
18
18
  // src/utils/version.ts
19
19
  var version = package_default.version;
@@ -2702,6 +2702,8 @@ var StateManager = class {
2702
2702
  __publicField(this, "editing", false);
2703
2703
  __publicField(this, "editingTarget");
2704
2704
  __publicField(this, "previousView");
2705
+ // MassPolygonManager 注册表(用于编辑模式隔离)
2706
+ __publicField(this, "massPolygonManagers", /* @__PURE__ */ new Set());
2705
2707
  // Emitters
2706
2708
  __publicField(this, "onSelectionChange", new Emitter());
2707
2709
  __publicField(this, "onEditingChange", new Emitter());
@@ -2752,6 +2754,26 @@ var StateManager = class {
2752
2754
  getPreviousCameraView() {
2753
2755
  return this.previousView;
2754
2756
  }
2757
+ // MassPolygonManager 注册管理
2758
+ /**
2759
+ * 注册 MassPolygonManager 实例
2760
+ * 用于编辑模式下统一管理所有图层的交互状态
2761
+ */
2762
+ registerMassPolygonManager(manager) {
2763
+ this.massPolygonManagers.add(manager);
2764
+ }
2765
+ /**
2766
+ * 注销 MassPolygonManager 实例
2767
+ */
2768
+ unregisterMassPolygonManager(manager) {
2769
+ this.massPolygonManagers.delete(manager);
2770
+ }
2771
+ /**
2772
+ * 获取所有已注册的 MassPolygonManager 实例
2773
+ */
2774
+ getAllMassPolygonManagers() {
2775
+ return Array.from(this.massPolygonManagers);
2776
+ }
2755
2777
  };
2756
2778
  var globalState = new StateManager();
2757
2779
 
@@ -4311,14 +4333,16 @@ var TriangleShape = class {
4311
4333
  * @param positionCallback - Callback function that returns current position
4312
4334
  * @param headingCallback - Callback function that returns current heading in degrees
4313
4335
  * @param properties - Additional properties for entities
4336
+ * @param scaleCallback - Optional callback function that returns current scale factor (default 1)
4314
4337
  * @returns Array of created entities [bottom faces, side faces]
4315
4338
  */
4316
- createEntities(layer, positionCallback, headingCallback, properties) {
4339
+ createEntities(layer, positionCallback, headingCallback, properties, scaleCallback) {
4317
4340
  const C = this.CesiumNS;
4318
4341
  const entities = [];
4319
4342
  const computeVertices = () => {
4320
4343
  const position = positionCallback();
4321
4344
  const heading = headingCallback();
4345
+ const scale = scaleCallback?.() ?? 1;
4322
4346
  const enu = C.Transforms.eastNorthUpToFixedFrame(position);
4323
4347
  const east4 = C.Matrix4.getColumn(enu, 0, new C.Cartesian4());
4324
4348
  const north4 = C.Matrix4.getColumn(enu, 1, new C.Cartesian4());
@@ -4330,9 +4354,12 @@ var TriangleShape = class {
4330
4354
  const sin = Math.sin(theta);
4331
4355
  const cos = Math.cos(theta);
4332
4356
  const toWorld = (x, y, z) => {
4333
- const ex = C.Cartesian3.multiplyByScalar(east, x * cos + y * sin, new C.Cartesian3());
4334
- const ny = C.Cartesian3.multiplyByScalar(north, -x * sin + y * cos, new C.Cartesian3());
4335
- const uz = C.Cartesian3.multiplyByScalar(up, z, new C.Cartesian3());
4357
+ const sx = x * scale;
4358
+ const sy = y * scale;
4359
+ const sz = z * scale;
4360
+ const ex = C.Cartesian3.multiplyByScalar(east, sx * cos + sy * sin, new C.Cartesian3());
4361
+ const ny = C.Cartesian3.multiplyByScalar(north, -sx * sin + sy * cos, new C.Cartesian3());
4362
+ const uz = C.Cartesian3.multiplyByScalar(up, sz, new C.Cartesian3());
4336
4363
  const offset = C.Cartesian3.add(ex, ny, new C.Cartesian3());
4337
4364
  C.Cartesian3.add(offset, uz, offset);
4338
4365
  return C.Cartesian3.add(position, offset, new C.Cartesian3());
@@ -4613,6 +4640,28 @@ var AirplaneCursor = class {
4613
4640
  * 创建三角形标记游标
4614
4641
  */
4615
4642
  createTriangleCursor(_color) {
4643
+ const C = this.CesiumNS;
4644
+ const baseScale = 1;
4645
+ const minScale = 0.1;
4646
+ const maxScale = 3;
4647
+ const referenceDistance = 800;
4648
+ const computeScaleFactor = () => {
4649
+ try {
4650
+ const cameraPos = this.viewer.camera.positionWC;
4651
+ const modelPos = this.pose.position;
4652
+ const distance = C.Cartesian3.distance(cameraPos, modelPos);
4653
+ const rawScale = baseScale * (distance / referenceDistance);
4654
+ const clampedScale = Math.max(minScale, Math.min(maxScale, rawScale));
4655
+ return clampedScale / baseScale;
4656
+ } catch {
4657
+ return 1;
4658
+ }
4659
+ };
4660
+ this.cachedScaleFactor = computeScaleFactor();
4661
+ this.cameraChangedListener = this.viewer.camera.changed.addEventListener(() => {
4662
+ this.cachedScaleFactor = computeScaleFactor();
4663
+ this.viewer.scene?.requestRender?.();
4664
+ });
4616
4665
  this.triangleShape = new TriangleShape(this.CesiumNS, {
4617
4666
  baseSize: 15,
4618
4667
  pyramidHeight: 25,
@@ -4622,7 +4671,9 @@ var AirplaneCursor = class {
4622
4671
  this.pyramidLayer,
4623
4672
  () => this.pose.position,
4624
4673
  () => this.pose.heading,
4625
- { _type: "airplane-cursor" }
4674
+ { _type: "airplane-cursor" },
4675
+ () => this.cachedScaleFactor
4676
+ // 传入缩放因子回调
4626
4677
  );
4627
4678
  triangleEntities.forEach((entity) => {
4628
4679
  entity.show = this.visible;
@@ -5423,7 +5474,7 @@ function calculatePathDistance(CesiumNS, positions, targetIndex, hiddenClimbInde
5423
5474
  const C = CesiumNS;
5424
5475
  let totalDistance = 0;
5425
5476
  const startIndex = 1;
5426
- if (targetIndex <= startIndex) return 0;
5477
+ if (targetIndex < startIndex) return 0;
5427
5478
  for (let i = startIndex; i <= targetIndex; i++) {
5428
5479
  try {
5429
5480
  const prevPos = positions[i - 1];
@@ -9989,7 +10040,7 @@ var PolygonEditor = class {
9989
10040
  this.editHandles = positions.map(
9990
10041
  (p, i) => layer.entities.add({
9991
10042
  position: p,
9992
- point: { pixelSize: 7, color: point_color, outlineColor: C.Color.BLACK, outlineWidth: 1 },
10043
+ point: { pixelSize: 12, color: point_color, outlineColor: C.Color.BLACK, outlineWidth: 2 },
9993
10044
  properties: { _vertexIndex: i }
9994
10045
  })
9995
10046
  );
@@ -10071,29 +10122,120 @@ var PolygonEditor = class {
10071
10122
  return void 0;
10072
10123
  }
10073
10124
  };
10074
- const highlightHandle = (index) => {
10125
+ let hoveredIndex = void 0;
10126
+ const getHighlightColors = () => {
10127
+ if (layer.name === "inverter") {
10128
+ return {
10129
+ hoverColor: C.Color.fromCssColorString("rgba(150, 255, 150, 1)"),
10130
+ // 浅绿色
10131
+ hoverOutline: C.Color.fromCssColorString("rgba(0, 150, 0, 1)"),
10132
+ // 深绿色
10133
+ selectColor: C.Color.fromCssColorString("rgba(100, 255, 100, 1)"),
10134
+ // 亮绿色
10135
+ selectOutline: C.Color.fromCssColorString("rgba(0, 100, 0, 1)")
10136
+ // 深绿色
10137
+ };
10138
+ } else {
10139
+ return {
10140
+ hoverColor: C.Color.fromCssColorString("rgba(255, 150, 150, 1)"),
10141
+ // 浅红色
10142
+ hoverOutline: C.Color.fromCssColorString("rgba(200, 0, 0, 1)"),
10143
+ // 深红色
10144
+ selectColor: C.Color.fromCssColorString("rgba(255, 100, 100, 1)"),
10145
+ // 亮红色
10146
+ selectOutline: C.Color.fromCssColorString("rgba(150, 0, 0, 1)")
10147
+ // 深红色
10148
+ };
10149
+ }
10150
+ };
10151
+ const highlightColors = getHighlightColors();
10152
+ const hoverHandle = (index) => {
10075
10153
  const handle = this.editHandles[index];
10076
10154
  if (handle && handle.point) {
10077
- handle.point.pixelSize = 10;
10078
- handle.point.color = C.Color.YELLOW;
10079
- handle.point.outlineColor = C.Color.RED;
10155
+ handle.point.pixelSize = 18;
10156
+ handle.point.color = highlightColors.hoverColor;
10157
+ handle.point.outlineColor = highlightColors.hoverOutline;
10158
+ handle.point.outlineWidth = 3;
10159
+ }
10160
+ };
10161
+ const unhoverHandle = (index) => {
10162
+ const handle = this.editHandles[index];
10163
+ if (handle && handle.point) {
10164
+ handle.point.pixelSize = 12;
10165
+ handle.point.color = point_color;
10166
+ handle.point.outlineColor = C.Color.BLACK;
10080
10167
  handle.point.outlineWidth = 2;
10081
10168
  }
10082
10169
  };
10170
+ const highlightHandle = (index) => {
10171
+ const handle = this.editHandles[index];
10172
+ if (handle && handle.point) {
10173
+ handle.point.pixelSize = 16;
10174
+ handle.point.color = highlightColors.selectColor;
10175
+ handle.point.outlineColor = highlightColors.selectOutline;
10176
+ handle.point.outlineWidth = 3;
10177
+ }
10178
+ };
10083
10179
  const unhighlightHandle = (index) => {
10084
10180
  const handle = this.editHandles[index];
10085
10181
  if (handle && handle.point) {
10086
- handle.point.pixelSize = 7;
10182
+ handle.point.pixelSize = 12;
10087
10183
  handle.point.color = point_color;
10088
10184
  handle.point.outlineColor = C.Color.BLACK;
10089
- handle.point.outlineWidth = 1;
10185
+ handle.point.outlineWidth = 2;
10186
+ }
10187
+ };
10188
+ const VERTEX_PICK_RADIUS = 30;
10189
+ const findNearestVertexByScreenDistance = (screenPos) => {
10190
+ if (!screenPos || typeof screenPos.x !== "number" || typeof screenPos.y !== "number") {
10191
+ return void 0;
10192
+ }
10193
+ const scene = this.viewer.scene;
10194
+ const ST = this.CesiumNS.SceneTransforms;
10195
+ let nearestIdx;
10196
+ let nearestDist = VERTEX_PICK_RADIUS;
10197
+ for (let i = 0; i < positions.length; i++) {
10198
+ const worldPos = positions[i];
10199
+ if (!worldPos) continue;
10200
+ let screenCoord;
10201
+ try {
10202
+ screenCoord = ST.wgs84ToWindowCoordinates?.(scene, worldPos);
10203
+ } catch {
10204
+ }
10205
+ if (!screenCoord) {
10206
+ try {
10207
+ screenCoord = ST.worldToWindowCoordinates?.(scene, worldPos);
10208
+ } catch {
10209
+ }
10210
+ }
10211
+ if (!screenCoord && scene.cartesianToCanvasCoordinates) {
10212
+ try {
10213
+ const canvasCoord = scene.cartesianToCanvasCoordinates(worldPos);
10214
+ if (canvasCoord) {
10215
+ screenCoord = { x: canvasCoord.x, y: canvasCoord.y };
10216
+ }
10217
+ } catch {
10218
+ }
10219
+ }
10220
+ if (!screenCoord) continue;
10221
+ const dx = screenPos.x - screenCoord.x;
10222
+ const dy = screenPos.y - screenCoord.y;
10223
+ const dist = Math.sqrt(dx * dx + dy * dy);
10224
+ if (dist < nearestDist) {
10225
+ nearestDist = dist;
10226
+ nearestIdx = i;
10227
+ }
10090
10228
  }
10229
+ return nearestIdx;
10091
10230
  };
10092
10231
  this.handler && this.handler.setInputAction(
10093
10232
  (movement) => {
10233
+ const screenPos = movement.position;
10234
+ const nearestVertexIdx = findNearestVertexByScreenDistance(screenPos);
10094
10235
  const picked = this.viewer.scene.pick?.(movement.position);
10095
10236
  const entity = picked?.id;
10096
- const idx = entity?.properties?._vertexIndex?.getValue?.() ?? entity?.properties?._vertexIndex;
10237
+ const pickedIdx = entity?.properties?._vertexIndex?.getValue?.() ?? entity?.properties?._vertexIndex;
10238
+ const idx = nearestVertexIdx ?? (typeof pickedIdx === "number" ? pickedIdx : void 0);
10097
10239
  if (this.draggingIndex === void 0) {
10098
10240
  if (typeof idx === "number") {
10099
10241
  this.draggingIndex = idx;
@@ -10127,7 +10269,7 @@ var PolygonEditor = class {
10127
10269
  positions.splice(insertIndex, 0, insertPoint);
10128
10270
  const newHandle = layer.entities.add({
10129
10271
  position: insertPoint,
10130
- point: { pixelSize: 7, color: point_color, outlineColor: C.Color.BLACK, outlineWidth: 1 },
10272
+ point: { pixelSize: 12, color: point_color, outlineColor: C.Color.BLACK, outlineWidth: 2 },
10131
10273
  properties: { _vertexIndex: insertIndex }
10132
10274
  });
10133
10275
  this.editHandles.splice(insertIndex, 0, newHandle);
@@ -10186,10 +10328,46 @@ var PolygonEditor = class {
10186
10328
  }
10187
10329
  this.insertPreviewHandle = void 0;
10188
10330
  }
10331
+ if (hoveredIndex !== void 0) {
10332
+ unhoverHandle(hoveredIndex);
10333
+ hoveredIndex = void 0;
10334
+ }
10189
10335
  return;
10190
10336
  }
10337
+ const winPos = movement?.endPosition ?? movement?.position ?? movement;
10338
+ if (winPos) {
10339
+ const nearestVertexIdx = findNearestVertexByScreenDistance(winPos);
10340
+ if (nearestVertexIdx !== void 0) {
10341
+ if (hoveredIndex !== nearestVertexIdx) {
10342
+ if (hoveredIndex !== void 0) {
10343
+ unhoverHandle(hoveredIndex);
10344
+ }
10345
+ hoveredIndex = nearestVertexIdx;
10346
+ hoverHandle(hoveredIndex);
10347
+ }
10348
+ if (this.segmentHighlight) {
10349
+ try {
10350
+ layer.entities.remove(this.segmentHighlight);
10351
+ } catch {
10352
+ }
10353
+ this.segmentHighlight = void 0;
10354
+ }
10355
+ if (this.insertPreviewHandle) {
10356
+ try {
10357
+ layer.entities.remove(this.insertPreviewHandle);
10358
+ } catch {
10359
+ }
10360
+ this.insertPreviewHandle = void 0;
10361
+ }
10362
+ return;
10363
+ } else {
10364
+ if (hoveredIndex !== void 0) {
10365
+ unhoverHandle(hoveredIndex);
10366
+ hoveredIndex = void 0;
10367
+ }
10368
+ }
10369
+ }
10191
10370
  try {
10192
- const winPos = movement?.endPosition ?? movement?.position ?? movement;
10193
10371
  if (!winPos) return;
10194
10372
  const ST = this.CesiumNS.SceneTransforms;
10195
10373
  const threshold = 8;
@@ -12195,6 +12373,8 @@ var CZMLManager = class {
12195
12373
  __publicField(this, "currentSelectedEntity", null);
12196
12374
  __publicField(this, "activePolygonSession", null);
12197
12375
  __publicField(this, "polygonSessionCleanup");
12376
+ // 编辑模式标志
12377
+ __publicField(this, "editingMode", false);
12198
12378
  __publicField(this, "_polygonEditor");
12199
12379
  // Path manager composition
12200
12380
  __publicField(this, "_pathMgr");
@@ -12484,10 +12664,17 @@ var CZMLManager = class {
12484
12664
  bringDataSourceToTop(this.viewer, "other");
12485
12665
  }
12486
12666
  const session = this.polygonEditor.startDrawing(type, layer, (entity) => {
12667
+ this.exitEditingMode();
12487
12668
  this.cancelActivePolygonDrawing();
12488
12669
  onComplete?.(entity);
12489
12670
  });
12490
12671
  if (session && typeof session.stop === "function") {
12672
+ this.enterEditingMode();
12673
+ const originalStop = session.stop;
12674
+ session.stop = () => {
12675
+ this.exitEditingMode();
12676
+ originalStop();
12677
+ };
12491
12678
  this.activePolygonSession = session;
12492
12679
  } else {
12493
12680
  this.activePolygonSession = null;
@@ -12589,6 +12776,39 @@ var CZMLManager = class {
12589
12776
  bringDataSourceToTop(this.viewer, "other");
12590
12777
  return this.polygonEditor.startPointDrawing?.(layer, iconSvg, onComplete);
12591
12778
  }
12779
+ /**
12780
+ * 进入编辑模式:禁用所有 MassPolygonManager 的交互
12781
+ * 防止编辑多边形时其他图层响应鼠标事件
12782
+ */
12783
+ enterEditingMode() {
12784
+ if (this.editingMode) return;
12785
+ this.editingMode = true;
12786
+ const managers = globalState.getAllMassPolygonManagers?.();
12787
+ if (managers) {
12788
+ for (const manager of managers) {
12789
+ manager.disableInteraction();
12790
+ }
12791
+ }
12792
+ }
12793
+ /**
12794
+ * 退出编辑模式:恢复所有 MassPolygonManager 的交互
12795
+ */
12796
+ exitEditingMode() {
12797
+ if (!this.editingMode) return;
12798
+ this.editingMode = false;
12799
+ const managers = globalState.getAllMassPolygonManagers?.();
12800
+ if (managers) {
12801
+ for (const manager of managers) {
12802
+ manager.enableInteraction();
12803
+ }
12804
+ }
12805
+ }
12806
+ /**
12807
+ * 检查是否处于编辑模式
12808
+ */
12809
+ isInEditingMode() {
12810
+ return this.editingMode;
12811
+ }
12592
12812
  // New: start editing an existing polygon entity's vertices
12593
12813
  // Accepts: an Entity, or an id string, or undefined to use the last selected entity from state
12594
12814
  startPolygonEditing(entityOrId, onComplete) {
@@ -12630,7 +12850,20 @@ var CZMLManager = class {
12630
12850
  } else if (dataSource.name === "other") {
12631
12851
  bringDataSourceToTop(this.viewer, "other");
12632
12852
  }
12633
- return this.polygonEditor.startEditing(entity, dataSource, onComplete);
12853
+ this.enterEditingMode();
12854
+ const wrappedOnComplete = (editedEntity) => {
12855
+ this.exitEditingMode();
12856
+ onComplete?.(editedEntity);
12857
+ };
12858
+ const session = this.polygonEditor.startEditing(entity, dataSource, wrappedOnComplete);
12859
+ if (session) {
12860
+ const originalStop = session.stop;
12861
+ session.stop = () => {
12862
+ this.exitEditingMode();
12863
+ originalStop();
12864
+ };
12865
+ }
12866
+ return session;
12634
12867
  }
12635
12868
  ensurePolygonSessionHooks() {
12636
12869
  if (this.polygonSessionCleanup || typeof window === "undefined" || typeof document === "undefined") {
@@ -14169,6 +14402,8 @@ var MassPolygonManager = class {
14169
14402
  __publicField(this, "hoverHandler");
14170
14403
  __publicField(this, "clickHandler");
14171
14404
  __publicField(this, "rightClickHandler");
14405
+ // 交互禁用标志(编辑模式时禁用)
14406
+ __publicField(this, "interactionDisabled", false);
14172
14407
  // 悬停状态
14173
14408
  __publicField(this, "highlightedId");
14174
14409
  __publicField(this, "originalHighlightFillColor");
@@ -14257,12 +14492,35 @@ var MassPolygonManager = class {
14257
14492
  getLayerCollection() {
14258
14493
  return this.layerCollection;
14259
14494
  }
14495
+ /**
14496
+ * 禁用所有交互(hover/click/rightClick)
14497
+ * 用于编辑模式下隔离其他图层的交互
14498
+ */
14499
+ disableInteraction() {
14500
+ this.interactionDisabled = true;
14501
+ this.clearHighlight();
14502
+ this.hideLabel();
14503
+ }
14504
+ /**
14505
+ * 启用所有交互
14506
+ * 用于退出编辑模式后恢复交互
14507
+ */
14508
+ enableInteraction() {
14509
+ this.interactionDisabled = false;
14510
+ }
14511
+ /**
14512
+ * 检查交互是否被禁用
14513
+ */
14514
+ isInteractionDisabled() {
14515
+ return this.interactionDisabled;
14516
+ }
14260
14517
  /**
14261
14518
  * 批量创建多边形
14262
14519
  */
14263
14520
  create(polygons, options) {
14264
14521
  const C = this.CesiumNS;
14265
14522
  this.clear();
14523
+ globalState.registerMassPolygonManager(this);
14266
14524
  this.currentOptions = options ?? {};
14267
14525
  this.layerName = options?.layerName;
14268
14526
  if (options?.style) {
@@ -14456,6 +14714,7 @@ var MassPolygonManager = class {
14456
14714
  this.hoverHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
14457
14715
  this.hoverHandler.setInputAction(
14458
14716
  (movement) => {
14717
+ if (this.interactionDisabled) return;
14459
14718
  const now = Date.now();
14460
14719
  if (now - this.lastPickTime < this.pickThrottleMs) return;
14461
14720
  this.lastPickTime = now;
@@ -14497,6 +14756,7 @@ var MassPolygonManager = class {
14497
14756
  this.clickHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
14498
14757
  this.clickHandler.setInputAction(
14499
14758
  (movement) => {
14759
+ if (this.interactionDisabled) return;
14500
14760
  let polygonId = null;
14501
14761
  if (this.isClampToGround) {
14502
14762
  polygonId = this.pickPolygonByPosition(movement.position);
@@ -14539,6 +14799,7 @@ var MassPolygonManager = class {
14539
14799
  this.rightClickHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
14540
14800
  this.rightClickHandler.setInputAction(
14541
14801
  (movement) => {
14802
+ if (this.interactionDisabled) return;
14542
14803
  let polygonId = null;
14543
14804
  if (this.isClampToGround) {
14544
14805
  polygonId = this.pickPolygonByPosition(movement.position);
@@ -15319,6 +15580,7 @@ var MassPolygonManager = class {
15319
15580
  * 清除所有多边形
15320
15581
  */
15321
15582
  clear() {
15583
+ globalState.unregisterMassPolygonManager(this);
15322
15584
  if (this.hoverHandler) {
15323
15585
  this.hoverHandler.destroy();
15324
15586
  this.hoverHandler = void 0;
@@ -15338,6 +15600,7 @@ var MassPolygonManager = class {
15338
15600
  this.originalSelectFillColor = void 0;
15339
15601
  this.originalSelectOutlineColor = void 0;
15340
15602
  this.hoverLabel = void 0;
15603
+ this.interactionDisabled = false;
15341
15604
  this.highlightPrimitive = void 0;
15342
15605
  this.selectPrimitive = void 0;
15343
15606
  if (this.layerCollection && this.viewer?.scene?.primitives) {