Compare commits
2 Commits
0303849072
...
037d1257ba
| Author | SHA1 | Date | |
|---|---|---|---|
| 037d1257ba | |||
| 00468b053b |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@ -111,7 +111,10 @@ export function useDisasterData() {
|
||||
bases: forcePreset.value.bases,
|
||||
|
||||
// 挖掘机建议数
|
||||
excavators: Math.max(1, Math.ceil(stationsCount / 2)),
|
||||
// excavators: Math.max(1, Math.ceil(stationsCount / 2)),
|
||||
|
||||
// 应急装备
|
||||
excavators: forcePreset.value.equipment,
|
||||
|
||||
// 阻断信息:固定建议
|
||||
blockInfo: '需发布',
|
||||
|
||||
@ -75,6 +75,9 @@ export function useDualMapCompare() {
|
||||
// viewer.scene.screenSpaceCameraController.enableTilt = false
|
||||
// viewer.scene.screenSpaceCameraController.enableLook = false
|
||||
|
||||
// 将 viewer 实例存储到容器上,供其他模块访问
|
||||
container._cesiumViewer = viewer
|
||||
|
||||
leftViewer.value = viewer
|
||||
console.log('[useDualMapCompare] 左侧Viewer初始化成功(交互已启用)') // 关键修改
|
||||
|
||||
@ -261,6 +264,32 @@ export function useDualMapCompare() {
|
||||
// 如果只是加载左侧模型(Viewer已存在)
|
||||
if (loadLeftModel && leftViewer.value) {
|
||||
console.log('[useDualMapCompare] 加载左侧灾前模型...')
|
||||
|
||||
// 在加载模型前,确保左侧相机位置与右侧同步
|
||||
if (rightViewerInstance && leftViewer.value) {
|
||||
console.log('[useDualMapCompare] 同步相机位置(延迟加载场景)...')
|
||||
const rightCamera = rightViewerInstance.camera
|
||||
|
||||
try {
|
||||
leftViewer.value.camera.setView({
|
||||
destination: rightCamera.position.clone(),
|
||||
orientation: {
|
||||
heading: rightCamera.heading,
|
||||
pitch: rightCamera.pitch,
|
||||
roll: rightCamera.roll
|
||||
}
|
||||
})
|
||||
|
||||
// 强制更新
|
||||
leftViewer.value.scene.requestRender()
|
||||
leftViewer.value.camera.changed.raiseEvent()
|
||||
|
||||
console.log('[useDualMapCompare] 相机位置同步完成')
|
||||
} catch (error) {
|
||||
console.error('[useDualMapCompare] 相机同步失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const tileset = await load3DTileset(leftViewer.value, 'before', false)
|
||||
if (tileset) {
|
||||
@ -321,9 +350,24 @@ export function useDualMapCompare() {
|
||||
throw error
|
||||
}
|
||||
|
||||
// 立即同步右侧相机的当前位置到左侧
|
||||
// 等待左侧 viewer 完全初始化
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
|
||||
// 立即同步右侧相机的当前位置到左侧(关键修复)
|
||||
console.log('[useDualMapCompare] 同步初始相机位置...')
|
||||
const rightCamera = rightViewerInstance.camera
|
||||
|
||||
// 记录当前右侧相机状态
|
||||
console.log('[useDualMapCompare] 右侧相机位置:', {
|
||||
position: rightCamera.position,
|
||||
heading: Cesium.Math.toDegrees(rightCamera.heading),
|
||||
pitch: Cesium.Math.toDegrees(rightCamera.pitch),
|
||||
roll: Cesium.Math.toDegrees(rightCamera.roll)
|
||||
})
|
||||
|
||||
// 强制同步相机位置(使用多种方式确保成功)
|
||||
try {
|
||||
// 方式1: 使用 setView (推荐)
|
||||
leftViewerInstance.camera.setView({
|
||||
destination: rightCamera.position.clone(),
|
||||
orientation: {
|
||||
@ -333,6 +377,30 @@ export function useDualMapCompare() {
|
||||
}
|
||||
})
|
||||
|
||||
// 方式2: 直接设置相机属性 (备份方案)
|
||||
leftViewerInstance.camera.position = rightCamera.position.clone()
|
||||
leftViewerInstance.camera.direction = rightCamera.direction.clone()
|
||||
leftViewerInstance.camera.up = rightCamera.up.clone()
|
||||
leftViewerInstance.camera.right = rightCamera.right.clone()
|
||||
|
||||
console.log('[useDualMapCompare] 初始相机同步成功')
|
||||
|
||||
// 验证同步结果
|
||||
const leftCamera = leftViewerInstance.camera
|
||||
console.log('[useDualMapCompare] 左侧相机位置:', {
|
||||
position: leftCamera.position,
|
||||
heading: Cesium.Math.toDegrees(leftCamera.heading),
|
||||
pitch: Cesium.Math.toDegrees(leftCamera.pitch),
|
||||
roll: Cesium.Math.toDegrees(leftCamera.roll)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[useDualMapCompare] 初始相机同步失败:', error)
|
||||
}
|
||||
|
||||
// 强制渲染左侧场景
|
||||
leftViewerInstance.scene.requestRender()
|
||||
leftViewerInstance.camera.changed.raiseEvent()
|
||||
|
||||
// 设置相机同步(单向:右→左)
|
||||
setupCameraSync(rightViewerInstance, leftViewerInstance)
|
||||
|
||||
@ -396,6 +464,13 @@ export function useDualMapCompare() {
|
||||
console.log('[useDualMapCompare] 左侧Viewer已销毁')
|
||||
}
|
||||
|
||||
// 清理容器上的 viewer 引用
|
||||
const leftContainer = document.getElementById('leftCesiumContainer')
|
||||
if (leftContainer && leftContainer._cesiumViewer) {
|
||||
delete leftContainer._cesiumViewer
|
||||
console.log('[useDualMapCompare] 已清理容器上的 viewer 引用')
|
||||
}
|
||||
|
||||
// 触发右侧viewer resize恢复全屏
|
||||
if (rightViewer.value && !rightViewer.value.isDestroyed()) {
|
||||
setTimeout(() => {
|
||||
|
||||
@ -127,6 +127,15 @@ export function useMapClickHandler({ tooltipComposable, icons, rangeCircleEntity
|
||||
: icons.emergencyBaseIcon
|
||||
} else if (type === 'reserveCenter' || type === 'presetPoint') {
|
||||
icon = type === 'reserveCenter' ? icons.reserveCenterIcon : icons.emergencyBaseIcon
|
||||
} else if (type === 'city' || type === 'district' || type === 'other') {
|
||||
// 新增:根据级别选择图标
|
||||
if (type === 'city') {
|
||||
icon = icons.cityEmergencyIcon
|
||||
} else if (type === 'district') {
|
||||
icon = icons.districtEmergencyIcon
|
||||
} else {
|
||||
icon = icons.otherEmergencyIcon
|
||||
}
|
||||
}
|
||||
|
||||
if (icon) {
|
||||
@ -285,6 +294,19 @@ export function useMapClickHandler({ tooltipComposable, icons, rangeCircleEntity
|
||||
)
|
||||
supportVideo = true
|
||||
videoTitle = '预置点'
|
||||
} else if (type === 'city' || type === 'district' || type === 'other') {
|
||||
// 新增:应急点(市级/区县级/其他)
|
||||
const level = properties.level?.getValue() || '应急点'
|
||||
title = `${level}应急点`
|
||||
fields.push(
|
||||
{ label: '名称', value: properties.name?.getValue() || '-' },
|
||||
{ label: '级别', value: level },
|
||||
{ label: '区县', value: properties.district?.getValue() || '-' },
|
||||
{ label: '人员数量', value: properties.personnelCount?.getValue() || '-' },
|
||||
{ label: '占地面积', value: properties.area?.getValue() || '-' }
|
||||
)
|
||||
supportVideo = true
|
||||
videoTitle = `${level}应急点`
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { ref } from 'vue'
|
||||
import * as Cesium from 'cesium'
|
||||
import { cesiumDataConfig } from '../config/cesiumData'
|
||||
import { collapseBoundaryData } from '../config/collapseBoundary'
|
||||
|
||||
// 图标导入
|
||||
import soldierIcon from '../assets/images/SketchPngfbec927027ff9e49207749ebaafd229429315341fda199251b6dfb1723ff17fb.png'
|
||||
@ -8,6 +9,10 @@ import deviceIcon from '../assets/images/SketchPng860d54f2a31f5f441fc6a88081224f
|
||||
import emergencyBaseIcon from '../assets/images/应急基地.png'
|
||||
import emergencyCenterIcon from '../assets/images/应急中心icon定位.png'
|
||||
import reserveCenterIcon from '../assets/images/储备中心.png'
|
||||
// 新增:根据级别的应急点图标
|
||||
import cityEmergencyIcon from '../assets/images/市应急点.png'
|
||||
import districtEmergencyIcon from '../assets/images/区县应急点.png'
|
||||
import otherEmergencyIcon from '../assets/images/其他应急点.png'
|
||||
|
||||
// 默认高度偏移(米)- 与 WuRenJi 保持一致
|
||||
const DEFAULT_HEIGHT_OFFSET = 100
|
||||
@ -21,6 +26,8 @@ export function useMapMarkers() {
|
||||
const markerEntities = ref([])
|
||||
const emergencyResourceEntities = ref([]) // 应急资源标记(由API数据动态生成)
|
||||
const reserveCenterEntities = ref([]) // 储备中心和预置点标记
|
||||
const collapseBoundaryEntity = ref(null) // 坍塌边界线实体(右侧实线)
|
||||
const collapseBoundaryLeftEntity = ref(null) // 坍塌边界线实体(左侧虚线)
|
||||
|
||||
/**
|
||||
* 获取塌陷区域的所有位置点
|
||||
@ -103,6 +110,187 @@ export function useMapMarkers() {
|
||||
return Cesium.HeightReference.CLAMP_TO_GROUND
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制坍塌边界蓝色实线(右侧地图)
|
||||
* 在右侧地图上显示灾后坍塌的边界轮廓
|
||||
* @param {Cesium.Viewer} viewer
|
||||
* @returns {Cesium.Entity | null} 返回创建的边界线实体
|
||||
*/
|
||||
const drawCollapseBoundary = (viewer) => {
|
||||
if (!viewer) {
|
||||
console.warn('[useMapMarkers] drawCollapseBoundary: viewer 为空')
|
||||
return null
|
||||
}
|
||||
|
||||
if (!Array.isArray(collapseBoundaryData) || collapseBoundaryData.length === 0) {
|
||||
console.warn('[useMapMarkers] drawCollapseBoundary: 配置数据为空')
|
||||
return null
|
||||
}
|
||||
|
||||
// 清除旧的边界线(如果存在)
|
||||
if (collapseBoundaryEntity.value) {
|
||||
viewer.entities.remove(collapseBoundaryEntity.value)
|
||||
collapseBoundaryEntity.value = null
|
||||
}
|
||||
|
||||
// 转换坐标点
|
||||
const positions = collapseBoundaryData.map(point =>
|
||||
new Cesium.Cartesian3(point.x, point.y, point.z)
|
||||
)
|
||||
|
||||
// 闭合线条(连接最后一个点到第一个点)
|
||||
positions.push(positions[0])
|
||||
|
||||
console.log('[useMapMarkers] 右侧坍塌边界点位数量:', positions.length)
|
||||
|
||||
// 创建蓝色实线边界
|
||||
const boundaryEntity = viewer.entities.add({
|
||||
polyline: {
|
||||
positions: positions,
|
||||
width: 4, // 增加线宽,更明显
|
||||
material: Cesium.Color.fromCssColorString('#1CA1FF').withAlpha(1.0), // 纯蓝色实线
|
||||
clampToGround: true,
|
||||
classificationType: Cesium.ClassificationType.BOTH, // 同时分类到地形和3D Tiles
|
||||
zIndex: 1 // 提高层级
|
||||
},
|
||||
properties: new Cesium.PropertyBag({
|
||||
type: 'collapseBoundary',
|
||||
name: '坍塌边界(右侧实线)'
|
||||
}),
|
||||
show: true // 明确设置为显示
|
||||
})
|
||||
|
||||
collapseBoundaryEntity.value = boundaryEntity
|
||||
console.log('[useMapMarkers] 右侧坍塌边界蓝色实线绘制完成, entityId:', boundaryEntity.id)
|
||||
|
||||
// 强制渲染场景
|
||||
viewer.scene.requestRender()
|
||||
|
||||
return boundaryEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制坍塌边界蓝色虚线(左侧地图)
|
||||
* 在左侧地图上显示灾前位置的虚线轮廓
|
||||
* @param {HTMLElement} leftContainer - 左侧地图容器元素
|
||||
* @returns {Cesium.Entity | null} 返回创建的边界线实体
|
||||
*/
|
||||
const drawCollapseBoundaryLeft = (leftContainer) => {
|
||||
if (!leftContainer) {
|
||||
console.warn('[useMapMarkers] drawCollapseBoundaryLeft: leftContainer 为空')
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取左侧 viewer(假设已经创建)
|
||||
const leftViewer = leftContainer._cesiumViewer
|
||||
if (!leftViewer) {
|
||||
console.warn('[useMapMarkers] drawCollapseBoundaryLeft: 左侧 viewer 未创建')
|
||||
return null
|
||||
}
|
||||
|
||||
if (!Array.isArray(collapseBoundaryData) || collapseBoundaryData.length === 0) {
|
||||
console.warn('[useMapMarkers] drawCollapseBoundaryLeft: 配置数据为空')
|
||||
return null
|
||||
}
|
||||
|
||||
// 清除旧的边界线(如果存在)
|
||||
if (collapseBoundaryLeftEntity.value) {
|
||||
leftViewer.entities.remove(collapseBoundaryLeftEntity.value)
|
||||
collapseBoundaryLeftEntity.value = null
|
||||
}
|
||||
|
||||
// 转换坐标点
|
||||
const positions = collapseBoundaryData.map(point =>
|
||||
new Cesium.Cartesian3(point.x, point.y, point.z)
|
||||
)
|
||||
|
||||
// 闭合线条(连接最后一个点到第一个点)
|
||||
positions.push(positions[0])
|
||||
|
||||
console.log('[useMapMarkers] 左侧坍塌边界点位数量:', positions.length)
|
||||
|
||||
// 创建蓝色虚线边界
|
||||
const boundaryEntity = leftViewer.entities.add({
|
||||
polyline: {
|
||||
positions: positions,
|
||||
width: 4,
|
||||
material: new Cesium.PolylineDashMaterialProperty({
|
||||
color: Cesium.Color.fromCssColorString('#1CA1FF').withAlpha(1.0), // 蓝色
|
||||
dashLength: 16.0, // 虚线段长度
|
||||
dashPattern: 255.0 // 虚线模式
|
||||
}),
|
||||
clampToGround: true,
|
||||
classificationType: Cesium.ClassificationType.BOTH,
|
||||
zIndex: 1
|
||||
},
|
||||
properties: new Cesium.PropertyBag({
|
||||
type: 'collapseBoundaryLeft',
|
||||
name: '坍塌边界(左侧虚线)'
|
||||
}),
|
||||
show: true
|
||||
})
|
||||
|
||||
collapseBoundaryLeftEntity.value = boundaryEntity
|
||||
console.log('[useMapMarkers] 左侧坍塌边界蓝色虚线绘制完成, entityId:', boundaryEntity.id)
|
||||
|
||||
// 强制渲染场景
|
||||
leftViewer.scene.requestRender()
|
||||
|
||||
return boundaryEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除坍塌边界线
|
||||
* @param {Cesium.Viewer} viewer - 右侧 viewer
|
||||
* @param {HTMLElement} leftContainer - 左侧地图容器(可选)
|
||||
*/
|
||||
const clearCollapseBoundary = (viewer, leftContainer = null) => {
|
||||
// 清除右侧边界线
|
||||
if (viewer && collapseBoundaryEntity.value) {
|
||||
viewer.entities.remove(collapseBoundaryEntity.value)
|
||||
collapseBoundaryEntity.value = null
|
||||
console.log('[useMapMarkers] 右侧坍塌边界线已清除')
|
||||
}
|
||||
|
||||
// 清除左侧边界线
|
||||
if (leftContainer && collapseBoundaryLeftEntity.value) {
|
||||
const leftViewer = leftContainer._cesiumViewer
|
||||
if (leftViewer) {
|
||||
leftViewer.entities.remove(collapseBoundaryLeftEntity.value)
|
||||
collapseBoundaryLeftEntity.value = null
|
||||
console.log('[useMapMarkers] 左侧坍塌边界线已清除')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示坍塌边界线
|
||||
*/
|
||||
const showCollapseBoundary = () => {
|
||||
if (collapseBoundaryEntity.value) {
|
||||
collapseBoundaryEntity.value.show = true
|
||||
console.log('[useMapMarkers] 显示右侧坍塌边界线')
|
||||
}
|
||||
if (collapseBoundaryLeftEntity.value) {
|
||||
collapseBoundaryLeftEntity.value.show = true
|
||||
console.log('[useMapMarkers] 显示左侧坍塌边界线')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏坍塌边界线
|
||||
*/
|
||||
const hideCollapseBoundary = () => {
|
||||
if (collapseBoundaryEntity.value) {
|
||||
collapseBoundaryEntity.value.show = false
|
||||
console.log('[useMapMarkers] 隐藏右侧坍塌边界线')
|
||||
}
|
||||
if (collapseBoundaryLeftEntity.value) {
|
||||
collapseBoundaryLeftEntity.value.show = false
|
||||
console.log('[useMapMarkers] 隐藏左侧坍塌边界线')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制塌陷区域多边形
|
||||
* 这个函数不涉及高度采样,直接使用配置中的绝对坐标
|
||||
@ -603,7 +791,7 @@ export function useMapMarkers() {
|
||||
* @param {string} reserveData[].gl1Qxmc - 区县名称
|
||||
* @param {string} reserveData[].gl1Rysl - 人员数量
|
||||
* @param {string} reserveData[].gl1Zdmj - 占地面积
|
||||
* @param {string} reserveData[].gl1Lx - 类型 (2=储备中心, 3=预置点)
|
||||
* @param {string} reserveData[].gl1Lx - 级别 (1=市级, 2=区县级, 3=其他)
|
||||
* @param {Object} options - 配置选项
|
||||
* @param {number} [options.heightOffset=10] - 相对地面的高度偏移(米)
|
||||
* @returns {Promise<void>}
|
||||
@ -641,27 +829,45 @@ export function useMapMarkers() {
|
||||
false
|
||||
)
|
||||
|
||||
// 根据类型选择图标和类型标识
|
||||
// gl1Lx: 2=储备中心, 3=预置点
|
||||
const itemType = String(item.gl1Lx).trim()
|
||||
const isReserveCenter = itemType === '2'
|
||||
const icon = isReserveCenter ? reserveCenterIcon : emergencyBaseIcon
|
||||
const type = isReserveCenter ? 'reserveCenter' : 'presetPoint'
|
||||
// 根据级别选择图标和类型标识
|
||||
// gl1Lx: "1市级", "2区县级", "3其他" 或者可能只是 "1", "2", "3"
|
||||
const levelString = String(item.gl1Lx || '').trim()
|
||||
let icon = otherEmergencyIcon // 默认使用其他应急点图标
|
||||
let type = 'other'
|
||||
let levelName = '其他'
|
||||
|
||||
// 判断级别(兼容 "1市级" 和 "1" 两种格式)
|
||||
if (levelString.startsWith('1') || levelString === '1') {
|
||||
icon = cityEmergencyIcon
|
||||
type = 'city'
|
||||
levelName = '市级'
|
||||
} else if (levelString.startsWith('2') || levelString === '2') {
|
||||
icon = districtEmergencyIcon
|
||||
type = 'district'
|
||||
levelName = '区县级'
|
||||
} else if (levelString.startsWith('3') || levelString === '3') {
|
||||
icon = otherEmergencyIcon
|
||||
type = 'other'
|
||||
levelName = '其他'
|
||||
}
|
||||
|
||||
console.log(`[useMapMarkers] 添加标记: ${item.gl1Yjllmc}, 级别: ${levelString} (${levelName})`)
|
||||
|
||||
const entity = viewer.entities.add({
|
||||
position: result.position,
|
||||
billboard: {
|
||||
image: icon,
|
||||
width: 48,
|
||||
height: 48,
|
||||
width: 29,
|
||||
height: 32,
|
||||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||
heightReference: resolveBillboardHeightReference(result.samplingSucceeded),
|
||||
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||||
},
|
||||
properties: {
|
||||
type,
|
||||
level: levelName,
|
||||
id: item.gl1Id,
|
||||
name: item.gl1Yjllmc || (isReserveCenter ? '储备中心' : '预置点'),
|
||||
name: item.gl1Yjllmc || `${levelName}应急点`,
|
||||
district: item.gl1Qxmc || '-',
|
||||
personnelCount: item.gl1Rysl || '0',
|
||||
area: item.gl1Zdmj || '-'
|
||||
@ -771,12 +977,19 @@ export function useMapMarkers() {
|
||||
markerEntities,
|
||||
emergencyResourceEntities,
|
||||
reserveCenterEntities,
|
||||
collapseBoundaryEntity,
|
||||
collapseBoundaryLeftEntity,
|
||||
initializeMarkers,
|
||||
clearMarkers,
|
||||
setMarkersSplitDirection,
|
||||
hideMarkers,
|
||||
showMarkers,
|
||||
drawCollapseArea,
|
||||
drawCollapseBoundary,
|
||||
drawCollapseBoundaryLeft,
|
||||
clearCollapseBoundary,
|
||||
showCollapseBoundary,
|
||||
hideCollapseBoundary,
|
||||
addFixedMarkers,
|
||||
addRandomMarkers,
|
||||
addEmergencyResourceMarkers,
|
||||
|
||||
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* 灾后坍塌边界Cartesian3坐标数据
|
||||
* 用于绘制蓝色实线边界
|
||||
*/
|
||||
export const collapseBoundaryData = [
|
||||
{
|
||||
x: -1706347.5312101133,
|
||||
y: 5248165.078710412,
|
||||
z: 3187394.127873529
|
||||
},
|
||||
{
|
||||
x: -1706350.6376697333,
|
||||
y: 5248165.028669288,
|
||||
z: 3187394.2121145395
|
||||
},
|
||||
{
|
||||
x: -1706352.8364036318,
|
||||
y: 5248165.537099652,
|
||||
z: 3187392.3620141866
|
||||
},
|
||||
{
|
||||
x: -1706354.4533845682,
|
||||
y: 5248165.6287691165,
|
||||
z: 3187390.116655845
|
||||
},
|
||||
{
|
||||
x: -1706355.2233232812,
|
||||
y: 5248165.6021544365,
|
||||
z: 3187387.277126487
|
||||
},
|
||||
{
|
||||
x: -1706354.7432117031,
|
||||
y: 5248164.178150934,
|
||||
z: 3187384.824506141
|
||||
},
|
||||
{
|
||||
x: -1706352.4841280153,
|
||||
y: 5248163.731050433,
|
||||
z: 3187383.6322611645
|
||||
},
|
||||
{
|
||||
x: -1706351.712005713,
|
||||
y: 5248162.186013809,
|
||||
z: 3187381.647760827
|
||||
},
|
||||
{
|
||||
x: -1706350.324299354,
|
||||
y: 5248162.767355746,
|
||||
z: 3187380.3936922415
|
||||
},
|
||||
{
|
||||
x: -1706348.0854380748,
|
||||
y: 5248165.163894288,
|
||||
z: 3187379.1822132985
|
||||
},
|
||||
{
|
||||
x: -1706346.0893322548,
|
||||
y: 5248165.439709174,
|
||||
z: 3187377.6419475204
|
||||
},
|
||||
{
|
||||
x: -1706343.2634703086,
|
||||
y: 5248165.840835863,
|
||||
z: 3187378.9524312993
|
||||
},
|
||||
{
|
||||
x: -1706341.9044425671,
|
||||
y: 5248167.062865315,
|
||||
z: 3187377.660352469
|
||||
},
|
||||
{
|
||||
x: -1706339.8929941722,
|
||||
y: 5248167.694347973,
|
||||
z: 3187378.3585356465
|
||||
},
|
||||
{
|
||||
x: -1706338.307401523,
|
||||
y: 5248167.350063955,
|
||||
z: 3187379.80788505
|
||||
},
|
||||
{
|
||||
x: -1706338.0093617737,
|
||||
y: 5248167.209763139,
|
||||
z: 3187381.8907824843
|
||||
},
|
||||
{
|
||||
x: -1706339.5459232442,
|
||||
y: 5248166.094283297,
|
||||
z: 3187382.861357757
|
||||
},
|
||||
{
|
||||
x: -1706339.2268297782,
|
||||
y: 5248165.94099689,
|
||||
z: 3187385.2711631004
|
||||
},
|
||||
{
|
||||
x: -1706340.8980982322,
|
||||
y: 5248162.72254414,
|
||||
z: 3187386.811143851
|
||||
},
|
||||
{
|
||||
x: -1706342.4054570391,
|
||||
y: 5248163.2478962615,
|
||||
z: 3187387.4919083416
|
||||
},
|
||||
{
|
||||
x: -1706342.8948843458,
|
||||
y: 5248163.095840862,
|
||||
z: 3187390.2277356824
|
||||
},
|
||||
{
|
||||
x: -1706344.3551372418,
|
||||
y: 5248163.910523915,
|
||||
z: 3187392.2502082493
|
||||
},
|
||||
{
|
||||
x: -1706346.0369703155,
|
||||
y: 5248164.550006937,
|
||||
z: 3187393.6480220454
|
||||
}
|
||||
]
|
||||
@ -284,6 +284,9 @@ import soldierIcon from './assets/images/SketchPngfbec927027ff9e49207749ebaafd22
|
||||
import deviceIcon from './assets/images/SketchPng860d54f2a31f5f441fc6a88081224f1e98534bf6d5ca1246e420983bdf690380.png'
|
||||
import emergencyBaseIcon from './assets/images/应急基地.png'
|
||||
import reserveCenterIcon from './assets/images/储备中心.png'
|
||||
import cityEmergencyIcon from './assets/images/市应急点.png'
|
||||
import districtEmergencyIcon from './assets/images/区县应急点.png'
|
||||
import otherEmergencyIcon from './assets/images/其他应急点.png'
|
||||
import mediaIcon from './assets/images/media.png'
|
||||
import collapseLeftArrow from './assets/images/折叠面板左箭头.png'
|
||||
import collapseRightArrow from './assets/images/折叠面板右箭头.png'
|
||||
@ -329,6 +332,11 @@ const {
|
||||
markerEntities,
|
||||
reserveCenterEntities,
|
||||
emergencyResourceEntities,
|
||||
drawCollapseBoundary,
|
||||
drawCollapseBoundaryLeft,
|
||||
clearCollapseBoundary,
|
||||
showCollapseBoundary,
|
||||
hideCollapseBoundary,
|
||||
} = useMapMarkers()
|
||||
|
||||
// 3D Tiles 加载
|
||||
@ -366,6 +374,9 @@ const mapClickHandler = useMapClickHandler({
|
||||
emergencyCenterIcon,
|
||||
emergencyBaseIcon,
|
||||
reserveCenterIcon,
|
||||
cityEmergencyIcon,
|
||||
districtEmergencyIcon,
|
||||
otherEmergencyIcon,
|
||||
},
|
||||
rangeCircleEntity,
|
||||
})
|
||||
@ -631,8 +642,8 @@ const handleForcePresetToggle = async () => {
|
||||
console.log('[index.vue] 已关闭地图对比模式')
|
||||
}
|
||||
|
||||
// 2. 显示所有标记和范围圈
|
||||
showAllMarkersAndRange()
|
||||
// 2. 显示所有标记和范围圈(现在是异步函数)
|
||||
await showAllMarkersAndRange()
|
||||
|
||||
// 3. 调整相机到最佳视角
|
||||
flyToBestViewForMarkers()
|
||||
@ -705,7 +716,7 @@ const handleDistanceChange = async (newDistance) => {
|
||||
/**
|
||||
* 显示所有标记点和范围圈
|
||||
*/
|
||||
const showAllMarkersAndRange = () => {
|
||||
const showAllMarkersAndRange = async () => {
|
||||
const viewer = mapStore.viewer
|
||||
if (!viewer) return
|
||||
|
||||
@ -730,15 +741,37 @@ const showAllMarkersAndRange = () => {
|
||||
|
||||
console.log('[index.vue] 已清除其他标记')
|
||||
|
||||
// 2. 显示储备中心/预置点标记
|
||||
reserveCenterEntities.value.forEach((entity) => {
|
||||
if (entity) {
|
||||
entity.show = true
|
||||
}
|
||||
})
|
||||
console.log(`[index.vue] 显示 ${reserveCenterEntities.value.length} 个储备中心/预置点标记`)
|
||||
// 2. 加载全部储备中心/预置点到地图(不限制距离)
|
||||
console.log('[index.vue] 加载全部储备中心/预置点到地图...')
|
||||
await loadReserveCentersAndPresets(DISASTER_CENTER.lon, DISASTER_CENTER.lat, true)
|
||||
|
||||
// 3. 在灾害中心点附近添加人员和装备点位
|
||||
// 3. 加载范围内的储备中心/预置点数据(用于面板显示和统计)
|
||||
console.log('[index.vue] 加载范围内储备中心/预置点数据(用于面板显示)...')
|
||||
const rangeResponse = await request({
|
||||
url: `/snow-ops-platform/yhYjll/list`,
|
||||
method: 'GET',
|
||||
params: {
|
||||
longitude: DISASTER_CENTER.lon,
|
||||
latitude: DISASTER_CENTER.lat,
|
||||
maxDistance: disasterData.forcePreset.value.searchRadius,
|
||||
},
|
||||
})
|
||||
|
||||
// 更新面板的 stations 数据(仅范围内)
|
||||
if (rangeResponse?.data && Array.isArray(rangeResponse.data)) {
|
||||
const transformedStations = disasterData.transformReserveDataToStations(
|
||||
rangeResponse.data,
|
||||
{ longitude: DISASTER_CENTER.lon, latitude: DISASTER_CENTER.lat }
|
||||
)
|
||||
if (transformedStations.length > 0) {
|
||||
disasterData.forcePreset.value.stations = transformedStations
|
||||
console.log('[index.vue] 已更新面板 stations(范围内):', transformedStations.length, '个')
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[index.vue] 显示全部储备中心/预置点标记`)
|
||||
|
||||
// 4. 在灾害中心点附近添加人员和装备点位
|
||||
const offset = 0.0002 // 约22米偏移,更明显
|
||||
|
||||
// 检查是否已存在中心点人员和装备标记,避免重复添加
|
||||
@ -800,7 +833,7 @@ const showAllMarkersAndRange = () => {
|
||||
// 强制渲染场景
|
||||
viewer.scene.requestRender()
|
||||
|
||||
// 4. 显示范围圈
|
||||
// 5. 显示范围圈
|
||||
showRangeCircle()
|
||||
|
||||
console.log('[index.vue] 快速响应标记显示完成')
|
||||
@ -947,35 +980,45 @@ const loadEmergencyResources = async (longitude, latitude) => {
|
||||
|
||||
/**
|
||||
* 加载储备中心和预置点数据
|
||||
* @param {number} longitude - 经度(可选,不传则查询全部)
|
||||
* @param {number} latitude - 纬度(可选,不传则查询全部)
|
||||
* @param {boolean} loadAllForMap - 是否加载全部点位到地图(true时不限制距离)
|
||||
*/
|
||||
const loadReserveCentersAndPresets = async (longitude, latitude) => {
|
||||
const loadReserveCentersAndPresets = async (longitude, latitude, loadAllForMap = false) => {
|
||||
try {
|
||||
// 构建请求参数
|
||||
const params = {}
|
||||
|
||||
if (!loadAllForMap && longitude !== undefined && latitude !== undefined) {
|
||||
// 正常模式:传递经纬度和距离限制
|
||||
params.longitude = longitude
|
||||
params.latitude = latitude
|
||||
params.maxDistance = disasterData.forcePreset.value.searchRadius
|
||||
}
|
||||
// loadAllForMap 为 true 时,不传任何参数,获取全部数据
|
||||
|
||||
const response = await request({
|
||||
url: `/snow-ops-platform/yhYjll/list`,
|
||||
method: 'GET',
|
||||
params: {
|
||||
longitude,
|
||||
latitude,
|
||||
maxDistance: disasterData.forcePreset.value.searchRadius,
|
||||
},
|
||||
params,
|
||||
})
|
||||
|
||||
if (response?.data && Array.isArray(response.data)) {
|
||||
console.log('[index.vue] 储备中心和预置点数据加载成功:', response.data)
|
||||
console.log('[index.vue] 储备中心和预置点数据加载成功:', response.data.length, '个点位')
|
||||
|
||||
// 1. 转换数据为标准 stations 格式并更新到 forcePreset
|
||||
// 1. 转换数据为标准 stations 格式
|
||||
const transformedStations = disasterData.transformReserveDataToStations(
|
||||
response.data,
|
||||
{ longitude, latitude }
|
||||
)
|
||||
|
||||
if (transformedStations.length > 0) {
|
||||
// 更新 forcePreset.stations (用于 station-list 显示)
|
||||
// 2. 仅在非"全部加载"模式下更新 forcePreset.stations(用于 station-list 显示)
|
||||
if (!loadAllForMap && transformedStations.length > 0) {
|
||||
disasterData.forcePreset.value.stations = transformedStations
|
||||
console.log('[index.vue] 已更新 forcePreset.stations:', transformedStations)
|
||||
console.log('[index.vue] 已更新 forcePreset.stations:', transformedStations.length, '个')
|
||||
}
|
||||
|
||||
// 2. 添加地图标记
|
||||
// 3. 添加地图标记(全部或范围内)
|
||||
if (mapStore.viewer) {
|
||||
console.log('[index.vue] 添加储备中心和预置点地图标记...')
|
||||
clearReserveCenterMarkers(mapStore.viewer)
|
||||
@ -1166,6 +1209,11 @@ const initializeScene = async () => {
|
||||
},
|
||||
})
|
||||
console.log('[index.vue] 中心点标记已添加')
|
||||
|
||||
// 绘制坍塌边界蓝色实线
|
||||
console.log('[index.vue] 绘制坍塌边界蓝色实线...')
|
||||
drawCollapseBoundary(viewer)
|
||||
console.log('[index.vue] 坍塌边界蓝色实线已添加')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[index.vue] 3D模型加载失败:', error)
|
||||
@ -1176,6 +1224,14 @@ const initializeScene = async () => {
|
||||
console.log('[index.vue] 开始加载左侧灾前模型...')
|
||||
await toggleCompareMode(true, viewer, { loadLeftModel: true })
|
||||
console.log('[index.vue] 左侧灾前模型加载完成')
|
||||
|
||||
// 在左侧地图绘制蓝色虚线边界
|
||||
const leftContainer = document.getElementById('leftCesiumContainer')
|
||||
if (leftContainer) {
|
||||
console.log('[index.vue] 绘制左侧坍塌边界蓝色虚线...')
|
||||
drawCollapseBoundaryLeft(leftContainer)
|
||||
console.log('[index.vue] 左侧坍塌边界蓝色虚线已添加')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[index.vue] 左侧模型加载失败:', error)
|
||||
}
|
||||
@ -1289,10 +1345,13 @@ onUnmounted(() => {
|
||||
console.log('[index.vue] 组件卸载,开始清理资源...')
|
||||
|
||||
const viewer = mapStore.viewer
|
||||
const leftContainer = document.getElementById('leftCesiumContainer')
|
||||
|
||||
// 清理范围圈
|
||||
if (viewer) {
|
||||
clearRangeCircle(viewer)
|
||||
// 清理坍塌边界线(包括左右两侧)
|
||||
clearCollapseBoundary(viewer, leftContainer)
|
||||
}
|
||||
|
||||
// 清理地图点击处理器
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user