|
|
|
@ -216,7 +216,11 @@ export default { |
|
|
|
PLATFORM_ROTATE_HANDLE_OFFSET_DEG: 0.0009, |
|
|
|
PLATFORM_DRAG_THRESHOLD_PX: 10, |
|
|
|
DESIRED_BOX_HALF_PX: 58, |
|
|
|
DESIRED_ROTATE_OFFSET_PX: 50 |
|
|
|
DESIRED_ROTATE_OFFSET_PX: 50, |
|
|
|
// 实体点击防抖,避免双击误触导致相机高度剧烈变化 |
|
|
|
entityClickDebounceTimer: null, |
|
|
|
lastEntityClickTime: 0, |
|
|
|
cameraStateBeforeEntityClick: null |
|
|
|
} |
|
|
|
}, |
|
|
|
components: { |
|
|
|
@ -1704,6 +1708,15 @@ export default { |
|
|
|
} |
|
|
|
this.loadOfflineMap() |
|
|
|
this.setup2DConstraints() |
|
|
|
// 移除 Cesium 自带的双击缩放,使双击实体/空白均无任何效果 |
|
|
|
try { |
|
|
|
const handler = this.viewer.screenSpaceEventHandler || (this.viewer.cesiumWidget && this.viewer.cesiumWidget.screenSpaceEventHandler) |
|
|
|
if (handler) { |
|
|
|
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
// 部分版本可能无此 action,忽略 |
|
|
|
} |
|
|
|
// 初始视野:中国中心(仅中国瓦片时无需世界瓦片,国外区域会无瓦片显示为空白) |
|
|
|
this.viewer.camera.setView({ |
|
|
|
destination: Cesium.Cartesian3.fromDegrees(116.3974, 39.9093, 12000000), |
|
|
|
@ -1721,7 +1734,7 @@ export default { |
|
|
|
this.initMouseCoordinates() |
|
|
|
console.log('Cesium离线二维地图已加载') |
|
|
|
|
|
|
|
// 1. 定义全局拾取处理器 |
|
|
|
// 1. 定义全局拾取处理器(含防抖,避免双击误触导致相机高度剧烈变化) |
|
|
|
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas); |
|
|
|
this.handler.setInputAction((click) => { |
|
|
|
// 隐藏右键菜单 |
|
|
|
@ -1735,31 +1748,69 @@ export default { |
|
|
|
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); |
|
|
|
if (platformIconData) return; |
|
|
|
|
|
|
|
// --- 修正后的安全日志 --- |
|
|
|
console.log(">>> [点击检测] 实体ID:", entity.id); |
|
|
|
|
|
|
|
// 获取属性时必须传入当前仿真时间 |
|
|
|
const now = Cesium.JulianDate.now(); |
|
|
|
const props = entity.properties ? entity.properties.getValue(now) : null; |
|
|
|
|
|
|
|
console.log(">>> [点击检测] 业务数据详情:", props); |
|
|
|
|
|
|
|
if (props && props.isMissionWaypoint) { |
|
|
|
const dbId = props.dbId; |
|
|
|
const routeId = props.routeId; |
|
|
|
const isWaypoint = props && props.isMissionWaypoint; |
|
|
|
const isRouteLine = props && props.isMissionRouteLine; |
|
|
|
const isPlatformIcon = !!platformIconData; |
|
|
|
// 仅对航线、航点、平台图标做防抖与相机保存(其它实体不处理) |
|
|
|
if (!isWaypoint && !isRouteLine && !isPlatformIcon) return; |
|
|
|
|
|
|
|
const nowMs = Date.now(); |
|
|
|
// 防抖:若与上次点击间隔过短,视为双击,仅清除定时器不触发弹窗 |
|
|
|
if (nowMs - this.lastEntityClickTime < 300) { |
|
|
|
if (this.entityClickDebounceTimer) { |
|
|
|
clearTimeout(this.entityClickDebounceTimer); |
|
|
|
this.entityClickDebounceTimer = null; |
|
|
|
} |
|
|
|
this.lastEntityClickTime = 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
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); |
|
|
|
if (isWaypoint || isRouteLine) { |
|
|
|
this.entityClickDebounceTimer = setTimeout(() => { |
|
|
|
this.entityClickDebounceTimer = null; |
|
|
|
this.lastEntityClickTime = 0; |
|
|
|
if (isWaypoint) { |
|
|
|
console.log(`>>> [地图触发] 点击了点 ${dbId}, 属于航线 ${routeId}`); |
|
|
|
// 关键:把航线 ID 也传给父组件 |
|
|
|
this.$emit('open-waypoint-dialog', dbId, routeId); |
|
|
|
} else if (props && props.isMissionRouteLine) { |
|
|
|
const routeId = props.routeId; |
|
|
|
} else if (isRouteLine) { |
|
|
|
console.log(`>>> [地图触发] 点击了航线 ${routeId}`); |
|
|
|
// 触发航线编辑弹窗事件 |
|
|
|
this.$emit('open-route-dialog', routeId); |
|
|
|
} |
|
|
|
}, 250); |
|
|
|
} |
|
|
|
} |
|
|
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
|
|
|
|
|
|
|
// 双击实体时恢复相机,避免误触导致地图放大过多 |
|
|
|
this.handler.setInputAction((click) => { |
|
|
|
if (this.isDrawing) return; |
|
|
|
const pickedObject = this.viewer.scene.pick(click.position); |
|
|
|
if (!Cesium.defined(pickedObject) || !pickedObject.id) return; |
|
|
|
const 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 isEntity = platformIconData || (props && (props.isMissionWaypoint || props.isMissionRouteLine)); |
|
|
|
if (isEntity && this.cameraStateBeforeEntityClick) { |
|
|
|
this.restoreCameraStateAfterEntityDoubleClick(); |
|
|
|
if (this.entityClickDebounceTimer) { |
|
|
|
clearTimeout(this.entityClickDebounceTimer); |
|
|
|
this.entityClickDebounceTimer = null; |
|
|
|
} |
|
|
|
this.lastEntityClickTime = 0; |
|
|
|
} |
|
|
|
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); |
|
|
|
} catch (error) { |
|
|
|
console.error('地图错误:', error) |
|
|
|
// 如果Cesium加载失败,显示错误信息 |
|
|
|
@ -2140,6 +2191,32 @@ export default { |
|
|
|
controller.enableLook = false |
|
|
|
scene.screenSpaceCameraController.maximumPitch = 0 |
|
|
|
scene.screenSpaceCameraController.minimumPitch = 0 |
|
|
|
// 限制最小相机高度,防止双击时地图放大过多(单位:米) |
|
|
|
controller.minimumZoomDistance = 2000 |
|
|
|
}, |
|
|
|
/** 在可能触发缩放的实体点击前保存相机状态,供双击时恢复 */ |
|
|
|
saveCameraStateBeforeEntityClick() { |
|
|
|
if (!this.viewer || !this.viewer.camera) return |
|
|
|
const cam = this.viewer.camera |
|
|
|
const carto = cam.positionCartographic |
|
|
|
this.cameraStateBeforeEntityClick = { |
|
|
|
longitude: carto.longitude, |
|
|
|
latitude: carto.latitude, |
|
|
|
height: carto.height, |
|
|
|
heading: cam.heading, |
|
|
|
pitch: cam.pitch, |
|
|
|
roll: cam.roll |
|
|
|
} |
|
|
|
}, |
|
|
|
/** 双击实体后恢复相机,避免误触导致地图放大过多 */ |
|
|
|
restoreCameraStateAfterEntityDoubleClick() { |
|
|
|
if (!this.viewer || !this.viewer.camera || !this.cameraStateBeforeEntityClick) return |
|
|
|
const s = this.cameraStateBeforeEntityClick |
|
|
|
this.viewer.camera.setView({ |
|
|
|
destination: Cesium.Cartesian3.fromRadians(s.longitude, s.latitude, s.height), |
|
|
|
orientation: { heading: s.heading, pitch: s.pitch, roll: s.roll } |
|
|
|
}) |
|
|
|
this.cameraStateBeforeEntityClick = null |
|
|
|
}, |
|
|
|
loadOfflineMap() { |
|
|
|
this.viewer.imageryLayers.removeAll() |
|
|
|
@ -4862,6 +4939,16 @@ export default { |
|
|
|
destroyViewer() { |
|
|
|
this.stopDrawing() |
|
|
|
this.clearAll(false) |
|
|
|
if (this.entityClickDebounceTimer) { |
|
|
|
clearTimeout(this.entityClickDebounceTimer) |
|
|
|
this.entityClickDebounceTimer = null |
|
|
|
} |
|
|
|
this.lastEntityClickTime = 0 |
|
|
|
this.cameraStateBeforeEntityClick = null |
|
|
|
if (this.handler) { |
|
|
|
this.handler.destroy() |
|
|
|
this.handler = null |
|
|
|
} |
|
|
|
|
|
|
|
if (this.pointMovementHandler) { |
|
|
|
this.pointMovementHandler.destroy() |
|
|
|
|