|
|
|
@ -381,6 +381,11 @@ export default { |
|
|
|
roomId: { |
|
|
|
type: [String, Number], |
|
|
|
default: null |
|
|
|
}, |
|
|
|
/** 是否允许地图拖动(由顶部“小手”图标切换,默认关闭) */ |
|
|
|
mapDragEnabled: { |
|
|
|
type: Boolean, |
|
|
|
default: false |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
@ -611,6 +616,13 @@ export default { |
|
|
|
this.updateCoordinatesDisplay() |
|
|
|
} |
|
|
|
}, |
|
|
|
mapDragEnabled: { |
|
|
|
handler(enabled) { |
|
|
|
if (this.viewer && this.viewer.scene && this.viewer.scene.screenSpaceCameraController) { |
|
|
|
this.viewer.scene.screenSpaceCameraController.enableTranslate = !!enabled |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
routeLabelVisible: { |
|
|
|
handler(newVal) { |
|
|
|
// 使用 debounce 或 setTimeout 避免频繁调用 |
|
|
|
@ -988,17 +1000,17 @@ export default { |
|
|
|
}, |
|
|
|
point: { |
|
|
|
pixelSize: 10, |
|
|
|
color: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#0078FF'), |
|
|
|
outlineWidth: 3, |
|
|
|
color: Cesium.Color.fromCssColorString('#f1f5f9'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
outlineWidth: 1.5, |
|
|
|
disableDepthTestDistance: Number.POSITIVE_INFINITY |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: `WP${wpIndex}`, |
|
|
|
font: '14px Microsoft YaHei', |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -20), |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#333333'), |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#334155'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), |
|
|
|
outlineWidth: 1, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
@ -1015,7 +1027,7 @@ export default { |
|
|
|
polyline: { |
|
|
|
positions: solidPositions, |
|
|
|
width: 3, |
|
|
|
material: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
material: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
} |
|
|
|
}); |
|
|
|
@ -1037,7 +1049,7 @@ export default { |
|
|
|
}, false), |
|
|
|
width: 3, |
|
|
|
material: new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
color: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
dashLength: 16 |
|
|
|
}), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
@ -1137,17 +1149,17 @@ export default { |
|
|
|
properties: { isMissionWaypoint: true, originalIndex: 1, temp: true }, |
|
|
|
point: { |
|
|
|
pixelSize: 10, |
|
|
|
color: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#0078FF'), |
|
|
|
outlineWidth: 3, |
|
|
|
color: Cesium.Color.fromCssColorString('#f1f5f9'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
outlineWidth: 1.5, |
|
|
|
disableDepthTestDistance: Number.POSITIVE_INFINITY |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: this.platformRouteDrawing.platformName, |
|
|
|
font: '14px Microsoft YaHei', |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -20), |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#333333'), |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#334155'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), |
|
|
|
outlineWidth: 1, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
@ -1179,7 +1191,7 @@ export default { |
|
|
|
}, false), |
|
|
|
width: 3, |
|
|
|
material: new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
color: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
dashLength: 16 |
|
|
|
}), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
@ -1204,17 +1216,17 @@ export default { |
|
|
|
properties: { isMissionWaypoint: true, originalIndex: wpIndex, temp: true }, |
|
|
|
point: { |
|
|
|
pixelSize: 10, |
|
|
|
color: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#0078FF'), |
|
|
|
outlineWidth: 3, |
|
|
|
color: Cesium.Color.fromCssColorString('#f1f5f9'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
outlineWidth: 1.5, |
|
|
|
disableDepthTestDistance: Number.POSITIVE_INFINITY |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: `WP${wpIndex}`, |
|
|
|
font: '14px Microsoft YaHei', |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -20), |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#333333'), |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#334155'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), |
|
|
|
outlineWidth: 1, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
@ -1239,7 +1251,7 @@ export default { |
|
|
|
polyline: { |
|
|
|
positions: solidPositions, |
|
|
|
width: 3, |
|
|
|
material: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
material: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
} |
|
|
|
}); |
|
|
|
@ -1253,7 +1265,7 @@ export default { |
|
|
|
}, false), |
|
|
|
width: 3, |
|
|
|
material: new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
color: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
dashLength: 16 |
|
|
|
}), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
@ -1295,17 +1307,17 @@ export default { |
|
|
|
properties: { isMissionWaypoint: true, temp: true }, |
|
|
|
point: { |
|
|
|
pixelSize: 10, |
|
|
|
color: Cesium.Color.WHITE, |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#0078FF'), |
|
|
|
outlineWidth: 3, |
|
|
|
color: Cesium.Color.fromCssColorString('#f1f5f9'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
outlineWidth: 1.5, |
|
|
|
disableDepthTestDistance: Number.POSITIVE_INFINITY |
|
|
|
}, |
|
|
|
label: { |
|
|
|
text: pr.platformName, |
|
|
|
font: '14px Microsoft YaHei', |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -20), |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#333333'), |
|
|
|
outlineColor: Cesium.Color.BLACK, |
|
|
|
fillColor: Cesium.Color.fromCssColorString('#334155'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), |
|
|
|
outlineWidth: 1, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
@ -1405,7 +1417,7 @@ export default { |
|
|
|
polyline: { |
|
|
|
positions: solidPositions, |
|
|
|
width: 3, |
|
|
|
material: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
material: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
} |
|
|
|
}); |
|
|
|
@ -1950,12 +1962,12 @@ export default { |
|
|
|
renderRouteWaypoints(waypoints, routeId = 'default', platformId, platform, style) { |
|
|
|
if (!waypoints || waypoints.length < 1) return; |
|
|
|
this.waypointDragPreview = null; |
|
|
|
// 清理旧线 |
|
|
|
// 清理旧线(主航线 + 透明点击层;含历史柔边层 id 以便兼容旧数据) |
|
|
|
const lineId = `route-line-${routeId}`; |
|
|
|
const existingLine = this.viewer.entities.getById(lineId); |
|
|
|
if (existingLine) { |
|
|
|
this.viewer.entities.remove(existingLine); |
|
|
|
} |
|
|
|
[lineId, lineId + '-hit', lineId + '-soft'].forEach((id) => { |
|
|
|
const existing = this.viewer.entities.getById(id); |
|
|
|
if (existing) this.viewer.entities.remove(existing); |
|
|
|
}); |
|
|
|
// 清理属于该航线的旧平台图标与标牌 |
|
|
|
const platformBillboardId = `route-platform-${routeId}`; |
|
|
|
const platformLabelId = `route-platform-label-${routeId}`; |
|
|
|
@ -1992,14 +2004,14 @@ export default { |
|
|
|
}); |
|
|
|
const wpStyle = (style && style.waypoint) ? style.waypoint : {}; |
|
|
|
const lineStyle = (style && style.line) ? style.line : {}; |
|
|
|
const pixelSize = wpStyle.pixelSize != null ? wpStyle.pixelSize : 7; |
|
|
|
const wpColor = wpStyle.color || '#ffffff'; |
|
|
|
const wpOutline = wpStyle.outlineColor || '#0078FF'; |
|
|
|
const wpOutlineW = wpStyle.outlineWidth != null ? wpStyle.outlineWidth : 2; |
|
|
|
// 航线默认墨绿色、线宽 3;与主航线一致的线型用于主线和转弯半径弧 |
|
|
|
const defaultPixelSize = wpStyle.pixelSize != null ? wpStyle.pixelSize : 10; |
|
|
|
const defaultWpColor = wpStyle.color || '#f1f5f9'; |
|
|
|
const defaultWpOutline = wpStyle.outlineColor || '#64748b'; |
|
|
|
const wpOutlineW = wpStyle.outlineWidth != null ? wpStyle.outlineWidth : 1.5; |
|
|
|
// 航线默认简约灰蓝色、线宽 3;与主航线一致的线型用于主线和转弯半径弧 |
|
|
|
const lineWidth = lineStyle.width != null ? lineStyle.width : 3; |
|
|
|
const lineColor = lineStyle.color || '#2E5C3E'; |
|
|
|
const gapColor = lineStyle.gapColor != null ? lineStyle.gapColor : '#000000'; |
|
|
|
const lineColor = lineStyle.color || '#64748b'; |
|
|
|
const gapColor = lineStyle.gapColor != null ? lineStyle.gapColor : '#cbd5e1'; |
|
|
|
const dashLen = lineStyle.dashLength != null ? lineStyle.dashLength : 20; |
|
|
|
const useDash = (lineStyle.style || 'solid') === 'dash'; |
|
|
|
const lineMaterial = useDash |
|
|
|
@ -2041,9 +2053,12 @@ export default { |
|
|
|
} |
|
|
|
return !!nextLogical; |
|
|
|
}; |
|
|
|
// 遍历并绘制航点标记:盘旋处在圆心画点+标签;有转弯半径时只画 entry/exit 两个虚拟点(见下方连线逻辑),不画原航点中心 |
|
|
|
// 遍历并绘制航点标记:盘旋处在圆心画点+标签;有转弯半径时只画 entry/exit 两个虚拟点(见下方连线逻辑),不画原航点中心。支持每航点 pixelSize/color/outlineColor |
|
|
|
waypoints.forEach((wp, index) => { |
|
|
|
const pos = originalPositions[index]; |
|
|
|
const pixelSize = wp.pixelSize != null ? Number(wp.pixelSize) : defaultPixelSize; |
|
|
|
const wpColor = wp.color || defaultWpColor; |
|
|
|
const wpOutline = wp.outlineColor != null ? wp.outlineColor : defaultWpOutline; |
|
|
|
if (this.isHoldWaypoint(wp)) { |
|
|
|
this.viewer.entities.add({ |
|
|
|
id: `wp_${routeId}_${wp.id}`, |
|
|
|
@ -2065,8 +2080,8 @@ export default { |
|
|
|
text: wp.name || `盘旋${index + 1}`, |
|
|
|
font: `${wp.labelFontSize != null ? Math.min(28, Math.max(10, Number(wp.labelFontSize))) : 14}px PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif`, |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -Math.max(14, pixelSize + 8)), |
|
|
|
fillColor: Cesium.Color.fromCssColorString(wp.labelColor || '#2c2c2c'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e8e8e8'), |
|
|
|
fillColor: Cesium.Color.fromCssColorString(wp.labelColor || '#334155'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), |
|
|
|
outlineWidth: 0.5, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
@ -2095,8 +2110,8 @@ export default { |
|
|
|
text: wp.name || `WP${index + 1}`, |
|
|
|
font: `${wp.labelFontSize != null ? Math.min(28, Math.max(10, Number(wp.labelFontSize))) : 14}px PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif`, |
|
|
|
pixelOffset: new Cesium.Cartesian2(0, -Math.max(14, pixelSize + 8)), |
|
|
|
fillColor: Cesium.Color.fromCssColorString(wp.labelColor || '#2c2c2c'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e8e8e8'), |
|
|
|
fillColor: Cesium.Color.fromCssColorString(wp.labelColor || '#334155'), |
|
|
|
outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), |
|
|
|
outlineWidth: 0.5, |
|
|
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE |
|
|
|
} |
|
|
|
@ -2453,6 +2468,9 @@ export default { |
|
|
|
properties: { routeId: routeId } |
|
|
|
}); |
|
|
|
const wpName = wp.name || `WP${i + 1}`; |
|
|
|
const arcPixelSize = wp.pixelSize != null ? Number(wp.pixelSize) : defaultPixelSize; |
|
|
|
const arcWpColor = wp.color || defaultWpColor; |
|
|
|
const arcWpOutline = wp.outlineColor != null ? wp.outlineColor : defaultWpOutline; |
|
|
|
[0, 1].forEach((idx) => { |
|
|
|
const suffix = idx === 0 ? '_entry' : '_exit'; |
|
|
|
const getPos = () => { const pts = getArcPoints(); return idx === 0 ? pts[0] : pts[pts.length - 1]; }; |
|
|
|
@ -2461,8 +2479,8 @@ export default { |
|
|
|
name: wpName, |
|
|
|
position: new Cesium.CallbackProperty(getPos, false), |
|
|
|
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: `${wp.labelFontSize != null ? Math.min(28, Math.max(10, Number(wp.labelFontSize))) : 14}px PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif`, pixelOffset: new Cesium.Cartesian2(0, -Math.max(14, pixelSize + 8)), fillColor: Cesium.Color.fromCssColorString(wp.labelColor || '#2c2c2c'), outlineColor: Cesium.Color.fromCssColorString('#e8e8e8'), outlineWidth: 0.5, style: Cesium.LabelStyle.FILL_AND_OUTLINE } |
|
|
|
point: { pixelSize: arcPixelSize, color: Cesium.Color.fromCssColorString(arcWpColor), outlineColor: Cesium.Color.fromCssColorString(arcWpOutline), outlineWidth: wpOutlineW, disableDepthTestDistance: Number.POSITIVE_INFINITY }, |
|
|
|
label: { text: wpName, font: `${wp.labelFontSize != null ? Math.min(28, Math.max(10, Number(wp.labelFontSize))) : 14}px PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif`, pixelOffset: new Cesium.Cartesian2(0, -Math.max(14, arcPixelSize + 8)), fillColor: Cesium.Color.fromCssColorString(wp.labelColor || '#334155'), outlineColor: Cesium.Color.fromCssColorString('#e2e8f0'), outlineWidth: 0.5, style: Cesium.LabelStyle.FILL_AND_OUTLINE } |
|
|
|
}); |
|
|
|
}); |
|
|
|
const arcPoints = getArcPoints(); |
|
|
|
@ -2478,21 +2496,40 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 绘制主航线:用 CallbackProperty 从各航点实体取当前位置,拖拽时实时连线 |
|
|
|
// 先加一层透明加宽“点击区域”,便于左键点中航线(细线难触发) |
|
|
|
const that = this; |
|
|
|
const hitLineId = lineId + '-hit'; |
|
|
|
const routePositionsCallback = new Cesium.CallbackProperty(function () { |
|
|
|
return that.getRouteLinePositionsFromWaypointEntities(routeId) || finalPathPositions; |
|
|
|
}, false); |
|
|
|
const hitEntity = this.viewer.entities.add({ |
|
|
|
id: hitLineId, |
|
|
|
polyline: { |
|
|
|
positions: routePositionsCallback, |
|
|
|
width: 48, |
|
|
|
material: Cesium.Color.TRANSPARENT, |
|
|
|
arcType: Cesium.ArcType.NONE, |
|
|
|
zIndex: 0 |
|
|
|
}, |
|
|
|
properties: { isMissionRouteLine: true, routeId: routeId } |
|
|
|
}); |
|
|
|
if (this.allEntities) { |
|
|
|
this.allEntities.push({ id: hitLineId, entity: hitEntity, type: 'route', routeId }); |
|
|
|
} |
|
|
|
const displayWidth = Math.max(lineWidth, 5); |
|
|
|
// 绘制主航线(视觉层,不参与拾取,点击由透明层响应) |
|
|
|
const routeEntity = this.viewer.entities.add({ |
|
|
|
id: lineId, |
|
|
|
polyline: { |
|
|
|
positions: new Cesium.CallbackProperty(function () { |
|
|
|
return that.getRouteLinePositionsFromWaypointEntities(routeId) || finalPathPositions; |
|
|
|
}, false), |
|
|
|
width: lineWidth, |
|
|
|
positions: routePositionsCallback, |
|
|
|
width: displayWidth, |
|
|
|
material: lineMaterial, |
|
|
|
arcType: Cesium.ArcType.NONE, |
|
|
|
zIndex: 1 |
|
|
|
}, |
|
|
|
properties: {isMissionRouteLine: true, routeId: routeId} |
|
|
|
properties: { isMissionRouteLine: true, routeId: routeId } |
|
|
|
}); |
|
|
|
routeEntity.isPickable = false; |
|
|
|
if (this.allEntities) { |
|
|
|
this.allEntities.push({ id: lineId, entity: routeEntity, type: 'route', routeId }); |
|
|
|
} |
|
|
|
@ -2535,6 +2572,27 @@ export default { |
|
|
|
return positions.length > 0 ? positions : null; |
|
|
|
}, |
|
|
|
|
|
|
|
/** 在屏幕坐标附近做半径拾取,若命中航线则返回 routeId,用于左键点击“附近”也能打开航线弹窗 */ |
|
|
|
pickRouteNearScreenPosition(screenPosition, radiusPixels) { |
|
|
|
if (!this.viewer || !this.viewer.scene) return null; |
|
|
|
const x = screenPosition.x; |
|
|
|
const y = screenPosition.y; |
|
|
|
const step = Math.max(4, Math.floor(radiusPixels / 4)); |
|
|
|
for (let dy = -radiusPixels; dy <= radiusPixels; dy += step) { |
|
|
|
for (let dx = -radiusPixels; dx <= radiusPixels; dx += step) { |
|
|
|
if (dx * dx + dy * dy > radiusPixels * radiusPixels) continue; |
|
|
|
const picked = this.viewer.scene.pick(new Cesium.Cartesian2(x + dx, y + dy)); |
|
|
|
if (!Cesium.defined(picked) || !picked.id) continue; |
|
|
|
const props = picked.id.properties ? picked.id.properties.getValue(Cesium.JulianDate.now()) : null; |
|
|
|
if (props && props.isMissionRouteLine && props.routeId != null) { |
|
|
|
const rid = props.routeId.getValue ? props.routeId.getValue() : props.routeId; |
|
|
|
return rid; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
}, |
|
|
|
|
|
|
|
/** 渲染/路径用:非首尾航点默认转弯坡度 45°,首尾为 0 */ |
|
|
|
getEffectiveTurnAngle(wp, index, waypointsLength) { |
|
|
|
if (index === 0 || index === waypointsLength - 1) return wp.turnAngle != null ? wp.turnAngle : 0; |
|
|
|
@ -3867,23 +3925,24 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
const pickedObject = this.viewer.scene.pick(click.position); |
|
|
|
let isWaypoint = false; |
|
|
|
let isRouteLine = false; |
|
|
|
let isPlatformIcon = false; |
|
|
|
let props = null; |
|
|
|
let entity = null; |
|
|
|
if (Cesium.defined(pickedObject) && pickedObject.id) { |
|
|
|
const entity = pickedObject.id; |
|
|
|
entity = pickedObject.id; |
|
|
|
const idStr = (entity && entity.id) ? entity.id : ''; |
|
|
|
if (idStr && (idStr.endsWith('-rotate-handle') || idStr.indexOf('-scale-') !== -1)) return; |
|
|
|
const platformIconData = this.allEntities.find(e => e.type === 'platformIcon' && e.entity === entity); |
|
|
|
|
|
|
|
// 获取属性时必须传入当前仿真时间 |
|
|
|
const now = Cesium.JulianDate.now(); |
|
|
|
const props = entity.properties ? entity.properties.getValue(now) : null; |
|
|
|
const isWaypoint = props && props.isMissionWaypoint; |
|
|
|
const isRouteLine = props && props.isMissionRouteLine; |
|
|
|
const isPlatformIcon = !!platformIconData; |
|
|
|
// 仅对航线、航点、平台图标做防抖与相机保存(其它实体不处理) |
|
|
|
if (!isWaypoint && !isRouteLine && !isPlatformIcon) return; |
|
|
|
|
|
|
|
props = entity.properties ? entity.properties.getValue(now) : null; |
|
|
|
isWaypoint = props && props.isMissionWaypoint; |
|
|
|
isRouteLine = props && props.isMissionRouteLine; |
|
|
|
isPlatformIcon = !!platformIconData; |
|
|
|
} |
|
|
|
if (isWaypoint || isRouteLine || isPlatformIcon) { |
|
|
|
const nowMs = Date.now(); |
|
|
|
// 防抖:若与上次点击间隔过短,视为双击,仅清除定时器不触发弹窗 |
|
|
|
if (nowMs - this.lastEntityClickTime < 300) { |
|
|
|
if (this.entityClickDebounceTimer) { |
|
|
|
clearTimeout(this.entityClickDebounceTimer); |
|
|
|
@ -3894,7 +3953,6 @@ export default { |
|
|
|
} |
|
|
|
this.lastEntityClickTime = nowMs; |
|
|
|
this.saveCameraStateBeforeEntityClick(); |
|
|
|
|
|
|
|
if (this.entityClickDebounceTimer) clearTimeout(this.entityClickDebounceTimer); |
|
|
|
const dbId = isWaypoint ? props.dbId : null; |
|
|
|
const routeId = isWaypoint ? props.routeId : (isRouteLine ? props.routeId : null); |
|
|
|
@ -3902,7 +3960,6 @@ export default { |
|
|
|
this.entityClickDebounceTimer = setTimeout(() => { |
|
|
|
this.entityClickDebounceTimer = null; |
|
|
|
this.lastEntityClickTime = 0; |
|
|
|
// 上锁的航线不打开编辑 |
|
|
|
if (this.routeLocked[routeId]) { |
|
|
|
this.$message && this.$message.info('该航线已上锁,请右键选择“解锁”后再编辑'); |
|
|
|
return; |
|
|
|
@ -3910,12 +3967,31 @@ export default { |
|
|
|
if (isWaypoint) { |
|
|
|
console.log(`>>> [地图触发] 点击了点 ${dbId}, 属于航线 ${routeId}`); |
|
|
|
this.$emit('open-waypoint-dialog', dbId, routeId); |
|
|
|
} else if (isRouteLine) { |
|
|
|
} else { |
|
|
|
console.log(`>>> [地图触发] 点击了航线 ${routeId}`); |
|
|
|
this.$emit('open-route-dialog', routeId); |
|
|
|
} |
|
|
|
}, 250); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
// 未点到航点/航线/平台时,在点击位置附近做半径拾取,方便点中航线 |
|
|
|
const routeIdFromRadius = this.pickRouteNearScreenPosition(click.position, 32); |
|
|
|
if (routeIdFromRadius != null) { |
|
|
|
const nowMs = Date.now(); |
|
|
|
if (nowMs - this.lastEntityClickTime < 300) return; |
|
|
|
this.lastEntityClickTime = nowMs; |
|
|
|
this.saveCameraStateBeforeEntityClick(); |
|
|
|
if (this.entityClickDebounceTimer) clearTimeout(this.entityClickDebounceTimer); |
|
|
|
this.entityClickDebounceTimer = setTimeout(() => { |
|
|
|
this.entityClickDebounceTimer = null; |
|
|
|
this.lastEntityClickTime = 0; |
|
|
|
if (this.routeLocked[routeIdFromRadius]) { |
|
|
|
this.$message && this.$message.info('该航线已上锁,请右键选择“解锁”后再编辑'); |
|
|
|
return; |
|
|
|
} |
|
|
|
this.$emit('open-route-dialog', routeIdFromRadius); |
|
|
|
}, 250); |
|
|
|
} |
|
|
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
|
|
|
|
|
|
|
@ -4077,8 +4153,26 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
initRightClickHandler() { |
|
|
|
const canvas = this.viewer.scene.canvas |
|
|
|
// 在整个地图组件根节点上拦截:包含地图、自定义右键菜单、工具栏等,避免点中菜单或任意子元素时仍弹出浏览器菜单 |
|
|
|
const container = this.$el |
|
|
|
if (!container) return |
|
|
|
this._contextMenuPreventContainer = container |
|
|
|
this._boundPreventContextMenu = (e) => { |
|
|
|
e.preventDefault() |
|
|
|
e.stopPropagation() |
|
|
|
} |
|
|
|
container.addEventListener('contextmenu', this._boundPreventContextMenu, true) |
|
|
|
// 兜底:window 捕获阶段拦截,仅当地点在本组件内时阻止 |
|
|
|
this._boundPreventContextMenuWindow = (e) => { |
|
|
|
if (container.contains(e.target)) { |
|
|
|
e.preventDefault() |
|
|
|
e.stopPropagation() |
|
|
|
} |
|
|
|
} |
|
|
|
window.addEventListener('contextmenu', this._boundPreventContextMenuWindow, true) |
|
|
|
// 创建屏幕空间事件处理器 |
|
|
|
this.rightClickHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas) |
|
|
|
this.rightClickHandler = new Cesium.ScreenSpaceEventHandler(canvas) |
|
|
|
// 右键点击事件:显示上下文菜单 |
|
|
|
this.rightClickHandler.setInputAction((click) => { |
|
|
|
// 如果正在绘制,不处理右键操作 |
|
|
|
@ -4599,6 +4693,8 @@ export default { |
|
|
|
controller.enableTilt = false |
|
|
|
controller.enableRotate = false |
|
|
|
controller.enableLook = false |
|
|
|
// 仅当 mapDragEnabled 为 true 时允许左键拖动地图 |
|
|
|
controller.enableTranslate = !!this.mapDragEnabled |
|
|
|
scene.screenSpaceCameraController.maximumPitch = 0 |
|
|
|
scene.screenSpaceCameraController.minimumPitch = 0 |
|
|
|
// 限制最小相机高度,防止双击时地图放大过多(单位:米) |
|
|
|
@ -6776,7 +6872,7 @@ export default { |
|
|
|
positions: positions, |
|
|
|
width: 3, |
|
|
|
material: new Cesium.PolylineDashMaterialProperty({ |
|
|
|
color: Cesium.Color.fromCssColorString('#2E5C3E'), |
|
|
|
color: Cesium.Color.fromCssColorString('#64748b'), |
|
|
|
dashLength: 16 |
|
|
|
}), |
|
|
|
arcType: Cesium.ArcType.NONE |
|
|
|
@ -9505,6 +9601,16 @@ export default { |
|
|
|
this.rightClickHandler.destroy() |
|
|
|
this.rightClickHandler = null |
|
|
|
} |
|
|
|
if (this._boundPreventContextMenuWindow) { |
|
|
|
window.removeEventListener('contextmenu', this._boundPreventContextMenuWindow, true) |
|
|
|
this._boundPreventContextMenuWindow = null |
|
|
|
} |
|
|
|
const preventContainer = this._contextMenuPreventContainer || (this.$el || (this.viewer && this.viewer.scene && this.viewer.scene.canvas && this.viewer.scene.canvas.parentElement)) |
|
|
|
if (preventContainer && this._boundPreventContextMenu) { |
|
|
|
preventContainer.removeEventListener('contextmenu', this._boundPreventContextMenu, true) |
|
|
|
this._contextMenuPreventContainer = null |
|
|
|
this._boundPreventContextMenu = null |
|
|
|
} |
|
|
|
|
|
|
|
if (this.mouseCoordinatesHandler) { |
|
|
|
this.mouseCoordinatesHandler.destroy() |
|
|
|
|