feat: 冰雪阻断大屏更新
This commit is contained in:
parent
efa6fcf288
commit
9783c32fcb
@ -2,7 +2,6 @@ import { request } from '@shared/utils/request'
|
||||
|
||||
// 获取业务底图
|
||||
export function getBaseMap() {
|
||||
// return [...ddt]
|
||||
return request({
|
||||
url: '/snow-ops-platform/dataDirectory/queryCatalog',
|
||||
method: 'GET',
|
||||
@ -14,7 +13,6 @@ export function getBaseMap() {
|
||||
|
||||
// 获取业务图
|
||||
export function getBusinessMap() {
|
||||
// return [...si]
|
||||
return request({
|
||||
url: '/snow-ops-platform/dataDirectory/queryCatalog',
|
||||
method: 'GET',
|
||||
@ -24,6 +22,48 @@ export function getBusinessMap() {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取所有的养护站
|
||||
export function getAllYHZList() {
|
||||
return request({
|
||||
url: '/snow-ops-platform/yhz/listByDistrict',
|
||||
method: 'get',
|
||||
params: {
|
||||
qxmc: ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function getYHZDetail(params) {
|
||||
return request({
|
||||
url: '/snow-ops-platform/yhz/getById',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获得高海拔路段图 high-altitude road
|
||||
export function getHighAltitudeRoadMap () {
|
||||
return request({
|
||||
url: '/snow-ops-platform/dataDirectory/queryCatalog',
|
||||
method: 'GET',
|
||||
params: {
|
||||
pcatalog: 'GHBMAP'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取天气预警统计
|
||||
export function getWeatherWarningStatistics (params) {
|
||||
return request({
|
||||
url: '/snow-ops-platform/weatherWarning/statistics',
|
||||
method: 'GET',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
<!-- 浮动面板层 -->
|
||||
<div class="panels-layer">
|
||||
<div class="panel-column left-panel">
|
||||
<WeatherWarning />
|
||||
<EmergencyResources />
|
||||
<WeatherWarning ref="weatherWarningRef" />
|
||||
<EmergencyResources @clickEmergencyResource="handleEmergencyResourceClick" />
|
||||
</div>
|
||||
|
||||
<div class="center-spacer" aria-hidden="true"></div>
|
||||
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 图例工具栏 -->
|
||||
<LegendToolbar class="legend-toolbar" :legendKeys="legendKeys" @marker-toggle="handleLegendMarkerToggle" />
|
||||
<LegendToolbar class="legend-toolbar" v-model="legendToolActiveItem" :legendKeys="legendKeys" @marker-toggle="handleLegendMarkerToggle" />
|
||||
|
||||
<!-- 应急力量详情提示框 -->
|
||||
<EmergencyForceTooltip
|
||||
@ -63,6 +63,8 @@ import emergencyForceMarkerIcon from '../assets/legendTool/应急力量icon定
|
||||
onMounted(()=>{
|
||||
// 加载地图业务底图 并 聚焦中心点
|
||||
mapBase.loadBaseData()
|
||||
|
||||
weatherWarningRef.value.loadData()
|
||||
})
|
||||
|
||||
// ==================== 常量定义 ====================
|
||||
@ -79,6 +81,9 @@ const EMERGENCY_FORCE_LAYER_ID = 'legend:emergencyForce'
|
||||
*/
|
||||
const EMERGENCY_FORCE_CACHE_TTL = 60 * 1000
|
||||
|
||||
// ==================== 组件实例 ====================
|
||||
const weatherWarningRef = ref(null)
|
||||
|
||||
// ==================== 状态管理 ====================
|
||||
|
||||
const mapStore = useMapStore()
|
||||
@ -101,7 +106,7 @@ const mapBase = useMapBase(mapStore)
|
||||
/**
|
||||
* 标记图hook,搭配lengendToolbar使用, 作用是点击某个图例项时,在地图上显示所有该图例的图
|
||||
*/
|
||||
const mapImageMark = useMapImageMark(mapStore)
|
||||
const mapImageMarkHook = useMapImageMark(mapStore)
|
||||
|
||||
/**
|
||||
* 应急力量数据加载状态
|
||||
@ -131,9 +136,22 @@ const emergencyForceAbortController = ref(null)
|
||||
/**
|
||||
* 工具图标列表通过key关联
|
||||
* key具体有哪些,请根据LegendToolbar.vue中定义的defaultLegendItems
|
||||
* 后续的ImageMarkData中也需要与这里的key值对应
|
||||
*/
|
||||
const legendKeys = ref(['serviceFacility','riskRoad','blockEvent','weatherAlert','emergencyForce'])
|
||||
|
||||
/**
|
||||
* 过滤标记对象,存放当前需要过滤的关键字
|
||||
*/
|
||||
const filterMark = ref({
|
||||
serviceFacility: []
|
||||
})
|
||||
|
||||
/**
|
||||
* 图例项
|
||||
*/
|
||||
const legendToolActiveItem = ref([])
|
||||
|
||||
// ==================== 工具函数 ====================
|
||||
|
||||
/**
|
||||
@ -413,6 +431,34 @@ const renderEmergencyForcePoints = async (entityService, points, markerIcon) =>
|
||||
|
||||
// ==================== 事件处理 ====================
|
||||
|
||||
/**
|
||||
* 应急资源表格行被点击时触发
|
||||
*/
|
||||
const handleEmergencyResourceClick = (resource) => {
|
||||
// 根据区县名称,过滤养护站
|
||||
const filterList = filterMark.value.serviceFacility
|
||||
const index = filterList.findIndex((item) => item == resource.qxmc)
|
||||
// 实现第一次点击表示选中,第二次点击表示取消选中
|
||||
if(index > -1) filterList.splice(index, 1)
|
||||
else filterList.push(resource.qxmc)
|
||||
|
||||
// 当点击了某个区县,需要将养护站的legend也点亮
|
||||
const legendIndex = legendToolActiveItem.value.indexOf('serviceFacility')
|
||||
// 如果过滤列表存在数据,则需要点亮legend
|
||||
if(filterList.length && legendIndex == -1) {
|
||||
legendToolActiveItem.value.push('serviceFacility')
|
||||
}
|
||||
// 如果过滤列表不存在,则需要关闭legend
|
||||
if(!filterList.length && legendIndex > -1) {
|
||||
legendToolActiveItem.value.splice(legendIndex, 1)
|
||||
}
|
||||
|
||||
mapImageMarkHook.filterYHZMark("serviceFacility", (item)=>{
|
||||
return filterList.find((filterItem) => filterItem == item.qxmc)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理图例工具栏的标记切换事件
|
||||
*
|
||||
@ -422,10 +468,19 @@ const renderEmergencyForcePoints = async (entityService, points, markerIcon) =>
|
||||
* @param {string} [payload.markerIcon] - 标记图标
|
||||
*/
|
||||
const handleLegendMarkerToggle = async ({ key, active, markerIcon }) => {
|
||||
if(key === 'riskRoad') {
|
||||
mapBase.toggleHighAltitudeRoadMap(active)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 只处理应急力量图例项
|
||||
if (key !== 'emergencyForce') {
|
||||
if(active == false) {
|
||||
filterMark.value[key] = []
|
||||
}
|
||||
|
||||
mapImageMark.toggleMark({ key, active, markerIcon })
|
||||
mapImageMarkHook.toggleMark({ key, active, markerIcon })
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
:class="{ 'row-alt': index % 2 === 0 }"
|
||||
>
|
||||
<div class="row-number">{{ index + 1 }}</div>
|
||||
<span class="district-name">{{ resource.qxmc }}</span>
|
||||
<span class="district-name" @click="emit('clickEmergencyResource' , resource)">{{ resource.qxmc }}</span>
|
||||
<span class="count green">{{ resource.yhzCount }}</span>
|
||||
<span class="count orange">{{ resource.wzCount }}</span>
|
||||
<div class="equipment-cell">
|
||||
@ -43,7 +43,9 @@
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { request } from '@shared/utils/request'
|
||||
|
||||
const resources = ref([
|
||||
const emit = defineEmits(['clickEmergencyResource'])
|
||||
|
||||
const testData = [
|
||||
{
|
||||
id: 1,
|
||||
name: '万州区',
|
||||
@ -98,7 +100,9 @@ const resources = ref([
|
||||
equipmentClass: 'red',
|
||||
hasAlert: false
|
||||
}
|
||||
])
|
||||
]
|
||||
|
||||
const resources = ref([])
|
||||
|
||||
// 请求后端接口 /district/statistics
|
||||
const getDistrictStatistics = async () => {
|
||||
@ -106,7 +110,6 @@ const getDistrictStatistics = async () => {
|
||||
url: '/snow-ops-platform/district/statistics',
|
||||
method: 'GET'
|
||||
})
|
||||
console.log(res)
|
||||
if(res.code === '00000') {
|
||||
resources.value = res.data
|
||||
} else {
|
||||
@ -240,6 +243,7 @@ onMounted(() => {
|
||||
|
||||
.district-name {
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.count {
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
import { createVNode, render } from 'vue'
|
||||
import ImageMarkTooltip from './ImageMarkTooltip.vue'
|
||||
import serviceFacility from './serviceFacilityToolTip.vue'
|
||||
|
||||
class ImageMarkTooltipUI {
|
||||
constructor() {
|
||||
const UIMap = {
|
||||
serviceFacility
|
||||
}
|
||||
|
||||
class ImageMarkTooltip {
|
||||
constructor({ key }) {
|
||||
this.key = key
|
||||
this.instance = null
|
||||
this.container = null
|
||||
this.entity = null
|
||||
@ -22,8 +27,10 @@ class ImageMarkTooltipUI {
|
||||
|
||||
this.entity = options.entity
|
||||
|
||||
const UIInstance = UIMap[this.key]
|
||||
|
||||
// 创建 VNode
|
||||
const vnode = createVNode(ImageMarkTooltip, {
|
||||
const vnode = createVNode(UIInstance, {
|
||||
visible: true,
|
||||
position: options.position || { x: 0, y: 0 },
|
||||
data: options.data || {},
|
||||
@ -37,6 +44,9 @@ class ImageMarkTooltipUI {
|
||||
// 渲染到容器
|
||||
render(vnode, this.container)
|
||||
this.instance = vnode.component
|
||||
if(this.instance.exposed.init) {
|
||||
this.instance.exposed.init()
|
||||
}
|
||||
return this.instance
|
||||
}
|
||||
|
||||
@ -68,11 +78,7 @@ class ImageMarkTooltipUI {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单例实例
|
||||
const instance = new ImageMarkTooltipUI()
|
||||
|
||||
export const CommonTooltip = instance
|
||||
|
||||
export const newImageMarkTooltip = () => {
|
||||
return new ImageMarkTooltipUI()
|
||||
export const newImageMarkTooltip = ({ key }) => {
|
||||
return new ImageMarkTooltip({ key })
|
||||
}
|
||||
@ -1,5 +1,23 @@
|
||||
<template>
|
||||
<div class="tool-tip-content">
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">名称:</span>
|
||||
<span class="value">{{ data.mc }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="info-item">
|
||||
<span class="label">所属区县:</span>
|
||||
<span class="value">{{ data.yjllpz }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">应急设备:</span>
|
||||
<span class="value">{{ data.wz }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<div class="content" v-if="data">
|
||||
<div class="info-item">
|
||||
<span class="label">名称:</span>
|
||||
<span class="value">{{ data.mc }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="info-item">
|
||||
<span class="label">所属区县:</span>
|
||||
<span class="value">{{ data.yjllpz }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">应急物资:</span>
|
||||
<span class="value">{{ data.wz }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@use '@/styles/mixins.scss' as *;
|
||||
|
||||
// 信息项
|
||||
.info-item {
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -11,8 +11,32 @@
|
||||
</button>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<div class="tooltip-content">
|
||||
<component v-if="hasData" :is="contentMap[data.mapData.layerId]" :data="data" />
|
||||
<div class="tooltip-content" v-if="!loading && detail">
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">名称:</span>
|
||||
<span class="value">{{ detail.mc }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">所属区县:</span>
|
||||
<span class="value">{{ detail.qxmc }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">应急设备:</span>
|
||||
<span class="value">{{ detail.sbsl }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">应急物资:</span>
|
||||
<span class="value">{{ detail.wzsl }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item">
|
||||
<span class="label">应急人员:</span>
|
||||
<span class="value">{{ detail.rysl }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 如果没有数据 -->
|
||||
<div v-if="!hasData" class="no-data">
|
||||
@ -36,11 +60,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import serviceFacility from './serviceFacility.vue'
|
||||
import riskRoad from './riskRoad.vue'
|
||||
import weatherAlert from './weatherAlert.vue'
|
||||
import blockEvent from './blockEvent.vue'
|
||||
|
||||
import { getYHZDetail } from '@/views/cockpit/api/commonHttp.js'
|
||||
/**
|
||||
* 应急力量详情提示框组件
|
||||
* 使用 HTML Overlay 方式显示在地图标记点上方
|
||||
@ -75,14 +95,6 @@ const props = defineProps({
|
||||
default: () => ({})
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载状态
|
||||
*/
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@ -93,16 +105,10 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
// ==================== State ====================
|
||||
const contentMap = ref({
|
||||
// 养护站内容
|
||||
serviceFacility,
|
||||
// 高海拔道路
|
||||
riskRoad,
|
||||
// 阻断事件
|
||||
blockEvent,
|
||||
// 气象预警
|
||||
weatherAlert,
|
||||
})
|
||||
|
||||
const title = ref('养护站')
|
||||
const detail = ref(null)
|
||||
const loading = ref(true)
|
||||
|
||||
// ==================== Emits ====================
|
||||
|
||||
@ -117,22 +123,22 @@ const hasData = computed(() => {
|
||||
return !!props.data
|
||||
})
|
||||
|
||||
const title = computed(() => {
|
||||
if (props.data.mapData.layerId === 'serviceFacility') {
|
||||
return '养护站'
|
||||
}
|
||||
if (props.data.mapData.layerId === 'riskRoad') {
|
||||
return '高海拔路段'
|
||||
}
|
||||
if (props.data.mapData.layerId === 'blockEvent') {
|
||||
return '阻断事件'
|
||||
}
|
||||
if (props.data.mapData.layerId === 'weatherAlert') {
|
||||
return '气象预警'
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== Methods ====================
|
||||
// 这个方法会在index.js中被执行
|
||||
const init = () => {
|
||||
getDetail()
|
||||
}
|
||||
|
||||
const getDetail = async () => {
|
||||
loading.value = true
|
||||
const res = await getYHZDetail({
|
||||
id: props.data.id
|
||||
})
|
||||
if (res.success) {
|
||||
detail.value = res.data
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理关闭按钮点击
|
||||
@ -140,11 +146,22 @@ const title = computed(() => {
|
||||
const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
init
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use '@/styles/mixins.scss' as *;
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.common-tooltip {
|
||||
// CSS 变量:控制背景图片尺寸和内边距
|
||||
// 注意:修改图片资源时,需要同步更新这些高度值以匹配实际 PNG 尺寸
|
||||
@ -161,7 +178,7 @@ const handleClose = () => {
|
||||
transform: translate(-50%, calc(-100% - 20px));
|
||||
|
||||
min-width: 200px;
|
||||
max-width: 300px;
|
||||
width: 300px;
|
||||
|
||||
// 上下 padding 需要容纳顶部和底部图片 + 内容间距
|
||||
// 左右 padding 保持一致
|
||||
@ -262,25 +279,43 @@ const handleClose = () => {
|
||||
|
||||
// 内容区域
|
||||
.tooltip-content {
|
||||
padding-right: 1.5rem; // 为关闭按钮留出空间
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr 1fr;
|
||||
gap: 5px;
|
||||
|
||||
.info-item:first-child {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
// padding-right: 1.5rem; // 为关闭按钮留出空间
|
||||
}
|
||||
|
||||
.mb {
|
||||
margin-bottom: 0.5rem
|
||||
}
|
||||
|
||||
// 信息项
|
||||
.info-item {
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
white-space: nowrap;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-right: 0.5rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #fff;
|
||||
font-family: SourceHanSansCN, SourceHanSansCN;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #14FFF6;
|
||||
line-height: 21px;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { getWeatherWarningStatistics } from '@/views/cockpit/api/commonHttp.js'
|
||||
|
||||
// 导入图片
|
||||
import glowTopIcon from '../assets/img/weather-badge-glow-top.png'
|
||||
@ -79,7 +80,8 @@ const warningLevels = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '蓝色预警',
|
||||
count: 320,
|
||||
key: 'blueWarningCount',
|
||||
count: 0,
|
||||
color: 'rgba(132, 199, 255, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon,
|
||||
@ -88,7 +90,8 @@ const warningLevels = ref([
|
||||
{
|
||||
id: 2,
|
||||
name: '黄色预警',
|
||||
count: 36,
|
||||
key: 'yellowWarningCount',
|
||||
count: 0,
|
||||
color: 'rgba(215, 209, 38, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon,
|
||||
@ -97,7 +100,8 @@ const warningLevels = ref([
|
||||
{
|
||||
id: 3,
|
||||
name: '橙色预警',
|
||||
count: 2,
|
||||
key: 'orangeWarningCount',
|
||||
count: 0,
|
||||
color: 'rgba(255, 114, 0, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon,
|
||||
@ -106,7 +110,8 @@ const warningLevels = ref([
|
||||
{
|
||||
id: 4,
|
||||
name: '红色预警',
|
||||
count: 1,
|
||||
key: 'redWarningCount',
|
||||
count: 0,
|
||||
color: 'rgba(255, 32, 0, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon,
|
||||
@ -121,6 +126,24 @@ const districts = ref([
|
||||
{ id: 4, name: '涪陵区', km: 35, warning: '蓝色预警', warningColor: 'rgba(47, 156, 246, 1)' },
|
||||
{ id: 5, name: '合川区', km: 46, warning: '蓝色预警', warningColor: 'rgba(47, 156, 246, 1)' }
|
||||
])
|
||||
|
||||
const loadData = async (areaCode) => {
|
||||
const param = {
|
||||
areaCode: areaCode || ''
|
||||
}
|
||||
const res = await getWeatherWarningStatistics(param)
|
||||
if(res.success) {
|
||||
for(const item of warningLevels.value) {
|
||||
item.count = res.data[item.key]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
loadData
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@ -11,16 +11,19 @@ export default class ImageMarkData {
|
||||
cacheData = null
|
||||
expiresAt = null
|
||||
abortController = null
|
||||
loading = false
|
||||
/**
|
||||
* 60秒内重复点击使用缓存数据,减少服务器压力
|
||||
*/
|
||||
cacheTime = 60 * 1000
|
||||
|
||||
constructor({ api, tooltip, onResponse }) {
|
||||
constructor({ api, tooltip, markerIcon, onResponse, key }) {
|
||||
this.api = api
|
||||
this.key = key
|
||||
this.response = onResponse
|
||||
this.markerIcon = markerIcon
|
||||
// 初始化提示框
|
||||
this.tooltip = tooltip || newImageMarkTooltip()
|
||||
this.tooltip = tooltip || newImageMarkTooltip({key})
|
||||
}
|
||||
|
||||
getCache = () => {
|
||||
@ -37,7 +40,7 @@ export default class ImageMarkData {
|
||||
// 首先查看缓存是否可用
|
||||
const cacheData = this.getCache()
|
||||
if (cacheData) return cacheData
|
||||
|
||||
this.loading = true
|
||||
const controller = this.createAbortController()
|
||||
const config = {}
|
||||
if (controller) config.signal = controller.signal
|
||||
@ -47,6 +50,7 @@ export default class ImageMarkData {
|
||||
} catch (error) {
|
||||
console.error('请求失败: ', error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
let data = null
|
||||
if (this.response) data = this.response(res)
|
||||
else data = this.commonOnResponse(res)
|
||||
@ -81,7 +85,6 @@ export default class ImageMarkData {
|
||||
// 通用的响应处理
|
||||
commonOnResponse = (res) => {
|
||||
if (res?.success) {
|
||||
res.data = res.data.slice(0, 2)
|
||||
const dataList = res.data.map((item) => {
|
||||
item.mapData = {
|
||||
id: this.key + '-' + item.rid,
|
||||
@ -91,7 +94,6 @@ export default class ImageMarkData {
|
||||
}
|
||||
return item
|
||||
})
|
||||
this.data = dataList
|
||||
return dataList
|
||||
}
|
||||
return []
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { getBaseMap, getBusinessMap } from '@/views/cockpit/api/commonHttp.js'
|
||||
import { getBaseMap, getBusinessMap, getHighAltitudeRoadMap } from '@/views/cockpit/api/commonHttp.js'
|
||||
import * as Cesium from 'cesium'
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@ import * as Cesium from 'cesium'
|
||||
// 主要是加载地图底图
|
||||
export const useMapBase = (mapStore) => {
|
||||
|
||||
let hightAltitudeRoadMapId
|
||||
|
||||
// 加载当前业务的底图, 类似于天地图,但是没有使用天地图作为底图,有大的地块的地形纹理,但是缩小范围很小,属于比较粗的图
|
||||
const loadBaseMap = async () => {
|
||||
const layerService = mapStore.services().layer
|
||||
@ -53,7 +55,7 @@ export const useMapBase = (mapStore) => {
|
||||
return layers;
|
||||
};
|
||||
|
||||
// 加载业务地图,业务地图主要是高亮当前业务下的地区的区县,边界都会有高亮线条
|
||||
// 加载业务地图,业务地图主要是高亮当前业务下的地区的区县与管线图,边界都会有高亮线条
|
||||
const loadBusinessMap = async () => {
|
||||
const layerService = mapStore.services().layer
|
||||
const res = await getBusinessMap()
|
||||
@ -75,6 +77,34 @@ export const useMapBase = (mapStore) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载高海拔底图
|
||||
const toggleHighAltitudeRoadMap = async (flag) => {
|
||||
const layerService = mapStore.services().layer
|
||||
|
||||
if(!flag && hightAltitudeRoadMapId) {
|
||||
layerService.removeLayer(hightAltitudeRoadMapId)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
const res = await getHighAltitudeRoadMap()
|
||||
const resData = res.data
|
||||
resData[0].Children = resData
|
||||
mapStore.baseMapGroups = resData
|
||||
for (const item of resData) {
|
||||
const layers = mapStore.getBaseMapLayersForGroup(item.Attribute?.rid || item.Rid)
|
||||
for (const layerConfig of layers) {
|
||||
const layer = {
|
||||
id: layerConfig.id,
|
||||
type: layerConfig.type,
|
||||
url: layerConfig.url,
|
||||
meta: layerConfig.meta,
|
||||
}
|
||||
hightAltitudeRoadMapId = await layerService.addLayer(layer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const loadBaseData = () => {
|
||||
setTimeout(() => {
|
||||
loadBaseMap()
|
||||
@ -83,6 +113,7 @@ export const useMapBase = (mapStore) => {
|
||||
}
|
||||
|
||||
return {
|
||||
loadBaseData
|
||||
loadBaseData,
|
||||
toggleHighAltitudeRoadMap
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,18 @@
|
||||
import { fetchEmergencyForceList } from '@/views/cockpit/api/emergencyForce'
|
||||
import { getAllYHZList } from '@/views/cockpit/api/commonHttp'
|
||||
|
||||
import ImageMarkData from './ImageMarkData'
|
||||
import * as Cesium from 'cesium'
|
||||
|
||||
|
||||
import serviceFacilityMarkerIcon from '../assets/legendTool/服务设施icon定位.png'
|
||||
import riskRoadMarkerIcon from '../assets/legendTool/风险路段icon定位.png'
|
||||
import blockEventMarkerIcon from '../assets/legendTool/阻断事件icon定位.png'
|
||||
import emergencyForceMarkerIcon from '../assets/legendTool/应急力量icon定位.png'
|
||||
import weatherAlertMarkerIcon from '../assets/legendTool/气象预警icon定位.png'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
|
||||
/**
|
||||
* 当前业务下的地图服务
|
||||
* 主要是涉及需要调用后端服务获得地图数据
|
||||
@ -15,16 +25,41 @@ export const useMapImageMark = (mapStore) => {
|
||||
|
||||
// 接口服务映射
|
||||
const imageMarkMap = {
|
||||
// 养护站 legend
|
||||
serviceFacility: new ImageMarkData({
|
||||
api: fetchEmergencyForceList,
|
||||
}),
|
||||
riskRoad: new ImageMarkData({
|
||||
api: fetchEmergencyForceList,
|
||||
key: 'serviceFacility',
|
||||
api: getAllYHZList,
|
||||
markerIcon: serviceFacilityMarkerIcon,
|
||||
onResponse: function (res) {
|
||||
if (res?.success) {
|
||||
res.data = res.data.filter((item) => {
|
||||
if (isNaN(item.jd) || isNaN(item.wd)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
const dataList = res.data.map((item) => {
|
||||
item.mapData = {
|
||||
id: this.key + '-' + item.id,
|
||||
layerId: this.key,
|
||||
position: [Number(item.jd), Number(item.wd), 0],
|
||||
image: this.markerIcon
|
||||
}
|
||||
return item
|
||||
})
|
||||
return dataList
|
||||
}
|
||||
return []
|
||||
}
|
||||
}),
|
||||
blockEvent: new ImageMarkData({
|
||||
key: 'blockEvent',
|
||||
markerIcon: blockEventMarkerIcon,
|
||||
api: fetchEmergencyForceList,
|
||||
}),
|
||||
weatherAlert: new ImageMarkData({
|
||||
key: 'weatherAlert',
|
||||
markerIcon: weatherAlertMarkerIcon,
|
||||
api: fetchEmergencyForceList,
|
||||
})
|
||||
}
|
||||
@ -59,10 +94,10 @@ export const useMapImageMark = (mapStore) => {
|
||||
// 帧渲染函数,也就是显示器的每一帧都会执行
|
||||
// 地图拖动与放大的监控,需要更新各个tooltips的位置, 通过消息来通知
|
||||
viewer.scene.postRender.addEventListener(() => {
|
||||
for(const key in imageMarkMap) {
|
||||
for (const key in imageMarkMap) {
|
||||
const imageMarkData = imageMarkMap[key]
|
||||
const entity = imageMarkData.tooltip.entity
|
||||
if(!entity) continue
|
||||
if (!entity) continue
|
||||
imageMarkData.tooltip.updatePosition(getScreenPosition(entity))
|
||||
}
|
||||
})
|
||||
@ -102,20 +137,20 @@ export const useMapImageMark = (mapStore) => {
|
||||
/**
|
||||
* 根据图标名称请求后台服务,动态加载图标列表
|
||||
*/
|
||||
const loadDynamicMark = async ({ key, markerIcon, params }) => {
|
||||
const loadDynamicMark = async ({ key, params }) => {
|
||||
const imageMarkData = imageMarkMap[key]
|
||||
if (!imageMarkData) return
|
||||
imageMarkData.markerIcon = markerIcon
|
||||
imageMarkData.key = key
|
||||
// 取消上一次请求
|
||||
imageMarkData.cancelRequest()
|
||||
const dataList = await imageMarkData.request(params)
|
||||
|
||||
clearLayerEntity(key)
|
||||
drawImageEntities(dataList)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示/隐藏地图标
|
||||
*/
|
||||
const toggleMark = async ({ key, active, markerIcon, params }) => {
|
||||
const toggleMark = async ({ key, active, params }) => {
|
||||
const imageMarkData = imageMarkMap[key]
|
||||
|
||||
if (!active) {
|
||||
@ -124,7 +159,23 @@ export const useMapImageMark = (mapStore) => {
|
||||
return
|
||||
}
|
||||
|
||||
loadDynamicMark({ key, markerIcon, params })
|
||||
loadDynamicMark({ key, params })
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤养护站图标
|
||||
*/
|
||||
const filterYHZMark = async (key, filterFn) => {
|
||||
const imageMarkData = imageMarkMap[key]
|
||||
if (!imageMarkData) return
|
||||
// 取消上一次请求
|
||||
imageMarkData.cancelRequest()
|
||||
let dataList = await imageMarkData.request()
|
||||
dataList = dataList.filter((item) => {
|
||||
return filterFn(item)
|
||||
})
|
||||
clearLayerEntity(key)
|
||||
drawImageEntities(dataList)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -171,7 +222,8 @@ export const useMapImageMark = (mapStore) => {
|
||||
}
|
||||
|
||||
return {
|
||||
toggleMark
|
||||
toggleMark,
|
||||
filterYHZMark
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user