feat(3d-situational-awareness): 增加对分级应急点和塌陷边界的支持
- 为城市、区域和其他应急点添加新图标 - 更新地图点击处理器以显示分级应急点详情 - 实现塌陷边界绘制,左右地图使用实线和虚线 - 修改标记添加功能,按级别处理应急点(城市、区域、其他)
This commit is contained in:
parent
0303849072
commit
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 |
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user