@jorgmoritz/gis-manager 0.1.21 → 0.1.26

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.21"};
16
+ version: "0.1.25"};
17
17
 
18
18
  // src/utils/version.ts
19
19
  var version = package_default.version;
@@ -106,6 +106,8 @@ var CameraEventBus = class {
106
106
  __publicField(this, "onPoseChange", new Emitter());
107
107
  /** 视锥体形状变化事件 */
108
108
  __publicField(this, "onFrustumShapeChange", new Emitter());
109
+ /** 飞机游标姿态变化事件 */
110
+ __publicField(this, "onCursorPoseChange", new Emitter());
109
111
  }
110
112
  /**
111
113
  * 清理所有监听器
@@ -114,9 +116,20 @@ var CameraEventBus = class {
114
116
  this.onFOVChange.clear();
115
117
  this.onPoseChange.clear();
116
118
  this.onFrustumShapeChange.clear();
119
+ this.onCursorPoseChange.clear();
117
120
  }
118
121
  };
119
- var globalCameraEventBus = new CameraEventBus();
122
+ var GLOBAL_KEY = "__gisManager_globalCameraEventBus__";
123
+ function getGlobalEventBus() {
124
+ if (typeof window !== "undefined") {
125
+ if (!window[GLOBAL_KEY]) {
126
+ window[GLOBAL_KEY] = new CameraEventBus();
127
+ }
128
+ return window[GLOBAL_KEY];
129
+ }
130
+ return new CameraEventBus();
131
+ }
132
+ var globalCameraEventBus = getGlobalEventBus();
120
133
 
121
134
  // src/core/LayerManager.ts
122
135
  var layerIdSeq = 0;
@@ -1124,7 +1137,9 @@ var SceneManager = class {
1124
1137
  depth: true,
1125
1138
  stencil: true,
1126
1139
  antialias: true,
1127
- powerPreference: "high-performance"
1140
+ powerPreference: "high-performance",
1141
+ preserveDrawingBuffer: true
1142
+ // 必需:允许 canvas.toDataURL() 截图
1128
1143
  }
1129
1144
  },
1130
1145
  ...viewerOptions
@@ -1562,8 +1577,8 @@ var CameraFOVController = class {
1562
1577
  if (!this.sliderEl) return;
1563
1578
  const sliderValue = parseFloat(this.sliderEl.value);
1564
1579
  const sliderIndex = this.focalLengthPresets.length - 1 - sliderValue;
1565
- const zoomMultiplier = this.interpolateZoomMultiplier(sliderIndex);
1566
- const fov = this.zoomMultiplierToFOV(zoomMultiplier);
1580
+ const focalLength = this.interpolateFocalLength(sliderIndex);
1581
+ const fov = this.focalLengthToFOV(focalLength);
1567
1582
  this.currentFOV = fov;
1568
1583
  this.updateDisplay();
1569
1584
  this.emitChange();
@@ -1571,24 +1586,35 @@ var CameraFOVController = class {
1571
1586
  this.sensorWidth = opts.sensorWidth ?? 36;
1572
1587
  this.focalLengthPresets = opts.focalLengthPresets ?? [112, 56, 14, 7, 3, 1];
1573
1588
  if (opts.minFOV === void 0 || opts.maxFOV === void 0) {
1574
- const minZoom = Math.min(...this.focalLengthPresets);
1575
- const maxZoom = Math.max(...this.focalLengthPresets);
1576
- this.maxFOV = this.zoomMultiplierToFOVDirect(minZoom);
1577
- this.minFOV = this.zoomMultiplierToFOVDirect(maxZoom);
1589
+ const minFocalLength = Math.min(...this.focalLengthPresets);
1590
+ const maxFocalLength = Math.max(...this.focalLengthPresets);
1591
+ this.maxFOV = this.focalLengthToFOVDirect(minFocalLength);
1592
+ this.minFOV = this.focalLengthToFOVDirect(maxFocalLength);
1578
1593
  } else {
1579
1594
  this.minFOV = opts.minFOV;
1580
1595
  this.maxFOV = opts.maxFOV;
1581
1596
  }
1582
- this.currentFOV = opts.initialFOV ?? this.zoomMultiplierToFOVDirect(3);
1597
+ this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(56);
1583
1598
  this.useGlobalEventBus = opts.useGlobalEventBus ?? true;
1584
1599
  this.createUI();
1600
+ this.setupExternalFOVListener();
1585
1601
  }
1586
1602
  /**
1587
- * 变焦倍数转换为 FOV(度)- 直接计算版本
1603
+ * 🆕 监听外部 FOV 变化事件(来自 UI 面板等),同步更新滑块位置
1588
1604
  */
