@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.
@@ -1911,14 +1911,15 @@ var HeightMarker = class {
1911
1911
  polyline: {
1912
1912
  positions: [C.Cartesian3.ZERO, C.Cartesian3.ZERO],
1913
1913
  width: this.opts.width ?? 2,
1914
- material: color,
1914
+ material: C.Color.YELLOW.withAlpha(0.4),
1915
+ // 黄色半透明垂直线
1915
1916
  clampToGround: false
1916
1917
  // vertical line in 3D space
1917
1918
  },
1918
1919
  ellipse: {
1919
- semiMajorAxis: this.opts.circleRadius ?? 5,
1920
- semiMinorAxis: this.opts.circleRadius ?? 5,
1921
- material: color.withAlpha ? color.withAlpha(0.65) : color,
1920
+ semiMajorAxis: this.opts.circleRadius ?? 3,
1921
+ semiMinorAxis: this.opts.circleRadius ?? 3,
1922
+ material: color.withAlpha ? color.withAlpha(0.45) : color,
1922
1923
  outline: true,
1923
1924
  outlineColor: color,
1924
1925
  heightReference: C.HeightReference.CLAMP_TO_GROUND
@@ -1929,12 +1930,13 @@ var HeightMarker = class {
1929
1930
  position: C.Cartesian3.ZERO,
1930
1931
  label: {
1931
1932
  text: "",
1932
- font: "14px sans-serif",
1933
+ font: "10px sans-serif",
1934
+ // 字体改小
1933
1935
  style: C.LabelStyle.FILL_AND_OUTLINE,
1934
1936
  fillColor: C.Color.BLACK,
1935
1937
  outlineColor: C.Color.WHITE,
1936
- outlineWidth: 3,
1937
- pixelOffset: new C.Cartesian2(0, -6),
1938
+ outlineWidth: 2,
1939
+ pixelOffset: new C.Cartesian2(0, -4),
1938
1940
  showBackground: false,
1939
1941
  horizontalOrigin: C.HorizontalOrigin.CENTER,
1940
1942
  verticalOrigin: C.VerticalOrigin.BOTTOM,
@@ -3460,6 +3462,8 @@ var AirplaneCursor = class {
3460
3462
  __publicField(this, "cachedScaleFactor", 1);
3461
3463
  // 相机变化事件监听器
3462
3464
  __publicField(this, "cameraChangedListener");
3465
+ /** 飞机游标模型可见性,默认 false */
3466
+ __publicField(this, "visible", false);
3463
3467
  const C = this.CesiumNS;
3464
3468
  this.opts = opts;
3465
3469
  this.pose = { position: startPosition, heading: 0, pitch: -10, roll: 0 };
@@ -3467,6 +3471,7 @@ var AirplaneCursor = class {
3467
3471
  this.angleStep = opts.angleStepDeg ?? 1;
3468
3472
  this.fastFactor = opts.fastFactor ?? 5;
3469
3473
  this.currentFOV = opts.fovDeg ?? DEFAULT_FOV;
3474
+ this.visible = opts.visible ?? false;
3470
3475
  this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
3471
3476
  this.attachKeyboard(opts);
3472
3477
  this.setupFOVListener();
@@ -3521,6 +3526,8 @@ var AirplaneCursor = class {
3521
3526
  runAnimations: true,
3522
3527
  clampAnimations: false
3523
3528
  },
3529
+ show: this.visible,
3530
+ // 根据 visible 设置初始显示状态
3524
3531
  properties: { _type: "airplane-cursor" }
3525
3532
  });
3526
3533
  this.entity = this.modelEntity;
@@ -3748,6 +3755,18 @@ var AirplaneCursor = class {
3748
3755
  altitude
3749
3756
  };
3750
3757
  }
3758
+ /** 设置飞机游标可见性 */
3759
+ setVisible(visible) {
3760
+ this.visible = visible;
3761
+ if (this.modelEntity) {
3762
+ this.modelEntity.show = visible;
3763
+ }
3764
+ this.viewer.scene?.requestRender?.();
3765
+ }
3766
+ /** 获取当前可见性状态 */
3767
+ isVisible() {
3768
+ return this.visible;
3769
+ }
3751
3770
  /** 获取内部实体(用于拾取识别) */
3752
3771
  getEntity() {
3753
3772
  return this.entity;
@@ -4938,6 +4957,34 @@ function calculateRelativeHeight(altitudeMode, absoluteHeight, startPointAltitud
4938
4957
  }
4939
4958
  }
4940
4959
 
4960
+ // src/utils/geometryUtils.ts
4961
+ function calculateDistanceAndMidpoint(CesiumNS, point1, point2) {
4962
+ const C = CesiumNS;
4963
+ const distance = C.Cartesian3.distance(point1, point2);
4964
+ const midpoint = new C.Cartesian3();
4965
+ C.Cartesian3.midpoint(point1, point2, midpoint);
4966
+ return { distance, midpoint };
4967
+ }
4968
+ function calculateHeadingBetweenPoints(CesiumNS, point1, point2) {
4969
+ const C = CesiumNS;
4970
+ try {
4971
+ const fromCarto = C.Cartographic.fromCartesian(point1);
4972
+ const toCarto = C.Cartographic.fromCartesian(point2);
4973
+ const deltaLon = toCarto.longitude - fromCarto.longitude;
4974
+ let heading = Math.atan2(
4975
+ Math.sin(deltaLon) * Math.cos(toCarto.latitude),
4976
+ Math.cos(fromCarto.latitude) * Math.sin(toCarto.latitude) - Math.sin(fromCarto.latitude) * Math.cos(toCarto.latitude) * Math.cos(deltaLon)
4977
+ );
4978
+ heading = C.Math.toDegrees(heading);
4979
+ if (heading > 180) heading -= 360;
4980
+ if (heading < -180) heading += 360;
4981
+ return heading;
4982
+ } catch (error) {
4983
+ console.error("[calculateHeadingBetweenPoints] Error:", error);
4984
+ return 0;
4985
+ }
4986
+ }
4987
+
4941
4988
  // src/core/path-manager/editing/PathEditingEventHandler.ts
4942
4989
  var PathEditingEventHandler = class {
4943
4990
  constructor(options, callbacks) {
@@ -4998,36 +5045,14 @@ var PathEditingEventHandler = class {
4998
5045
  if (typeof index === "number") {
4999
5046
  if (currentActiveIndex === index) {
5000
5047
  this.vertexDragHandler.startDrag(index, movement.position);
5001
- } else {
5002
- if (this.callbacks.onVertexSelect) {
5003
- this.callbacks.onVertexSelect(index);
5004
- }
5005
- console.log("[PathEditingEventHandler] \u9876\u70B9\u88AB\u70B9\u51FB\uFF0C\u7D22\u5F15:", index, "\u56DE\u8C03\u5B58\u5728:", !!this.callbacks.onVertexSelectDetail);
5006
- if (this.callbacks.onVertexSelectDetail) {
5007
- try {
5008
- const detailInfo = this.buildVertexDetailInfo(index);
5009
- console.log("[PathEditingEventHandler] \u8C03\u7528 onVertexSelectDetail \u56DE\u8C03");
5010
- this.callbacks.onVertexSelectDetail(detailInfo);
5011
- } catch (error) {
5012
- console.error("[PathEditingEventHandler] Error building vertex detail info:", error);
5013
- }
5014
- }
5015
5048
  }
5016
5049
  return;
5017
5050
  }
5018
5051
  }
5019
5052
  const idx = pickVertexIndex(this.viewer, movement.position, this.hiddenClimbIndex);
5020
5053
  if (typeof idx === "number") {
5021
- if (this.callbacks.onVertexSelect) {
5022
- this.callbacks.onVertexSelect(idx);
5023
- }
5024
- if (this.callbacks.onVertexSelectDetail) {
5025
- try {
5026
- const detailInfo = this.buildVertexDetailInfo(idx);
5027
- this.callbacks.onVertexSelectDetail(detailInfo);
5028
- } catch (error) {
5029
- console.error("Error building vertex detail info:", error);
5030
- }
5054
+ if (currentActiveIndex === idx) {
5055
+ this.vertexDragHandler.startDrag(idx, movement.position);
5031
5056
  }
5032
5057
  }
5033
5058
  }, C.ScreenSpaceEventType.LEFT_DOWN);
@@ -5046,6 +5071,26 @@ var PathEditingEventHandler = class {
5046
5071
  if (this.vertexDragHandler.isDragging()) {
5047
5072
  return;
5048
5073
  }
5074
+ const scene = this.viewer.scene;
5075
+ const picked = scene.pick?.(movement.position);
5076
+ const entity = picked?.id;
5077
+ if (entity?.properties?._type?.getValue?.() === "vertex-label") {
5078
+ const labelIndex = entity.properties._vertexIndex?.getValue?.();
5079
+ if (typeof labelIndex === "number") {
5080
+ if (this.callbacks.onVertexSelect) {
5081
+ this.callbacks.onVertexSelect(labelIndex);
5082
+ }
5083
+ if (this.callbacks.onVertexSelectDetail) {
5084
+ try {
5085
+ const detailInfo = this.buildVertexDetailInfo(labelIndex);
5086
+ this.callbacks.onVertexSelectDetail(detailInfo);
5087
+ } catch (error) {
5088
+ console.error("Error building vertex detail info:", error);
5089
+ }
5090
+ }
5091
+ return;
5092
+ }
5093
+ }
5049
5094
  const idx = pickVertexIndex(this.viewer, movement.position, this.hiddenClimbIndex);
5050
5095
  if (typeof idx === "number") {
5051
5096
  if (this.callbacks.onVertexSelect) {
@@ -5061,6 +5106,45 @@ var PathEditingEventHandler = class {
5061
5106
  }
5062
5107
  return;
5063
5108
  }
5109
+ const CLICK_THRESHOLD_PIXELS = 25;
5110
+ const positions = this.callbacks.getPositions?.() || [];
5111
+ if (positions.length > 0) {
5112
+ const clickPos = movement.position;
5113
+ let minDistance = Infinity;
5114
+ let nearestIndex = -1;
5115
+ for (let i = 0; i < positions.length; i++) {
5116
+ try {
5117
+ const screenPos = C.SceneTransforms.wgs84ToWindowCoordinates(
5118
+ scene,
5119
+ positions[i]
5120
+ );
5121
+ if (screenPos) {
5122
+ const dx = screenPos.x - clickPos.x;
5123
+ const dy = screenPos.y - clickPos.y;
5124
+ const distance = Math.sqrt(dx * dx + dy * dy);
5125
+ if (distance < minDistance) {
5126
+ minDistance = distance;
5127
+ nearestIndex = i;
5128
+ }
5129
+ }
5130
+ } catch {
5131
+ }
5132
+ }
5133
+ if (minDistance < CLICK_THRESHOLD_PIXELS && nearestIndex >= 0) {
5134
+ if (this.callbacks.onVertexSelect) {
5135
+ this.callbacks.onVertexSelect(nearestIndex);
5136
+ }
5137
+ if (this.callbacks.onVertexSelectDetail) {
5138
+ try {
5139
+ const detailInfo = this.buildVertexDetailInfo(nearestIndex);
5140
+ this.callbacks.onVertexSelectDetail(detailInfo);
5141
+ } catch (error) {
5142
+ console.error("Error building vertex detail info:", error);
5143
+ }
5144
+ }
5145
+ return;
5146
+ }
5147
+ }
5064
5148
  const quickEditEnabled = this.callbacks.getQuickEditEnabled?.();
5065
5149
  if (quickEditEnabled) {
5066
5150
  this.handleQuickEditClick(movement);
@@ -5164,6 +5248,14 @@ var PathEditingEventHandler = class {
5164
5248
  this.handleInsertVertex(activeIndex + 1, pose, "after");
5165
5249
  }
5166
5250
  });
5251
+ if (activeIndex < positions.length - 1) {
5252
+ menuItems.push({
5253
+ label: "\u5728\u4E2D\u95F4\u63D2\u5165\u822A\u70B9",
5254
+ action: () => {
5255
+ this.handleInsertMidpoint(activeIndex);
5256
+ }
5257
+ });
5258
+ }
5167
5259
  } else if (pose && visibleVertexCount <= 1) {
5168
5260
  menuItems.push({
5169
5261
  label: "\u6DFB\u52A0\u7B2C\u4E00\u4E2A\u822A\u70B9",
@@ -5310,6 +5402,27 @@ var PathEditingEventHandler = class {
5310
5402
  });
5311
5403
  }
5312
5404
  }
5405
+ /**
5406
+ * 🆕 在选中航点和下一个航点中间插入新航点
5407
+ */
5408
+ handleInsertMidpoint(activeIndex) {
5409
+ const positions = this.callbacks.getPositions?.() || [];
5410
+ const poseData = this.callbacks.getPoseData?.();
5411
+ if (activeIndex >= positions.length - 1) {
5412
+ console.warn("[handleInsertMidpoint] \u9009\u4E2D\u822A\u70B9\u662F\u6700\u540E\u4E00\u4E2A\uFF0C\u65E0\u6CD5\u63D2\u5165\u4E2D\u70B9");
5413
+ return;
5414
+ }
5415
+ const point1 = positions[activeIndex];
5416
+ const point2 = positions[activeIndex + 1];
5417
+ const { midpoint } = calculateDistanceAndMidpoint(this.CesiumNS, point1, point2);
5418
+ const heading = calculateHeadingBetweenPoints(this.CesiumNS, point1, point2);
5419
+ const pitch = poseData?.pitches[activeIndex] ?? -10;
5420
+ const roll = poseData?.rolls[activeIndex] ?? 0;
5421
+ console.log("[handleInsertMidpoint] \u5728\u7D22\u5F15", activeIndex, "\u548C", activeIndex + 1, "\u4E4B\u95F4\u63D2\u5165\u4E2D\u70B9");
5422
+ if (this.callbacks.onInsertVertex) {
5423
+ this.callbacks.onInsertVertex(activeIndex + 1, midpoint, { heading, pitch, roll });
5424
+ }
5425
+ }
5313
5426
  /**
5314
5427
  * 处理删除顶点
5315
5428
  */
@@ -5758,23 +5871,37 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5758
5871
  while (useGlobalHeightFlags.length < positions.length) {
5759
5872
  useGlobalHeightFlags.push(false);
5760
5873
  }
5761
- let quickEditEnabled = false;
5874
+ const waypointIds = [];
5875
+ if (options?.waypointIds && Array.isArray(options.waypointIds)) {
5876
+ const offset = 0;
5877
+ for (let i = 0; i < offset; i++) {
5878
+ waypointIds[i] = void 0;
5879
+ }
5880
+ options.waypointIds.forEach((id, idx) => {
5881
+ waypointIds[offset + idx] = id;
5882
+ });
5883
+ }
5884
+ while (waypointIds.length < positions.length) {
5885
+ waypointIds.push(void 0);
5886
+ }
5887
+ let quickEditEnabled = true;
5762
5888
  let quickEditOptions = {
5763
- enabled: false,
5889
+ enabled: true,
5764
5890
  climbHeight: currentDefaultAltitude,
5765
5891
  // 使用当前默认高度
5766
5892
  altitudeMode: currentAltitudeMode
5767
5893
  // 使用当前高度模式
5768
5894
  };
5769
- if (options?.quickEdit) {
5895
+ if (options?.quickEdit !== void 0) {
5770
5896
  if (typeof options.quickEdit === "boolean") {
5771
5897
  quickEditEnabled = options.quickEdit;
5772
5898
  quickEditOptions.enabled = options.quickEdit;
5773
5899
  } else {
5774
- quickEditEnabled = options.quickEdit.enabled ?? false;
5900
+ quickEditEnabled = options.quickEdit.enabled ?? true;
5775
5901
  quickEditOptions = {
5776
5902
  ...quickEditOptions,
5777
- ...options.quickEdit
5903
+ ...options.quickEdit,
5904
+ enabled: options.quickEdit.enabled ?? true
5778
5905
  };
5779
5906
  }
5780
5907
  }
@@ -5869,6 +5996,8 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5869
5996
  const stateManager = new PathStateManager(entity, positions, headings, pitches, rolls, fovs);
5870
5997
  let activeIndex;
5871
5998
  let editedIndices = /* @__PURE__ */ new Set();
5999
+ let isUpdatingFromCursor = false;
6000
+ let isUpdatingFromDrag = false;
5872
6001
  const handleStyleManager = new VertexHandleStyleManager(CesiumNS);
5873
6002
  const setActiveIndex = (idx) => {
5874
6003
  if (activeIndex !== void 0 && handles[activeIndex]) {
@@ -5974,6 +6103,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5974
6103
  useGlobalHeightFlags
5975
6104
  // 🆕 传递 useGlobalHeightFlags
5976
6105
  );
6106
+ waypointIds.splice(actualIndex, 0, void 0);
5977
6107
  console.log("[PathEditing] \u63D2\u5165\u9876\u70B9\u540E positions \u957F\u5EA6:", positions.length, "actualIndex:", actualIndex);
5978
6108
  entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
5979
6109
  setActiveIndex(actualIndex);
@@ -6006,6 +6136,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6006
6136
  fovs.splice(deleteAt, 1);
6007
6137
  heightMarkers.splice(deleteAt, 1);
6008
6138
  useGlobalHeightFlags.splice(deleteAt, 1);
6139
+ waypointIds.splice(deleteAt, 1);
6009
6140
  console.log("[PathEditing] \u5220\u9664\u9876\u70B9\u540E positions \u957F\u5EA6:", positions.length);
6010
6141
  entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
6011
6142
  const newEditedIndices = /* @__PURE__ */ new Set();
@@ -6092,12 +6223,36 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6092
6223
  }
6093
6224
  airplaneCursor.updateOptions({
6094
6225
  onPose: (pose) => {
6226
+ if (isUpdatingFromDrag) return;
6095
6227
  try {
6096
6228
  if (preview) {
6097
6229
  preview.setPose(pose.position, pose.heading, pose.pitch, pose.roll, 50);
6098
6230
  }
6099
6231
  } catch {
6100
6232
  }
6233
+ if (activeIndex !== void 0 && !isUpdatingFromCursor) {
6234
+ isUpdatingFromCursor = true;
6235
+ try {
6236
+ positions[activeIndex] = pose.position;
6237
+ headings[activeIndex] = pose.heading;
6238
+ pitches[activeIndex] = pose.pitch;
6239
+ rolls[activeIndex] = pose.roll;
6240
+ if (handles[activeIndex]) {
6241
+ handles[activeIndex].position = pose.position;
6242
+ }
6243
+ vertexLabelManager.updateLabelPosition(activeIndex, pose.position);
6244
+ createOrUpdateMarkerForIndex(activeIndex);
6245
+ editedIndices.add(activeIndex);
6246
+ useGlobalHeightFlags[activeIndex] = false;
6247
+ try {
6248
+ entity.polyline.positions = positions.slice();
6249
+ } catch {
6250
+ }
6251
+ viewer.scene?.requestRender?.();
6252
+ } finally {
6253
+ isUpdatingFromCursor = false;
6254
+ }
6255
+ }
6101
6256
  }
6102
6257
  });
6103
6258
  }
@@ -6173,24 +6328,38 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6173
6328
  },
6174
6329
  onVertexDragMove: (index, newPosition) => {
6175
6330
  console.log("[PathEditing] onVertexDragMove \u88AB\u8C03\u7528, index:", index);
6176
- positions[index] = newPosition;
6177
- if (handles[index]) {
6331
+ if (isUpdatingFromCursor) return;
6332
+ isUpdatingFromDrag = true;
6333
+ try {
6334
+ positions[index] = newPosition;
6335
+ if (handles[index]) {
6336
+ try {
6337
+ handles[index].position = newPosition;
6338
+ } catch {
6339
+ }
6340
+ }
6178
6341
  try {
6179
- handles[index].position = newPosition;
6342
+ vertexLabelManager.updateLabelPosition(index, newPosition);
6180
6343
  } catch {
6181
6344
  }
6182
- }
6183
- try {
6184
- vertexLabelManager.updateLabelPosition(index, newPosition);
6185
- } catch {
6186
- }
6187
- try {
6188
- entity.polyline.positions = positions.slice();
6189
- } catch {
6190
- }
6191
- try {
6192
- viewer.scene.requestRender();
6193
- } catch {
6345
+ try {
6346
+ entity.polyline.positions = positions.slice();
6347
+ } catch {
6348
+ }
6349
+ try {
6350
+ viewer.scene.requestRender();
6351
+ } catch {
6352
+ }
6353
+ if (airplaneCursor && index === activeIndex) {
6354
+ airplaneCursor.setPose(
6355
+ newPosition,
6356
+ headings[index] ?? 0,
6357
+ pitches[index] ?? -10,
6358
+ rolls[index] ?? 0
6359
+ );
6360
+ }
6361
+ } finally {
6362
+ isUpdatingFromDrag = false;
6194
6363
  }
6195
6364
  if (options?.onVertexDragMoveDetail) {
6196
6365
  try {
@@ -6394,6 +6563,55 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6394
6563
  // 🆕 添加相对高度
6395
6564
  };
6396
6565
  };
6566
+ if (options?.initialClickPosition && positions.length === 0) {
6567
+ console.log("[PathEditing] \u5904\u7406\u521D\u59CB\u70B9\u51FB\u4F4D\u7F6E\uFF0C\u7ACB\u5373\u6DFB\u52A0\u7B2C\u4E00\u4E2A\u822A\u70B9");
6568
+ let finalPosition = options.initialClickPosition;
6569
+ try {
6570
+ const cartographic = C.Cartographic.fromCartesian(options.initialClickPosition);
6571
+ const lon = C.Math.toDegrees(cartographic.longitude);
6572
+ const lat = C.Math.toDegrees(cartographic.latitude);
6573
+ let finalHeight;
6574
+ if (currentAltitudeMode === "absolute") {
6575
+ finalHeight = currentDefaultAltitude;
6576
+ } else if (currentAltitudeMode === "relativeToGround") {
6577
+ const terrainHeight = queryTerrainHeightSync(CesiumNS, viewer, options.initialClickPosition);
6578
+ finalHeight = terrainHeight + currentDefaultAltitude;
6579
+ } else if (currentAltitudeMode === "relativeToStart") {
6580
+ finalHeight = currentDefaultAltitude;
6581
+ } else {
6582
+ finalHeight = currentDefaultAltitude;
6583
+ }
6584
+ finalPosition = C.Cartesian3.fromDegrees(lon, lat, finalHeight);
6585
+ console.log("[PathEditing] \u521D\u59CB\u822A\u70B9\u9AD8\u5EA6\u8BA1\u7B97:", {
6586
+ altitudeMode: currentAltitudeMode,
6587
+ defaultAltitude: currentDefaultAltitude,
6588
+ finalHeight
6589
+ });
6590
+ } catch (error) {
6591
+ console.warn("[PathEditing] \u8BA1\u7B97\u521D\u59CB\u822A\u70B9\u9AD8\u5EA6\u5931\u8D25:", error);
6592
+ }
6593
+ const totalBefore = positions.length;
6594
+ insertVertex(0, finalPosition, { heading: 0, pitch: -10, roll: 0 });
6595
+ if (options?.onVertexInsertDetail) {
6596
+ try {
6597
+ const totalAfter = positions.length;
6598
+ const newVertex = buildVertexDetailInfo(0);
6599
+ const operationInfo = {
6600
+ type: "insert",
6601
+ index: 0,
6602
+ displayNumber: newVertex.displayNumber,
6603
+ totalVerticesBefore: totalBefore,
6604
+ totalVerticesAfter: totalAfter,
6605
+ newVertex,
6606
+ timestamp: /* @__PURE__ */ new Date(),
6607
+ totalDistance: getTotalDistance()
6608
+ };
6609
+ options.onVertexInsertDetail(operationInfo);
6610
+ } catch (error) {
6611
+ console.error("[PathEditing] \u89E6\u53D1 onVertexInsertDetail \u56DE\u8C03\u5931\u8D25:", error);
6612
+ }
6613
+ }
6614
+ }
6397
6615
  return {
6398
6616
  /** 保存并退出编辑模式 */
6399
6617
  saveAndStop: () => {
@@ -6435,8 +6653,10 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6435
6653
  distance: calculatePathDistance(CesiumNS, positions, index),
6436
6654
  ellipsoidHeight,
6437
6655
  relativeHeight,
6438
- useGlobalHeight: useGlobalHeightFlags[index] ?? false
6656
+ useGlobalHeight: useGlobalHeightFlags[index] ?? false,
6439
6657
  // 🆕 添加 useGlobalHeight
6658
+ waypointId: waypointIds[index]
6659
+ // 🆕 添加 waypointId(原有航点保留ID,新插入航点为 undefined)
6440
6660
  };
6441
6661
  });
6442
6662
  cleanupSession();
@@ -6819,6 +7039,67 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
6819
7039
  options2?.onProgress?.("error");
6820
7040
  return { success: false, error: String(error) };
6821
7041
  }
7042
+ },
7043
+ /**
7044
+ * 🆕 获取当前选中航点索引
7045
+ * @returns 当前选中的航点索引,如果没有选中则返回 undefined
7046
+ */
7047
+ getActiveIndex: () => {
7048
+ return activeIndex;
7049
+ },
7050
+ /**
7051
+ * 🆕 在选中航点和下一个航点中间插入新航点
7052
+ * @param index 选中航点的索引(如果不传则使用当前选中的航点)
7053
+ * @returns 是否插入成功
7054
+ */
7055
+ insertMidpoint: (index) => {
7056
+ const targetIndex = index ?? activeIndex;
7057
+ if (targetIndex === void 0) {
7058
+ console.warn("[insertMidpoint] \u6CA1\u6709\u9009\u4E2D\u822A\u70B9");
7059
+ return false;
7060
+ }
7061
+ if (targetIndex >= positions.length - 1) {
7062
+ console.warn("[insertMidpoint] \u9009\u4E2D\u822A\u70B9\u662F\u6700\u540E\u4E00\u4E2A\uFF0C\u65E0\u6CD5\u63D2\u5165\u4E2D\u70B9");
7063
+ return false;
7064
+ }
7065
+ const point1 = positions[targetIndex];
7066
+ const point2 = positions[targetIndex + 1];
7067
+ const midpoint = C.Cartesian3.midpoint(point1, point2, new C.Cartesian3());
7068
+ const carto1 = C.Cartographic.fromCartesian(point1);
7069
+ const carto2 = C.Cartographic.fromCartesian(point2);
7070
+ const deltaLon = carto2.longitude - carto1.longitude;
7071
+ let heading = Math.atan2(
7072
+ Math.sin(deltaLon) * Math.cos(carto2.latitude),
7073
+ Math.cos(carto1.latitude) * Math.sin(carto2.latitude) - Math.sin(carto1.latitude) * Math.cos(carto2.latitude) * Math.cos(deltaLon)
7074
+ );
7075
+ heading = C.Math.toDegrees(heading);
7076
+ if (heading > 180) heading -= 360;
7077
+ if (heading < -180) heading += 360;
7078
+ const pitch = pitches[targetIndex] ?? -10;
7079
+ const roll = rolls[targetIndex] ?? 0;
7080
+ console.log("[insertMidpoint] \u5728\u7D22\u5F15", targetIndex, "\u548C", targetIndex + 1, "\u4E4B\u95F4\u63D2\u5165\u4E2D\u70B9");
7081
+ const totalBefore = positions.length;
7082
+ insertVertex(targetIndex + 1, midpoint, { heading, pitch, roll });
7083
+ if (options?.onVertexInsertDetail) {
7084
+ try {
7085
+ const totalAfter = positions.length;
7086
+ const newVertex = buildVertexDetailInfo(targetIndex + 1);
7087
+ const operationInfo = {
7088
+ type: "insert",
7089
+ index: targetIndex + 1,
7090
+ displayNumber: newVertex.displayNumber,
7091
+ totalVerticesBefore: totalBefore,
7092
+ totalVerticesAfter: totalAfter,
7093
+ newVertex,
7094
+ timestamp: /* @__PURE__ */ new Date(),
7095
+ totalDistance: getTotalDistance()
7096
+ };
7097
+ options.onVertexInsertDetail(operationInfo);
7098
+ } catch (error) {
7099
+ console.error("Error in onVertexInsertDetail:", error);
7100
+ }
7101
+ }
7102
+ return true;
6822
7103
  }
6823
7104
  };
6824
7105
  }
@@ -6900,8 +7181,8 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
6900
7181
  try {
6901
7182
  const auto = options?.autoStartEditing;
6902
7183
  const editOptions = {
6903
- // 默认使用自由编辑模式(快速编辑和自由编辑互斥)
6904
- quickEdit: false
7184
+ // 🔧 修复:默认使用快速编辑模式,用户点击地图即可添加航点
7185
+ quickEdit: true
6905
7186
  };
6906
7187
  if (typeof auto === "object" && auto.preview) {
6907
7188
  editOptions.preview = auto.preview;
@@ -6927,8 +7208,9 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
6927
7208
  editOptions.altitudeMode = altitudeMode;
6928
7209
  editOptions.defaultAltitude = defaultAltitude;
6929
7210
  editOptions.climbHeight = climbHeight;
7211
+ editOptions.initialClickPosition = picked;
6930
7212
  editSession = startPathEditing(CesiumNS, viewer, created, editOptions);
6931
- 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");
7213
+ 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");
6932
7214
  if (editSession && options?.onEditingStarted) {
6933
7215
  try {
6934
7216
  options.onEditingStarted(editSession);