@jorgmoritz/gis-manager 0.1.43 → 0.1.45

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