1589
- zoomMultiplierToFOVDirect(zoomMultiplier) {
1590
- const focalLength = zoomMultiplier * this.sensorWidth;
1591
- const fovRad = 2 * Math.atan(this.sensorWidth / (2 * focalLength));
1605
+ setupExternalFOVListener() {
1606
+ if (!this.useGlobalEventBus) return;
1607
+ globalCameraEventBus.onFOVChange.on((event) => {
1608
+ if (event.source !== "controller") {
1609
+ this.setFOVSilent(event.fov);
1610
+ }
1611
+ });
1612
+ }
1613
+ /**
1614
+ * 焦距转换为 FOV(度)- 直接计算版本
1615
+ */
1616
+ focalLengthToFOVDirect(focalLengthMm) {
1617
+ const fovRad = 2 * Math.atan(this.sensorWidth / (2 * focalLengthMm));
1592
1618
  return fovRad * 180 / Math.PI;
1593
1619
  }
1594
1620
  /**
@@ -1712,7 +1738,7 @@ var CameraFOVController = class {
1712
1738
  `;
1713
1739
  this.focalLengthPresets.forEach((fl) => {
1714
1740
  const marker = document.createElement("div");
1715
- marker.textContent = `${fl}x`;
1741
+ marker.textContent = `${fl}`;
1716
1742
  marker.style.cssText = `
1717
1743
  cursor: pointer;
1718
1744
  padding: 2px 4px;
@@ -1727,7 +1753,7 @@ var CameraFOVController = class {
1727
1753
  marker.style.background = "transparent";
1728
1754
  });
1729
1755
  marker.addEventListener("click", () => {
1730
- this.setZoomMultiplier(fl);
1756
+ this.setFocalLength(fl);
1731
1757
  });
1732
1758
  markersContainer.appendChild(marker);
1733
1759
  });
@@ -1740,38 +1766,38 @@ var CameraFOVController = class {
1740
1766
  this.emitChange();
1741
1767
  }
1742
1768
  /**
1743
- * 根据索引插值计算变焦倍数
1769
+ * 根据索引插值计算焦距值
1744
1770
  */
1745
- interpolateZoomMultiplier(index) {
1771
+ interpolateFocalLength(index) {
1746
1772
  const clampedIndex = Math.max(0, Math.min(this.focalLengthPresets.length - 1, index));
1747
1773
  if (Number.isInteger(clampedIndex)) {
1748
1774
  return this.focalLengthPresets[clampedIndex];
1749
1775
  }
1750
1776
  const lowerIndex = Math.floor(clampedIndex);
1751
1777
  const upperIndex = Math.ceil(clampedIndex);
1752
- const lowerZoom = this.focalLengthPresets[lowerIndex];
1753
- const upperZoom = this.focalLengthPresets[upperIndex];
1778
+ const lowerFL = this.focalLengthPresets[lowerIndex];
1779
+ const upperFL = this.focalLengthPresets[upperIndex];
1754
1780
  const fraction = clampedIndex - lowerIndex;
1755
- return lowerZoom + (upperZoom - lowerZoom) * fraction;
1781
+ return lowerFL + (upperFL - lowerFL) * fraction;
1756
1782
  }
1757
1783
  /**
1758
- * 根据变焦倍数计算对应的索引(可以是小数)
1784
+ * 根据焦距值计算对应的索引(可以是小数)
1759
1785
  */
1760
- getZoomMultiplierIndex(zoomMultiplier) {
1761
- const minZoom = Math.min(...this.focalLengthPresets);
1762
- const maxZoom = Math.max(...this.focalLengthPresets);
1763
- const clampedZoom = Math.max(minZoom, Math.min(maxZoom, zoomMultiplier));
1786
+ getFocalLengthIndex(focalLength) {
1787
+ const minFL = Math.min(...this.focalLengthPresets);
1788
+ const maxFL = Math.max(...this.focalLengthPresets);
1789
+ const clampedFL = Math.max(minFL, Math.min(maxFL, focalLength));
1764
1790
  for (let i = 0; i < this.focalLengthPresets.length - 1; i++) {
1765
1791
  const current = this.focalLengthPresets[i];
1766
1792
  const next = this.focalLengthPresets[i + 1];
1767
- if (current <= clampedZoom && clampedZoom <= next || current >= clampedZoom && clampedZoom >= next) {
1768
- const fraction = (clampedZoom - current) / (next - current);
1793
+ if (current <= clampedFL && clampedFL <= next || current >= clampedFL && clampedFL >= next) {
1794
+ const fraction = (clampedFL - current) / (next - current);
1769
1795
  return i + fraction;
1770
1796
  }
1771
1797
  }
1772
1798
  return this.focalLengthPresets.indexOf(
1773
1799
  this.focalLengthPresets.reduce(
1774
- (prev, curr) => Math.abs(curr - clampedZoom) < Math.abs(prev - clampedZoom) ? curr : prev
1800
+ (prev, curr) => Math.abs(curr - clampedFL) < Math.abs(prev - clampedFL) ? curr : prev
1775
1801
  )
1776
1802
  );
1777
1803
  }
@@ -1780,8 +1806,7 @@ var CameraFOVController = class {
1780
1806
  */
1781
1807
  getClosestPresetIndex(fov) {
1782
1808
  const focalLength = this.fovToFocalLength(fov);
1783
- const zoomMultiplier = focalLength / this.sensorWidth;
1784
- const index = this.getZoomMultiplierIndex(zoomMultiplier);
1809
+ const index = this.getFocalLengthIndex(focalLength);
1785
1810
  return this.focalLengthPresets.length - 1 - index;
1786
1811
  }
1787
1812
  /**
@@ -1789,9 +1814,8 @@ var CameraFOVController = class {
1789
1814
  */
1790
1815
  updateDisplay() {
1791
1816
  const focalLength = this.fovToFocalLength(this.currentFOV);
1792
- const zoomMultiplier = focalLength / this.sensorWidth;
1793
1817
  if (this.labelEl) {
1794
- this.labelEl.textContent = `\u53D8\u7126 ${zoomMultiplier.toFixed(1)}X`;
1818
+ this.labelEl.textContent = `\u7126\u8DDD ${Math.round(focalLength)}`;
1795
1819
  }
1796
1820
  }
1797
1821
  /**
@@ -1862,6 +1886,18 @@ var CameraFOVController = class {
1862
1886
  this.updateDisplay();
1863
1887
  this.emitChange();
1864
1888
  }
1889
+ /**
1890
+ * 🆕 静默设置 FOV(度)- 只更新滑块位置,不广播事件
1891
+ * 用于响应外部 FOV 变化事件,避免循环广播
1892
+ */
1893
+ setFOVSilent(fovDeg) {
1894
+ this.currentFOV = Math.max(this.minFOV, Math.min(this.maxFOV, fovDeg));
1895
+ if (this.sliderEl) {
1896
+ const index = this.getClosestPresetIndex(this.currentFOV);
1897
+ this.sliderEl.value = String(index);
1898
+ }
1899
+ this.updateDisplay();
1900
+ }
1865
1901
  /**
1866
1902
  * 获取当前 FOV
1867
1903
  */
@@ -2928,6 +2964,7 @@ var AirplaneCursor = class {
2928
2964
  this.opts?.onPose?.({ ...pose });
2929
2965
  this.viewer.scene?.requestRender?.();
2930
2966
  this.updateFrustum();
2967
+ this.broadcastPoseChange();
2931
2968
  }
2932
2969
  requestAnimationFrame(update);
2933
2970
  };
@@ -2985,9 +3022,15 @@ var AirplaneCursor = class {
2985
3022
  } catch {
2986
3023
  }
2987
3024
  }
2988
- /** 获取当前姿态(注意:返回的是引用对象,不要在外部直接修改其字段) */
3025
+ /** 获取当前姿态(包含高度信息) */
2989
3026
  getPose() {
2990
- return this.pose;
3027
+ const C = this.CesiumNS;
3028
+ const cartographic = C.Cartographic.fromCartesian(this.pose.position);
3029
+ const altitude = cartographic ? cartographic.height : 0;
3030
+ return {
3031
+ ...this.pose,
3032
+ altitude
3033
+ };
2991
3034
  }
2992
3035
  /** 获取内部实体(用于拾取识别) */
2993
3036
  getEntity() {
@@ -3047,8 +3090,58 @@ var AirplaneCursor = class {
3047
3090
  } catch {
3048
3091
  }
3049
3092
  this.updateFrustum();
3093
+ this.broadcastPoseChange();
3050
3094
  this.viewer.scene?.requestRender?.();
3051
3095
  }
3096
+ /**
3097
+ * 广播游标姿态变化事件到全局事件总线
3098
+ */
3099
+ broadcastPoseChange() {
3100
+ try {
3101
+ const C = this.CesiumNS;
3102
+ const cartographic = C.Cartographic.fromCartesian(this.pose.position);
3103
+ const altitude = cartographic ? cartographic.height : 0;
3104
+ console.log("[AirplaneCursor] \u{1F4E1} \u5E7F\u64AD\u59FF\u6001\u53D8\u5316:", {
3105
+ heading: this.pose.heading,
3106
+ pitch: this.pose.pitch,
3107
+ altitude
3108
+ });
3109
+ globalCameraEventBus.onCursorPoseChange.emit({
3110
+ position: this.pose.position,
3111
+ heading: this.pose.heading,
3112
+ pitch: this.pose.pitch,
3113
+ roll: this.pose.roll,
3114
+ altitude,
3115
+ source: "cursor"
3116
+ });
3117
+ } catch (e) {
3118
+ }
3119
+ }
3120
+ /**
3121
+ * 模拟按键按下(用于虚拟控制器)
3122
+ * @param key 按键名称 (w/a/s/d/q/e/c/z)
3123
+ * @param duration 按键持续时间(毫秒),默认 100ms
3124
+ */
3125
+ simulateKeyPress(key, duration = 100) {
3126
+ const lowerKey = key.toLowerCase();
3127
+ const keyMap = {
3128
+ "c": "c",
3129
+ // 上升
3130
+ "z": "z"
3131
+ // 下降
3132
+ };
3133
+ const mappedKey = keyMap[lowerKey] || lowerKey;
3134
+ console.log("[AirplaneCursor] \u{1F3AE} simulateKeyPress:", mappedKey, "duration:", duration);
3135
+ console.log("[AirplaneCursor] \u{1F3AE} updateLoopRunning:", this.updateLoopRunning);
3136
+ this.keysPressed.add(mappedKey);
3137
+ if (!this.updateLoopRunning) {
3138
+ console.log("[AirplaneCursor] \u{1F3AE} \u542F\u52A8 updateLoop");
3139
+ this.startUpdateLoop();
3140
+ }
3141
+ setTimeout(() => {
3142
+ this.keysPressed.delete(mappedKey);
3143
+ }, duration);
3144
+ }
3052
3145
  destroy() {
3053
3146
  if (this.destroyed) return;
3054
3147
  this.destroyed = true;
@@ -5111,6 +5204,31 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5111
5204
  vertexLabelManager.updateLabelPosition(index, newPosition);
5112
5205
  } catch {
5113
5206
  }
5207
+ if (options?.onVertexDragMoveDetail) {
5208
+ try {
5209
+ let coordinates = { longitude: 0, latitude: 0, height: 0 };
5210
+ try {
5211
+ const cartographic = C.Cartographic.fromCartesian(newPosition);
5212
+ coordinates = {
5213
+ longitude: C.Math.toDegrees(cartographic.longitude),
5214
+ latitude: C.Math.toDegrees(cartographic.latitude),
5215
+ height: cartographic.height
5216
+ };
5217
+ } catch {
5218
+ }
5219
+ const displayNumber = hiddenClimbIndex === 1 && index > 1 ? index - 1 : index;
5220
+ const dragMoveInfo = {
5221
+ index,
5222
+ displayNumber,
5223
+ position: newPosition,
5224
+ coordinates,
5225
+ timestamp: /* @__PURE__ */ new Date()
5226
+ };
5227
+ options.onVertexDragMoveDetail(dragMoveInfo);
5228
+ } catch (error) {
5229
+ console.error("Error in onVertexDragMoveDetail:", error);
5230
+ }
5231
+ }
5114
5232
  },
5115
5233
  onVertexDragEnd: (index, finalPosition) => {
5116
5234
  editedIndices.add(index);
@@ -5151,6 +5269,12 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5151
5269
  getAirplaneCursor: () => airplaneCursor,
5152
5270
  getPoseData: () => ({ headings, pitches, rolls, fovs }),
5153
5271
  getEntity: () => entity,
5272
+ /** 模拟按键控制飞机游标(用于虚拟控制器) */
5273
+ simulateKeyPress: (key, duration) => {
5274
+ airplaneCursor?.simulateKeyPress(key, duration);
5275
+ },
5276
+ /** 获取游标当前姿态(包含高度) */
5277
+ getCursorPose: () => airplaneCursor?.getPose(),
5154
5278
  // 🆕 快速编辑回调
5155
5279
  getQuickEditEnabled: () => quickEditEnabled,
5156
5280
  getQuickEditOptions: () => ({
@@ -5333,9 +5457,166 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5333
5457
  /** 🆕 检查快速编辑模式是否启用 */
5334
5458
  isQuickEditEnabled: () => {
5335
5459
  return quickEditEnabled;
5336
- }
5460
+ },
5461
+ // ========================
5462
+ // 🆕 程序化更新方法
5463
+ // ========================
5464
+ /**
5465
+ * 🆕 程序化更新指定航点
5466
+ * @param index 航点索引
5467
+ * @param updates 需要更新的字段
5468
+ * @returns 是否更新成功
5469
+ */
5470
+ updateWaypoint: (index, updates) => {
5471
+ if (index < 0 || index >= positions.length) {
5472
+ console.warn(`[updateWaypoint] Invalid index: ${index}, valid range: 0-${positions.length - 1}`);
5473
+ return false;
5474
+ }
5475
+ try {
5476
+ let positionUpdated = false;
5477
+ if (updates.position) {
5478
+ positions[index] = updates.position;
5479
+ positionUpdated = true;
5480
+ }
5481
+ if (updates.altitude !== void 0 && !updates.position) {
5482
+ const currentPos = positions[index];
5483
+ const cartographic = C.Cartographic.fromCartesian(currentPos);
5484
+ const newPos = C.Cartesian3.fromRadians(
5485
+ cartographic.longitude,
5486
+ cartographic.latitude,
5487
+ updates.altitude
5488
+ );
5489
+ positions[index] = newPos;
5490
+ positionUpdated = true;
5491
+ }
5492
+ if (positionUpdated) {
5493
+ const newPos = positions[index];
5494
+ if (handles[index]) {
5495
+ try {
5496
+ handles[index].position = newPos;
5497
+ } catch {
5498
+ }
5499
+ }
5500
+ try {
5501
+ vertexLabelManager.updateLabelPosition(index, newPos);
5502
+ } catch {
5503
+ }
5504
+ try {
5505
+ createOrUpdateMarkerForIndex(index);
5506
+ } catch {
5507
+ }
5508
+ }
5509
+ if (updates.heading !== void 0) headings[index] = updates.heading;
5510
+ if (updates.pitch !== void 0) pitches[index] = updates.pitch;
5511
+ if (updates.roll !== void 0) rolls[index] = updates.roll;
5512
+ if (updates.fov !== void 0) {
5513
+ fovs[index] = updates.fov;
5514
+ if (index === activeIndex) {
5515
+ globalCameraEventBus.onFOVChange.emit({
5516
+ fov: updates.fov,
5517
+ focalLength: fovToFocalLength(updates.fov),
5518
+ source: "user"
5519
+ });
5520
+ }
5521
+ }
5522
+ if (index === activeIndex && airplaneCursor) {
5523
+ try {
5524
+ airplaneCursor.setPose(
5525
+ positions[index],
5526
+ headings[index] ?? 0,
5527
+ pitches[index] ?? -10,
5528
+ rolls[index] ?? 0
5529
+ );
5530
+ } catch {
5531
+ }
5532
+ }
5533
+ stateManager.persistToEntity(positions, headings, pitches, rolls, fovs);
5534
+ return true;
5535
+ } catch (error) {
5536
+ console.error("[updateWaypoint] Error:", error);
5537
+ return false;
5538
+ }
5539
+ },
5540
+ /**
5541
+ * 🆕 更新航点位置
5542
+ */
5543
+ updateWaypointPosition: function(index, position) {
5544
+ return this.updateWaypoint(index, { position });
5545
+ },
5546
+ /**
5547
+ * 🆕 更新航点高度(仅垂直方向,保持经纬度不变)
5548
+ */
5549
+ updateWaypointAltitude: function(index, altitude) {
5550
+ return this.updateWaypoint(index, { altitude });
5551
+ },
5552
+ /**
5553
+ * 🆕 更新航点偏航角
5554
+ */
5555
+ updateWaypointHeading: function(index, heading) {
5556
+ return this.updateWaypoint(index, { heading });
5557
+ },
5558
+ /**
5559
+ * 🆕 更新航点俯仰角
5560
+ */
5561
+ updateWaypointPitch: function(index, pitch) {
5562
+ return this.updateWaypoint(index, { pitch });
5563
+ },
5564
+ /**
5565
+ * 🆕 更新航点视野角
5566
+ */
5567
+ updateWaypointFov: function(index, fov) {
5568
+ return this.updateWaypoint(index, { fov });
5569
+ },
5570
+ /**
5571
+ * 🆕 批量更新多个航点
5572
+ */
5573
+ batchUpdateWaypoints: function(updates) {
5574
+ let allSuccess = true;
5575
+ for (const { index, data } of updates) {
5576
+ if (!this.updateWaypoint(index, data)) {
5577
+ allSuccess = false;
5578
+ }
5579
+ }
5580
+ return allSuccess;
5581
+ },
5582
+ /**
5583
+ * 🆕 程序化选中指定航点
5584
+ * 将飞机游标移动到指定航点位置,更新选中状态
5585
+ * @param index 航点索引
5586
+ * @returns 是否选中成功
5587
+ */
5588
+ selectVertex: (index) => {
5589
+ if (index < 0 || index >= positions.length) {
5590
+ console.warn(`[selectVertex] Invalid index: ${index}, valid range: 0-${positions.length - 1}`);
5591
+ return false;
5592
+ }
5593
+ try {
5594
+ setActiveIndex(index);
5595
+ return true;
5596
+ } catch (e) {
5597
+ console.error("[selectVertex] Failed to select vertex:", e);
5598
+ return false;
5599
+ }
5600
+ },
5601
+ /**
5602
+ * 🆕 模拟按键控制飞机游标(用于虚拟控制器)
5603
+ * @param key 按键名称 (w/a/s/d/q/e/c/z)
5604
+ * @param duration 按键持续时间(毫秒)
5605
+ */
5606
+ simulateKeyPress: (key, duration) => {
5607
+ airplaneCursor?.simulateKeyPress(key, duration);
5608
+ },
5609
+ /**
5610
+ * 🆕 获取游标当前姿态(包含高度)
5611
+ */
5612
+ getCursorPose: () => airplaneCursor?.getPose()
5337
5613
  };
5338
5614
  }
5615
+ function fovToFocalLength(fovDeg) {
5616
+ const sensorWidth = 36;
5617
+ const fovRad = fovDeg * Math.PI / 180;
5618
+ return sensorWidth / (2 * Math.tan(fovRad / 2));
5619
+ }
5339
5620
 
5340
5621
  // src/core/path-manager/ArrowShape.ts
5341
5622
  var ArrowShape = class {
@@ -5732,7 +6013,6 @@ function parsePoseFromAction(action) {
5732
6013
  fov: parseFloat(numbers[3])
5733
6014
  };
5734
6015
  }
5735
- console.warn("[sinoflyAdapter] \u65E0\u6CD5\u89E3\u6790 action \u5B57\u6BB5:", action, error);
5736
6016
  return {};
5737
6017
  }
5738
6018
  }
