|
|
|
@ -899,13 +899,18 @@ export default { |
|
|
|
if (existingPlatform) { |
|
|
|
this.viewer.entities.remove(existingPlatform); |
|
|
|
} |
|
|
|
// 清理所有属于该航线的旧点 |
|
|
|
// 清理所有属于该航线的旧点(含转弯半径两侧的 entry/exit 点) |
|
|
|
waypoints.forEach((wp,index) => { |
|
|
|
const waypointEntityId = `wp_${routeId}_${wp.id}`; |
|
|
|
const existingWaypoint = this.viewer.entities.getById(waypointEntityId); |
|
|
|
if (existingWaypoint) { |
|
|
|
this.viewer.entities.remove(existingWaypoint); |
|
|
|
} |
|
|
|
['_entry', '_exit'].forEach(suffix => { |
|
|
|
const entryExitId = `wp_${routeId}_${wp.id}${suffix}`; |
|
|
|
const existingEntryExit = this.viewer.entities.getById(entryExitId); |
|
|
|
if (existingEntryExit) this.viewer.entities.remove(existingEntryExit); |
|
|
|
}); |
|
|
|
const arcId = `arc-line-${routeId}-${index}`; |
|
|
|
const existingArc = this.viewer.entities.getById(arcId); |
|
|
|
if (existingArc) { |
|
|
|
@ -923,15 +928,46 @@ export default { |
|
|
|
const wpColor = wpStyle.color || '#ffffff'; |
|
|
|
const wpOutline = wpStyle.outlineColor || '#0078FF'; |
|
|
|
const wpOutlineW = wpStyle.outlineWidth != null ? wpStyle.outlineWidth : 2; |
|
|
|
// 遍历并绘制航点标记 |
|
|
|
// 航线默认紫色、线宽 3;与主航线一致的线型用于主线和转弯半径弧 |
|
|
|
const lineWidth = lineStyle.width != null ? lineStyle.width : 3; |
|
|
|
const lineColor = lineStyle.color || '#800080'; |
|
|
|
const gapColor = lineStyle.gapColor != null ? lineStyle.gapColor : '#000000'; |
|
|
|
const dashLen = lineStyle.dashLength != null ? lineStyle.dashLength : 20; |
|
|
|
const useDash = (lineStyle.style || 'dash') === 'dash'; |
|
|
|
const lineMaterial = useDash |
|
|
|
? new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString(lineColor), |
|
|
|
gapColor: Cesium.Color.fromCssColorString(gapColor), |
|
|
|
dashLength: dashLen |
|
|
|
}) |
|
|
|
: Cesium.Color.fromCssColorString(lineColor); |
|
|
|
// 先收集所有航点的世界坐标 |
|
|
|
const originalPositions = []; |
|
|
|
waypoints.forEach((wp, index) => { |
|
|
|
waypoints.forEach((wp) => { |
|
|
|
const lon = parseFloat(wp.lng); |
|
|
|
const lat = parseFloat(wp.lat); |
|
|
|
// 使用 Number 转换 Double 类型 |
|
|
|
const altValue = Number(wp.alt || 5000); |
|
|
|
const pos = Cesium.Cartesian3.fromDegrees(lon, lat, altValue); |
|
|
|
originalPositions.push(pos); |
|
|
|
originalPositions.push(Cesium.Cartesian3.fromDegrees(lon, lat, altValue)); |
|
|
|
}); |
|
|
|
// 判断航点 i 是否为“转弯半径”航点(将用弧线两端两个点替代中心点) |
|
|
|
const isTurnWaypointWithArc = (i) => { |
|
|
|
if (i < 1 || i >= waypoints.length - 1) return false; |
|
|
|
const wp = waypoints[i]; |
|
|
|
if (this.getWaypointRadius(wp) <= 0) return false; |
|
|
|
const nextPos = originalPositions[i + 1]; |
|
|
|
let nextLogical = nextPos; |
|
|
|
if (this.isHoldWaypoint(waypoints[i + 1])) { |
|
|
|
const holdParams = this.parseHoldParams(waypoints[i + 1]); |
|
|
|
nextLogical = holdParams && holdParams.radius != null |
|
|
|
? this.getCircleEntryPoint(originalPositions[i + 1], originalPositions[i], holdParams.radius) |
|
|
|
: this.getEllipseEntryPoint(originalPositions[i + 1], originalPositions[i], holdParams.semiMajor ?? 500, holdParams.semiMinor ?? 300, ((holdParams.headingDeg || 0) * Math.PI) / 180); |
|
|
|
} |
|
|
|
return !!nextLogical; |
|
|
|
}; |
|
|
|
// 遍历并绘制航点标记:转弯半径处不画中心点,改在下面画弧线时画两端两个点 |
|
|
|
waypoints.forEach((wp, index) => { |
|
|
|
if (isTurnWaypointWithArc(index)) return; |
|
|
|
const pos = originalPositions[index]; |
|
|
|
this.viewer.entities.add({ |
|
|
|
id: `wp_${routeId}_${wp.id}`, |
|
|
|
name: wp.name || `WP${index + 1}`, |
|
|
|
@ -1047,9 +1083,42 @@ export default { |
|
|
|
const arcPoints = this.computeArcPositions(lastPos, currPos, nextLogical, radius); |
|
|
|
this.viewer.entities.add({ |
|
|
|
id: `arc-line-${routeId}-${i}`, |
|
|
|
polyline: { positions: arcPoints, width: 8, material: Cesium.Color.RED, clampToGround: true, zIndex: 20 }, |
|
|
|
polyline: { positions: arcPoints, width: lineWidth, material: lineMaterial, clampToGround: true, zIndex: 20 }, |
|
|
|
properties: { routeId: routeId } |
|
|
|
}); |
|
|
|
// 转弯半径两侧航点与航线整体航点风格一致,点击均打开原航点编辑(dbId 为当前 wp.id) |
|
|
|
const wpName = wp.name || `WP${i + 1}`; |
|
|
|
const arcEntry = arcPoints[0]; |
|
|
|
const arcExit = arcPoints[arcPoints.length - 1]; |
|
|
|
[arcEntry, arcExit].forEach((pos, idx) => { |
|
|
|
const suffix = idx === 0 ? '_entry' : '_exit'; |
|
|
|
this.viewer.entities.add({ |
|
|
|
id: `wp_${routeId}_${wp.id}${suffix}`, |
|
|
|
name: wpName, |
|
|
|
position: pos, |
|
|
|
properties: { |
|
|
|
isMissionWaypoint: true, |
|
|
|
routeId: routeId, |
|
|
|
dbId: wp.id, |
|
|
|
}, |
|
|
|
point: { |
|
|
|
pixelSize: pixelSize, |
|
|
|
color: Cesium.Color.fromCssColorString(wpColor), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString(wpOutline), |
|
|
|
outlineWidth: wpOutlineW, |
|
|
|
disableDepthTestDistance: Number.POSITIVE_INFINITY |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: wpName, |
|
|
|
font: `${Math.max(9, pixelSize + 2)}px MicroSoft YaHei`, |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -Math.max(14, pixelSize + 8)), |
|
|
|
fillColor: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
outlineWidth: 2, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
finalPathPositions.push(...arcPoints); |
|
|
|
lastPos = arcPoints[arcPoints.length - 1]; |
|
|
|
} else { |
|
|
|
@ -1058,19 +1127,7 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
const lineWidth = lineStyle.width != null ? lineStyle.width : 4; |
|
|
|
const lineColor = lineStyle.color || '#ffffff'; |
|
|
|
const gapColor = lineStyle.gapColor != null ? lineStyle.gapColor : '#000000'; |
|
|
|
const dashLen = lineStyle.dashLength != null ? lineStyle.dashLength : 20; |
|
|
|
const useDash = (lineStyle.style || 'dash') === 'dash'; |
|
|
|
const lineMaterial = useDash |
|
|
|
? new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString(lineColor), |
|
|
|
gapColor: Cesium.Color.fromCssColorString(gapColor), |
|
|
|
dashLength: dashLen |
|
|
|
}) |
|
|
|
: Cesium.Color.fromCssColorString(lineColor); |
|
|
|
// 绘制包含弧线的 Polyline |
|
|
|
// 绘制包含弧线的 Polyline(lineWidth/lineMaterial 已在上方与航点样式一起计算,默认紫色线宽3) |
|
|
|
const routeEntity = this.viewer.entities.add({ |
|
|
|
id: lineId, |
|
|
|
polyline: { |
|
|
|
|