@jorgmoritz/gis-manager 0.1.42 → 0.1.44

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.js CHANGED
@@ -11,7 +11,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11
11
  // package.json
12
12
  var package_default = {
13
13
  name: "@jorgmoritz/gis-manager",
14
- version: "0.1.42"};
14
+ version: "0.1.43"};
15
15
 
16
16
  // src/utils/version.ts
17
17
  var version = package_default.version;
@@ -2002,14 +2002,15 @@ var HeightMarker = class {
2002
2002
  polyline: {
2003
2003
  positions: [C.Cartesian3.ZERO, C.Cartesian3.ZERO],
2004
2004
  width: this.opts.width ?? 2,
2005
- material: color,
2005
+ material: C.Color.YELLOW.withAlpha(0.4),
2006
+ // 黄色半透明垂直线
2006
2007
  clampToGround: false
2007
2008
  // vertical line in 3D space
2008
2009
  },
2009
2010
  ellipse: {
2010
- semiMajorAxis: this.opts.circleRadius ?? 5,
2011
- semiMinorAxis: this.opts.circleRadius ?? 5,
2012
- material: color.withAlpha ? color.withAlpha(0.65) : color,
2011
+ semiMajorAxis: this.opts.circleRadius ?? 3,
2012
+ semiMinorAxis: this.opts.circleRadius ?? 3,
2013
+ material: color.withAlpha ? color.withAlpha(0.45) : color,
2013
2014
  outline: true,
2014
2015
  outlineColor: color,
2015
2016
  heightReference: C.HeightReference.CLAMP_TO_GROUND
@@ -2020,12 +2021,13 @@ var HeightMarker = class {
2020
2021
  position: C.Cartesian3.ZERO,
2021
2022
  label: {
2022
2023
  text: "",
2023
- font: "14px sans-serif",
2024
+ font: "10px sans-serif",
2025
+ // 字体改小
2024
2026
  style: C.LabelStyle.FILL_AND_OUTLINE,
2025
2027
  fillColor: C.Color.BLACK,
2026
2028
  outlineColor: C.Color.WHITE,
2027
- outlineWidth: 3,
2028
- pixelOffset: new C.Cartesian2(0, -6),
2029
+ outlineWidth: 2,
2030
+ pixelOffset: new C.Cartesian2(0, -4),
2029
2031
  showBackground: false,
2030
2032
  horizontalOrigin: C.HorizontalOrigin.CENTER,
2031
2033
  verticalOrigin: C.VerticalOrigin.BOTTOM,
@@ -3551,6 +3553,8 @@ var AirplaneCursor = class {
3551
3553
  __publicField(this, "cachedScaleFactor", 1);
3552
3554
  // 相机变化事件监听器
3553
3555
  __publicField(this, "cameraChangedListener");
3556
+ /** 飞机游标模型可见性,默认 false */
3557
+ __publicField(this, "visible", false);
3554
3558
  const C = this.CesiumNS;
3555
3559
  this.opts = opts;
3556
3560
  this.pose = { position: startPosition, heading: 0, pitch: -10, roll: 0 };
@@ -3558,6 +3562,7 @@ var AirplaneCursor = class {
3558
3562
  this.angleStep = opts.angleStepDeg ?? 1;
3559
3563
  this.fastFactor = opts.fastFactor ?? 5;
3560
3564
  this.currentFOV = opts.fovDeg ?? DEFAULT_FOV;
3565
+ this.visible = opts.visible ?? false;
3561
3566
  this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
3562
3567
  this.attachKeyboard(opts);
3563
3568
  this.setupFOVListener();
@@ -3612,6 +3617,8 @@ var AirplaneCursor = class {
3612
3617
  runAnimations: true,
3613
3618
  clampAnimations: false
3614
3619
  },
3620
+ show: this.visible,
3621
+ // 根据 visible 设置初始显示状态
3615
3622
  properties: { _type: "airplane-cursor" }
3616
3623
  });
3617
3624
  this.entity = this.modelEntity;
@@ -3839,6 +3846,18 @@ var AirplaneCursor = class {
3839
3846
  altitude
3840
3847
  };
3841
3848
  }
3849
+ /** 设置飞机游标可见性 */
3850
+ setVisible(visible) {
3851
+ this.visible = visible;
3852
+ if (this.modelEntity) {
3853
+ this.modelEntity.show = visible;
3854
+ }
3855
+ this.viewer.scene?.requestRender?.();
3856
+ }
3857
+ /** 获取当前可见性状态 */
3858
+ isVisible() {
3859
+ return this.visible;
3860
+ }
3842
3861
  /** 获取内部实体(用于拾取识别) */
3843
3862
  getEntity() {
3844
3863
  return this.entity;
@@ -5068,6 +5087,44 @@ function calculateRelativeHeight(altitudeMode, absoluteHeight, startPointAltitud
5068
5087
  }
5069
5088
  }
5070
5089
 
5090
+ // src/utils/geometryUtils.ts
5091
+ function calculateDistanceAndMidpoint(CesiumNS, point1, point2) {
5092
+ const C = CesiumNS;
5093
+ const distance = C.Cartesian3.distance(point1, point2);
5094
+ const midpoint = new C.Cartesian3();
5095
+ C.Cartesian3.midpoint(point1, point2, midpoint);
5096
+ return { distance, midpoint };
5097
+ }
5098
+ function calculateDistance(CesiumNS, point1, point2) {
5099
+ const C = CesiumNS;
5100
+ return C.Cartesian3.distance(point1, point2);
5101
+ }
5102
+ function calculateMidpoint(CesiumNS, point1, point2) {
5103
+ const C = CesiumNS;
5104
+ const midpoint = new C.Cartesian3();
5105
+ C.Cartesian3.midpoint(point1, point2, midpoint);
5106
+ return midpoint;
5107
+ }
5108
+ function calculateHeadingBetweenPoints(CesiumNS, point1, point2) {
5109
+ const C = CesiumNS;
5110
+ try {
5111
+ const fromCarto = C.Cartographic.fromCartesian(point1);
5112
+ const toCarto = C.Cartographic.fromCartesian(point2);
5113
+ const deltaLon = toCarto.longitude - fromCarto.longitude;
5114
+ let heading = Math.atan2(
5115
+ Math.sin(deltaLon) * Math.cos(toCarto.latitude),
5116
+ Math.cos(fromCarto.latitude) * Math.sin(toCarto.latitude) - Math.sin(fromCarto.latitude) * Math.cos(toCarto.latitude) * Math.cos(deltaLon)
5117
+ );
5118
+ heading = C.Math.toDegrees(heading);
5119
+ if (heading > 180) heading -= 360;
5120
+ if (heading < -180) heading += 360;
5121
+ return heading;
5122
+ } catch (error) {
5123
+ console.error("[calculateHeadingBetweenPoints] Error:", error);
5124
+ return 0;
5125
+ }
5126
+ }
5127
+
5071
5128
  // src/core/path-manager/editing/PathEditingEventHandler.ts
5072
5129
  var PathEditingEventHandler = class {
5073
5130
  constructor(options, callbacks) {
@@ -5128,36 +5185,14 @@ var PathEditingEventHandler = class {
5128
5185
  if (typeof index === "number") {
5129
5186
  if (currentActiveIndex === index) {
5130
5187
  this.vertexDragHandler.startDrag(index, movement.position);
5131
- } else {
5132
- if (this.callbacks.onVertexSelect) {
5133
- this.callbacks.onVertexSelect(index);
5134
- }
5135
- console.log("[PathEditingEventHandler] \u9876\u70B9\u88AB\u70B9\u51FB\uFF0C\u7D22\u5F15:", index, "\u56DE\u8C03\u5B58\u5728:", !!this.callbacks.onVertexSelectDetail);
5136
- if (this.callbacks.onVertexSelectDetail) {
5137
- try {
5138
- const detailInfo = this.buildVertexDetailInfo(index);
5139
- console.log("[PathEditingEventHandler] \u8C03\u7528 onVertexSelectDetail \u56DE\u8C03");
5140
- this.callbacks.onVertexSelectDetail(detailInfo);
5141
- } catch (error) {
5142
- console.error("[PathEditingEventHandler] Error building vertex detail info:", error);
5143
- }
5144
- }
5145
5188
  }
5146
5189
  return;
5147
5190
  }
5148
5191
  }
5149
5192
  const idx = pickVertexIndex(this.viewer, movement.position, this.hiddenClimbIndex);
5150
5193
  if (typeof idx === "number") {
5151
- if (this.callbacks.onVertexSelect) {
5152
- this.callbacks.onVertexSelect(idx);
5153
- }
5154
- if (this.callbacks.onVertexSelectDetail) {
5155
- try {
5156
- const detailInfo = this.buildVertexDetailInfo(idx);
5157
- this.callbacks.onVertexSelectDetail(detailInfo);
5158
- } catch (error) {
5159
- console.error("Error building vertex detail info:", error);
5160
- }
5194
+ if (currentActiveIndex === idx) {
5195
+ this.vertexDragHandler.startDrag(idx, movement.position);
5161
5196
  }
5162
5197
  }
5163
5198
  }, C.ScreenSpaceEventType.LEFT_DOWN);
@@ -5176,6 +5211,26 @@ var PathEditingEventHandler = class {
5176
5211
  if (this.vertexDragHandler.isDragging()) {
5177
5212
  return;
5178
5213
  }
5214
+ const scene = this.viewer.scene;
5215
+ const picked = scene.pick?.(movement.position);
5216
+ const entity = picked?.id;
5217
+ if (entity?.properties?._type?.getValue?.() === "vertex-label") {
5218
+ const labelIndex = entity.properties._vertexIndex?.getValue?.();
5219
+ if (typeof labelIndex === "number") {
5220
+ if (this.callbacks.onVertexSelect) {
5221
+ this.callbacks.onVertexSelect(labelIndex);
5222
+ }
5223
+ if (this.callbacks.onVertexSelectDetail) {
5224
+ try {
5225
+ const detailInfo = this.buildVertexDetailInfo(labelIndex);
5226
+ this.callbacks.onVertexSelectDetail(detailInfo);
5227
+ } catch (error) {
5228
+ console.error("Error building vertex detail info:", error);
5229
+ }
5230
+ }
5231
+ return;
5232
+ }
5233
+ }
5179
5234
  const idx = pickVertexIndex(this.viewer, movement.position, this.hiddenClimbIndex);
5180
5235
  if (typeof idx === "number") {
5181
5236
  if (this.callbacks.onVertexSelect) {
@@ -5191,6 +5246,45 @@ var PathEditingEventHandler = class {
5191
5246
  }
5192
5247
  return;
5193
5248
  }
5249
+ const CLICK_THRESHOLD_PIXELS = 25;
5250
+ const positions = this.callbacks.getPositions?.() || [];
5251
+ if (positions.length > 0) {
5252
+ const clickPos = movement.position;
5253
+ let minDistance = Infinity;
5254
+ let nearestIndex = -1;
5255
+ for (let i = 0; i < positions.length; i++) {
5256
+ try {
5257
+ const screenPos = C.SceneTransforms.wgs84ToWindowCoordinates(
5258
+ scene,
5259
+ positions[i]
5260
+ );
5261
+ if (screenPos) {
5262
+ const dx = screenPos.x - clickPos.x;
5263
+ const dy = screenPos.y - clickPos.y;
5264
+ const distance = Math.sqrt(dx * dx + dy * dy);
5265
+ if (distance < minDistance) {
5266
+ minDistance = distance;
5267
+ nearestIndex = i;
5268
+ }
5269
+ }
5270
+ } catch {
5271
+ }
5272
+ }
5273
+ if (minDistance < CLICK_THRESHOLD_PIXELS && nearestIndex >= 0) {
5274
+ if (this.callbacks.onVertexSelect) {
5275
+ this.callbacks.onVertexSelect(nearestIndex);
5276
+ }
5277
+ if (this.callbacks.onVertexSelectDetail) {
5278
+ try {
5279
+ const detailInfo = this.buildVertexDetailInfo(nearestIndex);
5280
+ this.callbacks.onVertexSelectDetail(detailInfo);
5281
+ } catch (error) {
5282
+ console.error("Error building vertex detail info:", error);
5283
+ }
5284
+ }
5285
+ return;
5286
+ }
5287
+ }
5194
5288
  const quickEditEnabled = this.callbacks.getQuickEditEnabled?.();
5195
5289
  if (quickEditEnabled) {
5196
5290
  this.handleQuickEditClick(movement);
@@ -5294,6 +5388,14 @@ var PathEditingEventHandler = class {
5294
5388
  this.handleInsertVertex(activeIndex + 1, pose, "after");
5295
5389
  }
5296
5390
  });
5391
+ if (activeIndex < positions.length - 1) {
5392
+ menuItems.push({
5393
+ label: "\u5728\u4E2D\u95F4\u63D2\u5165\u822A\u70B9",
5394
+ action: () => {
5395
+ this.handleInsertMidpoint(activeIndex);
5396
+ }
5397
+ });
5398
+ }
5297
5399
  } else if (pose && visibleVertexCount <= 1) {
5298
5400
  menuItems.push({
5299
5401
  label: "\u6DFB\u52A0\u7B2C\u4E00\u4E2A\u822A\u70B9",
@@ -5440,6 +5542,27 @@ var PathEditingEventHandler = class {
5440
5542
  });
5441
5543
  }
5442
5544
  }
5545
+ /**
5546
+ * 🆕 在选中航点和下一个航点中间插入新航点
5547
+ */
5548
+ handleInsertMidpoint(activeIndex) {
5549
+ const positions = this.callbacks.getPositions?.() || [];
5550
+ const poseData = this.callbacks.getPoseData?.();
5551
+ if (activeIndex >= positions.length - 1) {
5552
+ console.warn("[handleInsertMidpoint] \u9009\u4E2D\u822A\u70B9\u662F\u6700\u540E\u4E00\u4E2A\uFF0C\u65E0\u6CD5\u63D2\u5165\u4E2D\u70B9");
5553
+ return;
5554
+ }
5555
+ const point1 = positions[activeIndex];
5556
+ const point2 = positions[activeIndex + 1];
5557
+ const { midpoint } = calculateDistanceAndMidpoint(this.CesiumNS, point1, point2);
5558
+ const heading = calculateHeadingBetweenPoints(this.CesiumNS, point1, point2);
5559
+ const pitch = poseData?.pitches[activeIndex] ?? -10;
5560
+ const roll = poseData?.rolls[activeIndex] ?? 0;
5561
+ console.log("[handleInsertMidpoint] \u5728\u7D22\u5F15", activeIndex, "\u548C", activeIndex + 1, "\u4E4B\u95F4\u63D2\u5165\u4E2D\u70B9");
5562
+ if (this.callbacks.onInsertVertex) {
5563
+ this.callbacks.onInsertVertex(activeIndex + 1, midpoint, { heading, pitch, roll });
5564
+ }
5565
+ }
5443
5566
  /**
5444
5567
  * 处理删除顶点
5445
5568
  */
@@ -5888,23 +6011,37 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5888
6011
  while (useGlobalHeightFlags.length < positions.length) {
5889
6012
  useGlobalHeightFlags.push(false);
5890
6013
  }
5891
- let quickEditEnabled = false;
6014
+ const waypointIds = [];
6015
+ if (options?.waypointIds && Array.isArray(options.waypointIds)) {
6016
+ const offset = 0;
6017
+ for (let i = 0; i < offset; i++) {
6018
+ waypointIds[i] = void 0;
6019
+ }
6020
+ options.waypointIds.forEach((id, idx) => {
6021
+ waypointIds[offset + idx] = id;
6022
+ });
6023
+ }
6024
+ while (waypointIds.length < positions.length) {
6025
+ waypointIds.push(void 0);
6026
+ }
6027
+ let quickEditEnabled = true;
5892
6028
  let quickEditOptions = {
5893
- enabled: false,
6029
+ enabled: true,
5894
6030
  climbHeight: currentDefaultAltitude,
5895
6031
  // 使用当前默认高度
5896
6032
  altitudeMode: currentAltitudeMode
5897
6033
  // 使用当前高度模式
5898
6034
  };
5899
- if (options?.quickEdit) {
6035
+ if (options?.quickEdit !== void 0) {
5900
6036
  if (typeof options.quickEdit === "boolean") {
5901
6037
  quickEditEnabled = options.quickEdit;
5902
6038
  quickEditOptions.enabled = options.quickEdit;
5903
6039
  } else {
5904
- quickEditEnabled = options.quickEdit.enabled ?? false;
6040
+ quickEditEnabled = options.quickEdit.enabled ?? true;
5905
6041
  quickEditOptions = {
5906
6042
  ...quickEditOptions,
5907
- ...options.quickEdit
6043
+ ...options.quickEdit,
6044
+ enabled: options.quickEdit.enabled ?? true
5908
6045
  };
5909
6046
  }
5910
6047
  }
@@ -5999,6 +6136,8 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5999
6136
  const stateManager = new PathStateManager(entity, positions, headings, pitches, rolls, fovs);
6000
6137
  let activeIndex;
6001
6138
  let editedIndices = /* @__PURE__ */ new Set();
6139
+ let isUpdatingFromCursor = false;
6140
+ let isUpdatingFromDrag = false;
6002
6141
  const handleStyleManager = new VertexHandleStyleManager(CesiumNS);
6003
6142
  const setActiveIndex = (idx) => {
6004
6143
  if (activeIndex !== void 0 && handles[activeIndex]) {
@@ -6104,6 +6243,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6104
6243
  useGlobalHeightFlags
6105
6244
  // 🆕 传递 useGlobalHeightFlags
6106
6245
  );
6246
+ waypointIds.splice(actualIndex, 0, void 0);
6107
6247
  console.log("[PathEditing] \u63D2\u5165\u9876\u70B9\u540E positions \u957F\u5EA6:", positions.length, "actualIndex:", actualIndex);
6108
6248
  entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
6109
6249
  setActiveIndex(actualIndex);
@@ -6136,6 +6276,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6136
6276
  fovs.splice(deleteAt, 1);
6137
6277
  heightMarkers.splice(deleteAt, 1);
6138
6278
  useGlobalHeightFlags.splice(deleteAt, 1);
6279
+ waypointIds.splice(deleteAt, 1);
6139
6280
  console.log("[PathEditing] \u5220\u9664\u9876\u70B9\u540E positions \u957F\u5EA6:", positions.length);
6140
6281
  entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
6141
6282
  const newEditedIndices = /* @__PURE__ */ new Set();
@@ -6222,12 +6363,36 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6222
6363
  }
6223
6364
  airplaneCursor.updateOptions({
6224
6365
  onPose: (pose) => {
6366
+ if (isUpdatingFromDrag) return;
6225
6367
  try {
6226
6368
  if (preview) {
6227
6369
  preview.setPose(pose.position, pose.heading, pose.pitch, pose.roll, 50);
6228
6370
  }
6229
6371
  } catch {
6230
6372
  }
6373
+ if (activeIndex !== void 0 && !isUpdatingFromCursor) {
6374
+ isUpdatingFromCursor = true;
6375
+ try {
6376
+ positions[activeIndex] = pose.position;
6377
+ headings[activeIndex] = pose.heading;
6378
+ pitches[activeIndex] = pose.pitch;
6379
+ rolls[activeIndex] = pose.roll;
6380
+ if (handles[activeIndex]) {
6381
+ handles[activeIndex].position = pose.position;
6382
+ }
6383
+ vertexLabelManager.updateLabelPosition(activeIndex, pose.position);
6384
+ createOrUpdateMarkerForIndex(activeIndex);
6385
+ editedIndices.add(activeIndex);
6386
+ useGlobalHeightFlags[activeIndex] = false;
6387
+ try {
6388
+ entity.polyline.positions = positions.slice();
6389
+ } catch {
6390
+ }
6391
+ viewer.scene?.requestRender?.();
6392
+ } finally {
6393
+ isUpdatingFromCursor = false;
6394
+ }
6395
+ }
6231
6396
  }
6232
6397
  });
6233
6398
  }
@@ -6303,24 +6468,38 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6303
6468
  },
6304
6469
  onVertexDragMove: (index, newPosition) => {
6305
6470
  console.log("[PathEditing] onVertexDragMove \u88AB\u8C03\u7528, index:", index);
6306
- positions[index] = newPosition;
6307
- if (handles[index]) {
6471
+ if (isUpdatingFromCursor) return;
6472
+ isUpdatingFromDrag = true;
6473
+ try {
6474
+ positions[index] = newPosition;
6475
+ if (handles[index]) {
6476
+ try {
6477
+ handles[index].position = newPosition;
6478
+ } catch {
6479
+ }
6480
+ }
6308
6481
  try {
6309
- handles[index].position = newPosition;
6482
+ vertexLabelManager.updateLabelPosition(index, newPosition);
6310
6483
  } catch {
6311
6484
  }
6312
- }
6313
- try {
6314
- vertexLabelManager.updateLabelPosition(index, newPosition);
6315
- } catch {
6316
- }
6317
- try {
6318
- entity.polyline.positions = positions.slice();
6319
- } catch {
6320
- }
6321
- try {
6322
- viewer.scene.requestRender();
6323
- } catch {
6485
+ try {
6486
+ entity.polyline.positions = positions.slice();
6487
+ } catch {
6488
+ }
6489
+ try {
6490
+ viewer.scene.requestRender();
6491
+ } catch {
6492
+ }
6493
+ if (airplaneCursor && index === activeIndex) {
6494
+ airplaneCursor.setPose(
6495
+ newPosition,
6496
+ headings[index] ?? 0,
6497
+ pitches[index] ?? -10,
6498
+ rolls[index] ?? 0
6499
+ );
6500
+ }
6501
+ } finally {
6502
+ isUpdatingFromDrag = false;
6324
6503
  }
6325
6504
  if (options?.onVertexDragMoveDetail) {
6326
6505
  try {
@@ -6524,6 +6703,55 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6524
6703
  // 🆕 添加相对高度
6525
6704
  };
6526
6705
  };
6706
+ if (options?.initialClickPosition && positions.length === 0) {
6707
+ console.log("[PathEditing] \u5904\u7406\u521D\u59CB\u70B9\u51FB\u4F4D\u7F6E\uFF0C\u7ACB\u5373\u6DFB\u52A0\u7B2C\u4E00\u4E2A\u822A\u70B9");
6708
+ let finalPosition = options.initialClickPosition;
6709
+ try {
6710
+ const cartographic = C.Cartographic.fromCartesian(options.initialClickPosition);
6711
+ const lon = C.Math.toDegrees(cartographic.longitude);
6712
+ const lat = C.Math.toDegrees(cartographic.latitude);
6713
+ let finalHeight;
6714
+ if (currentAltitudeMode === "absolute") {
6715
+ finalHeight = currentDefaultAltitude;
6716
+ } else if (currentAltitudeMode === "relativeToGround") {
6717
+ const terrainHeight = queryTerrainHeightSync(CesiumNS, viewer, options.initialClickPosition);
6718
+ finalHeight = terrainHeight + currentDefaultAltitude;
6719
+ } else if (currentAltitudeMode === "relativeToStart") {
6720
+ finalHeight = currentDefaultAltitude;
6721
+ } else {
6722
+ finalHeight = currentDefaultAltitude;
6723
+ }
6724
+ finalPosition = C.Cartesian3.fromDegrees(lon, lat, finalHeight);
6725
+ console.log("[PathEditing] \u521D\u59CB\u822A\u70B9\u9AD8\u5EA6\u8BA1\u7B97:", {
6726
+ altitudeMode: currentAltitudeMode,
6727
+ defaultAltitude: currentDefaultAltitude,
6728
+ finalHeight
6729
+ });
6730
+ } catch (error) {
6731
+ console.warn("[PathEditing] \u8BA1\u7B97\u521D\u59CB\u822A\u70B9\u9AD8\u5EA6\u5931\u8D25:", error);
6732
+ }
6733
+ const totalBefore = positions.length;
6734
+ insertVertex(0, finalPosition, { heading: 0, pitch: -10, roll: 0 });
6735
+ if (options?.onVertexInsertDetail) {
6736
+ try {
6737
+ const totalAfter = positions.length;
6738
+ const newVertex = buildVertexDetailInfo(0);
6739
+ const operationInfo = {
6740
+ type: "insert",
6741
+ index: 0,
6742
+ displayNumber: newVertex.displayNumber,
6743
+ totalVerticesBefore: totalBefore,
6744
+ totalVerticesAfter: totalAfter,
6745
+ newVertex,
6746
+ timestamp: /* @__PURE__ */ new Date(),
6747
+ totalDistance: getTotalDistance()
6748
+ };
6749
+ options.onVertexInsertDetail(operationInfo);
6750
+ } catch (error) {
6751
+ console.error("[PathEditing] \u89E6\u53D1 onVertexInsertDetail \u56DE\u8C03\u5931\u8D25:", error);
6752
+ }
6753
+ }
6754
+ }
6527
6755
  return {
6528
6756
  /** 保存并退出编辑模式 */
6529
6757
  saveAndStop: () => {
@@ -6565,8 +6793,10 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6565
6793
  distance: calculatePathDistance(CesiumNS, positions, index),
6566
6794
  ellipsoidHeight,
6567
6795
  relativeHeight,
6568
- useGlobalHeight: useGlobalHeightFlags[index] ?? false
6796
+ useGlobalHeight: useGlobalHeightFlags[index] ?? false,
6569
6797
  // 🆕 添加 useGlobalHeight
6798
+ waypointId: waypointIds[index]
6799
+ // 🆕 添加 waypointId(原有航点保留ID,新插入航点为 undefined)
6570
6800
  };
6571
6801
  });
6572
6802
  cleanupSession();
@@ -6949,6 +7179,67 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6949
7179
  options2?.onProgress?.("error");
6950
7180
  return { success: false, error: String(error) };
6951
7181
  }
7182
+ },
7183
+ /**
7184
+ * 🆕 获取当前选中航点索引
7185
+ * @returns 当前选中的航点索引,如果没有选中则返回 undefined
7186
+ */
7187
+ getActiveIndex: () => {
7188
+ return activeIndex;
7189
+ },
7190
+ /**
7191
+ * 🆕 在选中航点和下一个航点中间插入新航点
7192
+ * @param index 选中航点的索引(如果不传则使用当前选中的航点)
7193
+ * @returns 是否插入成功
7194
+ */
7195
+ insertMidpoint: (index) => {
7196
+ const targetIndex = index ?? activeIndex;
7197
+ if (targetIndex === void 0) {
7198
+ console.warn("[insertMidpoint] \u6CA1\u6709\u9009\u4E2D\u822A\u70B9");
7199
+ return false;
7200
+ }
7201
+ if (targetIndex >= positions.length - 1) {
7202
+ console.warn("[insertMidpoint] \u9009\u4E2D\u822A\u70B9\u662F\u6700\u540E\u4E00\u4E2A\uFF0C\u65E0\u6CD5\u63D2\u5165\u4E2D\u70B9");
7203
+ return false;
7204
+ }
7205
+ const point1 = positions[targetIndex];
7206
+ const point2 = positions[targetIndex + 1];
7207
+ const midpoint = C.Cartesian3.midpoint(point1, point2, new C.Cartesian3());
7208
+ const carto1 = C.Cartographic.fromCartesian(point1);
7209
+ const carto2 = C.Cartographic.fromCartesian(point2);
7210
+ const deltaLon = carto2.longitude - carto1.longitude;
7211
+ let heading = Math.atan2(
7212
+ Math.sin(deltaLon) * Math.cos(carto2.latitude),
7213
+ Math.cos(carto1.latitude) * Math.sin(carto2.latitude) - Math.sin(carto1.latitude) * Math.cos(carto2.latitude) * Math.cos(deltaLon)
7214
+ );
7215
+ heading = C.Math.toDegrees(heading);
7216
+ if (heading > 180) heading -= 360;
7217
+ if (heading < -180) heading += 360;
7218
+ const pitch = pitches[targetIndex] ?? -10;
7219
+ const roll = rolls[targetIndex] ?? 0;
7220
+ console.log("[insertMidpoint] \u5728\u7D22\u5F15", targetIndex, "\u548C", targetIndex + 1, "\u4E4B\u95F4\u63D2\u5165\u4E2D\u70B9");
7221
+ const totalBefore = positions.length;
7222
+ insertVertex(targetIndex + 1, midpoint, { heading, pitch, roll });
7223
+ if (options?.onVertexInsertDetail) {
7224
+ try {
7225
+ const totalAfter = positions.length;
7226
+ const newVertex = buildVertexDetailInfo(targetIndex + 1);
7227
+ const operationInfo = {
7228
+ type: "insert",
7229
+ index: targetIndex + 1,
7230
+ displayNumber: newVertex.displayNumber,
7231
+ totalVerticesBefore: totalBefore,
7232
+ totalVerticesAfter: totalAfter,
7233
+ newVertex,
7234
+ timestamp: /* @__PURE__ */ new Date(),
7235
+ totalDistance: getTotalDistance()
7236
+ };
7237
+ options.onVertexInsertDetail(operationInfo);
7238
+ } catch (error) {
7239
+ console.error("Error in onVertexInsertDetail:", error);
7240
+ }
7241
+ }
7242
+ return true;
6952
7243
  }
6953
7244
  };
6954
7245
  }
