diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/其他应急点.png b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/其他应急点.png new file mode 100644 index 0000000..6eb7d45 Binary files /dev/null and b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/其他应急点.png differ diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/区县应急点.png b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/区县应急点.png new file mode 100644 index 0000000..a3e7adc Binary files /dev/null and b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/区县应急点.png differ diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/市应急点.png b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/市应急点.png new file mode 100644 index 0000000..5de08c3 Binary files /dev/null and b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/市应急点.png differ diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapClickHandler.js b/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapClickHandler.js index 776ca59..ed6f867 100644 --- a/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapClickHandler.js +++ b/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapClickHandler.js @@ -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 { diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapMarkers.js b/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapMarkers.js index db16794..a17cd28 100644 --- a/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapMarkers.js +++ b/packages/screen/src/views/3DSituationalAwarenessRefactor/composables/useMapMarkers.js @@ -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} @@ -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,