@jorgmoritz/gis-manager 0.1.36 → 0.1.37
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/{VertexDetailInfo-Cz9y16HG.d.cts → VertexDetailInfo-DYr1P_fe.d.cts} +7 -3
- package/dist/{VertexDetailInfo-Cz9y16HG.d.ts → VertexDetailInfo-DYr1P_fe.d.ts} +7 -3
- package/dist/index.cjs +1083 -716
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +323 -34
- package/dist/index.d.ts +323 -34
- package/dist/index.js +1077 -717
- package/dist/index.js.map +1 -1
- package/dist/vue/index.cjs +824 -670
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.d.cts +1 -1
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.js +824 -670
- package/dist/vue/index.js.map +1 -1
- package/package.json +1 -1
package/dist/vue/index.js
CHANGED
|
@@ -2587,7 +2587,7 @@ var FrustumPyramid = class {
|
|
|
2587
2587
|
showAt(apex, headingDeg, pitchDeg = 0, rollDeg = 0, fovDeg, lengthOverride) {
|
|
2588
2588
|
if (this.destroyed) return;
|
|
2589
2589
|
const C = this.CesiumNS;
|
|
2590
|
-
const length = Math.max(1, lengthOverride ?? this.opts.length ??
|
|
2590
|
+
const length = Math.max(1, lengthOverride ?? this.opts.length ?? 500);
|
|
2591
2591
|
const lakeEdge = this.opts.color ?? C.Color.fromCssColorString("#1e90ff");
|
|
2592
2592
|
const alpha = this.opts.fillAlpha ?? 0.25;
|
|
2593
2593
|
const lakeFill = (this.opts.fillColor ?? C.Color.fromCssColorString("#1e90ff")).withAlpha(alpha);
|
|
@@ -2770,8 +2770,6 @@ var AirplaneCursor = class {
|
|
|
2770
2770
|
__publicField(this, "angleStep");
|
|
2771
2771
|
/** 加速倍率(按住 Shift 生效) */
|
|
2772
2772
|
__publicField(this, "fastFactor");
|
|
2773
|
-
/** 最小高度(米) */
|
|
2774
|
-
__publicField(this, "minHeight");
|
|
2775
2773
|
/** 外部传入的行为配置与回调 */
|
|
2776
2774
|
__publicField(this, "opts");
|
|
2777
2775
|
// 使用内联的 _FrustumPyramid
|
|
@@ -2799,7 +2797,6 @@ var AirplaneCursor = class {
|
|
|
2799
2797
|
this.step = opts.stepMeters ?? 2;
|
|
2800
2798
|
this.angleStep = opts.angleStepDeg ?? 1;
|
|
2801
2799
|
this.fastFactor = opts.fastFactor ?? 5;
|
|
2802
|
-
this.minHeight = opts.minHeight ?? 0;
|
|
2803
2800
|
this.currentFOV = opts.fovDeg ?? 50;
|
|
2804
2801
|
this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
|
|
2805
2802
|
this.attachKeyboard(opts);
|
|
@@ -3024,11 +3021,8 @@ var AirplaneCursor = class {
|
|
|
3024
3021
|
}
|
|
3025
3022
|
if (this.keysPressed.has("z")) {
|
|
3026
3023
|
const newPos = addVec(pose.position, C.Cartesian3.multiplyByScalar(u3, -step, new C.Cartesian3()));
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
setPos(newPos);
|
|
3030
|
-
moved = true;
|
|
3031
|
-
}
|
|
3024
|
+
setPos(newPos);
|
|
3025
|
+
moved = true;
|
|
3032
3026
|
}
|
|
3033
3027
|
if (this.keysPressed.has("q")) {
|
|
3034
3028
|
pose.heading = clampDeg(pose.heading - ang);
|
|
@@ -3081,8 +3075,8 @@ var AirplaneCursor = class {
|
|
|
3081
3075
|
this.viewer.dataSources.add(layer);
|
|
3082
3076
|
}
|
|
3083
3077
|
this.frustum = new FrustumPyramid(this.CesiumNS, layer, {
|
|
3084
|
-
fov: this.opts.fovDeg ??
|
|
3085
|
-
length:
|
|
3078
|
+
fov: this.opts.fovDeg ?? 40,
|
|
3079
|
+
length: 80,
|
|
3086
3080
|
color: this.opts.color,
|
|
3087
3081
|
fillAlpha: 0.25,
|
|
3088
3082
|
width: 2,
|
|
@@ -3090,14 +3084,17 @@ var AirplaneCursor = class {
|
|
|
3090
3084
|
logAngles: false,
|
|
3091
3085
|
logThrottleMs: 300
|
|
3092
3086
|
});
|
|
3087
|
+
const frustumFovScale = 0.6;
|
|
3088
|
+
const frustumLengthScale = 0.1;
|
|
3093
3089
|
this.frustum.showAtDynamic(
|
|
3094
3090
|
() => this.pose.position,
|
|
3095
3091
|
() => this.pose.heading,
|
|
3096
3092
|
() => this.pose.pitch,
|
|
3097
3093
|
() => this.pose.roll,
|
|
3098
|
-
() => this.currentFOV,
|
|
3099
|
-
//
|
|
3100
|
-
() => 1e3
|
|
3094
|
+
() => this.currentFOV * frustumFovScale,
|
|
3095
|
+
// 缩小 FOV
|
|
3096
|
+
() => 1e3 * frustumLengthScale
|
|
3097
|
+
// 缩小深度(1000 -> 100)
|
|
3101
3098
|
);
|
|
3102
3099
|
try {
|
|
3103
3100
|
this.heightMarker = new HeightMarker(this.CesiumNS, this.viewer, layer);
|
|
@@ -3613,7 +3610,7 @@ function calculatePathDistance(CesiumNS, positions, targetIndex, hiddenClimbInde
|
|
|
3613
3610
|
if (targetIndex < 0 || targetIndex >= positions.length) return 0;
|
|
3614
3611
|
const C = CesiumNS;
|
|
3615
3612
|
let totalDistance = 0;
|
|
3616
|
-
const startIndex =
|
|
3613
|
+
const startIndex = 1;
|
|
3617
3614
|
if (targetIndex <= startIndex) return 0;
|
|
3618
3615
|
for (let i = startIndex; i <= targetIndex; i++) {
|
|
3619
3616
|
try {
|
|
@@ -3656,9 +3653,11 @@ var VertexInsertionHandler = class {
|
|
|
3656
3653
|
* @param heightMarkers 高度标记数组(引用)
|
|
3657
3654
|
* @param airplaneCursor 飞机游标(可选)
|
|
3658
3655
|
* @param poseOrient 顶点姿态(可选)
|
|
3656
|
+
* @param useGlobalHeightFlags 🆕 是否使用全局高度标志数组(引用,可选)
|
|
3657
|
+
* @param altitudeModeOptions 🆕 高度模式选项(可选)
|
|
3659
3658
|
* @returns 实际插入的索引
|
|
3660
3659
|
*/
|
|
3661
|
-
insertVertex(insertAt, position, positions, handles, headings, pitches, rolls, fovs, editedIndices, vertexLabelManager, heightMarkers, airplaneCursor, poseOrient) {
|
|
3660
|
+
insertVertex(insertAt, position, positions, handles, headings, pitches, rolls, fovs, editedIndices, vertexLabelManager, heightMarkers, airplaneCursor, poseOrient, useGlobalHeightFlags) {
|
|
3662
3661
|
const C = this.CesiumNS;
|
|
3663
3662
|
if (this.hiddenClimbIndex === 1 && insertAt <= 1) {
|
|
3664
3663
|
insertAt = 2;
|
|
@@ -3693,6 +3692,12 @@ var VertexInsertionHandler = class {
|
|
|
3693
3692
|
pitches.splice(insertAt, 0, pose.pitch);
|
|
3694
3693
|
rolls.splice(insertAt, 0, pose.roll);
|
|
3695
3694
|
fovs.splice(insertAt, 0, 50);
|
|
3695
|
+
if (useGlobalHeightFlags) {
|
|
3696
|
+
for (let i = useGlobalHeightFlags.length - 1; i >= insertAt; i--) {
|
|
3697
|
+
useGlobalHeightFlags[i + 1] = useGlobalHeightFlags[i];
|
|
3698
|
+
}
|
|
3699
|
+
useGlobalHeightFlags[insertAt] = true;
|
|
3700
|
+
}
|
|
3696
3701
|
return insertAt;
|
|
3697
3702
|
}
|
|
3698
3703
|
/**
|
|
@@ -3901,7 +3906,6 @@ var VertexDragHandler = class {
|
|
|
3901
3906
|
__publicField(this, "CesiumNS");
|
|
3902
3907
|
__publicField(this, "viewer");
|
|
3903
3908
|
__publicField(this, "hiddenClimbIndex");
|
|
3904
|
-
__publicField(this, "minHeight");
|
|
3905
3909
|
__publicField(this, "callbacks");
|
|
3906
3910
|
__publicField(this, "dragState", null);
|
|
3907
3911
|
__publicField(this, "canvas");
|
|
@@ -3910,7 +3914,6 @@ var VertexDragHandler = class {
|
|
|
3910
3914
|
this.CesiumNS = options.CesiumNS;
|
|
3911
3915
|
this.viewer = options.viewer;
|
|
3912
3916
|
this.hiddenClimbIndex = options.hiddenClimbIndex;
|
|
3913
|
-
this.minHeight = options.minHeight ?? 0;
|
|
3914
3917
|
this.callbacks = callbacks;
|
|
3915
3918
|
this.canvas = this.viewer.scene.canvas;
|
|
3916
3919
|
this.setupKeyboardListeners();
|
|
@@ -4086,7 +4089,7 @@ var VertexDragHandler = class {
|
|
|
4086
4089
|
const cameraHeight = this.viewer.camera.positionCartographic.height;
|
|
4087
4090
|
const scaleFactor = Math.max(cameraHeight / 1e3, 0.5);
|
|
4088
4091
|
const heightDelta = -deltaY * scaleFactor;
|
|
4089
|
-
const newHeight =
|
|
4092
|
+
const newHeight = this.dragState.startHeight + heightDelta;
|
|
4090
4093
|
const newPosition = C.Cartesian3.fromDegrees(
|
|
4091
4094
|
this.dragState.startLonLat.lon,
|
|
4092
4095
|
this.dragState.startLonLat.lat,
|
|
@@ -4171,6 +4174,79 @@ var VertexDragHandler = class {
|
|
|
4171
4174
|
}
|
|
4172
4175
|
};
|
|
4173
4176
|
|
|
4177
|
+
// src/core/path-manager/utils/TerrainHeightQuery.ts
|
|
4178
|
+
async function queryTerrainHeights(CesiumNS, viewer, positions) {
|
|
4179
|
+
const C = CesiumNS;
|
|
4180
|
+
if (!positions || positions.length === 0) {
|
|
4181
|
+
return [];
|
|
4182
|
+
}
|
|
4183
|
+
const cartographics = positions.map((pos) => {
|
|
4184
|
+
try {
|
|
4185
|
+
return C.Cartographic.fromCartesian(pos);
|
|
4186
|
+
} catch {
|
|
4187
|
+
return new C.Cartographic(0, 0, 0);
|
|
4188
|
+
}
|
|
4189
|
+
});
|
|
4190
|
+
const terrainProvider = viewer.terrainProvider;
|
|
4191
|
+
if (!terrainProvider || !C.sampleTerrainMostDetailed) {
|
|
4192
|
+
console.warn("[TerrainHeightQuery] \u65E0\u53EF\u7528\u5730\u5F62\u63D0\u4F9B\u8005\uFF0C\u4F7F\u7528\u540C\u6B65\u56DE\u9000\u65B9\u6848");
|
|
4193
|
+
return positions.map((pos) => queryTerrainHeightSync(CesiumNS, viewer, pos));
|
|
4194
|
+
}
|
|
4195
|
+
try {
|
|
4196
|
+
const sampledPositions = await C.sampleTerrainMostDetailed(
|
|
4197
|
+
terrainProvider,
|
|
4198
|
+
cartographics
|
|
4199
|
+
);
|
|
4200
|
+
return sampledPositions.map((carto) => {
|
|
4201
|
+
const height = carto?.height;
|
|
4202
|
+
return typeof height === "number" && !isNaN(height) ? height : 0;
|
|
4203
|
+
});
|
|
4204
|
+
} catch (error) {
|
|
4205
|
+
console.warn("[TerrainHeightQuery] \u5F02\u6B65\u67E5\u8BE2\u5931\u8D25\uFF0C\u4F7F\u7528\u540C\u6B65\u56DE\u9000:", error);
|
|
4206
|
+
return positions.map((pos) => queryTerrainHeightSync(CesiumNS, viewer, pos));
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
function queryTerrainHeightSync(CesiumNS, viewer, position) {
|
|
4210
|
+
const C = CesiumNS;
|
|
4211
|
+
try {
|
|
4212
|
+
const cartographic = C.Cartographic.fromCartesian(position);
|
|
4213
|
+
const globe = viewer.scene.globe;
|
|
4214
|
+
if (globe && typeof globe.getHeight === "function") {
|
|
4215
|
+
const height = globe.getHeight(cartographic);
|
|
4216
|
+
if (typeof height === "number" && !isNaN(height)) {
|
|
4217
|
+
return height;
|
|
4218
|
+
}
|
|
4219
|
+
}
|
|
4220
|
+
} catch (error) {
|
|
4221
|
+
console.warn("[TerrainHeightQuery] \u540C\u6B65\u67E5\u8BE2\u5931\u8D25:", error);
|
|
4222
|
+
}
|
|
4223
|
+
return 0;
|
|
4224
|
+
}
|
|
4225
|
+
function calculateAbsoluteHeight(altitudeMode, defaultAltitude, startPointAltitude, terrainHeight) {
|
|
4226
|
+
switch (altitudeMode) {
|
|
4227
|
+
case "absolute":
|
|
4228
|
+
return defaultAltitude;
|
|
4229
|
+
case "relativeToStart":
|
|
4230
|
+
return startPointAltitude + defaultAltitude;
|
|
4231
|
+
case "relativeToGround":
|
|
4232
|
+
return terrainHeight + defaultAltitude;
|
|
4233
|
+
default:
|
|
4234
|
+
return defaultAltitude;
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
function calculateRelativeHeight(altitudeMode, absoluteHeight, startPointAltitude, terrainHeight) {
|
|
4238
|
+
switch (altitudeMode) {
|
|
4239
|
+
case "absolute":
|
|
4240
|
+
return absoluteHeight;
|
|
4241
|
+
case "relativeToStart":
|
|
4242
|
+
return absoluteHeight - startPointAltitude;
|
|
4243
|
+
case "relativeToGround":
|
|
4244
|
+
return absoluteHeight - terrainHeight;
|
|
4245
|
+
default:
|
|
4246
|
+
return absoluteHeight;
|
|
4247
|
+
}
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4174
4250
|
// src/core/path-manager/editing/PathEditingEventHandler.ts
|
|
4175
4251
|
var PathEditingEventHandler = class {
|
|
4176
4252
|
constructor(options, callbacks) {
|
|
@@ -4193,8 +4269,7 @@ var PathEditingEventHandler = class {
|
|
|
4193
4269
|
{
|
|
4194
4270
|
CesiumNS: this.CesiumNS,
|
|
4195
4271
|
viewer: this.viewer,
|
|
4196
|
-
hiddenClimbIndex: this.hiddenClimbIndex
|
|
4197
|
-
minHeight: options.minHeight
|
|
4272
|
+
hiddenClimbIndex: this.hiddenClimbIndex
|
|
4198
4273
|
},
|
|
4199
4274
|
{
|
|
4200
4275
|
onDragStart: (index) => {
|
|
@@ -4429,23 +4504,14 @@ var PathEditingEventHandler = class {
|
|
|
4429
4504
|
buildVertexContextMenuItems(vertexIndex) {
|
|
4430
4505
|
const menuItems = [];
|
|
4431
4506
|
const positions = this.callbacks.getPositions?.() || [];
|
|
4432
|
-
const
|
|
4433
|
-
|
|
4434
|
-
const isStartPoint = vertexIndex === 0 || this.hiddenClimbIndex === 1 && vertexIndex === 1;
|
|
4435
|
-
if (canDelete && !isStartPoint) {
|
|
4507
|
+
const canDelete = positions.length > 1;
|
|
4508
|
+
if (canDelete) {
|
|
4436
4509
|
menuItems.push({
|
|
4437
4510
|
label: `\u5220\u9664\u822A\u70B9 ${this.getVertexDisplayNumber(vertexIndex)}`,
|
|
4438
4511
|
action: () => {
|
|
4439
4512
|
this.handleDeleteVertex(vertexIndex);
|
|
4440
4513
|
}
|
|
4441
4514
|
});
|
|
4442
|
-
} else if (isStartPoint) {
|
|
4443
|
-
menuItems.push({
|
|
4444
|
-
label: "\u8D77\u70B9\u4E0D\u53EF\u5220\u9664",
|
|
4445
|
-
action: () => {
|
|
4446
|
-
},
|
|
4447
|
-
disabled: true
|
|
4448
|
-
});
|
|
4449
4515
|
} else {
|
|
4450
4516
|
menuItems.push({
|
|
4451
4517
|
label: "\u81F3\u5C11\u4FDD\u7559\u4E00\u4E2A\u822A\u70B9",
|
|
@@ -4457,12 +4523,10 @@ var PathEditingEventHandler = class {
|
|
|
4457
4523
|
return menuItems;
|
|
4458
4524
|
}
|
|
4459
4525
|
/**
|
|
4460
|
-
*
|
|
4526
|
+
* 获取顶点的显示编号
|
|
4527
|
+
* 🆕 不再跳过隐藏爬升点,直接返回索引
|
|
4461
4528
|
*/
|
|
4462
4529
|
getVertexDisplayNumber(index) {
|
|
4463
|
-
if (this.hiddenClimbIndex === 1 && index > 1) {
|
|
4464
|
-
return index - 1;
|
|
4465
|
-
}
|
|
4466
4530
|
return index;
|
|
4467
4531
|
}
|
|
4468
4532
|
/**
|
|
@@ -4494,18 +4558,17 @@ var PathEditingEventHandler = class {
|
|
|
4494
4558
|
};
|
|
4495
4559
|
}
|
|
4496
4560
|
const totalVertices = positions.length;
|
|
4497
|
-
const totalVisibleVertices = totalVertices
|
|
4498
|
-
const isStartPoint =
|
|
4499
|
-
const isHiddenClimb =
|
|
4500
|
-
const canDelete =
|
|
4561
|
+
const totalVisibleVertices = totalVertices;
|
|
4562
|
+
const isStartPoint = false;
|
|
4563
|
+
const isHiddenClimb = false;
|
|
4564
|
+
const canDelete = totalVertices > 1;
|
|
4501
4565
|
let pathProperties;
|
|
4502
4566
|
if (entity) {
|
|
4503
4567
|
try {
|
|
4504
4568
|
const props = entity.properties;
|
|
4505
4569
|
pathProperties = {
|
|
4506
4570
|
altitudeMode: props?._altitudeMode?.getValue?.() ?? props?._altitudeMode,
|
|
4507
|
-
climbHeight: props?._climbHeight?.getValue?.() ?? props?._climbHeight
|
|
4508
|
-
hasHiddenClimb: props?._hasHiddenClimb?.getValue?.() ?? props?._hasHiddenClimb
|
|
4571
|
+
climbHeight: props?._climbHeight?.getValue?.() ?? props?._climbHeight
|
|
4509
4572
|
};
|
|
4510
4573
|
} catch {
|
|
4511
4574
|
}
|
|
@@ -4544,11 +4607,9 @@ var PathEditingEventHandler = class {
|
|
|
4544
4607
|
}
|
|
4545
4608
|
/**
|
|
4546
4609
|
* 处理插入顶点
|
|
4610
|
+
* 🆕 不再跳过隐藏爬升点
|
|
4547
4611
|
*/
|
|
4548
4612
|
handleInsertVertex(insertAt, pose, type) {
|
|
4549
|
-
if (this.hiddenClimbIndex === 1 && insertAt <= 1) {
|
|
4550
|
-
insertAt = 2;
|
|
4551
|
-
}
|
|
4552
4613
|
if (this.callbacks.onInsertVertex) {
|
|
4553
4614
|
this.callbacks.onInsertVertex(insertAt, pose.position, {
|
|
4554
4615
|
heading: pose.heading,
|
|
@@ -4579,6 +4640,10 @@ var PathEditingEventHandler = class {
|
|
|
4579
4640
|
}
|
|
4580
4641
|
/**
|
|
4581
4642
|
* 🆕 处理快速编辑模式的点击
|
|
4643
|
+
* 根据 altitudeMode 计算航点高度:
|
|
4644
|
+
* - absolute: 航点高度 = defaultAltitude
|
|
4645
|
+
* - relativeToGround: 航点高度 = 地形高度 + defaultAltitude
|
|
4646
|
+
* - relativeToStart: 航点高度 = 起飞点高度 + defaultAltitude
|
|
4582
4647
|
*/
|
|
4583
4648
|
handleQuickEditClick(movement) {
|
|
4584
4649
|
const position = this.getPositionFromMouse(movement);
|
|
@@ -4588,11 +4653,9 @@ var PathEditingEventHandler = class {
|
|
|
4588
4653
|
}
|
|
4589
4654
|
const quickEditOptions = this.callbacks.getQuickEditOptions?.();
|
|
4590
4655
|
if (!quickEditOptions) return;
|
|
4591
|
-
const {
|
|
4656
|
+
const { defaultAltitude, altitudeMode } = quickEditOptions;
|
|
4657
|
+
const newPosition = this.calculatePositionByAltitudeMode(position, defaultAltitude, altitudeMode);
|
|
4592
4658
|
const C = this.CesiumNS;
|
|
4593
|
-
const originalCarto = C.Cartographic.fromCartesian(position);
|
|
4594
|
-
const originalHeight = originalCarto.height;
|
|
4595
|
-
const newPosition = this.applyClimbHeight(position, climbHeight, altitudeMode);
|
|
4596
4659
|
const newCarto = C.Cartographic.fromCartesian(newPosition);
|
|
4597
4660
|
const newHeight = newCarto.height;
|
|
4598
4661
|
const positions = this.callbacks.getPositions?.() || [];
|
|
@@ -4607,8 +4670,7 @@ var PathEditingEventHandler = class {
|
|
|
4607
4670
|
insertAt,
|
|
4608
4671
|
heading: heading.toFixed(2),
|
|
4609
4672
|
altitudeMode,
|
|
4610
|
-
|
|
4611
|
-
originalHeight: originalHeight.toFixed(2),
|
|
4673
|
+
defaultAltitude,
|
|
4612
4674
|
finalHeight: newHeight.toFixed(2)
|
|
4613
4675
|
});
|
|
4614
4676
|
this.callbacks.onInsertVertex(insertAt, newPosition, {
|
|
@@ -4620,21 +4682,35 @@ var PathEditingEventHandler = class {
|
|
|
4620
4682
|
}
|
|
4621
4683
|
}
|
|
4622
4684
|
/**
|
|
4623
|
-
* 🆕
|
|
4685
|
+
* 🆕 根据高度模式计算航点位置
|
|
4686
|
+
* - absolute: 航点高度 = defaultAltitude
|
|
4687
|
+
* - relativeToGround: 航点高度 = 地形高度 + defaultAltitude
|
|
4688
|
+
* - relativeToStart: 航点高度 = 起飞点高度 + defaultAltitude
|
|
4624
4689
|
*/
|
|
4625
|
-
|
|
4690
|
+
calculatePositionByAltitudeMode(position, defaultAltitude, altitudeMode) {
|
|
4626
4691
|
const C = this.CesiumNS;
|
|
4627
4692
|
try {
|
|
4628
4693
|
const cartographic = C.Cartographic.fromCartesian(position);
|
|
4629
4694
|
const lon = C.Math.toDegrees(cartographic.longitude);
|
|
4630
4695
|
const lat = C.Math.toDegrees(cartographic.latitude);
|
|
4631
|
-
let
|
|
4632
|
-
if (altitudeMode === "
|
|
4633
|
-
|
|
4634
|
-
} else if (altitudeMode === "
|
|
4635
|
-
|
|
4696
|
+
let finalHeight;
|
|
4697
|
+
if (altitudeMode === "absolute") {
|
|
4698
|
+
finalHeight = defaultAltitude;
|
|
4699
|
+
} else if (altitudeMode === "relativeToGround") {
|
|
4700
|
+
const terrainHeight = queryTerrainHeightSync(this.CesiumNS, this.viewer, position);
|
|
4701
|
+
finalHeight = terrainHeight + defaultAltitude;
|
|
4702
|
+
} else if (altitudeMode === "relativeToStart") {
|
|
4703
|
+
const startPointAltitude = this.callbacks.getStartPointAltitude?.() ?? 0;
|
|
4704
|
+
finalHeight = startPointAltitude + defaultAltitude;
|
|
4705
|
+
} else {
|
|
4706
|
+
finalHeight = defaultAltitude;
|
|
4636
4707
|
}
|
|
4637
|
-
|
|
4708
|
+
console.log("[QuickEdit] \u9AD8\u5EA6\u8BA1\u7B97:", {
|
|
4709
|
+
altitudeMode,
|
|
4710
|
+
defaultAltitude,
|
|
4711
|
+
finalHeight
|
|
4712
|
+
});
|
|
4713
|
+
return C.Cartesian3.fromDegrees(lon, lat, finalHeight);
|
|
4638
4714
|
} catch (error) {
|
|
4639
4715
|
console.error("[QuickEdit] \u9AD8\u5EA6\u8BA1\u7B97\u5931\u8D25:", error);
|
|
4640
4716
|
return position;
|
|
@@ -4726,19 +4802,19 @@ var VertexHandleStyleManager = class {
|
|
|
4726
4802
|
__publicField(this, "selectedStyle");
|
|
4727
4803
|
const C = CesiumNS;
|
|
4728
4804
|
this.normalStyle = {
|
|
4729
|
-
pixelSize: options?.normal?.pixelSize ??
|
|
4805
|
+
pixelSize: options?.normal?.pixelSize ?? 6,
|
|
4730
4806
|
color: options?.normal?.color ?? C.Color.YELLOW,
|
|
4731
4807
|
outlineColor: options?.normal?.outlineColor ?? C.Color.BLACK,
|
|
4732
4808
|
outlineWidth: options?.normal?.outlineWidth ?? 1
|
|
4733
4809
|
};
|
|
4734
4810
|
this.editedStyle = {
|
|
4735
|
-
pixelSize: options?.edited?.pixelSize ??
|
|
4811
|
+
pixelSize: options?.edited?.pixelSize ?? 6,
|
|
4736
4812
|
color: options?.edited?.color ?? C.Color.CYAN,
|
|
4737
4813
|
outlineColor: options?.edited?.outlineColor ?? C.Color.BLACK,
|
|
4738
4814
|
outlineWidth: options?.edited?.outlineWidth ?? 1
|
|
4739
4815
|
};
|
|
4740
4816
|
this.selectedStyle = {
|
|
4741
|
-
pixelSize: options?.selected?.pixelSize ??
|
|
4817
|
+
pixelSize: options?.selected?.pixelSize ?? 8,
|
|
4742
4818
|
color: options?.selected?.color ?? C.Color.ORANGE,
|
|
4743
4819
|
outlineColor: options?.selected?.outlineColor ?? C.Color.BLACK,
|
|
4744
4820
|
outlineWidth: options?.selected?.outlineWidth ?? 2
|
|
@@ -4946,18 +5022,57 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
4946
5022
|
} catch {
|
|
4947
5023
|
positions = [];
|
|
4948
5024
|
}
|
|
4949
|
-
|
|
5025
|
+
const hiddenClimbIndex = void 0;
|
|
5026
|
+
let currentAltitudeMode = "absolute";
|
|
5027
|
+
let currentDefaultAltitude = 100;
|
|
4950
5028
|
try {
|
|
4951
5029
|
const props = entity.properties;
|
|
4952
|
-
const
|
|
4953
|
-
if (
|
|
5030
|
+
const storedMode = props?._altitudeMode?.getValue?.() ?? props?._altitudeMode;
|
|
5031
|
+
if (storedMode === "absolute" || storedMode === "relativeToGround" || storedMode === "relativeToStart") {
|
|
5032
|
+
currentAltitudeMode = storedMode;
|
|
5033
|
+
}
|
|
5034
|
+
const storedDefaultAlt = props?._defaultAltitude?.getValue?.() ?? props?._defaultAltitude;
|
|
5035
|
+
if (typeof storedDefaultAlt === "number") {
|
|
5036
|
+
currentDefaultAltitude = storedDefaultAlt;
|
|
5037
|
+
}
|
|
4954
5038
|
} catch {
|
|
4955
5039
|
}
|
|
5040
|
+
if (options?.altitudeMode) {
|
|
5041
|
+
currentAltitudeMode = options.altitudeMode;
|
|
5042
|
+
}
|
|
5043
|
+
if (options?.defaultAltitude !== void 0) {
|
|
5044
|
+
currentDefaultAltitude = options.defaultAltitude;
|
|
5045
|
+
}
|
|
5046
|
+
let startPointAltitude = 0;
|
|
5047
|
+
try {
|
|
5048
|
+
if (positions.length > 0) {
|
|
5049
|
+
const startCarto = C.Cartographic.fromCartesian(positions[0]);
|
|
5050
|
+
startPointAltitude = startCarto.height ?? 0;
|
|
5051
|
+
}
|
|
5052
|
+
} catch {
|
|
5053
|
+
}
|
|
5054
|
+
const terrainHeightsCache = /* @__PURE__ */ new Map();
|
|
5055
|
+
const useGlobalHeightFlags = [];
|
|
5056
|
+
try {
|
|
5057
|
+
const props = entity.properties;
|
|
5058
|
+
const storedFlags = props?._useGlobalHeightFlags?.getValue?.() ?? props?._useGlobalHeightFlags;
|
|
5059
|
+
if (Array.isArray(storedFlags)) {
|
|
5060
|
+
storedFlags.forEach((flag, idx) => {
|
|
5061
|
+
useGlobalHeightFlags[idx] = flag;
|
|
5062
|
+
});
|
|
5063
|
+
}
|
|
5064
|
+
} catch {
|
|
5065
|
+
}
|
|
5066
|
+
while (useGlobalHeightFlags.length < positions.length) {
|
|
5067
|
+
useGlobalHeightFlags.push(false);
|
|
5068
|
+
}
|
|
4956
5069
|
let quickEditEnabled = false;
|
|
4957
5070
|
let quickEditOptions = {
|
|
4958
5071
|
enabled: false,
|
|
4959
|
-
climbHeight:
|
|
4960
|
-
|
|
5072
|
+
climbHeight: currentDefaultAltitude,
|
|
5073
|
+
// 使用当前默认高度
|
|
5074
|
+
altitudeMode: currentAltitudeMode
|
|
5075
|
+
// 使用当前高度模式
|
|
4961
5076
|
};
|
|
4962
5077
|
if (options?.quickEdit) {
|
|
4963
5078
|
if (typeof options.quickEdit === "boolean") {
|
|
@@ -4990,33 +5105,23 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
4990
5105
|
} catch {
|
|
4991
5106
|
}
|
|
4992
5107
|
const handles = positions.map((p, i) => {
|
|
4993
|
-
if (hiddenClimbIndex === i) return void 0;
|
|
4994
|
-
const isStartPoint = i === 0;
|
|
4995
5108
|
const h2 = existing[i];
|
|
4996
5109
|
if (h2) {
|
|
4997
5110
|
try {
|
|
4998
5111
|
h2.position = p;
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
h2.point.outlineWidth = 1;
|
|
5005
|
-
}
|
|
5112
|
+
h2.point = h2.point ?? { pixelSize: 6 };
|
|
5113
|
+
h2.point.pixelSize = 6;
|
|
5114
|
+
h2.point.color = C.Color.YELLOW;
|
|
5115
|
+
h2.point.outlineColor = C.Color.BLACK;
|
|
5116
|
+
h2.point.outlineWidth = 1;
|
|
5006
5117
|
h2.properties = { _type: "path-vertex", _ownerId: ownerId, _vertexIndex: i };
|
|
5007
5118
|
} catch {
|
|
5008
5119
|
}
|
|
5009
5120
|
return h2;
|
|
5010
5121
|
}
|
|
5011
|
-
if (isStartPoint) {
|
|
5012
|
-
return layer.entities.add({
|
|
5013
|
-
position: p,
|
|
5014
|
-
properties: { _type: "path-vertex", _ownerId: ownerId, _vertexIndex: i }
|
|
5015
|
-
});
|
|
5016
|
-
}
|
|
5017
5122
|
return layer.entities.add({
|
|
5018
5123
|
position: p,
|
|
5019
|
-
point: { pixelSize:
|
|
5124
|
+
point: { pixelSize: 6, color: C.Color.YELLOW, outlineColor: C.Color.BLACK, outlineWidth: 1 },
|
|
5020
5125
|
properties: { _type: "path-vertex", _ownerId: ownerId, _vertexIndex: i }
|
|
5021
5126
|
});
|
|
5022
5127
|
});
|
|
@@ -5033,8 +5138,6 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5033
5138
|
};
|
|
5034
5139
|
const createOrUpdateMarkerForIndex = (idx) => {
|
|
5035
5140
|
try {
|
|
5036
|
-
if (hiddenClimbIndex === 1 && idx === 1) return;
|
|
5037
|
-
if (idx === 0) return;
|
|
5038
5141
|
const pos = positions[idx];
|
|
5039
5142
|
if (!pos) return;
|
|
5040
5143
|
const markerLayer = ensureMarkerLayer();
|
|
@@ -5116,7 +5219,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5116
5219
|
};
|
|
5117
5220
|
const getTotalDistance = () => {
|
|
5118
5221
|
if (positions.length < 2) return 0;
|
|
5119
|
-
return calculatePathDistance(CesiumNS, positions, positions.length - 1
|
|
5222
|
+
return calculatePathDistance(CesiumNS, positions, positions.length - 1);
|
|
5120
5223
|
};
|
|
5121
5224
|
const vertexInsertionHandler = new VertexInsertionHandler({
|
|
5122
5225
|
CesiumNS,
|
|
@@ -5125,7 +5228,40 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5125
5228
|
hiddenClimbIndex
|
|
5126
5229
|
});
|
|
5127
5230
|
let cursorStart = positions[positions.length - 1];
|
|
5128
|
-
if (!cursorStart) cursorStart = positions[
|
|
5231
|
+
if (!cursorStart) cursorStart = positions[0];
|
|
5232
|
+
if (!cursorStart) {
|
|
5233
|
+
try {
|
|
5234
|
+
const cameraPos = viewer.camera.positionCartographic;
|
|
5235
|
+
if (cameraPos) {
|
|
5236
|
+
let initialHeight = currentDefaultAltitude;
|
|
5237
|
+
if (currentAltitudeMode === "relativeToGround") {
|
|
5238
|
+
const terrainHeight = queryTerrainHeightSync(
|
|
5239
|
+
CesiumNS,
|
|
5240
|
+
viewer,
|
|
5241
|
+
C.Cartesian3.fromRadians(cameraPos.longitude, cameraPos.latitude, 0)
|
|
5242
|
+
);
|
|
5243
|
+
initialHeight = terrainHeight + currentDefaultAltitude;
|
|
5244
|
+
console.log("[PathEditing] relativeToGround \u6A21\u5F0F\uFF0C\u5730\u5F62\u9AD8\u5EA6:", terrainHeight, "\u521D\u59CB\u9AD8\u5EA6:", initialHeight);
|
|
5245
|
+
} else if (currentAltitudeMode === "relativeToStart") {
|
|
5246
|
+
initialHeight = currentDefaultAltitude;
|
|
5247
|
+
console.log("[PathEditing] relativeToStart \u6A21\u5F0F\uFF08\u7A7A\u822A\u7EBF\uFF09\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u9AD8\u5EA6:", initialHeight);
|
|
5248
|
+
}
|
|
5249
|
+
cursorStart = C.Cartesian3.fromRadians(
|
|
5250
|
+
cameraPos.longitude,
|
|
5251
|
+
cameraPos.latitude,
|
|
5252
|
+
initialHeight
|
|
5253
|
+
);
|
|
5254
|
+
console.log("[PathEditing] \u7A7A\u822A\u7EBF\uFF0C\u4F7F\u7528\u76F8\u673A\u4F4D\u7F6E\u521D\u59CB\u5316\u6E38\u6807:", {
|
|
5255
|
+
lon: C.Math.toDegrees(cameraPos.longitude),
|
|
5256
|
+
lat: C.Math.toDegrees(cameraPos.latitude),
|
|
5257
|
+
height: initialHeight,
|
|
5258
|
+
altitudeMode: currentAltitudeMode
|
|
5259
|
+
});
|
|
5260
|
+
}
|
|
5261
|
+
} catch (error) {
|
|
5262
|
+
console.warn("[PathEditing] \u65E0\u6CD5\u83B7\u53D6\u76F8\u673A\u4F4D\u7F6E:", error);
|
|
5263
|
+
}
|
|
5264
|
+
}
|
|
5129
5265
|
let airplaneCursor;
|
|
5130
5266
|
const insertVertex = (insertAt, p3, poseOrient) => {
|
|
5131
5267
|
console.log("[PathEditing] \u63D2\u5165\u9876\u70B9\u524D positions \u957F\u5EA6:", positions.length, "insertAt:", insertAt);
|
|
@@ -5142,7 +5278,9 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5142
5278
|
vertexLabelManager,
|
|
5143
5279
|
heightMarkers,
|
|
5144
5280
|
airplaneCursor,
|
|
5145
|
-
poseOrient
|
|
5281
|
+
poseOrient,
|
|
5282
|
+
useGlobalHeightFlags
|
|
5283
|
+
// 🆕 传递 useGlobalHeightFlags
|
|
5146
5284
|
);
|
|
5147
5285
|
console.log("[PathEditing] \u63D2\u5165\u9876\u70B9\u540E positions \u957F\u5EA6:", positions.length, "actualIndex:", actualIndex);
|
|
5148
5286
|
entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
|
|
@@ -5151,16 +5289,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5151
5289
|
};
|
|
5152
5290
|
const deleteVertex = (deleteAt) => {
|
|
5153
5291
|
try {
|
|
5154
|
-
if (
|
|
5155
|
-
console.warn("Cannot delete start point");
|
|
5156
|
-
return;
|
|
5157
|
-
}
|
|
5158
|
-
if (hiddenClimbIndex !== void 0 && deleteAt === hiddenClimbIndex) {
|
|
5159
|
-
console.warn("Cannot delete hidden climb point");
|
|
5160
|
-
return;
|
|
5161
|
-
}
|
|
5162
|
-
const visibleVertexCount = positions.length - (hiddenClimbIndex === 1 ? 1 : 0);
|
|
5163
|
-
if (visibleVertexCount <= 1) {
|
|
5292
|
+
if (positions.length <= 1) {
|
|
5164
5293
|
console.warn("Cannot delete last vertex");
|
|
5165
5294
|
return;
|
|
5166
5295
|
}
|
|
@@ -5184,6 +5313,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5184
5313
|
rolls.splice(deleteAt, 1);
|
|
5185
5314
|
fovs.splice(deleteAt, 1);
|
|
5186
5315
|
heightMarkers.splice(deleteAt, 1);
|
|
5316
|
+
useGlobalHeightFlags.splice(deleteAt, 1);
|
|
5187
5317
|
console.log("[PathEditing] \u5220\u9664\u9876\u70B9\u540E positions \u957F\u5EA6:", positions.length);
|
|
5188
5318
|
entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
|
|
5189
5319
|
const newEditedIndices = /* @__PURE__ */ new Set();
|
|
@@ -5245,9 +5375,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5245
5375
|
}
|
|
5246
5376
|
},
|
|
5247
5377
|
// frustumLengthFactor: options?.preview?.lengthFactor ?? 0.3,
|
|
5248
|
-
fovDeg: options?.preview?.fov ?? 50
|
|
5249
|
-
minHeight: options?.minHeight
|
|
5250
|
-
// 传递最小高度限制
|
|
5378
|
+
fovDeg: options?.preview?.fov ?? 50
|
|
5251
5379
|
});
|
|
5252
5380
|
if (options?.preview?.enabled !== false && airplaneCursor) {
|
|
5253
5381
|
preview = new PathPreview(CesiumNS, viewer, {
|
|
@@ -5291,8 +5419,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5291
5419
|
{
|
|
5292
5420
|
CesiumNS,
|
|
5293
5421
|
viewer,
|
|
5294
|
-
hiddenClimbIndex
|
|
5295
|
-
minHeight: options?.minHeight
|
|
5422
|
+
hiddenClimbIndex
|
|
5296
5423
|
},
|
|
5297
5424
|
{
|
|
5298
5425
|
onVertexSelect: (index) => setActiveIndex(index),
|
|
@@ -5323,7 +5450,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5323
5450
|
},
|
|
5324
5451
|
onDeleteVertex: (index) => {
|
|
5325
5452
|
const totalBefore = positions.length;
|
|
5326
|
-
const displayNumber =
|
|
5453
|
+
const displayNumber = index;
|
|
5327
5454
|
deleteVertex(index);
|
|
5328
5455
|
if (options?.onVertexDeleteDetail) {
|
|
5329
5456
|
try {
|
|
@@ -5376,7 +5503,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5376
5503
|
};
|
|
5377
5504
|
} catch {
|
|
5378
5505
|
}
|
|
5379
|
-
const displayNumber =
|
|
5506
|
+
const displayNumber = index;
|
|
5380
5507
|
const dragMoveInfo = {
|
|
5381
5508
|
index,
|
|
5382
5509
|
displayNumber,
|
|
@@ -5393,6 +5520,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5393
5520
|
onVertexDragEnd: (index, finalPosition) => {
|
|
5394
5521
|
editedIndices.add(index);
|
|
5395
5522
|
positions[index] = finalPosition;
|
|
5523
|
+
useGlobalHeightFlags[index] = false;
|
|
5396
5524
|
if (handles[index]) {
|
|
5397
5525
|
handleStyleManager.applyStyle(handles[index], "edited");
|
|
5398
5526
|
}
|
|
@@ -5439,10 +5567,29 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5439
5567
|
getCursorPose: () => airplaneCursor?.getPose(),
|
|
5440
5568
|
// 🆕 快速编辑回调
|
|
5441
5569
|
getQuickEditEnabled: () => quickEditEnabled,
|
|
5442
|
-
getQuickEditOptions: () =>
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5570
|
+
getQuickEditOptions: () => {
|
|
5571
|
+
let climbHeight = 0;
|
|
5572
|
+
try {
|
|
5573
|
+
const props = entity.properties;
|
|
5574
|
+
climbHeight = props?._climbHeight?.getValue?.() ?? props?._climbHeight ?? 0;
|
|
5575
|
+
} catch {
|
|
5576
|
+
}
|
|
5577
|
+
return {
|
|
5578
|
+
climbHeight,
|
|
5579
|
+
defaultAltitude: currentDefaultAltitude,
|
|
5580
|
+
altitudeMode: currentAltitudeMode
|
|
5581
|
+
};
|
|
5582
|
+
},
|
|
5583
|
+
// 🆕 高度模式相关回调
|
|
5584
|
+
getStartPointAltitude: () => startPointAltitude,
|
|
5585
|
+
getDefaultAltitude: () => currentDefaultAltitude,
|
|
5586
|
+
// 🆕 useGlobalHeightFlags 相关回调
|
|
5587
|
+
getUseGlobalHeightFlags: () => useGlobalHeightFlags,
|
|
5588
|
+
setUseGlobalHeightFlag: (index, value) => {
|
|
5589
|
+
if (index >= 0 && index < useGlobalHeightFlags.length) {
|
|
5590
|
+
useGlobalHeightFlags[index] = value;
|
|
5591
|
+
}
|
|
5592
|
+
}
|
|
5446
5593
|
}
|
|
5447
5594
|
);
|
|
5448
5595
|
const cleanupSession = () => {
|
|
@@ -5482,6 +5629,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5482
5629
|
const buildVertexDetailInfo = (index) => {
|
|
5483
5630
|
const position = positions[index];
|
|
5484
5631
|
let coordinates = { longitude: 0, latitude: 0, height: 0 };
|
|
5632
|
+
let ellipsoidHeight = 0;
|
|
5485
5633
|
try {
|
|
5486
5634
|
const cartographic = C.Cartographic.fromCartesian(position);
|
|
5487
5635
|
coordinates = {
|
|
@@ -5489,8 +5637,16 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5489
5637
|
latitude: C.Math.toDegrees(cartographic.latitude),
|
|
5490
5638
|
height: cartographic.height
|
|
5491
5639
|
};
|
|
5640
|
+
ellipsoidHeight = cartographic.height ?? 0;
|
|
5492
5641
|
} catch {
|
|
5493
5642
|
}
|
|
5643
|
+
const terrainHeight = terrainHeightsCache.get(index) ?? 0;
|
|
5644
|
+
const relativeHeight = calculateRelativeHeight(
|
|
5645
|
+
currentAltitudeMode,
|
|
5646
|
+
ellipsoidHeight,
|
|
5647
|
+
startPointAltitude,
|
|
5648
|
+
terrainHeight
|
|
5649
|
+
);
|
|
5494
5650
|
const pose = {
|
|
5495
5651
|
heading: headings[index] ?? 0,
|
|
5496
5652
|
pitch: pitches[index] ?? 0,
|
|
@@ -5498,18 +5654,17 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5498
5654
|
fov: fovs[index] ?? 50
|
|
5499
5655
|
};
|
|
5500
5656
|
const totalVertices = positions.length;
|
|
5501
|
-
const totalVisibleVertices = totalVertices
|
|
5502
|
-
const isStartPoint =
|
|
5503
|
-
const isHiddenClimb =
|
|
5504
|
-
const canDelete =
|
|
5505
|
-
const displayNumber =
|
|
5657
|
+
const totalVisibleVertices = totalVertices;
|
|
5658
|
+
const isStartPoint = false;
|
|
5659
|
+
const isHiddenClimb = false;
|
|
5660
|
+
const canDelete = totalVertices > 1;
|
|
5661
|
+
const displayNumber = index;
|
|
5506
5662
|
let pathProperties;
|
|
5507
5663
|
try {
|
|
5508
5664
|
const props = entity.properties;
|
|
5509
5665
|
pathProperties = {
|
|
5510
5666
|
altitudeMode: props?._altitudeMode?.getValue?.() ?? props?._altitudeMode,
|
|
5511
|
-
climbHeight: props?._climbHeight?.getValue?.() ?? props?._climbHeight
|
|
5512
|
-
hasHiddenClimb: props?._hasHiddenClimb?.getValue?.() ?? props?._hasHiddenClimb
|
|
5667
|
+
climbHeight: props?._climbHeight?.getValue?.() ?? props?._climbHeight
|
|
5513
5668
|
};
|
|
5514
5669
|
} catch {
|
|
5515
5670
|
}
|
|
@@ -5525,44 +5680,68 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5525
5680
|
totalVisibleVertices,
|
|
5526
5681
|
totalVertices,
|
|
5527
5682
|
entity,
|
|
5528
|
-
pathProperties
|
|
5683
|
+
pathProperties,
|
|
5684
|
+
useGlobalHeight: useGlobalHeightFlags[index] ?? false,
|
|
5685
|
+
// 🆕 添加 useGlobalHeight
|
|
5686
|
+
ellipsoidHeight,
|
|
5687
|
+
// 🆕 添加椭球高度
|
|
5688
|
+
relativeHeight
|
|
5689
|
+
// 🆕 添加相对高度
|
|
5529
5690
|
};
|
|
5530
5691
|
};
|
|
5531
5692
|
return {
|
|
5532
5693
|
/** 保存并退出编辑模式 */
|
|
5533
5694
|
saveAndStop: () => {
|
|
5534
5695
|
stateManager.persistToEntity(positions, headings, pitches, rolls, fovs);
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5696
|
+
try {
|
|
5697
|
+
entity.properties._altitudeMode = currentAltitudeMode;
|
|
5698
|
+
entity.properties._defaultAltitude = currentDefaultAltitude;
|
|
5699
|
+
entity.properties._useGlobalHeightFlags = useGlobalHeightFlags.slice();
|
|
5700
|
+
} catch {
|
|
5701
|
+
}
|
|
5702
|
+
let altitudeMode = currentAltitudeMode;
|
|
5539
5703
|
let climbHeight;
|
|
5540
|
-
let hasHiddenClimb;
|
|
5541
5704
|
try {
|
|
5542
5705
|
const props = entity.properties;
|
|
5543
|
-
altitudeMode = props?._altitudeMode?.getValue?.() ?? props?._altitudeMode;
|
|
5544
5706
|
climbHeight = props?._climbHeight?.getValue?.() ?? props?._climbHeight;
|
|
5545
|
-
hasHiddenClimb = props?._hasHiddenClimb?.getValue?.() ?? props?._hasHiddenClimb;
|
|
5546
5707
|
} catch {
|
|
5547
5708
|
}
|
|
5548
|
-
const waypointData = positions.map((position, index) =>
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5709
|
+
const waypointData = positions.map((position, index) => {
|
|
5710
|
+
let ellipsoidHeight = 0;
|
|
5711
|
+
try {
|
|
5712
|
+
const carto = C.Cartographic.fromCartesian(position);
|
|
5713
|
+
ellipsoidHeight = carto.height ?? 0;
|
|
5714
|
+
} catch {
|
|
5715
|
+
}
|
|
5716
|
+
const terrainHeight = terrainHeightsCache.get(index) ?? 0;
|
|
5717
|
+
const relativeHeight = calculateRelativeHeight(
|
|
5718
|
+
currentAltitudeMode,
|
|
5719
|
+
ellipsoidHeight,
|
|
5720
|
+
startPointAltitude,
|
|
5721
|
+
terrainHeight
|
|
5722
|
+
);
|
|
5723
|
+
return {
|
|
5724
|
+
position,
|
|
5725
|
+
heading: headings[index] ?? 0,
|
|
5726
|
+
pitch: pitches[index] ?? -10,
|
|
5727
|
+
roll: rolls[index] ?? 0,
|
|
5728
|
+
fov: fovs[index] ?? 50,
|
|
5729
|
+
index,
|
|
5730
|
+
distance: calculatePathDistance(CesiumNS, positions, index),
|
|
5731
|
+
ellipsoidHeight,
|
|
5732
|
+
relativeHeight,
|
|
5733
|
+
useGlobalHeight: useGlobalHeightFlags[index] ?? false
|
|
5734
|
+
// 🆕 添加 useGlobalHeight
|
|
5735
|
+
};
|
|
5736
|
+
});
|
|
5557
5737
|
cleanupSession();
|
|
5558
5738
|
return {
|
|
5559
5739
|
entity,
|
|
5560
5740
|
positions: positions.slice(),
|
|
5561
|
-
startPoint,
|
|
5562
5741
|
climbHeight,
|
|
5563
5742
|
waypointData,
|
|
5564
5743
|
altitudeMode,
|
|
5565
|
-
|
|
5744
|
+
defaultAltitude: currentDefaultAltitude
|
|
5566
5745
|
};
|
|
5567
5746
|
},
|
|
5568
5747
|
/** 不保存退出(回滚到进入编辑时的状态) */
|
|
@@ -5785,45 +5964,32 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5785
5964
|
*/
|
|
5786
5965
|
getCursorPose: () => airplaneCursor?.getPose(),
|
|
5787
5966
|
/**
|
|
5788
|
-
* 🆕
|
|
5789
|
-
*
|
|
5790
|
-
* @param
|
|
5967
|
+
* 🆕 更新爬升高度(climbHeight)
|
|
5968
|
+
* 更新实体属性中的 _climbHeight 值
|
|
5969
|
+
* @param newClimbHeight 新的爬升高度(米)
|
|
5791
5970
|
* @returns 是否更新成功
|
|
5792
5971
|
*/
|
|
5793
|
-
updateClimbHeight: function(
|
|
5794
|
-
if (hiddenClimbIndex !== 1 || positions.length < 2) {
|
|
5795
|
-
console.warn("[updateClimbHeight] No hidden climb point exists");
|
|
5796
|
-
return false;
|
|
5797
|
-
}
|
|
5972
|
+
updateClimbHeight: function(newClimbHeight) {
|
|
5798
5973
|
try {
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
const success = this.updateWaypointAltitude(1, newAltitude);
|
|
5803
|
-
if (success) {
|
|
5804
|
-
try {
|
|
5805
|
-
entity.properties._climbHeight = climbHeight;
|
|
5806
|
-
} catch {
|
|
5807
|
-
}
|
|
5808
|
-
console.log("[updateClimbHeight] \u2705 \u722C\u5347\u9AD8\u5EA6\u5DF2\u66F4\u65B0:", climbHeight, "\u7C73");
|
|
5809
|
-
}
|
|
5810
|
-
return success;
|
|
5974
|
+
entity.properties._climbHeight = newClimbHeight;
|
|
5975
|
+
console.log("[updateClimbHeight] \u2705 \u722C\u5347\u9AD8\u5EA6\u5DF2\u66F4\u65B0:", newClimbHeight, "\u7C73");
|
|
5976
|
+
return true;
|
|
5811
5977
|
} catch (error) {
|
|
5812
5978
|
console.error("[updateClimbHeight] Error:", error);
|
|
5813
5979
|
return false;
|
|
5814
5980
|
}
|
|
5815
5981
|
},
|
|
5816
5982
|
/**
|
|
5817
|
-
* 🆕
|
|
5818
|
-
* @returns
|
|
5983
|
+
* 🆕 获取第一个航点信息
|
|
5984
|
+
* @returns 第一个航点的经纬度和高度
|
|
5819
5985
|
*/
|
|
5820
5986
|
getStartPoint: () => {
|
|
5821
5987
|
if (positions.length < 1) return null;
|
|
5822
5988
|
try {
|
|
5823
|
-
const
|
|
5824
|
-
const carto = C.Cartographic.fromCartesian(
|
|
5989
|
+
const firstPos = positions[0];
|
|
5990
|
+
const carto = C.Cartographic.fromCartesian(firstPos);
|
|
5825
5991
|
return {
|
|
5826
|
-
position:
|
|
5992
|
+
position: firstPos,
|
|
5827
5993
|
latitude: C.Math.toDegrees(carto.latitude),
|
|
5828
5994
|
longitude: C.Math.toDegrees(carto.longitude),
|
|
5829
5995
|
altitude: carto.height
|
|
@@ -5831,6 +5997,123 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
|
|
|
5831
5997
|
} catch {
|
|
5832
5998
|
return null;
|
|
5833
5999
|
}
|
|
6000
|
+
},
|
|
6001
|
+
/**
|
|
6002
|
+
* 🆕 获取当前高度模式
|
|
6003
|
+
*/
|
|
6004
|
+
getAltitudeMode: () => currentAltitudeMode,
|
|
6005
|
+
/**
|
|
6006
|
+
* 🆕 获取当前默认高度
|
|
6007
|
+
*/
|
|
6008
|
+
getDefaultAltitude: () => currentDefaultAltitude,
|
|
6009
|
+
/**
|
|
6010
|
+
* 🆕 更新默认高度
|
|
6011
|
+
*/
|
|
6012
|
+
updateDefaultAltitude: (altitude) => {
|
|
6013
|
+
currentDefaultAltitude = altitude;
|
|
6014
|
+
quickEditOptions.climbHeight = altitude;
|
|
6015
|
+
try {
|
|
6016
|
+
entity.properties._defaultAltitude = altitude;
|
|
6017
|
+
} catch {
|
|
6018
|
+
}
|
|
6019
|
+
console.log("[updateDefaultAltitude] \u2705 \u9ED8\u8BA4\u9AD8\u5EA6\u5DF2\u66F4\u65B0:", altitude, "\u7C73");
|
|
6020
|
+
},
|
|
6021
|
+
/**
|
|
6022
|
+
* 🆕 切换高度计算模式(异步,会重算所有航点高度)
|
|
6023
|
+
* @param newMode 新的高度模式
|
|
6024
|
+
* @param newDefaultAltitude 新的默认高度(可选)
|
|
6025
|
+
* @param options 选项(terrainProvider, onProgress)
|
|
6026
|
+
* @returns 切换结果 { success: boolean; error?: string }
|
|
6027
|
+
*/
|
|
6028
|
+
changeAltitudeMode: async (newMode, newDefaultAltitude, options2) => {
|
|
6029
|
+
try {
|
|
6030
|
+
const onProgress = options2?.onProgress;
|
|
6031
|
+
if (newMode === "relativeToGround") {
|
|
6032
|
+
const terrainProvider = options2?.terrainProvider ?? viewer.terrainProvider;
|
|
6033
|
+
const C_any = C;
|
|
6034
|
+
if (!terrainProvider || C_any.EllipsoidTerrainProvider && terrainProvider instanceof C_any.EllipsoidTerrainProvider) {
|
|
6035
|
+
console.error("[changeAltitudeMode] \u274C relativeToGround \u6A21\u5F0F\u9700\u8981\u6709\u6548\u7684 terrain \u56FE\u5C42");
|
|
6036
|
+
onProgress?.("error");
|
|
6037
|
+
return {
|
|
6038
|
+
success: false,
|
|
6039
|
+
error: "Terrain provider required for relativeToGround mode"
|
|
6040
|
+
};
|
|
6041
|
+
}
|
|
6042
|
+
}
|
|
6043
|
+
onProgress?.("loading");
|
|
6044
|
+
const oldMode = currentAltitudeMode;
|
|
6045
|
+
if (newDefaultAltitude !== void 0) {
|
|
6046
|
+
currentDefaultAltitude = newDefaultAltitude;
|
|
6047
|
+
quickEditOptions.climbHeight = newDefaultAltitude;
|
|
6048
|
+
}
|
|
6049
|
+
if (newMode === "relativeToGround" || oldMode === "relativeToGround") {
|
|
6050
|
+
const terrainHeights = await queryTerrainHeights(CesiumNS, viewer, positions);
|
|
6051
|
+
terrainHeights.forEach((height, index) => {
|
|
6052
|
+
terrainHeightsCache.set(index, height);
|
|
6053
|
+
});
|
|
6054
|
+
console.log("[changeAltitudeMode] \u5DF2\u67E5\u8BE2\u5730\u5F62\u9AD8\u5EA6:", terrainHeights);
|
|
6055
|
+
}
|
|
6056
|
+
if (newMode !== oldMode) {
|
|
6057
|
+
console.log("[changeAltitudeMode] \u5207\u6362\u9AD8\u5EA6\u6A21\u5F0F:", oldMode, "->", newMode);
|
|
6058
|
+
for (let i = 0; i < positions.length; i++) {
|
|
6059
|
+
const currentPos = positions[i];
|
|
6060
|
+
const carto = C.Cartographic.fromCartesian(currentPos);
|
|
6061
|
+
const currentAbsoluteHeight = carto.height ?? 0;
|
|
6062
|
+
const oldTerrainHeight = terrainHeightsCache.get(i) ?? 0;
|
|
6063
|
+
const relativeHeight = calculateRelativeHeight(
|
|
6064
|
+
oldMode,
|
|
6065
|
+
currentAbsoluteHeight,
|
|
6066
|
+
startPointAltitude,
|
|
6067
|
+
oldTerrainHeight
|
|
6068
|
+
);
|
|
6069
|
+
const newTerrainHeight = terrainHeightsCache.get(i) ?? 0;
|
|
6070
|
+
const newAbsoluteHeight = calculateAbsoluteHeight(
|
|
6071
|
+
newMode,
|
|
6072
|
+
relativeHeight,
|
|
6073
|
+
startPointAltitude,
|
|
6074
|
+
newTerrainHeight
|
|
6075
|
+
);
|
|
6076
|
+
const newPosition = C.Cartesian3.fromRadians(
|
|
6077
|
+
carto.longitude,
|
|
6078
|
+
carto.latitude,
|
|
6079
|
+
newAbsoluteHeight
|
|
6080
|
+
);
|
|
6081
|
+
positions[i] = newPosition;
|
|
6082
|
+
if (handles[i]) {
|
|
6083
|
+
try {
|
|
6084
|
+
handles[i].position = newPosition;
|
|
6085
|
+
} catch {
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6088
|
+
try {
|
|
6089
|
+
vertexLabelManager.updateLabelPosition(i, newPosition);
|
|
6090
|
+
} catch {
|
|
6091
|
+
}
|
|
6092
|
+
try {
|
|
6093
|
+
createOrUpdateMarkerForIndex(i);
|
|
6094
|
+
} catch {
|
|
6095
|
+
}
|
|
6096
|
+
}
|
|
6097
|
+
currentAltitudeMode = newMode;
|
|
6098
|
+
quickEditOptions.altitudeMode = newMode;
|
|
6099
|
+
try {
|
|
6100
|
+
entity.properties._altitudeMode = newMode;
|
|
6101
|
+
entity.properties._defaultAltitude = currentDefaultAltitude;
|
|
6102
|
+
} catch {
|
|
6103
|
+
}
|
|
6104
|
+
entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
|
|
6105
|
+
}
|
|
6106
|
+
console.log("[changeAltitudeMode] \u2705 \u9AD8\u5EA6\u6A21\u5F0F\u5207\u6362\u5B8C\u6210:", {
|
|
6107
|
+
mode: newMode,
|
|
6108
|
+
defaultAltitude: currentDefaultAltitude
|
|
6109
|
+
});
|
|
6110
|
+
onProgress?.("done");
|
|
6111
|
+
return { success: true };
|
|
6112
|
+
} catch (error) {
|
|
6113
|
+
console.error("[changeAltitudeMode] Error:", error);
|
|
6114
|
+
options2?.onProgress?.("error");
|
|
6115
|
+
return { success: false, error: String(error) };
|
|
6116
|
+
}
|
|
5834
6117
|
}
|
|
5835
6118
|
};
|
|
5836
6119
|
}
|
|
@@ -5840,221 +6123,18 @@ function fovToFocalLength(fovDeg) {
|
|
|
5840
6123
|
return sensorWidth / (2 * Math.tan(fovRad / 2));
|
|
5841
6124
|
}
|
|
5842
6125
|
|
|
5843
|
-
// src/core/path-manager/ArrowShape.ts
|
|
5844
|
-
var ArrowShape = class {
|
|
5845
|
-
constructor(CesiumNS, opts = {}) {
|
|
5846
|
-
this.CesiumNS = CesiumNS;
|
|
5847
|
-
__publicField(this, "height");
|
|
5848
|
-
__publicField(this, "shaftHeight");
|
|
5849
|
-
__publicField(this, "headHeight");
|
|
5850
|
-
__publicField(this, "shaftRadius");
|
|
5851
|
-
__publicField(this, "headRadius");
|
|
5852
|
-
__publicField(this, "baseRadius");
|
|
5853
|
-
__publicField(this, "color");
|
|
5854
|
-
__publicField(this, "shaftAlpha");
|
|
5855
|
-
__publicField(this, "headAlpha");
|
|
5856
|
-
__publicField(this, "baseAlpha");
|
|
5857
|
-
__publicField(this, "outline");
|
|
5858
|
-
__publicField(this, "outlineColor");
|
|
5859
|
-
// 动态缩放相关
|
|
5860
|
-
__publicField(this, "dynamicScale");
|
|
5861
|
-
__publicField(this, "viewer");
|
|
5862
|
-
__publicField(this, "referenceDistance");
|
|
5863
|
-
__publicField(this, "minScale");
|
|
5864
|
-
__publicField(this, "maxScale");
|
|
5865
|
-
__publicField(this, "cachedScaleFactor", 1);
|
|
5866
|
-
const C = this.CesiumNS;
|
|
5867
|
-
this.shaftHeight = opts.shaftHeight ?? 17;
|
|
5868
|
-
this.headHeight = opts.headHeight ?? 8;
|
|
5869
|
-
this.height = opts.height ?? this.shaftHeight + this.headHeight;
|
|
5870
|
-
this.shaftRadius = opts.shaftRadius ?? 3;
|
|
5871
|
-
this.headRadius = opts.headRadius ?? 6;
|
|
5872
|
-
this.baseRadius = opts.baseRadius ?? 8;
|
|
5873
|
-
this.color = opts.color ? C.Color.fromCssColorString(opts.color) : C.Color.fromCssColorString("#FFD700");
|
|
5874
|
-
this.shaftAlpha = opts.shaftAlpha ?? 1;
|
|
5875
|
-
this.headAlpha = opts.headAlpha ?? 1;
|
|
5876
|
-
this.baseAlpha = opts.baseAlpha ?? 0.65;
|
|
5877
|
-
this.outline = opts.outline ?? false;
|
|
5878
|
-
this.outlineColor = opts.outlineColor ? C.Color.fromCssColorString(opts.outlineColor) : this.color.darken(0.3, new C.Color());
|
|
5879
|
-
this.dynamicScale = opts.dynamicScale ?? false;
|
|
5880
|
-
this.viewer = opts.viewer;
|
|
5881
|
-
this.referenceDistance = opts.referenceDistance ?? 500;
|
|
5882
|
-
this.minScale = opts.minScale ?? 0.3;
|
|
5883
|
-
this.maxScale = opts.maxScale ?? 3;
|
|
5884
|
-
}
|
|
5885
|
-
/**
|
|
5886
|
-
* Create arrow entities at given position
|
|
5887
|
-
* Returns array of 3 entities: [shaft, head, base]
|
|
5888
|
-
*
|
|
5889
|
-
* @param layer - Cesium CustomDataSource to add entities to
|
|
5890
|
-
* @param position - Ground position (Cartesian3)
|
|
5891
|
-
* @param baseHeight - Ground height in meters
|
|
5892
|
-
* @param properties - Additional properties for entities
|
|
5893
|
-
* @returns Array of created entities [shaft, head, base]
|
|
5894
|
-
*/
|
|
5895
|
-
createEntities(layer, position, baseHeight, properties) {
|
|
5896
|
-
const C = this.CesiumNS;
|
|
5897
|
-
const entities = [];
|
|
5898
|
-
const carto = C.Cartographic.fromCartesian(position);
|
|
5899
|
-
const lon = C.Math.toDegrees(carto.longitude);
|
|
5900
|
-
const lat = C.Math.toDegrees(carto.latitude);
|
|
5901
|
-
const computeScaleFactor = () => {
|
|
5902
|
-
if (!this.dynamicScale || !this.viewer) return 1;
|
|
5903
|
-
try {
|
|
5904
|
-
const cameraPos = this.viewer.camera.positionWC;
|
|
5905
|
-
const distance = C.Cartesian3.distance(cameraPos, position);
|
|
5906
|
-
const rawScale = distance / this.referenceDistance;
|
|
5907
|
-
return Math.max(this.minScale, Math.min(this.maxScale, rawScale));
|
|
5908
|
-
} catch {
|
|
5909
|
-
return 1;
|
|
5910
|
-
}
|
|
5911
|
-
};
|
|
5912
|
-
if (this.dynamicScale && this.viewer) {
|
|
5913
|
-
this.viewer.scene.preRender.addEventListener(() => {
|
|
5914
|
-
this.cachedScaleFactor = computeScaleFactor();
|
|
5915
|
-
});
|
|
5916
|
-
}
|
|
5917
|
-
const hpr = new C.HeadingPitchRoll(0, 0, 0);
|
|
5918
|
-
const baseOrientation = C.Transforms.headingPitchRollQuaternion(position, hpr);
|
|
5919
|
-
const fixedOrientation = new C.ConstantProperty(baseOrientation);
|
|
5920
|
-
const getShaftPosition = () => {
|
|
5921
|
-
const scale = this.cachedScaleFactor;
|
|
5922
|
-
return C.Cartesian3.fromDegrees(lon, lat, baseHeight + this.shaftHeight * scale / 2);
|
|
5923
|
-
};
|
|
5924
|
-
const getHeadPosition = () => {
|
|
5925
|
-
const scale = this.cachedScaleFactor;
|
|
5926
|
-
return C.Cartesian3.fromDegrees(lon, lat, baseHeight + this.shaftHeight * scale + this.headHeight * scale / 2);
|
|
5927
|
-
};
|
|
5928
|
-
const shaftEntity = layer.entities.add({
|
|
5929
|
-
position: this.dynamicScale ? new C.CallbackProperty(getShaftPosition, false) : new C.ConstantPositionProperty(C.Cartesian3.fromDegrees(lon, lat, baseHeight + this.shaftHeight / 2)),
|
|
5930
|
-
orientation: fixedOrientation,
|
|
5931
|
-
cylinder: {
|
|
5932
|
-
length: this.dynamicScale ? new C.CallbackProperty(() => this.shaftHeight * this.cachedScaleFactor, false) : this.shaftHeight,
|
|
5933
|
-
topRadius: this.dynamicScale ? new C.CallbackProperty(() => this.shaftRadius * this.cachedScaleFactor, false) : this.shaftRadius,
|
|
5934
|
-
bottomRadius: this.dynamicScale ? new C.CallbackProperty(() => this.shaftRadius * this.cachedScaleFactor, false) : this.shaftRadius,
|
|
5935
|
-
material: this.color.withAlpha(this.shaftAlpha),
|
|
5936
|
-
outline: this.outline,
|
|
5937
|
-
outlineColor: this.outlineColor,
|
|
5938
|
-
outlineWidth: 2
|
|
5939
|
-
},
|
|
5940
|
-
properties: {
|
|
5941
|
-
...properties,
|
|
5942
|
-
_arrowPart: "shaft"
|
|
5943
|
-
}
|
|
5944
|
-
});
|
|
5945
|
-
entities.push(shaftEntity);
|
|
5946
|
-
const headEntity = layer.entities.add({
|
|
5947
|
-
position: this.dynamicScale ? new C.CallbackProperty(getHeadPosition, false) : new C.ConstantPositionProperty(C.Cartesian3.fromDegrees(lon, lat, baseHeight + this.shaftHeight + this.headHeight / 2)),
|
|
5948
|
-
orientation: fixedOrientation,
|
|
5949
|
-
cylinder: {
|
|
5950
|
-
length: this.dynamicScale ? new C.CallbackProperty(() => this.headHeight * this.cachedScaleFactor, false) : this.headHeight,
|
|
5951
|
-
topRadius: 0,
|
|
5952
|
-
// Creates cone shape
|
|
5953
|
-
bottomRadius: this.dynamicScale ? new C.CallbackProperty(() => this.headRadius * this.cachedScaleFactor, false) : this.headRadius,
|
|
5954
|
-
material: this.color.withAlpha(this.headAlpha),
|
|
5955
|
-
outline: this.outline,
|
|
5956
|
-
outlineColor: this.outlineColor,
|
|
5957
|
-
outlineWidth: 2
|
|
5958
|
-
},
|
|
5959
|
-
properties: {
|
|
5960
|
-
...properties,
|
|
5961
|
-
_arrowPart: "head"
|
|
5962
|
-
}
|
|
5963
|
-
});
|
|
5964
|
-
entities.push(headEntity);
|
|
5965
|
-
const baseEntity = layer.entities.add({
|
|
5966
|
-
position,
|
|
5967
|
-
ellipse: {
|
|
5968
|
-
semiMajorAxis: this.dynamicScale ? new C.CallbackProperty(() => this.baseRadius * this.cachedScaleFactor, false) : this.baseRadius,
|
|
5969
|
-
semiMinorAxis: this.dynamicScale ? new C.CallbackProperty(() => this.baseRadius * this.cachedScaleFactor, false) : this.baseRadius,
|
|
5970
|
-
height: baseHeight,
|
|
5971
|
-
material: this.color.withAlpha(this.baseAlpha),
|
|
5972
|
-
outline: this.outline,
|
|
5973
|
-
outlineColor: this.outlineColor,
|
|
5974
|
-
outlineWidth: 2
|
|
5975
|
-
},
|
|
5976
|
-
properties: {
|
|
5977
|
-
...properties,
|
|
5978
|
-
_arrowPart: "base"
|
|
5979
|
-
}
|
|
5980
|
-
});
|
|
5981
|
-
entities.push(baseEntity);
|
|
5982
|
-
return entities;
|
|
5983
|
-
}
|
|
5984
|
-
/**
|
|
5985
|
-
* Get the color
|
|
5986
|
-
*/
|
|
5987
|
-
getColor() {
|
|
5988
|
-
return this.color;
|
|
5989
|
-
}
|
|
5990
|
-
/**
|
|
5991
|
-
* Update arrow color
|
|
5992
|
-
*/
|
|
5993
|
-
setColor(color) {
|
|
5994
|
-
const C = this.CesiumNS;
|
|
5995
|
-
this.color = C.Color.fromCssColorString(color);
|
|
5996
|
-
}
|
|
5997
|
-
/**
|
|
5998
|
-
* Update dimensions
|
|
5999
|
-
*/
|
|
6000
|
-
setDimensions(opts) {
|
|
6001
|
-
if (opts.shaftHeight !== void 0) this.shaftHeight = opts.shaftHeight;
|
|
6002
|
-
if (opts.headHeight !== void 0) this.headHeight = opts.headHeight;
|
|
6003
|
-
if (opts.shaftRadius !== void 0) this.shaftRadius = opts.shaftRadius;
|
|
6004
|
-
if (opts.headRadius !== void 0) this.headRadius = opts.headRadius;
|
|
6005
|
-
if (opts.baseRadius !== void 0) this.baseRadius = opts.baseRadius;
|
|
6006
|
-
this.height = this.shaftHeight + this.headHeight;
|
|
6007
|
-
}
|
|
6008
|
-
/**
|
|
6009
|
-
* Update transparency
|
|
6010
|
-
*/
|
|
6011
|
-
setAlpha(opts) {
|
|
6012
|
-
if (opts.shaftAlpha !== void 0) this.shaftAlpha = opts.shaftAlpha;
|
|
6013
|
-
if (opts.headAlpha !== void 0) this.headAlpha = opts.headAlpha;
|
|
6014
|
-
if (opts.baseAlpha !== void 0) this.baseAlpha = opts.baseAlpha;
|
|
6015
|
-
}
|
|
6016
|
-
/**
|
|
6017
|
-
* Get current dimensions
|
|
6018
|
-
*/
|
|
6019
|
-
getDimensions() {
|
|
6020
|
-
return {
|
|
6021
|
-
height: this.height,
|
|
6022
|
-
shaftHeight: this.shaftHeight,
|
|
6023
|
-
headHeight: this.headHeight,
|
|
6024
|
-
shaftRadius: this.shaftRadius,
|
|
6025
|
-
headRadius: this.headRadius,
|
|
6026
|
-
baseRadius: this.baseRadius
|
|
6027
|
-
};
|
|
6028
|
-
}
|
|
6029
|
-
/**
|
|
6030
|
-
* Get current alpha values
|
|
6031
|
-
*/
|
|
6032
|
-
getAlpha() {
|
|
6033
|
-
return {
|
|
6034
|
-
shaftAlpha: this.shaftAlpha,
|
|
6035
|
-
headAlpha: this.headAlpha,
|
|
6036
|
-
baseAlpha: this.baseAlpha
|
|
6037
|
-
};
|
|
6038
|
-
}
|
|
6039
|
-
/**
|
|
6040
|
-
* Get total height
|
|
6041
|
-
*/
|
|
6042
|
-
getHeight() {
|
|
6043
|
-
return this.height;
|
|
6044
|
-
}
|
|
6045
|
-
};
|
|
6046
|
-
|
|
6047
6126
|
// src/core/path-manager/startPathDrawing.ts
|
|
6048
6127
|
function startPathDrawing(CesiumNS, viewer, options, onComplete) {
|
|
6049
6128
|
const C = CesiumNS;
|
|
6050
6129
|
const layer = options?.layer ?? new C.CustomDataSource("Paths");
|
|
6051
6130
|
if (!options?.layer) viewer.dataSources.add(layer);
|
|
6052
6131
|
const altitudeMode = options?.altitudeMode ?? "absolute";
|
|
6053
|
-
const climbHeight = Number(options?.climbHeight) ||
|
|
6054
|
-
const
|
|
6055
|
-
|
|
6056
|
-
let hasStart = false;
|
|
6132
|
+
const climbHeight = Number(options?.climbHeight) || 0;
|
|
6133
|
+
const defaultAltitude = options?.defaultAltitude ?? options?.defaultHeight ?? 100;
|
|
6134
|
+
const DEFAULT_MAIN_WIDTH = options?.width ?? 3;
|
|
6057
6135
|
let createdEntity = void 0;
|
|
6136
|
+
let entityCreated = false;
|
|
6137
|
+
let editSession = void 0;
|
|
6058
6138
|
const getPositionFromMouse = (movement) => {
|
|
6059
6139
|
const scene = viewer.scene;
|
|
6060
6140
|
const winPos = movement?.position ?? movement?.endPosition ?? movement;
|
|
@@ -6070,129 +6150,54 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
|
|
|
6070
6150
|
}
|
|
6071
6151
|
return cart;
|
|
6072
6152
|
};
|
|
6073
|
-
const toCartographic = (cart) => {
|
|
6074
|
-
try {
|
|
6075
|
-
return C.Cartographic.fromCartesian(cart);
|
|
6076
|
-
} catch {
|
|
6077
|
-
return void 0;
|
|
6078
|
-
}
|
|
6079
|
-
};
|
|
6080
6153
|
let handler;
|
|
6081
|
-
const positions = [];
|
|
6082
|
-
const tempHandles = [];
|
|
6083
6154
|
handler = new C.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
6084
6155
|
handler.setInputAction((movement) => {
|
|
6085
|
-
if (hasStart) return;
|
|
6086
6156
|
const picked = getPositionFromMouse(movement);
|
|
6087
6157
|
if (!picked) return;
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
const groundPos = C.Cartesian3.fromDegrees(
|
|
6092
|
-
C.Math.toDegrees(carto.longitude),
|
|
6093
|
-
C.Math.toDegrees(carto.latitude),
|
|
6094
|
-
startCartographic.height
|
|
6095
|
-
);
|
|
6096
|
-
positions.push(groundPos);
|
|
6097
|
-
const arrowCarto = toCartographic(groundPos);
|
|
6098
|
-
const baseHeight = arrowCarto ? arrowCarto.height : 0;
|
|
6099
|
-
const arrowShape = new ArrowShape(CesiumNS, {
|
|
6100
|
-
shaftHeight: 12,
|
|
6101
|
-
headHeight: 12,
|
|
6102
|
-
shaftRadius: 4,
|
|
6103
|
-
headRadius: 8,
|
|
6104
|
-
baseRadius: 12,
|
|
6105
|
-
color: "#FFD700",
|
|
6106
|
-
shaftAlpha: 1,
|
|
6107
|
-
headAlpha: 1,
|
|
6108
|
-
baseAlpha: 0.5,
|
|
6109
|
-
// 启用动态缩放,和无人机模型一样根据相机距离调整大小
|
|
6110
|
-
dynamicScale: true,
|
|
6111
|
-
viewer,
|
|
6112
|
-
referenceDistance: 300,
|
|
6113
|
-
minScale: 0.3,
|
|
6114
|
-
maxScale: 2
|
|
6115
|
-
});
|
|
6116
|
-
const arrowEntities = arrowShape.createEntities(
|
|
6117
|
-
layer,
|
|
6118
|
-
groundPos,
|
|
6119
|
-
baseHeight,
|
|
6120
|
-
{ _type: "path-vertex", _vertexIndex: 0, _isStart: true }
|
|
6121
|
-
);
|
|
6122
|
-
tempHandles.push(...arrowEntities);
|
|
6123
|
-
hasStart = true;
|
|
6124
|
-
if (climbHeight > 0) {
|
|
6125
|
-
const climbPos = C.Cartesian3.fromDegrees(
|
|
6126
|
-
C.Math.toDegrees(startCartographic.longitude),
|
|
6127
|
-
C.Math.toDegrees(startCartographic.latitude),
|
|
6128
|
-
startCartographic.height + climbHeight
|
|
6129
|
-
);
|
|
6130
|
-
positions.push(climbPos);
|
|
6131
|
-
}
|
|
6132
|
-
let created;
|
|
6133
|
-
try {
|
|
6134
|
-
const id = `${options?.idPrefix ?? "path"}-${Date.now().toString(36)}`;
|
|
6135
|
-
const pathPositions = new C.CallbackProperty(() => {
|
|
6136
|
-
const p = created?.polyline?.positions;
|
|
6137
|
-
if (p && typeof p.getValue === "function") {
|
|
6138
|
-
try {
|
|
6139
|
-
return p.getValue();
|
|
6140
|
-
} catch {
|
|
6141
|
-
}
|
|
6142
|
-
}
|
|
6143
|
-
return positions.slice();
|
|
6144
|
-
}, false);
|
|
6145
|
-
created = layer.entities.add({
|
|
6146
|
-
id,
|
|
6147
|
-
name: "Path",
|
|
6148
|
-
polyline: {
|
|
6149
|
-
positions: pathPositions,
|
|
6150
|
-
width: DEFAULT_MAIN_WIDTH,
|
|
6151
|
-
material: new C.PolylineOutlineMaterialProperty({
|
|
6152
|
-
color: C.Color.LIME,
|
|
6153
|
-
outlineColor: C.Color.WHITE,
|
|
6154
|
-
outlineWidth: 2
|
|
6155
|
-
}),
|
|
6156
|
-
clampToGround: false
|
|
6157
|
-
},
|
|
6158
|
-
properties: {
|
|
6159
|
-
_altitudeMode: altitudeMode,
|
|
6160
|
-
_climbHeight: climbHeight,
|
|
6161
|
-
_hasHiddenClimb: climbHeight > 0
|
|
6162
|
-
}
|
|
6163
|
-
});
|
|
6164
|
-
createdEntity = created;
|
|
6158
|
+
if (!entityCreated) {
|
|
6159
|
+
entityCreated = true;
|
|
6160
|
+
let created;
|
|
6165
6161
|
try {
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6162
|
+
const id = `${options?.idPrefix ?? "path"}-${Date.now().toString(36)}`;
|
|
6163
|
+
const positions = [];
|
|
6164
|
+
const pathPositions = new C.CallbackProperty(() => positions.slice(), false);
|
|
6165
|
+
created = layer.entities.add({
|
|
6166
|
+
id,
|
|
6167
|
+
name: "Path",
|
|
6168
|
+
polyline: {
|
|
6169
|
+
positions: pathPositions,
|
|
6170
|
+
width: DEFAULT_MAIN_WIDTH,
|
|
6171
|
+
material: C.Color.fromCssColorString("#00E676"),
|
|
6172
|
+
clampToGround: false
|
|
6173
|
+
},
|
|
6174
|
+
properties: {
|
|
6175
|
+
_altitudeMode: altitudeMode,
|
|
6176
|
+
_defaultAltitude: defaultAltitude,
|
|
6177
|
+
_climbHeight: climbHeight,
|
|
6178
|
+
_useGlobalHeightFlags: []
|
|
6179
|
+
// 🆕 空数组,航点由编辑模式添加
|
|
6176
6180
|
}
|
|
6177
6181
|
});
|
|
6178
|
-
|
|
6179
|
-
}
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
handler = void 0;
|
|
6186
|
-
}
|
|
6187
|
-
if (created) {
|
|
6188
|
-
try {
|
|
6189
|
-
onComplete?.(created);
|
|
6190
|
-
} catch {
|
|
6182
|
+
createdEntity = created;
|
|
6183
|
+
} finally {
|
|
6184
|
+
try {
|
|
6185
|
+
handler?.destroy();
|
|
6186
|
+
} catch {
|
|
6187
|
+
}
|
|
6188
|
+
handler = void 0;
|
|
6191
6189
|
}
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6190
|
+
if (created) {
|
|
6191
|
+
try {
|
|
6192
|
+
onComplete?.(created);
|
|
6193
|
+
} catch {
|
|
6194
|
+
}
|
|
6195
|
+
try {
|
|
6196
|
+
const auto = options?.autoStartEditing;
|
|
6197
|
+
const editOptions = {
|
|
6198
|
+
// 🔧 默认使用自由编辑模式(快速编辑和自由编辑互斥)
|
|
6199
|
+
quickEdit: false
|
|
6200
|
+
};
|
|
6196
6201
|
if (typeof auto === "object" && auto.preview) {
|
|
6197
6202
|
editOptions.preview = auto.preview;
|
|
6198
6203
|
} else {
|
|
@@ -6214,30 +6219,35 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
|
|
|
6214
6219
|
if (autoOpts.onVertexDeleteDetail) {
|
|
6215
6220
|
editOptions.onVertexDeleteDetail = autoOpts.onVertexDeleteDetail;
|
|
6216
6221
|
}
|
|
6217
|
-
|
|
6222
|
+
editOptions.altitudeMode = altitudeMode;
|
|
6223
|
+
editOptions.defaultAltitude = defaultAltitude;
|
|
6224
|
+
editOptions.climbHeight = climbHeight;
|
|
6225
|
+
editSession = startPathEditing(CesiumNS, viewer, created, editOptions);
|
|
6226
|
+
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");
|
|
6218
6227
|
if (editSession && options?.onEditingStarted) {
|
|
6219
6228
|
try {
|
|
6220
6229
|
options.onEditingStarted(editSession);
|
|
6221
6230
|
} catch {
|
|
6222
6231
|
}
|
|
6223
6232
|
}
|
|
6233
|
+
} catch (error) {
|
|
6234
|
+
console.error("[startPathDrawing] \u8FDB\u5165\u7F16\u8F91\u6A21\u5F0F\u5931\u8D25:", error);
|
|
6224
6235
|
}
|
|
6225
|
-
} catch {
|
|
6226
6236
|
}
|
|
6227
6237
|
}
|
|
6228
6238
|
}, C.ScreenSpaceEventType.LEFT_CLICK);
|
|
6229
6239
|
return {
|
|
6230
6240
|
stop: () => {
|
|
6231
|
-
for (const h2 of tempHandles) {
|
|
6232
|
-
try {
|
|
6233
|
-
layer.entities.remove(h2);
|
|
6234
|
-
} catch {
|
|
6235
|
-
}
|
|
6236
|
-
}
|
|
6237
6241
|
try {
|
|
6238
6242
|
handler?.destroy();
|
|
6239
6243
|
} catch {
|
|
6240
6244
|
}
|
|
6245
|
+
if (editSession) {
|
|
6246
|
+
try {
|
|
6247
|
+
editSession.stop();
|
|
6248
|
+
} catch {
|
|
6249
|
+
}
|
|
6250
|
+
}
|
|
6241
6251
|
if (createdEntity) {
|
|
6242
6252
|
try {
|
|
6243
6253
|
layer.entities.remove(createdEntity);
|
|
@@ -6322,77 +6332,6 @@ function parseCoordinate(value) {
|
|
|
6322
6332
|
}
|
|
6323
6333
|
return 0;
|
|
6324
6334
|
}
|
|
6325
|
-
function parseTakeOffRefPoint(takeOffRefPoint, takeOffSecurityHeight, CesiumNS) {
|
|
6326
|
-
if (!takeOffRefPoint || typeof takeOffRefPoint !== "string" || takeOffRefPoint.trim() === "") {
|
|
6327
|
-
return null;
|
|
6328
|
-
}
|
|
6329
|
-
const C = CesiumNS;
|
|
6330
|
-
let longitude;
|
|
6331
|
-
let latitude;
|
|
6332
|
-
let height;
|
|
6333
|
-
const trimmed = takeOffRefPoint.trim();
|
|
6334
|
-
if (trimmed.includes(",")) {
|
|
6335
|
-
try {
|
|
6336
|
-
const parts = trimmed.split(",").map((p) => p.trim());
|
|
6337
|
-
if (parts.length >= 2) {
|
|
6338
|
-
latitude = parseFloat(parts[0]);
|
|
6339
|
-
longitude = parseFloat(parts[1]);
|
|
6340
|
-
height = parts.length >= 3 ? parseFloat(parts[2]) : takeOffSecurityHeight;
|
|
6341
|
-
if (isNaN(latitude) || isNaN(longitude) || isNaN(height)) {
|
|
6342
|
-
throw new Error("\u65E0\u6CD5\u89E3\u6790\u9017\u53F7\u5206\u9694\u7684\u5750\u6807\u503C");
|
|
6343
|
-
}
|
|
6344
|
-
const startPosition = C.Cartesian3.fromDegrees(longitude, latitude, height);
|
|
6345
|
-
const climbPosition = C.Cartesian3.fromDegrees(
|
|
6346
|
-
longitude,
|
|
6347
|
-
latitude,
|
|
6348
|
-
height + takeOffSecurityHeight
|
|
6349
|
-
);
|
|
6350
|
-
return {
|
|
6351
|
-
startPosition,
|
|
6352
|
-
climbPosition
|
|
6353
|
-
};
|
|
6354
|
-
}
|
|
6355
|
-
} catch (error) {
|
|
6356
|
-
}
|
|
6357
|
-
}
|
|
6358
|
-
try {
|
|
6359
|
-
const parsed = JSON.parse(takeOffRefPoint);
|
|
6360
|
-
if (typeof parsed !== "object" || parsed === null) {
|
|
6361
|
-
return null;
|
|
6362
|
-
}
|
|
6363
|
-
if (typeof parsed.longitude === "number") {
|
|
6364
|
-
longitude = parsed.longitude;
|
|
6365
|
-
} else if (typeof parsed.lon === "number") {
|
|
6366
|
-
longitude = parsed.lon;
|
|
6367
|
-
} else {
|
|
6368
|
-
return null;
|
|
6369
|
-
}
|
|
6370
|
-
if (typeof parsed.latitude === "number") {
|
|
6371
|
-
latitude = parsed.latitude;
|
|
6372
|
-
} else if (typeof parsed.lat === "number") {
|
|
6373
|
-
latitude = parsed.lat;
|
|
6374
|
-
} else {
|
|
6375
|
-
return null;
|
|
6376
|
-
}
|
|
6377
|
-
if (typeof parsed.height === "number") {
|
|
6378
|
-
height = parsed.height;
|
|
6379
|
-
} else {
|
|
6380
|
-
height = takeOffSecurityHeight;
|
|
6381
|
-
}
|
|
6382
|
-
const startPosition = C.Cartesian3.fromDegrees(longitude, latitude, height);
|
|
6383
|
-
const climbPosition = C.Cartesian3.fromDegrees(
|
|
6384
|
-
longitude,
|
|
6385
|
-
latitude,
|
|
6386
|
-
height + takeOffSecurityHeight
|
|
6387
|
-
);
|
|
6388
|
-
return {
|
|
6389
|
-
startPosition,
|
|
6390
|
-
climbPosition
|
|
6391
|
-
};
|
|
6392
|
-
} catch (error) {
|
|
6393
|
-
return null;
|
|
6394
|
-
}
|
|
6395
|
-
}
|
|
6396
6335
|
function convertSinoflyWayline(data, options) {
|
|
6397
6336
|
const {
|
|
6398
6337
|
CesiumNS,
|
|
@@ -6415,11 +6354,6 @@ function convertSinoflyWayline(data, options) {
|
|
|
6415
6354
|
if (data.waylineId === void 0 || data.waylineId === null) {
|
|
6416
6355
|
throw new Error("[sinoflyAdapter] waylineId \u4E0D\u80FD\u4E3A\u7A7A");
|
|
6417
6356
|
}
|
|
6418
|
-
const takeOffInfo = parseTakeOffRefPoint(
|
|
6419
|
-
data.takeOffRefPoint,
|
|
6420
|
-
data.takeOffSecurityHeight,
|
|
6421
|
-
CesiumNS
|
|
6422
|
-
);
|
|
6423
6357
|
let waypoints = data.waypointInfo;
|
|
6424
6358
|
if (filterWaypoint) {
|
|
6425
6359
|
waypoints = waypoints.filter(filterWaypoint);
|
|
@@ -6427,31 +6361,6 @@ function convertSinoflyWayline(data, options) {
|
|
|
6427
6361
|
if (sortByIndex) {
|
|
6428
6362
|
waypoints = [...waypoints].sort((a, b) => a.index - b.index);
|
|
6429
6363
|
}
|
|
6430
|
-
const finalWaypointData = [];
|
|
6431
|
-
if (takeOffInfo) {
|
|
6432
|
-
finalWaypointData.push({
|
|
6433
|
-
position: takeOffInfo.startPosition,
|
|
6434
|
-
heading: defaultHeading,
|
|
6435
|
-
pitch: defaultPitch,
|
|
6436
|
-
roll: defaultRoll,
|
|
6437
|
-
fov: defaultFov,
|
|
6438
|
-
index: 0
|
|
6439
|
-
});
|
|
6440
|
-
finalWaypointData.push({
|
|
6441
|
-
position: takeOffInfo.climbPosition,
|
|
6442
|
-
heading: defaultHeading,
|
|
6443
|
-
pitch: defaultPitch,
|
|
6444
|
-
roll: defaultRoll,
|
|
6445
|
-
fov: defaultFov,
|
|
6446
|
-
index: 1
|
|
6447
|
-
});
|
|
6448
|
-
}
|
|
6449
|
-
let waypointStartIndex;
|
|
6450
|
-
if (takeOffInfo) {
|
|
6451
|
-
waypointStartIndex = 2;
|
|
6452
|
-
} else {
|
|
6453
|
-
waypointStartIndex = 0;
|
|
6454
|
-
}
|
|
6455
6364
|
const convertedWaypoints = waypoints.map((wp, idx) => {
|
|
6456
6365
|
try {
|
|
6457
6366
|
if (!wp) {
|
|
@@ -6487,15 +6396,16 @@ function convertSinoflyWayline(data, options) {
|
|
|
6487
6396
|
pitch,
|
|
6488
6397
|
roll,
|
|
6489
6398
|
fov,
|
|
6490
|
-
index:
|
|
6491
|
-
//
|
|
6399
|
+
index: idx,
|
|
6400
|
+
// 从 0 开始分配 index
|
|
6401
|
+
useGlobalHeight: false
|
|
6402
|
+
// 🆕 从服务端加载的航点默认使用实际高度
|
|
6492
6403
|
};
|
|
6493
6404
|
} catch (error) {
|
|
6494
6405
|
throw new Error(`\u822A\u70B9 ${idx} \u8F6C\u6362\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
6495
6406
|
}
|
|
6496
6407
|
});
|
|
6497
|
-
|
|
6498
|
-
if (!Array.isArray(waypointData)) {
|
|
6408
|
+
if (!Array.isArray(convertedWaypoints)) {
|
|
6499
6409
|
throw new Error("[sinoflyAdapter] waypointData \u4E0D\u662F\u6570\u7EC4");
|
|
6500
6410
|
}
|
|
6501
6411
|
const metadata = {
|
|
@@ -6506,8 +6416,8 @@ function convertSinoflyWayline(data, options) {
|
|
|
6506
6416
|
autoFlightSpeed: data.autoFlightSpeed,
|
|
6507
6417
|
distance: data.distance,
|
|
6508
6418
|
duration: data.duration,
|
|
6509
|
-
|
|
6510
|
-
|
|
6419
|
+
climbHeight: data.takeOffSecurityHeight
|
|
6420
|
+
// 使用 climbHeight 作为字段名
|
|
6511
6421
|
};
|
|
6512
6422
|
if (data.stationId !== void 0) metadata.stationId = data.stationId;
|
|
6513
6423
|
if (data.subarrayId !== void 0) metadata.subarrayId = data.subarrayId;
|
|
@@ -6517,7 +6427,7 @@ function convertSinoflyWayline(data, options) {
|
|
|
6517
6427
|
id: `wayline-${data.waylineId}`,
|
|
6518
6428
|
name: data.waylineName || `\u822A\u7EBF-${data.waylineId}`,
|
|
6519
6429
|
description: `\u822A\u7EBFID: ${data.waylineId}, \u7C7B\u578B: ${data.waylineType}, \u822A\u70B9\u6570: ${data.waypointNumber}`,
|
|
6520
|
-
waypointData,
|
|
6430
|
+
waypointData: convertedWaypoints,
|
|
6521
6431
|
metadata
|
|
6522
6432
|
};
|
|
6523
6433
|
}
|
|
@@ -6530,7 +6440,6 @@ function renderFlightPath(CesiumNS, viewer, options) {
|
|
|
6530
6440
|
let entityId;
|
|
6531
6441
|
let entityName;
|
|
6532
6442
|
let entityDescription;
|
|
6533
|
-
let hasHiddenClimb;
|
|
6534
6443
|
let altitudeMode;
|
|
6535
6444
|
let climbHeight;
|
|
6536
6445
|
try {
|
|
@@ -6546,12 +6455,8 @@ function renderFlightPath(CesiumNS, viewer, options) {
|
|
|
6546
6455
|
entityId = options.id ?? converted.id ?? `wayline-${sinoflyData.waylineId}`;
|
|
6547
6456
|
entityName = options.name ?? converted.name;
|
|
6548
6457
|
entityDescription = options.description ?? converted.description;
|
|
6549
|
-
const sortedWaypoints2 = [...waypointData].sort((a, b) => a.index - b.index);
|
|
6550
|
-
const hasIndex1 = sortedWaypoints2.some((wp) => wp.index === 1);
|
|
6551
|
-
const hasTakeOffRefPoint = converted.metadata?.hasTakeOffRefPoint ?? !!sinoflyData.takeOffRefPoint;
|
|
6552
|
-
hasHiddenClimb = options.hasHiddenClimb ?? (hasTakeOffRefPoint && hasIndex1);
|
|
6553
6458
|
altitudeMode = options.altitudeMode ?? converted.metadata?.altitudeMode;
|
|
6554
|
-
climbHeight = options.climbHeight ?? converted.metadata?.climbHeight
|
|
6459
|
+
climbHeight = options.climbHeight ?? converted.metadata?.climbHeight;
|
|
6555
6460
|
} catch (error) {
|
|
6556
6461
|
console.error("[renderFlightPath] Sinofly \u6570\u636E\u8F6C\u6362\u5931\u8D25:", error);
|
|
6557
6462
|
throw new Error(`Sinofly \u6570\u636E\u8F6C\u6362\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -6573,66 +6478,25 @@ function renderFlightPath(CesiumNS, viewer, options) {
|
|
|
6573
6478
|
layer = new C.CustomDataSource(`flight-path-datasource-${Date.now()}`);
|
|
6574
6479
|
viewer.dataSources.add(layer);
|
|
6575
6480
|
}
|
|
6576
|
-
const hiddenClimbIndex =
|
|
6577
|
-
const
|
|
6481
|
+
const hiddenClimbIndex = void 0;
|
|
6482
|
+
const useGlobalHeightFlags = sortedWaypoints.map((wp) => wp.useGlobalHeight ?? false);
|
|
6578
6483
|
const entity = layer.entities.add({
|
|
6579
6484
|
id: entityId,
|
|
6580
6485
|
name: entityName,
|
|
6581
6486
|
description: entityDescription,
|
|
6582
6487
|
polyline: {
|
|
6583
6488
|
positions: positions.slice(),
|
|
6584
|
-
width: options.style?.width ??
|
|
6585
|
-
material: options.style?.material ?? options.style?.color ??
|
|
6586
|
-
color: C.Color.GREEN,
|
|
6587
|
-
outlineColor: C.Color.WHITE,
|
|
6588
|
-
outlineWidth: 3
|
|
6589
|
-
}),
|
|
6489
|
+
width: options.style?.width ?? 3,
|
|
6490
|
+
material: options.style?.material ?? options.style?.color ?? C.Color.fromCssColorString("#00E676"),
|
|
6590
6491
|
clampToGround: false
|
|
6591
6492
|
},
|
|
6592
6493
|
properties: {
|
|
6593
6494
|
_altitudeMode: altitudeMode,
|
|
6594
6495
|
_climbHeight: climbHeight,
|
|
6595
|
-
|
|
6496
|
+
_useGlobalHeightFlags: useGlobalHeightFlags
|
|
6497
|
+
// 🆕 保存 useGlobalHeightFlags
|
|
6596
6498
|
}
|
|
6597
6499
|
});
|
|
6598
|
-
const shouldShowArrow = hasStartPoint && hasHiddenClimb;
|
|
6599
|
-
if (shouldShowArrow) {
|
|
6600
|
-
try {
|
|
6601
|
-
const startPosition = positions[0];
|
|
6602
|
-
const carto = C.Cartographic.fromCartesian(startPosition);
|
|
6603
|
-
const baseHeight = carto ? carto.height : 0;
|
|
6604
|
-
const arrowShape = new ArrowShape(CesiumNS, {
|
|
6605
|
-
shaftHeight: 12,
|
|
6606
|
-
headHeight: 12,
|
|
6607
|
-
shaftRadius: 4,
|
|
6608
|
-
headRadius: 8,
|
|
6609
|
-
baseRadius: 12,
|
|
6610
|
-
color: "#FFD700",
|
|
6611
|
-
shaftAlpha: 0.98,
|
|
6612
|
-
headAlpha: 0.98,
|
|
6613
|
-
baseAlpha: 0.65,
|
|
6614
|
-
// 启用动态缩放
|
|
6615
|
-
dynamicScale: true,
|
|
6616
|
-
viewer,
|
|
6617
|
-
referenceDistance: 300,
|
|
6618
|
-
minScale: 0.3,
|
|
6619
|
-
maxScale: 2
|
|
6620
|
-
});
|
|
6621
|
-
arrowShape.createEntities(
|
|
6622
|
-
layer,
|
|
6623
|
-
startPosition,
|
|
6624
|
-
baseHeight,
|
|
6625
|
-
{
|
|
6626
|
-
_type: "path-vertex",
|
|
6627
|
-
_ownerId: entityId,
|
|
6628
|
-
_vertexIndex: 0,
|
|
6629
|
-
_isStart: true
|
|
6630
|
-
}
|
|
6631
|
-
);
|
|
6632
|
-
} catch (error) {
|
|
6633
|
-
console.error("Failed to create start arrow:", error);
|
|
6634
|
-
}
|
|
6635
|
-
}
|
|
6636
6500
|
try {
|
|
6637
6501
|
const vertexLabelManager = new VertexLabelManager(
|
|
6638
6502
|
CesiumNS,
|
|
@@ -6673,8 +6537,6 @@ function renderFlightPathPreview(CesiumNS, viewer, options) {
|
|
|
6673
6537
|
} catch (e) {
|
|
6674
6538
|
console.warn("[renderFlightPathPreview] \u65E0\u6CD5\u83B7\u53D6\u822A\u70B9\u6570\u636E:", e);
|
|
6675
6539
|
}
|
|
6676
|
-
const hasHiddenClimb = entity.properties?._hasHiddenClimb?.getValue?.() ?? false;
|
|
6677
|
-
const hiddenClimbIndex = hasHiddenClimb ? 1 : void 0;
|
|
6678
6540
|
const updateWaypointHighlight = (newIndex) => {
|
|
6679
6541
|
if (!vertexLabelManager || positions.length === 0) return;
|
|
6680
6542
|
const editedIndices = /* @__PURE__ */ new Set();
|
|
@@ -6694,14 +6556,7 @@ function renderFlightPathPreview(CesiumNS, viewer, options) {
|
|
|
6694
6556
|
const ownerId = properties._ownerId?.getValue?.(C.JulianDate.now());
|
|
6695
6557
|
const vertexIndex = properties._vertexIndex?.getValue?.(C.JulianDate.now());
|
|
6696
6558
|
if (type === "vertex-label" && ownerId === entity.id && vertexIndex !== void 0) {
|
|
6697
|
-
|
|
6698
|
-
if (hiddenClimbIndex === 1) {
|
|
6699
|
-
if (vertexIndex >= 2) {
|
|
6700
|
-
displayIndex = vertexIndex - 2;
|
|
6701
|
-
}
|
|
6702
|
-
} else {
|
|
6703
|
-
displayIndex = vertexIndex;
|
|
6704
|
-
}
|
|
6559
|
+
const displayIndex = vertexIndex;
|
|
6705
6560
|
selectedWaypointIndex = vertexIndex;
|
|
6706
6561
|
updateWaypointHighlight(selectedWaypointIndex);
|
|
6707
6562
|
if (options.onWaypointClick) {
|
|
@@ -6719,18 +6574,10 @@ function renderFlightPathPreview(CesiumNS, viewer, options) {
|
|
|
6719
6574
|
updateWaypointHighlight(null);
|
|
6720
6575
|
return;
|
|
6721
6576
|
}
|
|
6722
|
-
|
|
6723
|
-
if (hiddenClimbIndex === 1) {
|
|
6724
|
-
actualIndex = index + 2;
|
|
6725
|
-
}
|
|
6726
|
-
selectedWaypointIndex = actualIndex;
|
|
6577
|
+
selectedWaypointIndex = index;
|
|
6727
6578
|
updateWaypointHighlight(selectedWaypointIndex);
|
|
6728
6579
|
},
|
|
6729
6580
|
getSelectedWaypoint: () => {
|
|
6730
|
-
if (selectedWaypointIndex === null) return null;
|
|
6731
|
-
if (hiddenClimbIndex === 1) {
|
|
6732
|
-
return selectedWaypointIndex >= 2 ? selectedWaypointIndex - 2 : null;
|
|
6733
|
-
}
|
|
6734
6581
|
return selectedWaypointIndex;
|
|
6735
6582
|
},
|
|
6736
6583
|
destroy: () => {
|
|
@@ -6740,6 +6587,299 @@ function renderFlightPathPreview(CesiumNS, viewer, options) {
|
|
|
6740
6587
|
return { entity, controller };
|
|
6741
6588
|
}
|
|
6742
6589
|
|
|
6590
|
+
// src/core/path-manager/FlightSimulator.ts
|
|
6591
|
+
var FlightSimulator = class {
|
|
6592
|
+
constructor(CesiumNS, viewer, options) {
|
|
6593
|
+
__publicField(this, "CesiumNS");
|
|
6594
|
+
__publicField(this, "viewer");
|
|
6595
|
+
__publicField(this, "options");
|
|
6596
|
+
__publicField(this, "state", "idle");
|
|
6597
|
+
__publicField(this, "progress", 0);
|
|
6598
|
+
__publicField(this, "waypoints", []);
|
|
6599
|
+
__publicField(this, "totalDistance", 0);
|
|
6600
|
+
__publicField(this, "currentDistance", 0);
|
|
6601
|
+
__publicField(this, "airplaneCursor");
|
|
6602
|
+
__publicField(this, "trackEntity");
|
|
6603
|
+
__publicField(this, "passedTrackEntity");
|
|
6604
|
+
__publicField(this, "animationFrameId");
|
|
6605
|
+
__publicField(this, "lastTimestamp");
|
|
6606
|
+
__publicField(this, "onStateChange", new Emitter());
|
|
6607
|
+
/**
|
|
6608
|
+
* 动画循环
|
|
6609
|
+
*/
|
|
6610
|
+
__publicField(this, "animate", (timestamp) => {
|
|
6611
|
+
if (this.state !== "playing") return;
|
|
6612
|
+
if (this.lastTimestamp === void 0) {
|
|
6613
|
+
this.lastTimestamp = timestamp;
|
|
6614
|
+
}
|
|
6615
|
+
const deltaTime = (timestamp - this.lastTimestamp) / 1e3;
|
|
6616
|
+
this.lastTimestamp = timestamp;
|
|
6617
|
+
this.currentDistance += this.options.speed * deltaTime;
|
|
6618
|
+
if (this.currentDistance >= this.totalDistance) {
|
|
6619
|
+
if (this.options.loop) {
|
|
6620
|
+
this.currentDistance = 0;
|
|
6621
|
+
} else {
|
|
6622
|
+
this.currentDistance = this.totalDistance;
|
|
6623
|
+
this.setState("stopped");
|
|
6624
|
+
return;
|
|
6625
|
+
}
|
|
6626
|
+
}
|
|
6627
|
+
this.progress = this.totalDistance > 0 ? this.currentDistance / this.totalDistance : 0;
|
|
6628
|
+
if (this.airplaneCursor) {
|
|
6629
|
+
const position = this.getCurrentPosition();
|
|
6630
|
+
const { heading, pitch, roll } = this.getCurrentPose();
|
|
6631
|
+
this.airplaneCursor.setPose(position, heading, pitch, roll);
|
|
6632
|
+
}
|
|
6633
|
+
this.viewer.scene.requestRender();
|
|
6634
|
+
this.animationFrameId = requestAnimationFrame(this.animate);
|
|
6635
|
+
});
|
|
6636
|
+
this.CesiumNS = CesiumNS;
|
|
6637
|
+
this.viewer = viewer;
|
|
6638
|
+
this.options = {
|
|
6639
|
+
waylineData: options.waylineData,
|
|
6640
|
+
speed: options.speed ?? 10,
|
|
6641
|
+
loop: options.loop ?? false,
|
|
6642
|
+
showFrustum: options.showFrustum ?? true,
|
|
6643
|
+
layer: options.layer,
|
|
6644
|
+
trackHighlight: options.trackHighlight
|
|
6645
|
+
};
|
|
6646
|
+
this.initWaypoints();
|
|
6647
|
+
this.createEntities();
|
|
6648
|
+
}
|
|
6649
|
+
/**
|
|
6650
|
+
* 初始化航点数据
|
|
6651
|
+
*/
|
|
6652
|
+
initWaypoints() {
|
|
6653
|
+
const C = this.CesiumNS;
|
|
6654
|
+
const converted = convertSinoflyWayline(this.options.waylineData, { CesiumNS: this.CesiumNS });
|
|
6655
|
+
if (!converted.waypointData || converted.waypointData.length < 2) {
|
|
6656
|
+
console.warn("[FlightSimulator] \u822A\u70B9\u6570\u91CF\u4E0D\u8DB3");
|
|
6657
|
+
return;
|
|
6658
|
+
}
|
|
6659
|
+
const tempWaypoints = converted.waypointData.map((wp) => ({
|
|
6660
|
+
cartesian: wp.position,
|
|
6661
|
+
heading: wp.heading ?? 0,
|
|
6662
|
+
pitch: wp.pitch ?? 0,
|
|
6663
|
+
roll: wp.roll ?? 0,
|
|
6664
|
+
cumulativeDistance: 0
|
|
6665
|
+
}));
|
|
6666
|
+
let cumulativeDistance = 0;
|
|
6667
|
+
for (let i = 0; i < tempWaypoints.length; i++) {
|
|
6668
|
+
if (i > 0) {
|
|
6669
|
+
const prevCartesian = tempWaypoints[i - 1].cartesian;
|
|
6670
|
+
const currCartesian = tempWaypoints[i].cartesian;
|
|
6671
|
+
cumulativeDistance += C.Cartesian3.distance(prevCartesian, currCartesian);
|
|
6672
|
+
}
|
|
6673
|
+
tempWaypoints[i].cumulativeDistance = cumulativeDistance;
|
|
6674
|
+
}
|
|
6675
|
+
this.waypoints = tempWaypoints;
|
|
6676
|
+
this.totalDistance = cumulativeDistance;
|
|
6677
|
+
}
|
|
6678
|
+
/**
|
|
6679
|
+
* 创建可视化实体
|
|
6680
|
+
*/
|
|
6681
|
+
createEntities() {
|
|
6682
|
+
if (this.waypoints.length === 0) return;
|
|
6683
|
+
const firstWaypoint = this.waypoints[0];
|
|
6684
|
+
this.airplaneCursor = new AirplaneCursor(
|
|
6685
|
+
this.CesiumNS,
|
|
6686
|
+
this.viewer,
|
|
6687
|
+
firstWaypoint.cartesian,
|
|
6688
|
+
{
|
|
6689
|
+
// 禁用键盘控制(仿真模式下不需要手动控制)
|
|
6690
|
+
stepMeters: 0,
|
|
6691
|
+
angleStepDeg: 0,
|
|
6692
|
+
fovDeg: 50
|
|
6693
|
+
}
|
|
6694
|
+
);
|
|
6695
|
+
this.airplaneCursor.setPose(
|
|
6696
|
+
firstWaypoint.cartesian,
|
|
6697
|
+
firstWaypoint.heading,
|
|
6698
|
+
firstWaypoint.pitch,
|
|
6699
|
+
firstWaypoint.roll
|
|
6700
|
+
);
|
|
6701
|
+
if (this.options.trackHighlight?.enabled) {
|
|
6702
|
+
this.createTrackHighlight();
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
/**
|
|
6706
|
+
* 创建航迹高亮
|
|
6707
|
+
*/
|
|
6708
|
+
createTrackHighlight() {
|
|
6709
|
+
const C = this.CesiumNS;
|
|
6710
|
+
const entities = this.options.layer?.entities ?? this.viewer.entities;
|
|
6711
|
+
const highlightOpts = this.options.trackHighlight;
|
|
6712
|
+
const allPositions = this.waypoints.map((wp) => wp.cartesian);
|
|
6713
|
+
this.trackEntity = entities.add({
|
|
6714
|
+
id: `flight-simulator-track-${Date.now()}`,
|
|
6715
|
+
polyline: {
|
|
6716
|
+
positions: allPositions,
|
|
6717
|
+
width: highlightOpts.width ?? 4,
|
|
6718
|
+
material: (highlightOpts.color ?? C.Color.CYAN).withAlpha(0.3),
|
|
6719
|
+
clampToGround: false
|
|
6720
|
+
},
|
|
6721
|
+
properties: {
|
|
6722
|
+
_type: "flight-simulator-track"
|
|
6723
|
+
}
|
|
6724
|
+
});
|
|
6725
|
+
this.passedTrackEntity = entities.add({
|
|
6726
|
+
id: `flight-simulator-passed-track-${Date.now()}`,
|
|
6727
|
+
polyline: {
|
|
6728
|
+
positions: new C.CallbackProperty(() => this.getPassedPositions(), false),
|
|
6729
|
+
width: (highlightOpts.width ?? 4) + 2,
|
|
6730
|
+
material: highlightOpts.color ?? C.Color.CYAN,
|
|
6731
|
+
clampToGround: false
|
|
6732
|
+
},
|
|
6733
|
+
properties: {
|
|
6734
|
+
_type: "flight-simulator-passed-track"
|
|
6735
|
+
}
|
|
6736
|
+
});
|
|
6737
|
+
}
|
|
6738
|
+
/**
|
|
6739
|
+
* 获取当前位置
|
|
6740
|
+
*/
|
|
6741
|
+
getCurrentPosition() {
|
|
6742
|
+
if (this.waypoints.length === 0) {
|
|
6743
|
+
return this.CesiumNS.Cartesian3.ZERO;
|
|
6744
|
+
}
|
|
6745
|
+
const C = this.CesiumNS;
|
|
6746
|
+
for (let i = 1; i < this.waypoints.length; i++) {
|
|
6747
|
+
const prev = this.waypoints[i - 1];
|
|
6748
|
+
const curr = this.waypoints[i];
|
|
6749
|
+
if (this.currentDistance <= curr.cumulativeDistance) {
|
|
6750
|
+
const segmentStart = prev.cumulativeDistance;
|
|
6751
|
+
const segmentEnd = curr.cumulativeDistance;
|
|
6752
|
+
const segmentLength = segmentEnd - segmentStart;
|
|
6753
|
+
if (segmentLength <= 0) {
|
|
6754
|
+
return prev.cartesian;
|
|
6755
|
+
}
|
|
6756
|
+
const t = (this.currentDistance - segmentStart) / segmentLength;
|
|
6757
|
+
return C.Cartesian3.lerp(prev.cartesian, curr.cartesian, t, new C.Cartesian3());
|
|
6758
|
+
}
|
|
6759
|
+
}
|
|
6760
|
+
return this.waypoints[this.waypoints.length - 1].cartesian;
|
|
6761
|
+
}
|
|
6762
|
+
/**
|
|
6763
|
+
* 获取当前姿态(用于更新 AirplaneCursor)
|
|
6764
|
+
*/
|
|
6765
|
+
getCurrentPose() {
|
|
6766
|
+
const C = this.CesiumNS;
|
|
6767
|
+
let heading = 0;
|
|
6768
|
+
let pitch = 0;
|
|
6769
|
+
let roll = 0;
|
|
6770
|
+
for (let i = 1; i < this.waypoints.length; i++) {
|
|
6771
|
+
const prev = this.waypoints[i - 1];
|
|
6772
|
+
const curr = this.waypoints[i];
|
|
6773
|
+
if (this.currentDistance <= curr.cumulativeDistance) {
|
|
6774
|
+
const segmentStart = prev.cumulativeDistance;
|
|
6775
|
+
const segmentEnd = curr.cumulativeDistance;
|
|
6776
|
+
const segmentLength = segmentEnd - segmentStart;
|
|
6777
|
+
if (segmentLength > 0) {
|
|
6778
|
+
const t = (this.currentDistance - segmentStart) / segmentLength;
|
|
6779
|
+
heading = C.Math.lerp(prev.heading, curr.heading, t);
|
|
6780
|
+
pitch = C.Math.lerp(prev.pitch, curr.pitch, t);
|
|
6781
|
+
roll = C.Math.lerp(prev.roll, curr.roll, t);
|
|
6782
|
+
} else {
|
|
6783
|
+
heading = prev.heading;
|
|
6784
|
+
pitch = prev.pitch;
|
|
6785
|
+
roll = prev.roll;
|
|
6786
|
+
}
|
|
6787
|
+
break;
|
|
6788
|
+
}
|
|
6789
|
+
}
|
|
6790
|
+
return { heading, pitch, roll };
|
|
6791
|
+
}
|
|
6792
|
+
/**
|
|
6793
|
+
* 获取已飞过的位置数组
|
|
6794
|
+
*/
|
|
6795
|
+
getPassedPositions() {
|
|
6796
|
+
const positions = [];
|
|
6797
|
+
for (let i = 0; i < this.waypoints.length; i++) {
|
|
6798
|
+
const wp = this.waypoints[i];
|
|
6799
|
+
if (wp.cumulativeDistance <= this.currentDistance) {
|
|
6800
|
+
positions.push(wp.cartesian);
|
|
6801
|
+
} else {
|
|
6802
|
+
positions.push(this.getCurrentPosition());
|
|
6803
|
+
break;
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6806
|
+
return positions;
|
|
6807
|
+
}
|
|
6808
|
+
/**
|
|
6809
|
+
* 设置状态并发射事件
|
|
6810
|
+
*/
|
|
6811
|
+
setState(newState) {
|
|
6812
|
+
if (this.state === newState) return;
|
|
6813
|
+
this.state = newState;
|
|
6814
|
+
this.onStateChange.emit({ state: newState, progress: this.progress });
|
|
6815
|
+
}
|
|
6816
|
+
// ==================== 公共方法 ====================
|
|
6817
|
+
start() {
|
|
6818
|
+
if (this.waypoints.length < 2) {
|
|
6819
|
+
console.warn("[FlightSimulator] \u822A\u70B9\u6570\u91CF\u4E0D\u8DB3\uFF0C\u65E0\u6CD5\u5F00\u59CB\u4EFF\u771F");
|
|
6820
|
+
return;
|
|
6821
|
+
}
|
|
6822
|
+
this.currentDistance = 0;
|
|
6823
|
+
this.progress = 0;
|
|
6824
|
+
this.lastTimestamp = void 0;
|
|
6825
|
+
this.setState("playing");
|
|
6826
|
+
this.animationFrameId = requestAnimationFrame(this.animate);
|
|
6827
|
+
}
|
|
6828
|
+
pause() {
|
|
6829
|
+
if (this.state !== "playing") return;
|
|
6830
|
+
if (this.animationFrameId !== void 0) {
|
|
6831
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
6832
|
+
this.animationFrameId = void 0;
|
|
6833
|
+
}
|
|
6834
|
+
this.lastTimestamp = void 0;
|
|
6835
|
+
this.setState("paused");
|
|
6836
|
+
}
|
|
6837
|
+
resume() {
|
|
6838
|
+
if (this.state !== "paused") return;
|
|
6839
|
+
this.lastTimestamp = void 0;
|
|
6840
|
+
this.setState("playing");
|
|
6841
|
+
this.animationFrameId = requestAnimationFrame(this.animate);
|
|
6842
|
+
}
|
|
6843
|
+
stop() {
|
|
6844
|
+
if (this.animationFrameId !== void 0) {
|
|
6845
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
6846
|
+
this.animationFrameId = void 0;
|
|
6847
|
+
}
|
|
6848
|
+
this.currentDistance = 0;
|
|
6849
|
+
this.progress = 0;
|
|
6850
|
+
this.lastTimestamp = void 0;
|
|
6851
|
+
this.setState("stopped");
|
|
6852
|
+
this.viewer.scene.requestRender();
|
|
6853
|
+
}
|
|
6854
|
+
destroy() {
|
|
6855
|
+
this.stop();
|
|
6856
|
+
const entities = this.options.layer?.entities ?? this.viewer.entities;
|
|
6857
|
+
if (this.airplaneCursor) {
|
|
6858
|
+
this.airplaneCursor.destroy();
|
|
6859
|
+
this.airplaneCursor = void 0;
|
|
6860
|
+
}
|
|
6861
|
+
if (this.trackEntity) {
|
|
6862
|
+
entities.remove(this.trackEntity);
|
|
6863
|
+
this.trackEntity = void 0;
|
|
6864
|
+
}
|
|
6865
|
+
if (this.passedTrackEntity) {
|
|
6866
|
+
entities.remove(this.passedTrackEntity);
|
|
6867
|
+
this.passedTrackEntity = void 0;
|
|
6868
|
+
}
|
|
6869
|
+
this.waypoints = [];
|
|
6870
|
+
this.setState("idle");
|
|
6871
|
+
}
|
|
6872
|
+
setSpeed(speed) {
|
|
6873
|
+
this.options.speed = Math.max(0.1, speed);
|
|
6874
|
+
}
|
|
6875
|
+
getState() {
|
|
6876
|
+
return this.state;
|
|
6877
|
+
}
|
|
6878
|
+
getProgress() {
|
|
6879
|
+
return this.progress;
|
|
6880
|
+
}
|
|
6881
|
+
};
|
|
6882
|
+
|
|
6743
6883
|
// src/core/CZMLPathManager.ts
|
|
6744
6884
|
var _CZMLPathManager = class _CZMLPathManager {
|
|
6745
6885
|
constructor(CesiumNS, viewer) {
|
|
@@ -7016,6 +7156,20 @@ var _CZMLPathManager = class _CZMLPathManager {
|
|
|
7016
7156
|
options
|
|
7017
7157
|
);
|
|
7018
7158
|
}
|
|
7159
|
+
/**
|
|
7160
|
+
* Start flight simulation/preview for a wayline.
|
|
7161
|
+
* Animates an aircraft model along the wayline path with controls for play/pause/stop.
|
|
7162
|
+
* @param options - Configuration for the flight simulator
|
|
7163
|
+
* @returns A controller object with start/pause/resume/stop/destroy methods
|
|
7164
|
+
*/
|
|
7165
|
+
startFlightPreview(options) {
|
|
7166
|
+
const simulator = new FlightSimulator(
|
|
7167
|
+
this.CesiumNS,
|
|
7168
|
+
this.viewer,
|
|
7169
|
+
options
|
|
7170
|
+
);
|
|
7171
|
+
return simulator;
|
|
7172
|
+
}
|
|
7019
7173
|
// ensureLayerForEntity moved into path-editing module
|
|
7020
7174
|
};
|
|
7021
7175
|
__publicField(_CZMLPathManager, "SAMPLES_KEY", "__czmlPathSamples__");
|