@@ -7030,8 +7321,8 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
7030
7321
  try {
7031
7322
  const auto = options?.autoStartEditing;
7032
7323
  const editOptions = {
7033
- // 默认使用自由编辑模式(快速编辑和自由编辑互斥)
7034
- quickEdit: false
7324
+ // 🔧 修复:默认使用快速编辑模式,用户点击地图即可添加航点
7325
+ quickEdit: true
7035
7326
  };
7036
7327
  if (typeof auto === "object" && auto.preview) {
7037
7328
  editOptions.preview = auto.preview;
@@ -7057,8 +7348,9 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
7057
7348
  editOptions.altitudeMode = altitudeMode;
7058
7349
  editOptions.defaultAltitude = defaultAltitude;
7059
7350
  editOptions.climbHeight = climbHeight;
7351
+ editOptions.initialClickPosition = picked;
7060
7352
  editSession = startPathEditing(CesiumNS, viewer, created, editOptions);
7061
- console.log("[startPathDrawing] \u7F16\u8F91\u6A21\u5F0F\u5DF2\u542F\u52A8\uFF0C\u81EA\u7531\u7F16\u8F91\u6A21\u5F0F\uFF0C\u4F7F\u7528\u98DE\u673A\u6E38\u6807\u6DFB\u52A0\u822A\u70B9");
7353
+ console.log("[startPathDrawing] \u7F16\u8F91\u6A21\u5F0F\u5DF2\u542F\u52A8\uFF0C\u5FEB\u901F\u7F16\u8F91\u6A21\u5F0F\uFF0C\u70B9\u51FB\u5730\u56FE\u6DFB\u52A0\u822A\u70B9");
7062
7354
  if (editSession && options?.onEditingStarted) {
7063
7355
  try {
7064
7356
  options.onEditingStarted(editSession);
@@ -12061,8 +12353,8 @@ function convertPathToSinofly(data, options) {
12061
12353
  );
12062
12354
  const action = convertPoseToActionGroup(wp.heading, wp.pitch, wp.roll, wp.fov, newIndex);
12063
12355
  const waypoint = {
12064
- waypointId: "",
12065
- // 由服务器自动生成
12356
+ waypointId: wp.waypointId ?? "",
12357
+ // 🆕 使用传入的 waypointId,新航点为空字符串
12066
12358
  waylineId,
12067
12359
  index: newIndex,
12068
12360
  latitude,
@@ -12500,6 +12792,6 @@ var PathSafetyChecker = class {
12500
12792
  var placeholder = { ready: true };
12501
12793
  var droneModelUrl = wurenji_default;
12502
12794
 
12503
- export { CZMLManager, CameraEventBus, CameraFOVController, CameraManager, Emitter, FlightSimulator, FrustumPyramid, LayerManager, PathSafetyChecker, PointCloudPicker, PolygonEditor, SceneManager, Selector, StateManager, assertCesiumAssetsConfigured, calculateAbsoluteHeight, calculateBoundsDiagonal, calculateGeoBounds, calculateRelativeHeight, configureCesiumAssets, configureCesiumIonToken, convertPathToSinofly, convertSinoflyWayline, convertSinoflyWaylines, droneModelUrl, ensureCesiumIonToken, expandBounds, getCesiumBaseUrl, getCesiumIonToken, globalCameraEventBus, globalState, isPointInBounds, mergeBounds, placeholder, queryTerrainHeightAsync, queryTerrainHeightByLonLat, queryTerrainHeightByLonLatSync, queryTerrainHeightSync, queryTerrainHeights, queryTerrainHeightsByLonLat, renderFlightPath, renderFlightPathPreview, toggle2D3D, version, versionInfo };
12795
+ export { CZMLManager, CameraEventBus, CameraFOVController, CameraManager, Emitter, FlightSimulator, FrustumPyramid, LayerManager, PathSafetyChecker, PointCloudPicker, PolygonEditor, SceneManager, Selector, StateManager, assertCesiumAssetsConfigured, calculateAbsoluteHeight, calculateBoundsDiagonal, calculateDistance, calculateDistanceAndMidpoint, calculateGeoBounds, calculateHeadingBetweenPoints, calculateMidpoint, calculateRelativeHeight, configureCesiumAssets, configureCesiumIonToken, convertPathToSinofly, convertSinoflyWayline, convertSinoflyWaylines, droneModelUrl, ensureCesiumIonToken, expandBounds, getCesiumBaseUrl, getCesiumIonToken, globalCameraEventBus, globalState, isPointInBounds, mergeBounds, placeholder, queryTerrainHeightAsync, queryTerrainHeightByLonLat, queryTerrainHeightByLonLatSync, queryTerrainHeightSync, queryTerrainHeights, queryTerrainHeightsByLonLat, renderFlightPath, renderFlightPathPreview, toggle2D3D, version, versionInfo };
12504
12796
  //# sourceMappingURL=index.js.map
12505
12797
  //# sourceMappingURL=index.js.map