Compare commits

..

No commits in common. "6123522fc9d3e07a742d9499eef4e625f2bf9ae7" and "0c828777cdba63920c0a89cdd03ce4e578682c01" have entirely different histories.

12 changed files with 178 additions and 417 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -66,13 +66,13 @@ const locationInfo = [
.location-panel { .location-panel {
width: 100%; width: 100%;
padding: clamp(16px, vh(16), 18px) clamp(6px, vw(6), 6px); padding: clamp(12px, vh(16), 20px) clamp(16px, vw(20), 28px);
background: url('../../assets/images/LocationPanel/地理位置内容背景.png') no-repeat center center; background: url('../../assets/images/LocationPanel/地理位置内容背景.png') no-repeat center center;
background-size: 100% 100%; background-size: 100% 100%;
border-radius: vw(8); border-radius: vw(8);
box-shadow: 0 0 vw(12) rgba(0, 0, 0, 0.35); box-shadow: 0 0 vw(12) rgba(0, 0, 0, 0.35);
overflow: hidden; overflow: hidden;
min-width: 248px; min-width: 240px;
max-width: 100%; max-width: 100%;
// min-height: 160px; // min-height: 160px;
} }
@ -82,7 +82,7 @@ const locationInfo = [
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr));
gap: clamp(2px, vh(4), 6px) 0px; gap: clamp(4px, vh(6), 8px) clamp(4px, vw(6), 8px);
width: 100%; width: 100%;
height: 100%; height: 100%;
} }

View File