@@ -5750,15 +6030,40 @@ function parseTakeOffRefPoint(takeOffRefPoint, takeOffSecurityHeight, CesiumNS)
5750
6030
  if (!takeOffRefPoint || typeof takeOffRefPoint !== "string" || takeOffRefPoint.trim() === "") {
5751
6031
  return null;
5752
6032
  }
6033
+ const C = CesiumNS;
6034
+ let longitude;
6035
+ let latitude;
6036
+ let height;
6037
+ const trimmed = takeOffRefPoint.trim();
6038
+ if (trimmed.includes(",")) {
6039
+ try {
6040
+ const parts = trimmed.split(",").map((p) => p.trim());
6041
+ if (parts.length >= 2) {
6042
+ latitude = parseFloat(parts[0]);
6043
+ longitude = parseFloat(parts[1]);
6044
+ height = parts.length >= 3 ? parseFloat(parts[2]) : takeOffSecurityHeight;
6045
+ if (isNaN(latitude) || isNaN(longitude) || isNaN(height)) {
6046
+ throw new Error("\u65E0\u6CD5\u89E3\u6790\u9017\u53F7\u5206\u9694\u7684\u5750\u6807\u503C");
6047
+ }
6048
+ const startPosition = C.Cartesian3.fromDegrees(longitude, latitude, height);
6049
+ const climbPosition = C.Cartesian3.fromDegrees(
6050
+ longitude,
6051
+ latitude,
6052
+ height + takeOffSecurityHeight
6053
+ );
6054
+ return {
6055
+ startPosition,
6056
+ climbPosition
6057
+ };
6058
+ }
6059
+ } catch (error) {
6060
+ }
6061
+ }
5753
6062
  try {
5754
6063
  const parsed = JSON.parse(takeOffRefPoint);
5755
6064
  if (typeof parsed !== "object" || parsed === null) {
5756
6065
  return null;
5757
6066
  }
5758
- const C = CesiumNS;
5759
- let longitude;
5760
- let latitude;
5761
- let height;
5762
6067
  if (typeof parsed.longitude === "number") {
5763
6068
  longitude = parsed.longitude;
5764
6069
  } else if (typeof parsed.lon === "number") {
@@ -5789,7 +6094,6 @@ function parseTakeOffRefPoint(takeOffRefPoint, takeOffSecurityHeight, CesiumNS)
5789
6094
  climbPosition
5790
6095
  };
5791
6096
  } catch (error) {
5792
- console.warn("[sinoflyAdapter] \u65E0\u6CD5\u89E3\u6790 takeOffRefPoint:", takeOffRefPoint, error);
5793
6097
  return null;
5794
6098
  }
