@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.
@@ -62,6 +62,8 @@ var CameraEventBus = class {
62
62
  __publicField(this, "onPoseChange", new Emitter());
63
63
  /** 视锥体形状变化事件 */
64
64
  __publicField(this, "onFrustumShapeChange", new Emitter());
65
+ /** 飞机游标姿态变化事件 */
66
+ __publicField(this, "onCursorPoseChange", new Emitter());
65
67
  }
66
68
  /**
67
69
  * 清理所有监听器
@@ -70,9 +72,20 @@ var CameraEventBus = class {
70
72
  this.onFOVChange.clear();
71
73
  this.onPoseChange.clear();
72
74
  this.onFrustumShapeChange.clear();
75
+ this.onCursorPoseChange.clear();
73
76
  }
74
77
  };
75
- var globalCameraEventBus = new CameraEventBus();
78
+ var GLOBAL_KEY = "__gisManager_globalCameraEventBus__";
79
+ function getGlobalEventBus() {
80
+ if (typeof window !== "undefined") {
81
+ if (!window[GLOBAL_KEY]) {
82
+ window[GLOBAL_KEY] = new CameraEventBus();
83
+ }
84
+ return window[GLOBAL_KEY];
85
+ }
86
+ return new CameraEventBus();
87
+ }
88
+ var globalCameraEventBus = getGlobalEventBus();
76
89
 
77
90
  // src/core/LayerManager.ts
78
91
  var layerIdSeq = 0;
@@ -1080,7 +1093,9 @@ var SceneManager = class {
1080
1093
  depth: true,
1081
1094
  stencil: true,
1082
1095
  antialias: true,
1083
- powerPreference: "high-performance"
1096
+ powerPreference: "high-performance",
1097
+ preserveDrawingBuffer: true
1098
+ // 必需:允许 canvas.toDataURL() 截图
1084
1099
  }
1085
1100
  },
1086
1101
  ...viewerOptions
@@ -1518,8 +1533,8 @@ var CameraFOVController = class {
1518
1533
  if (!this.sliderEl) return;
1519
1534
  const sliderValue = parseFloat(this.sliderEl.value);
1520
1535
  const sliderIndex = this.focalLengthPresets.length - 1 - sliderValue;
1521
- const zoomMultiplier = this.interpolateZoomMultiplier(sliderIndex);
1522
- const fov = this.zoomMultiplierToFOV(zoomMultiplier);
1536
+ const focalLength = this.interpolateFocalLength(sliderIndex);
1537
+ const fov = this.focalLengthToFOV(focalLength);
1523
1538
  this.currentFOV = fov;
1524
1539
  this.updateDisplay();
1525
1540
  this.emitChange();
@@ -1527,24 +1542,35 @@ var CameraFOVController = class {
1527
1542
  this.sensorWidth = opts.sensorWidth ?? 36;
1528
1543
  this.focalLengthPresets = opts.focalLengthPresets ?? [112, 56, 14, 7, 3, 1];
1529
1544
  if (opts.minFOV === void 0 || opts.maxFOV === void 0) {
1530
- const minZoom = Math.min(...this.focalLengthPresets);
1531
- const maxZoom = Math.max(...this.focalLengthPresets);
1532
- this.maxFOV = this.zoomMultiplierToFOVDirect(minZoom);
1533
- this.minFOV = this.zoomMultiplierToFOVDirect(maxZoom);
1545
+ const minFocalLength = Math.min(...this.focalLengthPresets);
1546
+ const maxFocalLength = Math.max(...this.focalLengthPresets);
1547
+ this.maxFOV = this.focalLengthToFOVDirect(minFocalLength);
1548
+ this.minFOV = this.focalLengthToFOVDirect(maxFocalLength);
1534
1549
  } else {
1535
1550
  this.minFOV = opts.minFOV;
1536
1551
  this.maxFOV = opts.maxFOV;
1537
1552
  }
1538
- this.currentFOV = opts.initialFOV ?? this.zoomMultiplierToFOVDirect(3);
1553
+ this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(56);
1539
1554
  this.useGlobalEventBus = opts.useGlobalEventBus ?? true;
1540
1555
  this.createUI();
1556
+ this.setupExternalFOVListener();
1541
1557
  }
1542
1558
  /**
1543
- * 变焦倍数转换为 FOV(度)- 直接计算版本
1559
+ * 🆕 监听外部 FOV 变化事件(来自 UI 面板等),同步更新滑块位置
1544
1560
  */