@ -7,7 +7,6 @@
src="../../assets/images/摄像头.png" src="../../assets/images/摄像头.png"
alt="摄像头" alt="摄像头"
class="camera-icon" class="camera-icon"
@click.stop="handleCameraClick"
/> />
</template> </template>
<DisasterAnalysis /> <DisasterAnalysis />
@ -56,14 +55,6 @@
<DisasterAnalysis /> <DisasterAnalysis />
</LocationPanel> </LocationPanel>
</div> </div>
<!-- 视频弹窗 -->
<VideoModal
v-if="showVideoModal"
:visible="showVideoModal"
:monitor="cameraVideoData"
@close="handleCloseVideoModal"
/>
</div> </div>
</template> </template>
@ -74,7 +65,6 @@ import DisasterAnalysis from './DisasterAnalysis.vue'
import ForcePreset from './ForcePreset.vue' import ForcePreset from './ForcePreset.vue'
import ForceDispatch from './ForceDispatch.vue' import ForceDispatch from './ForceDispatch.vue'
import LocationPanel from './LocationPanel.vue' import LocationPanel from './LocationPanel.vue'
import VideoModal from '../RightPanel/VideoModal.vue'
const isLocationOpen = ref(true) const isLocationOpen = ref(true)
@ -82,30 +72,6 @@ const toggleLocation = () => {
isLocationOpen.value = !isLocationOpen.value isLocationOpen.value = !isLocationOpen.value
} }
//
const showVideoModal = ref(false)
const cameraVideoData = ref({
id: 999,
type: 'drone',
title: '现场实时监控',
videoSrc: '', //
dateRange: '',
hasAudio: true,
hasMegaphone: false,
hasZoom: false,
hasDirectionControl: false
})
//
const handleCameraClick = () => {
showVideoModal.value = true
}
//
const handleCloseVideoModal = () => {
showVideoModal.value = false
}
// //
const emit = defineEmits(['start-dispatch']) const emit = defineEmits(['start-dispatch'])
@ -135,8 +101,6 @@ const handleStartDispatch = (payload) => {
overflow-y: auto; overflow-y: auto;
overscroll-behavior: contain; overscroll-behavior: contain;
padding-left: vw(40); // padding-left: vw(40); //
padding-top: var(--sa-header-height);
box-sizing: border-box;
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: vw(6); width: vw(6);
@ -158,7 +122,7 @@ const handleStartDispatch = (payload) => {
.location-entry { .location-entry {
position: absolute; position: absolute;
top: var(--sa-header-height); top: vh(32);
left: 100%; left: 100%;
margin-left: vw(12); margin-left: vw(12);
display: flex; display: flex;
@ -224,21 +188,15 @@ const handleStartDispatch = (payload) => {
} }
.camera-icon { .camera-icon {
width: vw(30); width: vw(20);
height: vw(30); height: vw(20);
flex-shrink: 0; margin-left: vw(6);
object-fit: contain;
align-self: center;
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: opacity 0.2s ease;
vertical-align: middle;
&:hover { &:hover {
opacity: 0.8; opacity: 0.8;
transform: scale(1.1);
}
&:active {
transform: scale(0.95);
} }
} }
</style> </style>

View File

@ -62,7 +62,7 @@ const handleBack = () => {
align-items: center; align-items: center;
gap: vw(10); gap: vw(10);
padding: vh(10) vw(24); padding: vh(10) vw(24);
margin-top: 50px; margin-top: vh(20);
background: url('../assets/images/返回按钮.png') 0 -1px no-repeat; background: url('../assets/images/返回按钮.png') 0 -1px no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
border: none; border: none;

View File

@ -40,132 +40,129 @@
muted muted
controls controls
/> />
</div>
<!-- 操作台仅无人机等有方向控制的监控 --> <!-- 操作台仅无人机等有方向控制的监控 -->
<div v-if="monitor.hasDirectionControl" class="video-modal__console"> <div v-if="monitor.hasDirectionControl" class="video-modal__console">
<!-- 轮盘图标 --> <img
<img src="../../assets/images/video-control-console.png"
src="../../assets/images/video-control-console.png" alt="操作台背景"
alt="操作台" class="video-modal__console-bg"
class="video-modal__console-bg" />
/>
<!-- 控制按钮容器 --> <div class="video-modal__control-bar">
<div class="video-modal__control-bar"> <!-- 喊话 -->
<div
v-if="monitor.hasMegaphone"
class="video-modal__control-item"
role="button"
tabindex="0"
@click="$emit('megaphone', monitor.id)"
@keydown.enter.prevent="$emit('megaphone', monitor.id)"
>
<img
src="../../assets/images/video-control-megaphone.png"
alt="喊话"
class="video-modal__control-icon"
/>
<span class="video-modal__control-label">喊话</span>
</div>
<!-- 喊话 --> <!-- 声音 -->
<div <div
v-if="monitor.hasMegaphone" v-if="monitor.hasAudio"
class="video-modal__control-item" class="video-modal__control-item"
role="button" role="button"
tabindex="0" tabindex="0"
@click="$emit('megaphone', monitor.id)" @click="$emit('audio', monitor.id)"
@keydown.enter.prevent="$emit('megaphone', monitor.id)" @keydown.enter.prevent="$emit('audio', monitor.id)"
> >
<img <img
src="../../assets/images/video-control-megaphone.png" src="../../assets/images/video-control-sound.png"
alt="喊话" alt="声音"
class="video-modal__control-icon" class="video-modal__control-icon"
/> />
<span class="video-modal__control-label">喊话</span> <span class="video-modal__control-label">声音</span>
</div> </div>
<!-- 声音 --> <!-- 视觉左移 -->
<div <div
v-if="monitor.hasAudio" class="video-modal__control-item"
class="video-modal__control-item" role="button"
role="button" tabindex="0"
tabindex="0" @click="handleMove('left')"
@click="$emit('audio', monitor.id)" @keydown.enter.prevent="handleMove('left')"
@keydown.enter.prevent="$emit('audio', monitor.id)" >
> <img
<img src="../../assets/images/video-control-left.png"
src="../../assets/images/video-control-sound.png" alt="左移"
alt="声音" class="video-modal__control-icon"
class="video-modal__control-icon" />
/> <span class="video-modal__control-label">视觉左移</span>
<span class="video-modal__control-label">声音</span> </div>
</div>
<!-- 视觉左--> <!-- 视觉右-->
<div <div
class="video-modal__control-item" class="video-modal__control-item"
role="button" role="button"
tabindex="0" tabindex="0"
@click="handleMove('left')" @click="handleMove('right')"
@keydown.enter.prevent="handleMove('left')" @keydown.enter.prevent="handleMove('right')"
> >
<img <img
src="../../assets/images/video-control-left.png" src="../../assets/images/video-control-right.png"
alt="左移" alt="右移"
class="video-modal__control-icon" class="video-modal__control-icon"
/> />
<span class="video-modal__control-label">视觉</span> <span class="video-modal__control-label">视觉</span>
</div> </div>
<!-- 视觉右--> <!-- 视觉上-->
<div <div
class="video-modal__control-item" class="video-modal__control-item"
role="button" role="button"
tabindex="0" tabindex="0"
@click="handleMove('right')" @click="handleMove('up')"
@keydown.enter.prevent="handleMove('right')" @keydown.enter.prevent="handleMove('up')"
> >
<img <img
src="../../assets/images/video-control-right.png" src="../../assets/images/video-control-up.png"
alt="右移" alt="上移"
class="video-modal__control-icon" class="video-modal__control-icon"
/> />
<span class="video-modal__control-label">视觉</span> <span class="video-modal__control-label">视觉</span>
</div> </div>
<!-- 视觉上--> <!-- 视觉下-->
<div <div
class="video-modal__control-item" class="video-modal__control-item"
role="button" role="button"
tabindex="0" tabindex="0"
@click="handleMove('up')" @click="handleMove('down')"
@keydown.enter.prevent="handleMove('up')" @keydown.enter.prevent="handleMove('down')"
> >
<img <img
src="../../assets/images/video-control-up.png" src="../../assets/images/video-control-down.png"
alt="上移" alt="下移"
class="video-modal__control-icon" class="video-modal__control-icon"
/> />
<span class="video-modal__control-label">视觉</span> <span class="video-modal__control-label">视觉</span>
</div> </div>
<!-- 视觉下移 --> <!-- 缩小 -->
<div <div
class="video-modal__control-item" class="video-modal__control-item"
role="button" role="button"
tabindex="0" tabindex="0"
@click="handleMove('down')" @click="handleClose"
@keydown.enter.prevent="handleMove('down')" @keydown.enter.prevent="handleClose"
> >
<img <img
src="../../assets/images/video-control-down.png" src="../../assets/images/video-control-shrink.png"
alt="下移" alt="缩小"
class="video-modal__control-icon" class="video-modal__control-icon"
/> />
<span class="video-modal__control-label">视觉下移</span> <span class="video-modal__control-label">缩小</span>
</div>
<!-- 缩小 -->
<div
class="video-modal__control-item"
role="button"
tabindex="0"
@click="handleClose"
@keydown.enter.prevent="handleClose"
>
<img
src="../../assets/images/video-control-shrink.png"
alt="缩小"
class="video-modal__control-icon"
/>
<span class="video-modal__control-label">缩小</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -351,7 +348,6 @@ body.body--no-scroll {
background: rgba(0, 0, 0, 0.6); background: rgba(0, 0, 0, 0.6);
padding: clamp(10px, 1.5vh, 20px); padding: clamp(10px, 1.5vh, 20px);
overflow: hidden; overflow: hidden;
position: relative;
} }
&__video { &__video {
@ -363,50 +359,49 @@ body.body--no-scroll {
border-radius: vw(8); border-radius: vw(8);
} }
// //
&__console { &__console {
flex-shrink: 0;
position: absolute; position: absolute;
bottom: 100px; bottom: 80px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
z-index: 10; height: clamp(80px, 10vh, 120px);
display: flex; display: flex;
align-items: center; align-items: center;
gap: clamp(10px, 1.5vw, 20px); justify-content: center;
} }
//
&__console-bg { &__console-bg {
width: clamp(120px, 7vw, 140px); // position: absolute;
height: clamp(120px, 7vw, 140px); top: 0;
object-fit: contain; left: 0;
flex-shrink: 0; // width: 100%;
height: 85%;
object-fit: cover;
z-index: 0;
} }
//
&__control-bar { &__control-bar {
position: relative;
z-index: 1;
display: flex; display: flex;
align-items: center; align-items: center;
gap: clamp(20px, 2.5vw, 40px); justify-content: center;
padding: clamp(8px, 1vh, 12px) clamp(20px, 2.5vw, 40px); gap: clamp(15px, 2vw, 30px);
background: rgba(0, 0, 0, 0.75); padding: 0 clamp(20px, 2vw, 40px);
border-radius: 50px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
} }
&__control-item { &__control-item {
display: flex; display: flex;
flex-direction: row; flex-direction: column;
align-items: center; align-items: center;
gap: clamp(6px, 0.8vw, 10px); gap: clamp(4px, 0.5vh, 8px);
cursor: pointer; cursor: pointer;
transition: transform 0.2s ease, opacity 0.2s ease; transition: transform 0.2s ease;
padding: clamp(4px, 0.5vh, 8px);
&:hover { &:hover {
transform: scale(1.15); transform: scale(1.1);
opacity: 0.9;
} }
&:active { &:active {
@ -416,24 +411,22 @@ body.body--no-scroll {
&:focus-visible { &:focus-visible {
outline: 2px solid rgba(135, 206, 250, 0.8); outline: 2px solid rgba(135, 206, 250, 0.8);
outline-offset: 4px; outline-offset: 4px;
border-radius: clamp(4px, 0.5vw, 8px); border-radius: vw(4);
} }
} }
&__control-icon { &__control-icon {
width: clamp(28px, 3vw, 42px); width: clamp(24px, 2.5vw, 36px);
height: clamp(28px, 3vw, 42px); height: clamp(24px, 2.5vw, 36px);
object-fit: contain; object-fit: contain;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
} }
&__control-label { &__control-label {
font-size: clamp(12px, 1.1vw, 14px); font-size: clamp(11px, 1vw, 13px);
font-family: SourceHanSansCN-Regular, sans-serif; font-family: SourceHanSansCN-Regular, sans-serif;
color: #ffffff; color: #ffffff;
white-space: nowrap; white-space: nowrap;
line-height: 1.2; line-height: 1.2;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
} }
} }
</style> </style>

View File

@ -225,8 +225,8 @@ onUnmounted(() => {
top: -1px; top: -1px;
left: -3px; left: -3px;
z-index: 2; z-index: 2;
width: clamp(140px, 10.1vw, 154px); width: clamp(140px, 10.1vw, 194px);
height: clamp(18px, vh(18), 18px); height: clamp(28px, vh(32), 36px);
background: url("../../assets/images/video-time-bg.png") no-repeat background: url("../../assets/images/video-time-bg.png") no-repeat
center center; center center;
background-size: 100% 100%; background-size: 100% 100%;
@ -275,10 +275,9 @@ onUnmounted(() => {
transform-origin: center; transform-origin: center;
&__icon { &__icon {
width: clamp(20px, vw(20), 24px); width: clamp(12px, vw(14), 18px);
// height: clamp(14px, vw(14), 18px); height: clamp(12px, vh(14), 18px);
height: auto; margin-right: clamp(4px, vw(6), 8px);
// margin-right: clamp(4px, vw(6), 8px);
flex-shrink: 0; flex-shrink: 0;
object-fit: contain; object-fit: contain;
} }

View File

@ -41,8 +41,6 @@ import CollaborationInfo from './CollaborationInfo.vue'
overflow-y: auto; overflow-y: auto;
overscroll-behavior: contain; overscroll-behavior: contain;
padding-right: vw(40); // padding-right: vw(40); //
padding-top: var(--sa-header-height);
box-sizing: border-box;
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: vw(6); width: vw(6);

View File

@ -60,16 +60,16 @@ const valueClass = computed(() => {
&__label { &__label {
color: var(--text-white); color: var(--text-white);
font-size: fs(14); font-size: fs(14);
// font-family: SourceHanSansCN-Medium, sans-serif; font-family: SourceHanSansCN-Medium, sans-serif;
font-weight: 500; font-weight: 500;
white-space: nowrap; white-space: nowrap;
} }
&__value { &__value {
color: var(--text-white); color: var(--text-white);
font-size: fs(15); font-size: fs(14);
font-family: PingFangSC-Semibold, sans-serif; font-family: PingFangSC-Semibold, sans-serif;
font-weight: 700; font-weight: 600;
flex: 1; flex: 1;
text-align: right; text-align: right;
} }

View File

@ -6,8 +6,7 @@ import { cesiumDataConfig } from '../config/cesiumData'
import soldierIcon from '../assets/images/SketchPngfbec927027ff9e49207749ebaafd229429315341fda199251b6dfb1723ff17fb.png' import soldierIcon from '../assets/images/SketchPngfbec927027ff9e49207749ebaafd229429315341fda199251b6dfb1723ff17fb.png'
import deviceIcon from '../assets/images/SketchPng860d54f2a31f5f441fc6a88081224f1e98534bf6d5ca1246e420983bdf690380.png' import deviceIcon from '../assets/images/SketchPng860d54f2a31f5f441fc6a88081224f1e98534bf6d5ca1246e420983bdf690380.png'
import emergencyBaseIcon from '../assets/images/应急基地.png' import emergencyBaseIcon from '../assets/images/应急基地.png'
import emergencyCenterIcon from '../assets/images/应急中心icon定位.png' import emergencyCenterIcon from '../assets/images/应急中心.png'
import reserveCenterIcon from '../assets/images/储备中心.png'
// 默认高度偏移(米)- 与 WuRenJi 保持一致 // 默认高度偏移(米)- 与 WuRenJi 保持一致
const DEFAULT_HEIGHT_OFFSET = 100 const DEFAULT_HEIGHT_OFFSET = 100
@ -20,7 +19,6 @@ export function useMapMarkers() {
const collapseAreaEntities = ref([]) const collapseAreaEntities = ref([])
const markerEntities = ref([]) const markerEntities = ref([])
const emergencyResourceEntities = ref([]) // 应急资源标记由API数据动态生成 const emergencyResourceEntities = ref([]) // 应急资源标记由API数据动态生成
const reserveCenterEntities = ref([]) // 储备中心和预置点标记
/** /**
* 获取塌陷区域的所有位置点 * 获取塌陷区域的所有位置点
@ -576,108 +574,6 @@ export function useMapMarkers() {
emergencyResourceEntities.value = [] emergencyResourceEntities.value = []
} }
/**
* 清除储备中心和预置点标记
* @param {Cesium.Viewer} viewer
*/
const clearReserveCenterMarkers = (viewer) => {
if (!viewer) return
console.log(`[useMapMarkers] 清除 ${reserveCenterEntities.value.length} 个储备中心/预置点标记`)
reserveCenterEntities.value.forEach(entity => {
if (entity) viewer.entities.remove(entity)
})
reserveCenterEntities.value = []
}
/**
* 根据API数据添加储备中心和预置点标记
* @param {Cesium.Viewer} viewer
* @param {Array} reserveData - API返回的储备中心和预置点数据列表
* @param {string} reserveData[].gl1Id - ID
* @param {string} reserveData[].gl1Yjllmc - 名称
* @param {number} reserveData[].gl1Lng - 经度
* @param {number} reserveData[].gl1Lat - 纬度
* @param {string} reserveData[].gl1Qxmc - 区县名称
* @param {string} reserveData[].gl1Rysl - 人员数量
* @param {string} reserveData[].gl1Zdmj - 占地面积
* @param {string} reserveData[].gl1Lx - 类型 (2=储备中心, 3=预置点)
* @param {Object} options - 配置选项
* @param {number} [options.heightOffset=10] - 相对地面的高度偏移
* @returns {Promise<void>}
*/
const addReserveCenterMarkers = async (viewer, reserveData, options = {}) => {
if (!viewer) {
console.warn('[useMapMarkers] addReserveCenterMarkers: viewer 为空')
return
}
if (!Array.isArray(reserveData) || reserveData.length === 0) {
console.warn('[useMapMarkers] addReserveCenterMarkers: reserveData 为空或不是数组')
return
}
const markerOptions = {
heightOffset: options.heightOffset ?? DEFAULT_HEIGHT_OFFSET
}
console.log('[useMapMarkers] 开始添加储备中心和预置点标记...', reserveData.length)
const entities = []
for (const item of reserveData) {
if (!item.gl1Lat || !item.gl1Lng) {
console.warn('[useMapMarkers] 数据缺少坐标信息:', item)
continue
}
const result = await resolveCartesianFromDegrees(
viewer,
item.gl1Lng,
item.gl1Lat,
markerOptions.heightOffset,
false
)
// 根据类型选择图标和类型标识
// gl1Lx: 2=储备中心, 3=预置点
const itemType = String(item.gl1Lx).trim()
const isReserveCenter = itemType === '2'
const icon = isReserveCenter ? reserveCenterIcon : emergencyBaseIcon
const type = isReserveCenter ? 'reserveCenter' : 'presetPoint'
const entity = viewer.entities.add({
position: result.position,
billboard: {
image: icon,
width: 48,
height: 48,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
heightReference: resolveBillboardHeightReference(result.samplingSucceeded),
disableDepthTestDistance: Number.POSITIVE_INFINITY
},
properties: {
type,
id: item.gl1Id,
name: item.gl1Yjllmc || (isReserveCenter ? '储备中心' : '预置点'),
district: item.gl1Qxmc || '-',
personnelCount: item.gl1Rysl || '0',
area: item.gl1Zdmj || '-'
}
})
entities.push(entity)
}
reserveCenterEntities.value = entities
console.log(`[useMapMarkers] 添加储备中心/预置点标记 ${entities.length}`)
// 强制渲染场景,确保 CLAMP_TO_GROUND 立即生效
if (entities.length > 0) {
viewer.scene.requestRender()
}
}
/** /**
* 根据API数据添加应急资源标记养护站 * 根据API数据添加应急资源标记养护站
* @param {Cesium.Viewer} viewer * @param {Cesium.Viewer} viewer
@ -769,7 +665,6 @@ export function useMapMarkers() {
collapseAreaEntities, collapseAreaEntities,
markerEntities, markerEntities,
emergencyResourceEntities, emergencyResourceEntities,
reserveCenterEntities,
initializeMarkers, initializeMarkers,
clearMarkers, clearMarkers,
setMarkersSplitDirection, setMarkersSplitDirection,
@ -780,8 +675,6 @@ export function useMapMarkers() {
addRandomMarkers, addRandomMarkers,
addEmergencyResourceMarkers, addEmergencyResourceMarkers,
clearEmergencyResourceMarkers, clearEmergencyResourceMarkers,
addReserveCenterMarkers,
clearReserveCenterMarkers,
getCollapseCenter: calculateCollapseCenter // 提前获取中心点,不依赖标记初始化 getCollapseCenter: calculateCollapseCenter // 提前获取中心点,不依赖标记初始化
} }
} }

View File

@ -44,7 +44,7 @@ export const AFTER_3DTILES_CONFIG = {
// 3D Tiles 服务 URL // 3D Tiles 服务 URL
// url: 'http://222.212.85.86:9000/300bdf2b-a150-406e-be63-d28bd29b409f/model/S107/terra_b3dms/tileset.json', // url: 'http://222.212.85.86:9000/300bdf2b-a150-406e-be63-d28bd29b409f/model/S107/terra_b3dms/tileset.json',
url: 'http://222.212.85.86:9000/300bdf2b-a150-406e-be63-d28bd29b409f/model/ylzg/zxyj1120/terra_b3dms/tileset.json', url: 'http://222.212.85.86:9000/300bdf2b-a150-406e-be63-d28bd29b409f/model/ylzg/zxyj1119/terra_b3dms/tileset.json',
// 默认可见性(初始化时灾后模型默认显示) // 默认可见性(初始化时灾后模型默认显示)

View File

@ -181,7 +181,6 @@ import eventIcon from "./assets/images/事件icon.png";
import soldierIcon from "./assets/images/SketchPngfbec927027ff9e49207749ebaafd229429315341fda199251b6dfb1723ff17fb.png"; import soldierIcon from "./assets/images/SketchPngfbec927027ff9e49207749ebaafd229429315341fda199251b6dfb1723ff17fb.png";
import deviceIcon from "./assets/images/SketchPng860d54f2a31f5f441fc6a88081224f1e98534bf6d5ca1246e420983bdf690380.png"; import deviceIcon from "./assets/images/SketchPng860d54f2a31f5f441fc6a88081224f1e98534bf6d5ca1246e420983bdf690380.png";
import emergencyBaseIcon from "./assets/images/应急基地.png"; import emergencyBaseIcon from "./assets/images/应急基地.png";
import reserveCenterIcon from "./assets/images/储备中心.png";
// //
import collapseLeftArrow from "./assets/images/折叠面板左箭头.png"; import collapseLeftArrow from "./assets/images/折叠面板左箭头.png";
@ -204,9 +203,6 @@ const handleDistanceChange = async (newDistance) => {
// //
await loadEmergencyResources(108.011506, 30.175827); await loadEmergencyResources(108.011506, 30.175827);
//
await loadReserveCentersAndPresets(108.011506, 30.175827);
}; };
// 使 // 使
@ -226,8 +222,6 @@ const {
getCollapseCenter, getCollapseCenter,
addEmergencyResourceMarkers, addEmergencyResourceMarkers,
clearEmergencyResourceMarkers, clearEmergencyResourceMarkers,
addReserveCenterMarkers,
clearReserveCenterMarkers,
} = useMapMarkers(); } = useMapMarkers();
// Tooltip // Tooltip
@ -306,11 +300,6 @@ const setupMapClickHandler = (viewer) => {
showMarkerTooltip(viewer, markerEntity, click.position, icon); showMarkerTooltip(viewer, markerEntity, click.position, icon);
foundMarker = true; foundMarker = true;
break; break;
} else if (type === 'reserveCenter' || type === 'presetPoint') {
const icon = type === 'reserveCenter' ? reserveCenterIcon : emergencyBaseIcon;
showMarkerTooltip(viewer, markerEntity, click.position, icon);
foundMarker = true;
break;
} }
} }
} }
@ -339,10 +328,6 @@ const setupMapClickHandler = (viewer) => {
? emergencyCenterIcon ? emergencyCenterIcon
: emergencyBaseIcon; : emergencyBaseIcon;
showMarkerTooltip(viewer, entity, click.position, icon); showMarkerTooltip(viewer, entity, click.position, icon);
} else if (type === 'reserveCenter' || type === 'presetPoint') {
//
const icon = type === 'reserveCenter' ? reserveCenterIcon : emergencyBaseIcon;
showMarkerTooltip(viewer, entity, click.position, icon);
} }
} }
} else { } else {
@ -446,23 +431,6 @@ const showMarkerTooltip = (viewer, entity, screenPosition, icon) => {
{ label: '距离', value: `${distance}公里` } { label: '距离', value: `${distance}公里` }
); );
} }
} else if (type === 'reserveCenter') {
//
title = '储备中心';
fields.push(
{ label: '名称', value: properties.name?.getValue() || '-' },
{ label: '区县', value: properties.district?.getValue() || '-' },
{ label: '人员数量', value: properties.personnelCount?.getValue() || '0' },
{ label: '占地面积', value: properties.area?.getValue() ? `${properties.area?.getValue()}` : '-' }
);
} else if (type === 'presetPoint') {
//
title = '预置点';
fields.push(
{ label: '名称', value: properties.name?.getValue() || '-' },
{ label: '区县', value: properties.district?.getValue() || '-' },
{ label: '人员数量', value: properties.personnelCount?.getValue() || '0' }
);
} }
// Tooltip使 // Tooltip使
@ -551,20 +519,22 @@ onMounted(() => {
}); });
viewer.entities.add(defaultPoint); viewer.entities.add(defaultPoint);
// 10 // 1010km
// 1111km13096km
// 10km0.090.104
const simulatedPoints = [ const simulatedPoints = [
// (6) // -
{ type: 'soldier', name: '张三', department: '应急救援队', lon: 107.97, lat: 30.25, distance: 2.5, icon: soldierIcon }, { type: 'soldier', name: '张三', department: '应急救援队', lon: 108.051, lat: 30.205, distance: 4.2, icon: soldierIcon },
{ type: 'soldier', name: '李四', department: '消防队', lon: 107.971901, lat: 30.251428, distance: 2.3, icon: soldierIcon }, { type: 'soldier', name: '李四', department: '消防队', lon: 107.975, lat: 30.195, distance: 5.8, icon: soldierIcon },
{ type: 'soldier', name: '王五', department: '医疗队', lon: 107.974901, lat: 30.241428, distance: 3.1, icon: soldierIcon }, { type: 'soldier', name: '王五', department: '医疗队', lon: 108.025, lat: 30.155, distance: 3.5, icon: soldierIcon },
{ type: 'soldier', name: '赵六', department: '应急救援队', lon: 108.047344, lat: 30.164313, distance: 4.2, icon: soldierIcon }, { type: 'soldier', name: '赵六', department: '应急救援队', lon: 108.085, lat: 30.168, distance: 7.2, icon: soldierIcon },
{ type: 'soldier', name: '刘七', department: '消防队', lon: 108.046344, lat: 30.168313, distance: 3.8, icon: soldierIcon }, { type: 'soldier', name: '刘七', department: '消防队', lon: 107.945, lat: 30.182, distance: 8.5, icon: soldierIcon },
{ type: 'soldier', name: '陈八', department: '医疗队', lon: 108.050344, lat: 30.170313, distance: 4.5, icon: soldierIcon }, // -
// (4) { type: 'device', name: '救援车辆A', deviceType: '消防车', lon: 108.065, lat: 30.185, distance: 6.3, icon: deviceIcon },
{ type: 'device', name: '救援车辆A', deviceType: '消防车', lon: 107.98088, lat: 30.2487, distance: 2.8, icon: deviceIcon }, { type: 'device', name: '救援车辆B', deviceType: '救护车', lon: 107.960, lat: 30.165, distance: 6.8, icon: deviceIcon },
{ type: 'device', name: '救援车辆B', deviceType: '救护车', lon: 107.97898, lat: 30.2502, distance: 2.6, icon: deviceIcon }, { type: 'device', name: '无人机A', deviceType: 'DJI', lon: 108.035, lat: 30.225, distance: 5.5, icon: deviceIcon },
{ type: 'device', name: '无人机A', deviceType: 'DJI', lon: 108.049344, lat: 30.160313, distance: 4.8, icon: deviceIcon }, { type: 'device', name: '无人机B', deviceType: 'DJI', lon: 108.095, lat: 30.195, distance: 9.2, icon: deviceIcon },
{ type: 'device', name: '无人机B', deviceType: 'DJI', lon: 108.043344, lat: 30.169313, distance: 3.6, icon: deviceIcon } { type: 'device', name: '通讯设备', deviceType: '卫星电话', lon: 107.930, lat: 30.175, distance: 9.8, icon: deviceIcon }
]; ];
simulatedPoints.forEach(point => { simulatedPoints.forEach(point => {
@ -751,60 +721,10 @@ const loadEmergencyResources = async (longitude, latitude) => {
} }
}; };
//
const loadReserveCentersAndPresets = async (longitude, latitude) => {
try {
const response = await request({
url: `/snow-ops-platform/yhYjll/list`,
method: "GET",
params: {
longitude,
latitude,
maxDistance: disasterData.forcePreset.value.searchRadius,
},
});
if (response?.data && Array.isArray(response.data)) {
console.log("[index.vue] 储备中心和预置点数据加载成功:", response.data);
//
if (mapStore.viewer) {
console.log("[index.vue] 添加储备中心和预置点地图标记...");
//
clearReserveCenterMarkers(mapStore.viewer);
//
await addReserveCenterMarkers(
mapStore.viewer,
response.data,
{ heightOffset: 10 }
);
} else {
console.warn("[index.vue] 地图viewer未就绪跳过标记更新");
}
} else {
console.warn("[index.vue] 储备中心和预置点接口返回数据为空");
}
return response;
} catch (error) {
console.error("[index.vue] 加载储备中心和预置点数据失败:", error);
ElMessage.warning({
message: "储备中心和预置点数据加载失败",
duration: 3000,
});
return null;
}
};
onMounted(async () => { onMounted(async () => {
// (使) // (使)
// await loadEmergencyResources(108.011506, 30.175827); // await loadEmergencyResources(108.011506, 30.175827);
const response = await loadEmergencyResources(108.011506, 30.175827); const response = await loadEmergencyResources(108.011506, 30.175827);
// (使)
await loadReserveCentersAndPresets(108.011506, 30.175827);
}); });
/** /**
@ -1214,8 +1134,8 @@ const showMapTooltip = ({ x, y, title = "", icon = "", data = null }) => {
// - // -
&__panel-column { &__panel-column {
position: absolute; position: absolute;
// top: var(--sa-header-height); // header top: var(--sa-header-height); // header
// bottom: 0; bottom: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--sa-gap); // gap: var(--sa-gap); //
@ -1354,7 +1274,7 @@ const showMapTooltip = ({ x, y, title = "", icon = "", data = null }) => {
// - // -
&__loading-layer { &__loading-layer {
position: absolute; position: absolute;
top: calc(var(--sa-header-height) + vh(40)); top: calc(var(--sa-header-height) + vh(20));
left: 0; left: 0;
right: 0; right: 0;
// bottom: 0; // bottom: 0;