5795
6099
  }
@@ -5811,16 +6115,10 @@ function convertSinoflyWayline(data, options) {
5811
6115
  if (!data.waypointInfo || !Array.isArray(data.waypointInfo)) {
5812
6116
  throw new Error("[sinoflyAdapter] waypointInfo \u5FC5\u987B\u662F\u6570\u7EC4");
5813
6117
  }
5814
- if (data.waypointInfo.length === 0) {
5815
- console.warn("[sinoflyAdapter] waypointInfo \u6570\u7EC4\u4E3A\u7A7A\uFF0C\u5C06\u8FD4\u56DE\u7A7A\u7684\u822A\u70B9\u6570\u636E");
5816
- }
6118
+ if (data.waypointInfo.length === 0) ;
5817
6119
  if (data.waylineId === void 0 || data.waylineId === null) {
5818
6120
  throw new Error("[sinoflyAdapter] waylineId \u4E0D\u80FD\u4E3A\u7A7A");
5819
6121
  }
5820
- console.log(`[sinoflyAdapter] \u5F00\u59CB\u8F6C\u6362\u822A\u7EBF ${data.waylineId}\uFF0C\u5305\u542B ${data.waypointInfo.length} \u4E2A\u822A\u70B9`);
5821
- if (data.takeOffRefPoint) {
5822
- console.log(`[sinoflyAdapter] \u68C0\u6D4B\u5230 takeOffRefPoint: ${data.takeOffRefPoint}`);
5823
- }
5824
6122
  const takeOffInfo = parseTakeOffRefPoint(
5825
6123
  data.takeOffRefPoint,
5826
6124
  data.takeOffSecurityHeight,
@@ -5885,7 +6183,6 @@ function convertSinoflyWayline(data, options) {
5885
6183
  if (poseFromAction.roll !== void 0) roll = poseFromAction.roll;
5886
6184
  if (poseFromAction.fov !== void 0) fov = poseFromAction.fov;
5887
6185
  } catch (actionError) {
5888
- console.warn(`[sinoflyAdapter] \u822A\u70B9 ${idx} action \u89E3\u6790\u5931\u8D25:`, actionError);
5889
6186
  }
5890
6187
  }
5891
6188
  return {
@@ -5898,7 +6195,6 @@ function convertSinoflyWayline(data, options) {
5898
6195
  // 重新分配 index,从 waypointStartIndex 开始
5899
6196
  };
5900
6197
  } catch (error) {
5901
- console.error(`[sinoflyAdapter] \u822A\u70B9 ${idx} \u8F6C\u6362\u5931\u8D25:`, error);
5902
6198
  throw new Error(`\u822A\u70B9 ${idx} \u8F6C\u6362\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
5903
6199
  }
5904
6200
  });
@@ -5906,7 +6202,6 @@ function convertSinoflyWayline(data, options) {
5906
6202
  if (!Array.isArray(waypointData)) {
5907
6203
  throw new Error("[sinoflyAdapter] waypointData \u4E0D\u662F\u6570\u7EC4");
5908
6204
  }
5909
- console.log(`[sinoflyAdapter] \u8F6C\u6362\u5B8C\u6210\uFF0C\u5171\u751F\u6210 ${waypointData.length} \u4E2A\u822A\u70B9`);
5910
6205
  const metadata = {
5911
6206
  waylineId: data.waylineId,
5912
6207
  waylineType: data.waylineType,