menghao 3 weeks ago
parent
commit
9858561654
  1. 4
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/RouteWaypointsMapper.java
  2. 9
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RouteWaypointsServiceImpl.java
  3. 4
      ruoyi-system/src/main/resources/mapper/system/RouteWaypointsMapper.xml
  4. 852
      ruoyi-ui/src/views/cesiumMap/index.vue
  5. 217
      ruoyi-ui/src/views/childRoom/index.vue

4
ruoyi-system/src/main/java/com/ruoyi/system/mapper/RouteWaypointsMapper.java

@ -1,6 +1,7 @@
package com.ruoyi.system.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.system.domain.RouteWaypoints;
/**
@ -30,6 +31,9 @@ public interface RouteWaypointsMapper
/** 查询指定航线下最大的序号 */
public Integer selectMaxSeqByRouteId(Long routeId);
/** 将指定航线中 seq >= targetSeq 的航点序号均加 1,用于在指定位置插入新航点 */
int incrementSeqFrom(@Param("routeId") Long routeId, @Param("seq") Long targetSeq);
/**
* 新增航线具体航点明细
*

9
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/RouteWaypointsServiceImpl.java

@ -52,11 +52,14 @@ public class RouteWaypointsServiceImpl implements IRouteWaypointsService
@Override
public int insertRouteWaypoints(RouteWaypoints routeWaypoints)
{
// 1. 获取该航线当前的最高序号
Long requestedSeq = routeWaypoints.getSeq();
Integer maxSeq = routeWaypointsMapper.selectMaxSeqByRouteId(routeWaypoints.getRouteId());
// 2. 如果是第一条,序号为1;否则在最大值基础上 +1
if (maxSeq == null) {
// 若前端传入有效 seq(在指定位置插入),则先将该位置及之后的航点 seq 均加 1,再插入
if (requestedSeq != null && requestedSeq > 0 && maxSeq != null && requestedSeq <= maxSeq) {
routeWaypointsMapper.incrementSeqFrom(routeWaypoints.getRouteId(), requestedSeq);
// 使用前端传入的 seq
} else if (maxSeq == null) {
routeWaypoints.setSeq(1L);
} else {
routeWaypoints.setSeq((long) (maxSeq + 1));

4
ruoyi-system/src/main/resources/mapper/system/RouteWaypointsMapper.xml

@ -51,6 +51,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select max(seq) from ry.route_waypoints where route_id = #{routeId}
</select>
<update id="incrementSeqFrom">
update route_waypoints set seq = seq + 1 where route_id = #{routeId} and seq &gt;= #{seq}
</update>
<insert id="insertRouteWaypoints" parameterType="RouteWaypoints" useGeneratedKeys="true" keyProperty="id">
insert into route_waypoints
<trim prefix="(" suffix=")" suffixOverrides=",">

852
ruoyi-ui/src/views/cesiumMap/index.vue

File diff suppressed because it is too large

217
ruoyi-ui/src/views/childRoom/index.vue

@ -4113,9 +4113,9 @@ export default {
/**
* 按速度与计划时间构建航线时间轴含飞行段盘旋段与提前到达则等待的等待段
* pathData 可选{ path, segmentEndIndices, holdArcRanges } getRoutePathWithSegmentIndices 提供用于输出 hold
* holdRadiusByLegIndex 可选{ [legIndex]: number }为盘旋段指定半径用于推演时落点精准在切点
* 圆形盘旋半径由速度+坡度公式固定计算盘旋时间靠多转圈数解决不反算半径
*/
buildRouteTimeline(waypoints, globalMin, globalMax, pathData, holdRadiusByLegIndex) {
buildRouteTimeline(waypoints, globalMin, globalMax, pathData) {
const warnings = [];
if (!waypoints || waypoints.length === 0) return { segments: [], warnings };
const points = waypoints.map((wp, idx) => ({
@ -4153,7 +4153,12 @@ export default {
const path = pathData && pathData.path;
const segmentEndIndices = pathData && pathData.segmentEndIndices;
const holdArcRanges = pathData && pathData.holdArcRanges || {};
let skipNextLeg = false;
for (let i = 0; i < points.length - 1; i++) {
if (skipNextLeg) {
skipNextLeg = false;
continue;
}
if (this.isHoldWaypoint(waypoints[i + 1]) && path && segmentEndIndices && holdArcRanges[i]) {
const range = holdArcRanges[i];
const startIdx = i === 0 ? 0 : segmentEndIndices[i - 1] + 1;
@ -4183,25 +4188,35 @@ export default {
}
const holdEndTime = points[i + 1].minutes; // K+10
const exitPos = holdPathSlice.length ? holdPathSlice[holdPathSlice.length - 1] : (toEntrySlice.length ? toEntrySlice[toEntrySlice.length - 1] : { lng: points[i].lng, lat: points[i].lat, alt: points[i].alt });
let loopEndIdx = 1;
for (let k = 1; k < Math.min(holdPathSlice.length, 200); k++) {
if (this.segmentDistance(holdPathSlice[0], holdPathSlice[k]) < 80) { loopEndIdx = k; break; }
let loopEndIdx;
if (range.loopEndIndex != null) {
loopEndIdx = range.loopEndIndex - range.start;
} else {
const minSearchIdx = Math.max(2, Math.floor(holdPathSlice.length * 0.33));
loopEndIdx = holdPathSlice.length - 1;
for (let k = minSearchIdx; k < holdPathSlice.length; k++) {
if (this.segmentDistance(holdPathSlice[0], holdPathSlice[k]) < 80) { loopEndIdx = k; break; }
}
}
const holdClosedLoopPath = holdPathSlice.slice(0, loopEndIdx + 1);
if (loopEndIdx < 1) loopEndIdx = 1;
if (loopEndIdx >= holdPathSlice.length) loopEndIdx = holdPathSlice.length - 1;
const holdClosedLoopRaw = holdPathSlice.slice(0, loopEndIdx + 1);
const holdClosedLoopPath = holdClosedLoopRaw.length >= 2
? [...holdClosedLoopRaw.slice(0, -1), { ...holdClosedLoopRaw[0] }]
: holdClosedLoopRaw;
const holdLoopLength = this.pathSliceDistance(holdClosedLoopPath) || 1;
//
let exitIdxOnLoop = holdPathSlice.length - 1;
let minD = 1e9;
for (let k = 0; k < holdPathSlice.length; k++) {
const d = this.segmentDistance(holdPathSlice[k], exitPos);
if (d < minD) { minD = d; exitIdxOnLoop = k; }
}
const holdExitDistanceOnLoop = this.pathSliceDistance(holdPathSlice.slice(0, exitIdxOnLoop + 1));
const holdEntryToExitRaw = holdPathSlice.slice(loopEndIdx);
const holdEntryToExitSlice = holdEntryToExitRaw.length >= 2
? [{ ...holdClosedLoopPath[0] }, ...holdEntryToExitRaw.slice(1)]
: holdEntryToExitRaw;
const holdExitDistanceOnLoop = this.pathSliceDistance(holdEntryToExitSlice);
const holdSpeedKmh = points[i + 1].speed || 800;
const HOLD_SPEED_KMH = 800;
const speedMpMin = (HOLD_SPEED_KMH * 1000) / 60;
const requiredDistAtK10 = (holdEndTime - arrivalEntry) * speedMpMin;
let n = Math.ceil((requiredDistAtK10 - holdExitDistanceOnLoop) / holdLoopLength);
const rawLoops = (requiredDistAtK10 - holdExitDistanceOnLoop) / holdLoopLength;
let n = Math.ceil(rawLoops - 1e-9);
if (n < 0 || !Number.isFinite(n)) n = 0;
const segmentEndTime = arrivalEntry + (holdExitDistanceOnLoop + n * holdLoopLength) / speedMpMin;
if (segmentEndTime > holdEndTime) {
@ -4222,22 +4237,22 @@ export default {
const distExitToNext = this.pathSliceDistance(toNextSlice);
const travelExitMin = (distExitToNext / 1000) * (60 / holdSpeedKmh);
const arrivalNext = segmentEndTime + travelExitMin;
effectiveTime[i + 1] = holdEndTime;
effectiveTime[i + 1] = segmentEndTime;
if (i + 2 < points.length) effectiveTime[i + 2] = arrivalNext;
const posCur = { lng: points[i].lng, lat: points[i].lat, alt: points[i].alt };
const entryPos = toEntrySlice.length ? toEntrySlice[toEntrySlice.length - 1] : posCur;
const holdWp = waypoints[i + 1];
const holdParams = this.parseHoldParams(holdWp);
const holdCenter = holdWp ? { lng: parseFloat(holdWp.lng), lat: parseFloat(holdWp.lat), alt: Number(holdWp.alt) || 0 } : null;
const overrideR = holdRadiusByLegIndex && holdRadiusByLegIndex[i] != null ? holdRadiusByLegIndex[i] : null;
const holdRadius = (overrideR != null && Number.isFinite(overrideR)) ? overrideR : (holdParams && holdParams.radius != null ? holdParams.radius : null);
const computedR = this.$refs.cesiumMap ? this.$refs.cesiumMap.getWaypointRadius(holdWp) : null;
const holdRadius = (computedR != null && computedR > 0) ? computedR : 500;
const holdClockwise = holdParams && holdParams.clockwise !== false;
const holdCircumference = holdRadius != null ? 2 * Math.PI * holdRadius : null;
const holdEntryAngle = holdCenter && entryPos && holdRadius != null
? this.angleFromCenterToPoint(holdCenter.lng, holdCenter.lat, entryPos.lng, entryPos.lat)
: null;
segments.push({ startTime: effectiveTime[i], endTime: arrivalEntry, startPos: posCur, endPos: entryPos, type: 'fly', legIndex: i, pathSlice: toEntrySlice, speedKmh: speedKmhForLeg });
const holdEntryToExitPath = holdClosedLoopPath.slice(0, exitIdxOnLoop + 1);
const holdEntryToExitPath = holdEntryToExitSlice;
segments.push({
startTime: arrivalEntry,
endTime: segmentEndTime,
@ -4259,8 +4274,18 @@ export default {
holdClockwise,
holdEntryAngle
});
segments.push({ startTime: segmentEndTime, endTime: arrivalNext, startPos: exitPos, endPos: toNextSlice.length ? toNextSlice[toNextSlice.length - 1] : exitPos, type: 'fly', legIndex: i, pathSlice: toNextSlice, speedKmh: holdSpeedKmh });
continue; // i++ WP2WP3
// fly
const exitEndPos = toNextSlice.length ? toNextSlice[toNextSlice.length - 1] : exitPos;
// WP_{i+2} fly
// effectiveTime 使
if (i + 2 < points.length && this.isHoldWaypoint(waypoints[i + 2])) {
segments.push({ startTime: segmentEndTime, endTime: arrivalNext, startPos: exitPos, endPos: exitEndPos, type: 'fly', legIndex: i + 1, pathSlice: toNextSlice, speedKmh: holdSpeedKmh });
} else {
segments.push({ startTime: segmentEndTime, endTime: arrivalNext, startPos: exitPos, endPos: exitEndPos, type: 'fly', legIndex: i + 1, pathSlice: toNextSlice, speedKmh: holdSpeedKmh });
// fly leg i+1
skipNextLeg = true;
}
continue;
}
const dist = this.segmentDistance(points[i], points[i + 1]);
const speedKmh = points[i].speed || 800;
@ -4287,7 +4312,15 @@ export default {
effectiveTime[i + 1] = Math.max(actualArrival, scheduled);
const posCur = { lng: points[i].lng, lat: points[i].lat, alt: points[i].alt };
const posNext = { lng: points[i + 1].lng, lat: points[i + 1].lat, alt: points[i + 1].alt };
segments.push({ startTime: effectiveTime[i], endTime: actualArrival, startPos: posCur, endPos: posNext, type: 'fly', legIndex: i, speedKmh: speedKmh });
let flyPathSlice = null;
if (path && segmentEndIndices) {
const startIdx = i === 0 ? 0 : (segmentEndIndices[i - 1] != null ? segmentEndIndices[i - 1] : 0);
const endIdx = segmentEndIndices[i];
if (endIdx != null && endIdx >= startIdx) {
flyPathSlice = path.slice(startIdx, endIdx + 1);
}
}
segments.push({ startTime: effectiveTime[i], endTime: actualArrival, startPos: posCur, endPos: posNext, type: 'fly', legIndex: i, speedKmh: speedKmh, pathSlice: flyPathSlice });
if (actualArrival < effectiveTime[i + 1]) {
segments.push({ startTime: actualArrival, endTime: effectiveTime[i + 1], startPos: posNext, endPos: posNext, type: 'wait', legIndex: i });
}
@ -4402,24 +4435,27 @@ export default {
const cesiumMap = this.$refs.cesiumMap;
let pathData = null;
if (cesiumMap && cesiumMap.getRoutePathWithSegmentIndices) {
const cachedRadii = (routeId != null && cesiumMap._routeHoldRadiiByRoute && cesiumMap._routeHoldRadiiByRoute[routeId]) ? cesiumMap._routeHoldRadiiByRoute[routeId] : {};
const cachedEllipse = (routeId != null && cesiumMap._routeHoldEllipseParamsByRoute && cesiumMap._routeHoldEllipseParamsByRoute[routeId]) ? cesiumMap._routeHoldEllipseParamsByRoute[routeId] : {};
const opts = (Object.keys(cachedRadii).length > 0 || Object.keys(cachedEllipse).length > 0) ? { holdRadiusByLegIndex: cachedRadii, holdEllipseParamsByLegIndex: cachedEllipse } : {};
const opts = Object.keys(cachedEllipse).length > 0 ? { holdEllipseParamsByLegIndex: cachedEllipse } : {};
const ret = cesiumMap.getRoutePathWithSegmentIndices(waypoints, opts);
if (ret.path && ret.path.length > 0 && ret.segmentEndIndices && ret.segmentEndIndices.length > 0) {
pathData = { path: ret.path, segmentEndIndices: ret.segmentEndIndices, holdArcRanges: ret.holdArcRanges || {} };
}
}
let { segments, warnings, earlyArrivalLegs } = this.buildRouteTimeline(waypoints, globalMin, globalMax, pathData);
const holdRadiusByLegIndex = {};
// +
// /semiMajor/semiMinor
const holdEllipseParamsByLegIndex = {};
if (cesiumMap && segments && pathData) {
for (let idx = 0; idx < segments.length; idx++) {
const s = segments[idx];
if (s.type !== 'hold' || s.holdCenter == null) continue;
const i = s.legIndex;
const holdEndTime = s.holdEndTime != null ? s.holdEndTime : this.waypointStartTimeToMinutesDecimal(waypoints[i + 1]?.startTime);
const holdWp = waypoints[i + 1];
if (!holdWp) continue;
const isHoldEllipse = (holdWp.pointType || holdWp.point_type) === 'hold_ellipse';
if (!isHoldEllipse || !cesiumMap.computeEllipseParamsForDuration) continue;
const holdEndTime = s.holdEndTime != null ? s.holdEndTime : this.waypointStartTimeToMinutesDecimal(holdWp?.startTime);
const segTarget = holdWp && (holdWp.segmentTargetMinutes ?? holdWp.displayStyle?.segmentTargetMinutes);
const arrivalAtHold = (holdWp && holdWp.segmentMode === 'fixed_time' && segTarget != null && segTarget !== '')
? Number(segTarget) : s.startTime;
@ -4428,123 +4464,36 @@ export default {
const totalHoldDistM = speedKmh * (holdDurationMin / 60) * 1000;
const prevWp = waypoints[i];
const nextWp = (i + 2) < waypoints.length ? waypoints[i + 2] : holdWp;
if (!prevWp || !holdWp) continue;
if (!prevWp) continue;
const centerCartesian = Cesium.Cartesian3.fromDegrees(parseFloat(holdWp.lng), parseFloat(holdWp.lat), Number(holdWp.alt) || 0);
const prevCartesian = Cesium.Cartesian3.fromDegrees(parseFloat(prevWp.lng), parseFloat(prevWp.lat), Number(prevWp.alt) || 0);
const nextCartesian = nextWp ? Cesium.Cartesian3.fromDegrees(parseFloat(nextWp.lng), parseFloat(nextWp.lat), Number(nextWp.alt) || 0) : centerCartesian;
const clockwise = s.holdClockwise !== false;
const isHoldEllipse = waypoints[i + 1] && (waypoints[i + 1].pointType || waypoints[i + 1].point_type) === 'hold_ellipse';
const isEllipse = isHoldEllipse || s.holdRadius == null;
if (isEllipse && !isHoldEllipse && cesiumMap.computeEllipseParamsForDuration) {
const holdParams = this.parseHoldParams(holdWp);
const headingDeg = holdParams && holdParams.headingDeg != null ? holdParams.headingDeg : 0;
const a0 = holdParams && (holdParams.semiMajor != null || holdParams.semiMajorAxis != null) ? (holdParams.semiMajor ?? holdParams.semiMajorAxis) : 500;
const b0 = holdParams && (holdParams.semiMinor != null || holdParams.semiMinorAxis != null) ? (holdParams.semiMinor ?? holdParams.semiMinorAxis) : 300;
const out = cesiumMap.computeEllipseParamsForDuration(centerCartesian, prevCartesian, nextCartesian, clockwise, totalHoldDistM, headingDeg, a0, b0);
if (out && out.semiMajor != null && out.semiMinor != null) {
holdEllipseParamsByLegIndex[i] = {
semiMajor: out.semiMajor,
semiMinor: out.semiMinor,
headingDeg
};
}
} else if (!isEllipse && cesiumMap.computeHoldRadiusForDuration) {
let R = cesiumMap.computeHoldRadiusForDuration(centerCartesian, prevCartesian, nextCartesian, clockwise, totalHoldDistM);
if (R == null || !Number.isFinite(R)) {
R = totalHoldDistM / (2 * Math.PI);
}
if (R != null && Number.isFinite(R) && R > 0) {
holdRadiusByLegIndex[i] = R;
}
const holdParams = this.parseHoldParams(holdWp);
const headingDeg = holdParams && holdParams.headingDeg != null ? holdParams.headingDeg : 0;
const a0 = holdParams && (holdParams.semiMajor != null || holdParams.semiMajorAxis != null) ? (holdParams.semiMajor ?? holdParams.semiMajorAxis) : 500;
const b0 = holdParams && (holdParams.semiMinor != null || holdParams.semiMinorAxis != null) ? (holdParams.semiMinor ?? holdParams.semiMinorAxis) : 300;
const out = cesiumMap.computeEllipseParamsForDuration(centerCartesian, prevCartesian, nextCartesian, s.holdClockwise !== false, totalHoldDistM, headingDeg, a0, b0);
if (out && out.semiMajor != null && out.semiMinor != null) {
holdEllipseParamsByLegIndex[i] = { semiMajor: out.semiMajor, semiMinor: out.semiMinor, headingDeg };
}
}
const hasCircle = Object.keys(holdRadiusByLegIndex).length > 0;
const hasEllipse = Object.keys(holdEllipseParamsByLegIndex).length > 0;
if (hasCircle || hasEllipse) {
let pathData2 = null;
let segments2 = null;
for (let iter = 0; iter < 4; iter++) {
const ret2 = cesiumMap.getRoutePathWithSegmentIndices(waypoints, { holdRadiusByLegIndex, holdEllipseParamsByLegIndex });
if (!ret2.path || ret2.path.length === 0 || !ret2.segmentEndIndices || ret2.segmentEndIndices.length === 0) break;
pathData2 = { path: ret2.path, segmentEndIndices: ret2.segmentEndIndices, holdArcRanges: ret2.holdArcRanges || {} };
const out = this.buildRouteTimeline(waypoints, globalMin, globalMax, pathData2, holdRadiusByLegIndex);
segments2 = out.segments;
let changed = false;
if (hasCircle) {
const nextRadii = {};
for (let idx = 0; idx < segments2.length; idx++) {
const s = segments2[idx];
if (s.type !== 'hold' || s.holdRadius == null || s.holdCenter == null) continue;
const i = s.legIndex;
const holdWpCircle = waypoints[i + 1];
const holdEndTimeCircle = s.holdEndTime != null ? s.holdEndTime : this.waypointStartTimeToMinutesDecimal(holdWpCircle?.startTime);
const segTargetCircle = holdWpCircle && (holdWpCircle.segmentTargetMinutes ?? holdWpCircle.displayStyle?.segmentTargetMinutes);
const arrivalAtHoldCircle = (holdWpCircle && holdWpCircle.segmentMode === 'fixed_time' && segTargetCircle != null && segTargetCircle !== '')
? Number(segTargetCircle) : s.startTime;
const holdDurationMin = Math.max(0, holdEndTimeCircle - arrivalAtHoldCircle);
const speedKmh = s.speedKmh != null ? s.speedKmh : (Number(holdWpCircle?.speed) || 800);
const totalHoldDistM = speedKmh * (holdDurationMin / 60) * 1000;
const prevWp = waypoints[i];
const holdWp = holdWpCircle;
const nextWp = (i + 2) < waypoints.length ? waypoints[i + 2] : holdWp;
if (!prevWp || !holdWp) continue;
const centerCartesian = Cesium.Cartesian3.fromDegrees(parseFloat(holdWp.lng), parseFloat(holdWp.lat), Number(holdWp.alt) || 0);
const prevCartesian = Cesium.Cartesian3.fromDegrees(parseFloat(prevWp.lng), parseFloat(prevWp.lat), Number(prevWp.alt) || 0);
const nextCartesian = nextWp ? Cesium.Cartesian3.fromDegrees(parseFloat(nextWp.lng), parseFloat(nextWp.lat), Number(nextWp.alt) || 0) : centerCartesian;
let Rnew = cesiumMap.computeHoldRadiusForDuration(centerCartesian, prevCartesian, nextCartesian, s.holdClockwise !== false, totalHoldDistM);
if (Rnew == null || !Number.isFinite(Rnew)) Rnew = totalHoldDistM / (2 * Math.PI);
if (Rnew != null && Number.isFinite(Rnew) && Rnew > 0) {
nextRadii[i] = Rnew;
if (holdRadiusByLegIndex[i] == null || Math.abs(nextRadii[i] - holdRadiusByLegIndex[i]) > 1) changed = true;
}
}
Object.assign(holdRadiusByLegIndex, nextRadii);
}
if (hasEllipse) {
for (let idx = 0; idx < segments2.length; idx++) {
const s = segments2[idx];
if (s.type !== 'hold' || s.holdRadius != null || s.holdCenter == null) continue;
const i = s.legIndex;
const holdWp = waypoints[i + 1];
if ((holdWp && (holdWp.pointType || holdWp.point_type) === 'hold_ellipse')) continue;
const holdParams = this.parseHoldParams(holdWp);
const holdEndTime = s.holdEndTime != null ? s.holdEndTime : this.waypointStartTimeToMinutesDecimal(holdWp?.startTime);
const segTargetEllipse = holdWp && (holdWp.segmentTargetMinutes ?? holdWp.displayStyle?.segmentTargetMinutes);
const arrivalAtHold = (holdWp && holdWp.segmentMode === 'fixed_time' && segTargetEllipse != null && segTargetEllipse !== '')
? Number(segTargetEllipse) : s.startTime;
const holdDurationMin = Math.max(0, holdEndTime - arrivalAtHold);
const speedKmh = s.speedKmh != null ? s.speedKmh : (Number(holdWp?.speed) || 800);
const totalHoldDistM = speedKmh * (holdDurationMin / 60) * 1000;
const prevWp = waypoints[i];
const nextWp = (i + 2) < waypoints.length ? waypoints[i + 2] : holdWp;
if (!prevWp || !holdWp || !cesiumMap.computeEllipseParamsForDuration) continue;
const centerCartesian = Cesium.Cartesian3.fromDegrees(parseFloat(holdWp.lng), parseFloat(holdWp.lat), Number(holdWp.alt) || 0);
const prevCartesian = Cesium.Cartesian3.fromDegrees(parseFloat(prevWp.lng), parseFloat(prevWp.lat), Number(prevWp.alt) || 0);
const nextCartesian = nextWp ? Cesium.Cartesian3.fromDegrees(parseFloat(nextWp.lng), parseFloat(nextWp.lat), Number(nextWp.alt) || 0) : centerCartesian;
const headingDeg = holdParams && holdParams.headingDeg != null ? holdParams.headingDeg : 0;
const a0 = holdParams && (holdParams.semiMajor != null || holdParams.semiMajorAxis != null) ? (holdParams.semiMajor ?? holdParams.semiMajorAxis) : 500;
const b0 = holdParams && (holdParams.semiMinor != null || holdParams.semiMinorAxis != null) ? (holdParams.semiMinor ?? holdParams.semiMinorAxis) : 300;
const out = cesiumMap.computeEllipseParamsForDuration(centerCartesian, prevCartesian, nextCartesian, s.holdClockwise !== false, totalHoldDistM, headingDeg, a0, b0);
if (out && out.semiMajor != null) {
const smj = out.semiMajor;
const smn = out.semiMinor;
const old = holdEllipseParamsByLegIndex[i];
if (!old || Math.abs(smj - old.semiMajor) > 1) changed = true;
holdEllipseParamsByLegIndex[i] = { semiMajor: smj, semiMinor: smn, headingDeg };
}
}
}
if (!changed || iter === 3) break;
if (hasEllipse) {
const ret2 = cesiumMap.getRoutePathWithSegmentIndices(waypoints, { holdEllipseParamsByLegIndex });
if (ret2.path && ret2.path.length > 0 && ret2.segmentEndIndices && ret2.segmentEndIndices.length > 0) {
pathData = { path: ret2.path, segmentEndIndices: ret2.segmentEndIndices, holdArcRanges: ret2.holdArcRanges || {} };
const out2 = this.buildRouteTimeline(waypoints, globalMin, globalMax, pathData);
segments = out2.segments;
}
if (pathData2) pathData = pathData2;
if (segments2) segments = segments2;
if (routeId != null) {
if (cesiumMap.setRouteHoldRadii) cesiumMap.setRouteHoldRadii(routeId, holdRadiusByLegIndex);
if (cesiumMap.setRouteHoldEllipseParams) cesiumMap.setRouteHoldEllipseParams(routeId, holdEllipseParamsByLegIndex);
if (routeId != null && cesiumMap.setRouteHoldEllipseParams) {
cesiumMap.setRouteHoldEllipseParams(routeId, holdEllipseParamsByLegIndex);
}
} else if (routeId != null) {
if (cesiumMap.setRouteHoldRadii) cesiumMap.setRouteHoldRadii(routeId, {});
if (cesiumMap.setRouteHoldEllipseParams) cesiumMap.setRouteHoldEllipseParams(routeId, {});
} else if (routeId != null && cesiumMap.setRouteHoldEllipseParams) {
cesiumMap.setRouteHoldEllipseParams(routeId, {});
}
// 使
if (routeId != null && cesiumMap.setRouteHoldRadii) {
cesiumMap.setRouteHoldRadii(routeId, {});
}
}
const path = pathData ? pathData.path : null;

Loading…
Cancel
Save