1545
- zoomMultiplierToFOVDirect(zoomMultiplier) {
1546
- const focalLength = zoomMultiplier * this.sensorWidth;
1547
- const fovRad = 2 * Math.atan(this.sensorWidth / (2 * focalLength));
1561
+ setupExternalFOVListener() {
1562
+ if (!this.useGlobalEventBus) return;
1563
+ globalCameraEventBus.onFOVChange.on((event) => {
1564
+ if (event.source !== "controller") {
1565
+ this.setFOVSilent(event.fov);
1566
+ }
1567
+ });
1568
+ }
1569
+ /**
1570
+ * 焦距转换为 FOV(度)- 直接计算版本
1571
+ */
1572
+ focalLengthToFOVDirect(focalLengthMm) {
1573
+ const fovRad = 2 * Math.atan(this.sensorWidth / (2 * focalLengthMm));
1548
1574
  return fovRad * 180 / Math.PI;
1549
1575
  }
1550
1576
  /**
@@ -1668,7 +1694,7 @@ var CameraFOVController = class {
1668
1694
  `;
1669
1695
  this.focalLengthPresets.forEach((fl) => {
1670
1696
  const marker = document.createElement("div");
1671
- marker.textContent = `${fl}x`;
1697
+ marker.textContent = `${fl}`;
1672
1698
  marker.style.cssText = `
1673
1699
  cursor: pointer;
1674
1700
  padding: 2px 4px;
@@ -1683,7 +1709,7 @@ var CameraFOVController = class {
1683
1709
  marker.style.background = "transparent";
1684
1710
  });
1685
1711
  marker.addEventListener("click", () => {
1686
- this.setZoomMultiplier(fl);
1712
+ this.setFocalLength(fl);
1687
1713
  });
1688
1714
  markersContainer.appendChild(marker);
1689
1715
  });
@@ -1696,38 +1722,38 @@ var CameraFOVController = class {
1696
1722
  this.emitChange();
1697
1723
  }
1698
1724
  /**
1699
- * 根据索引插值计算变焦倍数
1725
+ * 根据索引插值计算焦距值
1700
1726
  */
1701
- interpolateZoomMultiplier(index) {
1727
+ interpolateFocalLength(index) {
1702
1728
  const clampedIndex = Math.max(0, Math.min(this.focalLengthPresets.length - 1, index));
1703
1729
  if (Number.isInteger(clampedIndex)) {
1704
1730
  return this.focalLengthPresets[clampedIndex];
1705
1731
  }
1706
1732
  const lowerIndex = Math.floor(clampedIndex);
1707
1733
  const upperIndex = Math.ceil(clampedIndex);
1708
- const lowerZoom = this.focalLengthPresets[lowerIndex];
1709
- const upperZoom = this.focalLengthPresets[upperIndex];
1734
+ const lowerFL = this.focalLengthPresets[lowerIndex];
1735
+ const upperFL = this.focalLengthPresets[upperIndex];
1710
1736
  const fraction = clampedIndex - lowerIndex;
1711
- return lowerZoom + (upperZoom - lowerZoom) * fraction;
1737
+ return lowerFL + (upperFL - lowerFL) * fraction;
1712
1738
  }
1713
1739
  /**
1714
- * 根据变焦倍数计算对应的索引(可以是小数)
1740
+ * 根据焦距值计算对应的索引(可以是小数)
1715
1741
  */
1716
- getZoomMultiplierIndex(zoomMultiplier) {
1717
- const minZoom = Math.min(...this.focalLengthPresets);
1718
- const maxZoom = Math.max(...this.focalLengthPresets);
1719
- const clampedZoom = Math.max(minZoom, Math.min(maxZoom, zoomMultiplier));
1742
+ getFocalLengthIndex(focalLength) {
1743
+ const minFL = Math.min(...this.focalLengthPresets);
1744
+ const maxFL = Math.max(...this.focalLengthPresets);
1745
+ const clampedFL = Math.max(minFL, Math.min(maxFL, focalLength));
1720
1746
  for (let i = 0; i < this.focalLengthPresets.length - 1; i++) {
1721
1747
  const current = this.focalLengthPresets[i];
1722
1748
  const next = this.focalLengthPresets[i + 1];
1723
- if (current <= clampedZoom && clampedZoom <= next || current >= clampedZoom && clampedZoom >= next) {
1724
- const fraction = (clampedZoom - current) / (next - current);
1749
+ if (current <= clampedFL && clampedFL <= next || current >= clampedFL && clampedFL >= next) {
1750
+ const fraction = (clampedFL - current) / (next - current);
1725
1751
  return i + fraction;
1726
1752
  }
1727
1753
  }
1728
1754
  return this.focalLengthPresets.indexOf(
1729
1755
  this.focalLengthPresets.reduce(
1730
- (prev, curr) => Math.abs(curr - clampedZoom) < Math.abs(prev - clampedZoom) ? curr : prev
1756
+ (prev, curr) => Math.abs(curr - clampedFL) < Math.abs(prev - clampedFL) ? curr : prev
1731
1757
  )
1732
1758
  );
1733
1759
  }
@@ -1736,8 +1762,7 @@ var CameraFOVController = class {
1736
1762
  */
1737
1763
  getClosestPresetIndex(fov) {
1738
1764
  const focalLength = this.fovToFocalLength(fov);
1739
- const zoomMultiplier = focalLength / this.sensorWidth;
1740
- const index = this.getZoomMultiplierIndex(zoomMultiplier);
1765
+ const index = this.getFocalLengthIndex(focalLength);
1741
1766
  return this.focalLengthPresets.length - 1 - index;
1742
1767
  }
1743
1768
  /**
@@ -1745,9 +1770,8 @@ var CameraFOVController = class {
1745
1770
  */
1746
1771
  updateDisplay() {
1747
1772
  const focalLength = this.fovToFocalLength(this.currentFOV);
1748
- const zoomMultiplier = focalLength / this.sensorWidth;
1749
1773
  if (this.labelEl) {
1750
- this.labelEl.textContent = `\u53D8\u7126 ${zoomMultiplier.toFixed(1)}X`;
1774
+ this.labelEl.textContent = `\u7126\u8DDD ${Math.round(focalLength)}`;
1751
1775
  }
1752
1776
  }
1753
1777
  /**
@@ -1818,6 +1842,18 @@ var CameraFOVController = class {
1818
1842
  this.updateDisplay();
1819
1843
  this.emitChange();
1820
1844
  }
1845
+ /**
1846
+ * 🆕 静默设置 FOV(度)- 只更新滑块位置,不广播事件
1847
+ * 用于响应外部 FOV 变化事件,避免循环广播
1848
+ */
1849
+ setFOVSilent(fovDeg) {
1850
+ this.currentFOV = Math.max(this.minFOV, Math.min(this.maxFOV, fovDeg));
1851
+ if (this.sliderEl) {
1852
+ const index = this.getClosestPresetIndex(this.currentFOV);
1853
+ this.sliderEl.value = String(index);
1854
+ }
1855
+ this.updateDisplay();
1856
+ }
1821
1857
  /**
1822
1858
  * 获取当前 FOV
1823
1859
  */
@@ -2884,6 +2920,7 @@ var AirplaneCursor = class {
2884
2920
  this.opts?.onPose?.({ ...pose });
2885
2921
  this.viewer.scene?.requestRender?.();
2886
2922
  this.updateFrustum();
2923
+ this.broadcastPoseChange();
2887
2924
  }
2888
2925
  requestAnimationFrame(update);
2889
2926
  };
@@ -2941,9 +2978,15 @@ var AirplaneCursor = class {
2941
2978
  } catch {
2942
2979
  }
2943
2980
  }
2944
- /** 获取当前姿态(注意:返回的是引用对象,不要在外部直接修改其字段) */
2981
+ /** 获取当前姿态(包含高度信息) */
2945
2982
  getPose() {
2946
- return this.pose;
2983
+ const C = this.CesiumNS;
2984
+ const cartographic = C.Cartographic.fromCartesian(this.pose.position);
2985
+ const altitude = cartographic ? cartographic.height : 0;
2986
+ return {
2987
+ ...this.pose,
2988
+ altitude
2989
+ };
2947
2990
  }
2948
2991
  /** 获取内部实体(用于拾取识别) */
2949
2992
  getEntity() {
@@ -3003,8 +3046,58 @@ var AirplaneCursor = class {
3003
3046
  } catch {
3004
3047
  }
3005
3048
  this.updateFrustum();
3049
+ this.broadcastPoseChange();
3006
3050
  this.viewer.scene?.requestRender?.();
3007
3051
  }
3052
+ /**
3053
+ * 广播游标姿态变化事件到全局事件总线
3054
+ */
3055
+ broadcastPoseChange() {
3056
+ try {
3057
+ const C = this.CesiumNS;
3058
+ const cartographic = C.Cartographic.fromCartesian(this.pose.position);
3059
+ const altitude = cartographic ? cartographic.height : 0;
3060
+ console.log("[AirplaneCursor] \u{1F4E1} \u5E7F\u64AD\u59FF\u6001\u53D8\u5316:", {
3061
+ heading: this.pose.heading,
3062
+ pitch: this.pose.pitch,
3063
+ altitude
3064
+ });
3065
+ globalCameraEventBus.onCursorPoseChange.emit({
3066
+ position: this.pose.position,
3067
+ heading: this.pose.heading,
3068
+ pitch: this.pose.pitch,
3069
+ roll: this.pose.roll,
3070
+ altitude,
3071
+ source: "cursor"
3072
+ });
3073
+ } catch (e) {
3074
+ }
3075
+ }
3076
+ /**
3077
+ * 模拟按键按下(用于虚拟控制器)
3078
+ * @param key 按键名称 (w/a/s/d/q/e/c/z)
3079
+ * @param duration 按键持续时间(毫秒),默认 100ms
3080
+ */
3081
+ simulateKeyPress(key, duration = 100) {
3082
+ const lowerKey = key.toLowerCase();
3083
+ const keyMap = {
3084
+ "c": "c",
3085
+ // 上升
3086
+ "z": "z"
3087
+ // 下降
3088
+ };
3089
+ const mappedKey = keyMap[lowerKey] || lowerKey;
3090
+ console.log("[AirplaneCursor] \u{1F3AE} simulateKeyPress:", mappedKey, "duration:", duration);
3091
+ console.log("[AirplaneCursor] \u{1F3AE} updateLoopRunning:", this.updateLoopRunning);
3092
+ this.keysPressed.add(mappedKey);
3093
+ if (!this.updateLoopRunning) {
3094
+ console.log("[AirplaneCursor] \u{1F3AE} \u542F\u52A8 updateLoop");
3095
+ this.startUpdateLoop();
3096
+ }
3097
+ setTimeout(() => {
3098
+ this.keysPressed.delete(mappedKey);
3099
+ }, duration);
3100
+ }
3008
3101
  destroy() {
3009
3102
  if (this.destroyed) return;
3010
3103
  this.destroyed = true;
@@ -5067,6 +5160,31 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5067
5160
  vertexLabelManager.updateLabelPosition(index, newPosition);
5068
5161
  } catch {
5069
5162
  }
5163
+ if (options?.onVertexDragMoveDetail) {
5164
+ try {
5165
+ let coordinates = { longitude: 0, latitude: 0, height: 0 };
5166
+ try {
5167
+ const cartographic = C.Cartographic.fromCartesian(newPosition);
5168
+ coordinates = {
5169
+ longitude: C.Math.toDegrees(cartographic.longitude),
5170
+ latitude: C.Math.toDegrees(cartographic.latitude),
5171
+ height: cartographic.height
5172
+ };
5173
+ } catch {
5174
+ }
5175
+ const displayNumber = hiddenClimbIndex === 1 && index > 1 ? index - 1 : index;
5176
+ const dragMoveInfo = {
5177
+ index,
5178
+ displayNumber,
5179
+ position: newPosition,
5180
+ coordinates,
5181
+ timestamp: /* @__PURE__ */ new Date()
5182
+ };
5183
+ options.onVertexDragMoveDetail(dragMoveInfo);
5184
+ } catch (error) {
5185
+ console.error("Error in onVertexDragMoveDetail:", error);
5186
+ }
5187
+ }
5070
5188
  },
5071
5189
  onVertexDragEnd: (index, finalPosition) => {
5072
5190
  editedIndices.add(index);
@@ -5107,6 +5225,12 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5107
5225
  getAirplaneCursor: () => airplaneCursor,
5108
5226
  getPoseData: () => ({ headings, pitches, rolls, fovs }),
5109
5227
  getEntity: () => entity,
5228
+ /** 模拟按键控制飞机游标(用于虚拟控制器) */
5229
+ simulateKeyPress: (key, duration) => {
5230
+ airplaneCursor?.simulateKeyPress(key, duration);
5231
+ },
5232
+ /** 获取游标当前姿态(包含高度) */
5233
+ getCursorPose: () => airplaneCursor?.getPose(),
5110
5234
  // 🆕 快速编辑回调
5111
5235
  getQuickEditEnabled: () => quickEditEnabled,
5112
5236
  getQuickEditOptions: () => ({
@@ -5289,9 +5413,166 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5289
5413
  /** 🆕 检查快速编辑模式是否启用 */
5290
5414
  isQuickEditEnabled: () => {
5291
5415
  return quickEditEnabled;
5292
- }
5416
+ },
5417
+ // ========================
5418
+ // 🆕 程序化更新方法
5419
+ // ========================
5420
+ /**
5421
+ * 🆕 程序化更新指定航点
5422
+ * @param index 航点索引
5423
+ * @param updates 需要更新的字段
5424
+ * @returns 是否更新成功
5425
+ */
5426
+ updateWaypoint: (index, updates) => {
5427
+ if (index < 0 || index >= positions.length) {
5428
+ console.warn(`[updateWaypoint] Invalid index: ${index}, valid range: 0-${positions.length - 1}`);
5429
+ return false;
5430
+ }
5431
+ try {
5432
+ let positionUpdated = false;
5433
+ if (updates.position) {
5434
+ positions[index] = updates.position;
5435
+ positionUpdated = true;
5436
+ }
5437
+ if (updates.altitude !== void 0 && !updates.position) {
5438
+ const currentPos = positions[index];
5439
+ const cartographic = C.Cartographic.fromCartesian(currentPos);
5440
+ const newPos = C.Cartesian3.fromRadians(
5441
+ cartographic.longitude,
5442
+ cartographic.latitude,
5443
+ updates.altitude
5444
+ );
5445
+ positions[index] = newPos;
5446
+ positionUpdated = true;
5447
+ }
5448
+ if (positionUpdated) {
5449
+ const newPos = positions[index];
5450
+ if (handles[index]) {
5451
+ try {
5452
+ handles[index].position = newPos;
5453
+ } catch {
5454
+ }
5455
+ }
5456
+ try {
5457
+ vertexLabelManager.updateLabelPosition(index, newPos);
5458
+ } catch {
5459
+ }
5460
+ try {
5461
+ createOrUpdateMarkerForIndex(index);
5462
+ } catch {
5463
+ }
5464
+ }
5465
+ if (updates.heading !== void 0) headings[index] = updates.heading;
5466
+ if (updates.pitch !== void 0) pitches[index] = updates.pitch;
5467
+ if (updates.roll !== void 0) rolls[index] = updates.roll;
5468
+ if (updates.fov !== void 0) {
5469
+ fovs[index] = updates.fov;
5470
+ if (index === activeIndex) {
5471
+ globalCameraEventBus.onFOVChange.emit({
5472
+ fov: updates.fov,
5473
+ focalLength: fovToFocalLength(updates.fov),
5474
+ source: "user"
5475
+ });
5476
+ }
5477
+ }
5478
+ if (index === activeIndex && airplaneCursor) {
5479
+ try {
5480
+ airplaneCursor.setPose(
5481
+ positions[index],
5482
+ headings[index] ?? 0,
5483
+ pitches[index] ?? -10,
5484
+ rolls[index] ?? 0
5485
+ );
5486
+ } catch {
5487
+ }
5488
+ }
5489
+ stateManager.persistToEntity(positions, headings, pitches, rolls, fovs);
5490
+ return true;
5491
+ } catch (error) {
5492
+ console.error("[updateWaypoint] Error:", error);
5493
+ return false;
5494
+ }
5495
+ },
5496
+ /**
5497
+ * 🆕 更新航点位置
5498
+ */
5499
+ updateWaypointPosition: function(index, position) {
5500
+ return this.updateWaypoint(index, { position });
5501
+ },
5502
+ /**
5503
+ * 🆕 更新航点高度(仅垂直方向,保持经纬度不变)
5504
+ */
5505
+ updateWaypointAltitude: function(index, altitude) {
5506
+ return this.updateWaypoint(index, { altitude });
5507
+ },
5508
+ /**
5509
+ * 🆕 更新航点偏航角
5510
+ */
5511
+ updateWaypointHeading: function(index, heading) {
5512
+ return this.updateWaypoint(index, { heading });
5513
+ },
5514
+ /**
5515
+ * 🆕 更新航点俯仰角
5516
+ */
5517
+ updateWaypointPitch: function(index, pitch) {
5518
+ return this.updateWaypoint(index, { pitch });
5519
+ },
5520
+ /**
5521
+ * 🆕 更新航点视野角
5522
+ */
5523
+ updateWaypointFov: function(index, fov) {
5524
+ return this.updateWaypoint(index, { fov });
5525
+ },
5526
+ /**
5527
+ * 🆕 批量更新多个航点
5528
+ */
5529
+ batchUpdateWaypoints: function(updates) {
5530
+ let allSuccess = true;
5531
+ for (const { index, data } of updates) {
5532
+ if (!this.updateWaypoint(index, data)) {
5533
+ allSuccess = false;
5534
+ }
5535
+ }
5536
+ return allSuccess;
5537
+ },
5538
+ /**
5539
+ * 🆕 程序化选中指定航点
5540
+ * 将飞机游标移动到指定航点位置,更新选中状态
5541
+ * @param index 航点索引
5542
+ * @returns 是否选中成功
5543
+ */
5544
+ selectVertex: (index) => {
5545
+ if (index < 0 || index >= positions.length) {
5546
+ console.warn(`[selectVertex] Invalid index: ${index}, valid range: 0-${positions.length - 1}`);
5547
+ return false;
5548
+ }
5549
+ try {
5550
+ setActiveIndex(index);
5551
+ return true;
5552
+ } catch (e) {
5553
+ console.error("[selectVertex] Failed to select vertex:", e);
5554
+ return false;
5555
+ }
5556
+ },
5557
+ /**
5558
+ * 🆕 模拟按键控制飞机游标(用于虚拟控制器)
5559
+ * @param key 按键名称 (w/a/s/d/q/e/c/z)
5560
+ * @param duration 按键持续时间(毫秒)
5561
+ */
5562
+ simulateKeyPress: (key, duration) => {
5563
+ airplaneCursor?.simulateKeyPress(key, duration);
5564
+ },
5565
+ /**
5566
+ * 🆕 获取游标当前姿态(包含高度)
5567
+ */
5568
+ getCursorPose: () => airplaneCursor?.getPose()
5293
5569
  };
5294
5570
  }
5571
+ function fovToFocalLength(fovDeg) {
5572
+ const sensorWidth = 36;
5573
+ const fovRad = fovDeg * Math.PI / 180;
5574
+ return sensorWidth / (2 * Math.tan(fovRad / 2));
5575
+ }
5295
5576
 
5296
5577
  // src/core/path-manager/ArrowShape.ts
5297
5578
  var ArrowShape = class {
@@ -5688,7 +5969,6 @@ function parsePoseFromAction(action) {
5688
5969
  fov: parseFloat(numbers[3])
5689
5970
  };
5690
5971
  }
5691
- console.warn("[sinoflyAdapter] \u65E0\u6CD5\u89E3\u6790 action \u5B57\u6BB5:", action, error);
5692
5972
  return {};
5693
5973
  }
5694
5974
  }
