增加地图元素清空功能,完成附近医院路线规划功能

This commit is contained in:
zk
2024-05-23 15:05:34 +08:00
parent 1599ffd6d8
commit 0eb5fad72f
11 changed files with 611 additions and 31 deletions
+3 -2
View File
@@ -47,7 +47,8 @@ export const tabList = [
export const helicopter = new URL('/@/assets/img/helicopter.png', import.meta.url).href;
export const mapbg = new URL('/@/assets/img/helicopter.png', import.meta.url).href;
export const alarmIcon = new URL('/@/assets/img/alarm-icon.png', import.meta.url).href;
export const male = new URL('/@/assets/img/male.png', import.meta.url).href;
export const female = new URL('/@/assets/img/female.png', import.meta.url).href;
// 直升机位置数据
export const aircraft = [
{
@@ -171,4 +172,4 @@ export function getKmStr(distance: number): string {
if (!distance) return '';
let d = convertMetersToKilometers(distance);
return d >= 1 ? d + '公里' : d * 100 + '米';
}
}
+130 -1
View File
@@ -36,6 +36,16 @@
<div v-show="!routeList.length" class="empty-data"> 暂无数据</div>
</div>
</div>
<div v-show="showHospitalList" class="reset-map" @click="resetMap">
<RedoOutlined title="重置地图" />
</div>
<RoutePanel
class="driving-route-panel"
v-show="showDrivingPanel"
:drivingRoute="drivingRoute"
:drivingTitle="drivingTitle"
@out-click="showDrivingPanel = false"
/>
<div style="flex: 1; overflow: hidden; margin: 0 0 10px">
<div id="mapContainer" class="mapContainer"></div>
</div>
@@ -58,35 +68,62 @@
<div class="text">累计处置</div>
</div>
</div>
<!-- 附近医院医疗点 -->
<div class="hospital-list" v-if="showHospitalList">
<div class="hospital-item" v-for="(item, index) in hospitalList" :key="index" @click="showDrivingLine(item)">
<div>{{ item.name }}</div>
<div>相距{{ item.distance }}</div>
<div>驾车大约{{ item.driveTime }}</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { nextTick, onMounted, ref } from 'vue';
import { message } from 'ant-design-vue';
import { RedoOutlined } from '@ant-design/icons-vue';
import { Map } from '/@/assets/mapUtils/map';
import { aircraft, getKmStr, getTimeStr, legendList, mapApiSwitch, tabList, TabType } from '/@/components/chinaMap/chinaHooks';
import { useDetailStore } from '/@/store/modules/detailData.ts';
import RoutePanel from '/@/components/chinaMap/components/routePanel.vue';
const props = defineProps({
//是否展示底部统计
showFooter: {
type: Boolean,
default: () => {
return true;
},
},
//地图是否按照接口数据的中心点定位
computedCenter: {
type: Boolean,
default: () => {
return true;
},
},
// 地图配置
mapOptions: {
type: Object,
default: () => {
return {};
},
},
//是否展示最近的三个医院
showHospitalList: {
type: Boolean,
default: () => {
return false;
},
},
hospitalList: {
type: Array,
default: () => {
return [];
},
},
});
const emits = defineEmits(['clearHospitalList']);
const useDetail = useDetailStore();
const formState = ref({
start: '',
@@ -98,6 +135,7 @@
function changeTab(item, i: number) {
currentIndex.value = i; // 地方医院
Map.clearActiveHospital();
closeDrivingElement();
Map.map.off('moveend', logMapinfo);
if (TabType.diFangYiYuan == item.type) {
Map.removeOverlayGroup();
@@ -237,6 +275,36 @@
formState.value.start = '';
formState.value.end = '';
}
// 驾车路线
const drivingRoute = ref([]);
const drivingTitle = ref('');
const showDrivingPanel = ref(false);
function showDrivingLine(item) {
nextTick(() => {
drivingTitle.value = '全程' + item.driveTime + item.distance;
drivingRoute.value = item.routeList?.map((item) => item?.instruction);
showDrivingPanel.value = true;
if (item.lon) {
Map.clearNaviLine();
Map.createNaviLine(item.userLocation, [item.lon, item.lat]);
}
});
}
function closeDrivingElement() {
Map.clearNavigationElements();
formState.value.start = '';
formState.value.end = '';
showDrivingPanel.value = false;
emits('clearHospitalList');
}
function resetMap() {
closeDrivingElement();
changeTab(list.value[currentIndex.value], currentIndex.value);
}
</script>
<style lang="less" scoped>
.center-map {
@@ -409,6 +477,34 @@
}
}
.reset-map {
position: absolute;
left: 0;
top: 50px;
z-index: 99;
font-size: 20px;
color: #05d5ff;
cursor: pointer;
background: #243b5d;
padding: 0px 6px;
}
//驾驶路线导航面板
.driving-route-panel {
position: absolute;
right: 0;
top: 86px;
width: 288px;
padding: 9px 18px;
min-height: 200px;
max-height: 473px;
overflow: auto;
background: #2a4164;
border-radius: 2px;
border: 1px solid #1b7ef2;
z-index: 99;
}
.mapContainer {
flex: 1;
height: calc(100% + 22px);
@@ -472,5 +568,38 @@
}
}
}
.hospital-list {
position: absolute;
bottom: 200px;
width: 800px;
left: 50%;
transform: translateX(-50%);
display: flex;
.hospital-item {
position: relative;
flex: 1;
gap: 20px;
min-width: 230px;
max-width: 230px;
height: 110px;
text-align: center;
padding: 10px;
margin: 0 10px;
color: #fff;
font-size: 16px;
background-color: #00152b;
border: 1px solid #1b7ef2;
border-radius: 12px;
box-shadow: 0 1px 11px 0 rgba(194, 189, 189, 0.5);
cursor: pointer;
}
.hospital-item:hover {
background-color: #192a46;
box-shadow: inset 0px 0px 16px 3px #2562a9;
}
}
}
</style>
@@ -0,0 +1,120 @@
<template>
<div class="route-panel">
<div v-show="drivingRoute.length" class="has-data">
<div class="line-title">
<div>{{ drivingTitle }}</div>
<div class="close-icon">
<CloseCircleOutlined style="font-size: 16px" @click="outClick" />
</div>
</div>
<div class="line-content">
<div class="start">起点</div>
<div class="line-body">
<div class="line"></div>
<div class="line-desc">
<p v-for="(item, i) in drivingRoute" :key="i">{{ item }}</p>
</div>
</div>
<div class="end">终点</div>
</div>
</div>
<div v-show="!drivingRoute.length" class="empty-data"> 暂无数据</div>
</div>
</template>
<script setup lang="ts">
import { CloseCircleOutlined } from '@ant-design/icons-vue';
const props = defineProps({
drivingRoute: {
type: Array,
default: () => [],
},
drivingTitle: {
type: String,
default: '',
},
});
const emit = defineEmits(['outClick']);
function outClick() {
emit('outClick', false);
}
</script>
<style scoped lang="less">
.route-panel {
.line-title {
position: relative;
margin-bottom: 9px;
font-size: 14px;
font-weight: 700;
color: rgba(255, 255, 255, 0.8);
.close-icon {
position: absolute;
top: 1px;
right: -13px;
}
}
.line-content {
font-size: 12px;
.start {
display: flex;
align-items: center;
&::before {
content: '起';
color: #fff;
width: 20px;
height: 20px;
margin-right: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #1478f5;
}
}
.end {
display: flex;
align-items: center;
&::before {
content: '终';
color: #fff;
width: 20px;
height: 20px;
margin-right: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #1478f5;
}
}
.line-body {
display: flex;
//max-height: 370px;
}
.line {
width: 1px;
//max-height: 370px;
background-color: #1478f5;
margin: 5px 19px 5px 8px;
}
.line-sesc {
flex: 1;
}
}
.empty-data {
margin-top: 30%;
text-align: center;
}
}
</style>