@@ -5706,15 +5986,40 @@ function parseTakeOffRefPoint(takeOffRefPoint, takeOffSecurityHeight, CesiumNS)
5706
5986
  if (!takeOffRefPoint || typeof takeOffRefPoint !== "string" || takeOffRefPoint.trim() === "") {
5707
5987
  return null;
5708
5988
  }
5989
+ const C = CesiumNS;
5990
+ let longitude;
5991
+ let latitude;
5992
+ let height;
5993
+ const trimmed = takeOffRefPoint.trim();
5994
+ if (trimmed.includes(",")) {
5995
+ try {
5996
+ const parts = trimmed.split(",").map((p) => p.trim());
5997
+ if (parts.length >= 2) {
5998
+ latitude = parseFloat(parts[0]);
5999
+ longitude = parseFloat(parts[1]);
6000
+ height = parts.length >= 3 ? parseFloat(parts[2]) : takeOffSecurityHeight;
6001
+ if (isNaN(latitude) || isNaN(longitude) || isNaN(height)) {
6002
+ throw new Error("\u65E0\u6CD5\u89E3\u6790\u9017\u53F7\u5206\u9694\u7684\u5750\u6807\u503C");
6003
+ }
6004
+ const startPosition = C.Cartesian3.fromDegrees(longitude, latitude, height);
6005
+ const climbPosition = C.Cartesian3.fromDegrees(
6006
+ longitude,
6007
+ latitude,
6008
+ height + takeOffSecurityHeight
6009
+ );
6010
+ return {
6011
+ startPosition,
6012
+ climbPosition
6013
+ };
6014
+ }
6015
+ } catch (error) {
6016
+ }
6017
+ }
5709
6018
  try {
5710
6019
  const parsed = JSON.parse(takeOffRefPoint);
5711
6020
  if (typeof parsed !== "object" || parsed === null) {
5712
6021
  return null;
5713
6022
  }
5714
- const C = CesiumNS;
5715
- let longitude;
5716
- let latitude;
5717
- let height;
5718
6023
  if (typeof parsed.longitude === "number") {
5719
6024
  longitude = parsed.longitude;
5720
6025
  } else if (typeof parsed.lon === "number") {
@@ -5745,7 +6050,6 @@ function parseTakeOffRefPoint(takeOffRefPoint, takeOffSecurityHeight, CesiumNS)
5745
6050
  climbPosition
5746
6051
  };
5747
6052
  } catch (error) {
5748
- console.warn("[sinoflyAdapter] \u65E0\u6CD5\u89E3\u6790 takeOffRefPoint:", takeOffRefPoint, error);
5749
6053
  return null;
5750
6054
  }
5751
6055
  }
@@ -5767,16 +6071,10 @@ function convertSinoflyWayline(data, options) {
5767
6071
  if (!data.waypointInfo || !Array.isArray(data.waypointInfo)) {
5768
6072
  throw new Error("[sinoflyAdapter] waypointInfo \u5FC5\u987B\u662F\u6570\u7EC4");
5769
6073
  }
5770
- if (data.waypointInfo.length === 0) {
5771
- console.warn("[sinoflyAdapter] waypointInfo \u6570\u7EC4\u4E3A\u7A7A\uFF0C\u5C06\u8FD4\u56DE\u7A7A\u7684\u822A\u70B9\u6570\u636E");
5772
- }
6074
+ if (data.waypointInfo.length === 0) ;
5773
6075
  if (data.waylineId === void 0 || data.waylineId === null) {
5774
6076
  throw new Error("[sinoflyAdapter] waylineId \u4E0D\u80FD\u4E3A\u7A7A");
5775
6077
  }
5776
- console.log(`[sinoflyAdapter] \u5F00\u59CB\u8F6C\u6362\u822A\u7EBF ${data.waylineId}\uFF0C\u5305\u542B ${data.waypointInfo.length} \u4E2A\u822A\u70B9`);
5777
- if (data.takeOffRefPoint) {
5778
- console.log(`[sinoflyAdapter] \u68C0\u6D4B\u5230 takeOffRefPoint: ${data.takeOffRefPoint}`);
5779
- }
5780
6078
  const takeOffInfo = parseTakeOffRefPoint(
5781
6079
  data.takeOffRefPoint,
5782
6080
  data.takeOffSecurityHeight,
@@ -5841,7 +6139,6 @@ function convertSinoflyWayline(data, options) {
5841
6139
  if (poseFromAction.roll !== void 0) roll = poseFromAction.roll;
5842
6140
  if (poseFromAction.fov !== void 0) fov = poseFromAction.fov;
5843
6141
  } catch (actionError) {
5844
- console.warn(`[sinoflyAdapter] \u822A\u70B9 ${idx} action \u89E3\u6790\u5931\u8D25:`, actionError);
5845
6142
  }
5846
6143
  }
5847
6144
  return {
@@ -5854,7 +6151,6 @@ function convertSinoflyWayline(data, options) {
5854
6151
  // 重新分配 index,从 waypointStartIndex 开始
5855
6152
  };
5856
6153
  } catch (error) {
5857
- console.error(`[sinoflyAdapter] \u822A\u70B9 ${idx} \u8F6C\u6362\u5931\u8D25:`, error);
5858
6154
  throw new Error(`\u822A\u70B9 ${idx} \u8F6C\u6362\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
5859
6155
  }
5860
6156
  });
@@ -5862,7 +6158,6 @@ function convertSinoflyWayline(data, options) {
5862
6158
  if (!Array.isArray(waypointData)) {
5863
6159
  throw new Error("[sinoflyAdapter] waypointData \u4E0D\u662F\u6570\u7EC4");
5864
6160
  }
5865
- console.log(`[sinoflyAdapter] \u8F6C\u6362\u5B8C\u6210\uFF0C\u5171\u751F\u6210 ${waypointData.length} \u4E2A\u822A\u70B9`);
5866
6161
  const metadata = {
5867
6162
  waylineId: data.waylineId,
5868
6163
  waylineType: data.waylineType,