|
@@ -28,6 +28,41 @@
|
|
|
</div>
|
|
|
<div v-show="!!selectData.longitude && !!selectData.latitude" class="search-box">
|
|
|
<div class="search-title">{{ selectData.event_title }}</div>
|
|
|
+ <div class="search-item">
|
|
|
+ <div class="text1">选择救灾资源</div>
|
|
|
+ <el-select
|
|
|
+ v-model="queryParams.dataType"
|
|
|
+ class="custom-select select-box"
|
|
|
+ placeholder="请选择"
|
|
|
+ popper-class="custom-select-popper"
|
|
|
+ :teleported="false"
|
|
|
+ >
|
|
|
+ <el-option v-for="item in disaster_relief_material" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="search-item2">
|
|
|
+ <el-input v-model="queryParams.keyword" class="custom-input2" placeholder="请输入关键字搜索" style="width: 200px" />
|
|
|
+ <div class="common-btn-primary" @click="getList">搜索</div>
|
|
|
+ </div>
|
|
|
+ <div class="search-item3">
|
|
|
+ <el-checkbox v-model="checked1">自定义距离</el-checkbox>
|
|
|
+ <el-input v-model="distance" class="custom-input2" placeholder="自定义距离(公里)" style="width: 200px" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="list2">
|
|
|
+ <div>总数: {{ total }}个</div>
|
|
|
+ <div class="list-content">
|
|
|
+ <div v-for="(item, index) in dataList" :key="index" class="list-item">
|
|
|
+ <div class="text1">{{ item.name }}</div>
|
|
|
+ <div class="text-box">
|
|
|
+ <div class="text2">{{ item.address }}</div>
|
|
|
+ <div class="text3" @click="handleRoutes(item)">路线</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="text2"></div>
|
|
|
<div v-for="(item, index) in routeData" :key="index" class="route-item" @click="drawRoute(item)">
|
|
|
{{ item.policy }} | {{ item.distance / 1000 }}公里
|
|
|
</div>
|
|
@@ -39,18 +74,44 @@
|
|
|
// 初始化地图
|
|
|
import { useAMap } from '@/hooks/AMap/useAMap';
|
|
|
import { getEventActiveList } from '@/api/duty/eventing';
|
|
|
-import { getPointInfo } from '@/api/globalMap';
|
|
|
-import { iconList } from '@/views/globalMap/data/mapData';
|
|
|
+import { getEmergencyRescuePointInfoList, getPointInfo, getPointInfoList } from '@/api/globalMap';
|
|
|
+import { iconList, pointDetailTemplate } from '@/views/globalMap/data/mapData';
|
|
|
+import { getDictLabel } from '@/utils/dict';
|
|
|
+import {
|
|
|
+ getBuildingProjectDetails,
|
|
|
+ getChemicalcompanyDetails,
|
|
|
+ getChemicalWarehouseDetails,
|
|
|
+ getConstructionSitesDetails,
|
|
|
+ getEmergencyDisasterInfoOfficerDetails,
|
|
|
+ getEmergencyExpertDetails,
|
|
|
+ getEmergencyShelterTypeDetails,
|
|
|
+ getEmergencyTransportResourcesDetails,
|
|
|
+ getGasolinestationDetails,
|
|
|
+ getHospitalDetails,
|
|
|
+ getMajorHazardSourceDetails,
|
|
|
+ getMidmapDzzhDetails,
|
|
|
+ getMiningcompanyDetails,
|
|
|
+ getMiningOperationsDetails,
|
|
|
+ getRainbowDetails,
|
|
|
+ getSchoolDetails,
|
|
|
+ getShipRealtilmePositionDetails,
|
|
|
+ getStationInfoDetails,
|
|
|
+ getTouristAttractionDetails,
|
|
|
+ getUAVDetails,
|
|
|
+ getWarehouseDetails,
|
|
|
+ getWaterloggedRoadsDetails,
|
|
|
+ getYardSitesDetails
|
|
|
+} from '@/api/globalMap/spatialAnalysis';
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
-const { emergency_resource } = toRefs<any>(proxy?.useDict('emergency_resource'));
|
|
|
+const { emergency_resource, disaster_relief_material } = toRefs<any>(proxy?.useDict('emergency_resource', 'disaster_relief_material'));
|
|
|
// 应急资源
|
|
|
let expand = ref(true);
|
|
|
let AMap, map, driving;
|
|
|
let end = ref([110.925176, 21.678993]);
|
|
|
let routeData = ref([]);
|
|
|
let routeLine, startMarker, endMarker;
|
|
|
-const { getAMap, getMap, creatMask, switchMap, addMarker, clearMarker } = useAMap({
|
|
|
+const { getAMap, getMap, creatMask, switchMap, addMarker, clearMarker, showInfo, hideInfo } = useAMap({
|
|
|
el: 'aMap2',
|
|
|
key: '30d3d8448efd68cb0b284549fd41adcf', // 申请好的Web端开发者Key,首次调用 load 时必填
|
|
|
version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
|
@@ -69,7 +130,58 @@ const { getAMap, getMap, creatMask, switchMap, addMarker, clearMarker } = useAMa
|
|
|
//构造路线导航类
|
|
|
driving = new AMap.Driving({});
|
|
|
},
|
|
|
- onMarkerClick: (data) => {}
|
|
|
+ onMarkerClick: (data) => {
|
|
|
+ // 多点位
|
|
|
+ if (data.type === '1') {
|
|
|
+ let path = [];
|
|
|
+ props.pointType.forEach((item) => {
|
|
|
+ path.push(item.component);
|
|
|
+ });
|
|
|
+ getPointInfoList({
|
|
|
+ option: path.toString(),
|
|
|
+ longitude: data.longitude.toString(),
|
|
|
+ latitude: data.latitude.toString()
|
|
|
+ }).then((res) => {
|
|
|
+ const data2 = res.data.list;
|
|
|
+ let content = document.createElement('div');
|
|
|
+ // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
|
|
|
+ content.className = 'point-info';
|
|
|
+ let content2 = '';
|
|
|
+ content2 += '<div class="title-box"><div class="gradient-text">多点位信息</div></div>';
|
|
|
+ content2 += '<div class="icon1"></div>';
|
|
|
+ content2 += '<div class="icon2"></div>';
|
|
|
+ content2 += '<div class="icon3"></div>';
|
|
|
+ content2 += '<div class="icon4"></div>';
|
|
|
+ content.innerHTML = content2;
|
|
|
+ let tableBox = document.createElement('div');
|
|
|
+ tableBox.className = 'table-box';
|
|
|
+ let table = document.createElement('div');
|
|
|
+ table.className = 'table';
|
|
|
+ table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
|
|
|
+ data2.forEach((item) => {
|
|
|
+ item.longitude = data.longitude;
|
|
|
+ item.latitude = data.latitude;
|
|
|
+ const div = document.createElement('div');
|
|
|
+ div.className = 'point-item point-item-hover';
|
|
|
+ div.innerHTML =
|
|
|
+ '<div class="td4">' + getDictLabel(point_type.value, item.dataType.toString()) + '</div><div class="td4">' + item.name + '</div>';
|
|
|
+ div.addEventListener('click', () => {
|
|
|
+ handlePointDetails(item);
|
|
|
+ });
|
|
|
+ table.appendChild(div);
|
|
|
+ });
|
|
|
+ tableBox.appendChild(table);
|
|
|
+ content.appendChild(tableBox);
|
|
|
+ let closeBtn = document.createElement('div');
|
|
|
+ closeBtn.className = 'close';
|
|
|
+ closeBtn.onclick = hideInfo;
|
|
|
+ content.appendChild(closeBtn);
|
|
|
+ showInfo(content, [data.longitude, data.latitude], true);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ handlePointDetails(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
});
|
|
|
let eventList = ref([]);
|
|
|
let selectData = ref({
|
|
@@ -78,20 +190,30 @@ let selectData = ref({
|
|
|
latitude: ''
|
|
|
});
|
|
|
let selectMarker;
|
|
|
+let checked1 = ref(false);
|
|
|
+let distance = ref('');
|
|
|
+let queryParams = reactive({
|
|
|
+ keyword: '',
|
|
|
+ dataType: ''
|
|
|
+});
|
|
|
+let total = ref(0);
|
|
|
+let dataList = ref([]);
|
|
|
const toSelect = () => {
|
|
|
map.on('click', handleClickMap);
|
|
|
};
|
|
|
const handleClickMap = (e) => {
|
|
|
map.off('click', handleClickMap);
|
|
|
- selectEvent({
|
|
|
- longitude: e.lnglat.getLng(),
|
|
|
- latitude: e.lnglat.getLat()
|
|
|
- }, true);
|
|
|
+ selectEvent(
|
|
|
+ {
|
|
|
+ longitude: e.lnglat.getLng(),
|
|
|
+ latitude: e.lnglat.getLat()
|
|
|
+ },
|
|
|
+ true
|
|
|
+ );
|
|
|
};
|
|
|
// 选中事件
|
|
|
const selectEvent = (item, unFitView) => {
|
|
|
selectData.value = item;
|
|
|
- calculateRoutes([item.longitude, item.latitude], end.value, 0);
|
|
|
if (!!selectMarker) {
|
|
|
selectMarker.setMap(null);
|
|
|
selectMarker = null;
|
|
@@ -111,6 +233,11 @@ const selectEvent = (item, unFitView) => {
|
|
|
map.setFitView([selectMarker]);
|
|
|
}
|
|
|
};
|
|
|
+const handleRoutes = (item) => {
|
|
|
+ const start = [item.longitude, item.latitude];
|
|
|
+ const end = [selectData.value.longitude, selectData.value.latitude];
|
|
|
+ calculateRoutes(start, end, 0);
|
|
|
+};
|
|
|
// 计算并展示三条路线
|
|
|
const calculateRoutes = (start, end, index) => {
|
|
|
if (index >= 3) {
|
|
@@ -202,6 +329,186 @@ const parseRouteToPath = (route) => {
|
|
|
|
|
|
return path;
|
|
|
};
|
|
|
+const handlePointDetails = (data) => {
|
|
|
+ let methodList = {
|
|
|
+ '1': getEmergencyExpertDetails,
|
|
|
+ '2': getWarehouseDetails,
|
|
|
+ '3': getEmergencyShelterTypeDetails,
|
|
|
+ '4': getWaterloggedRoadsDetails,
|
|
|
+ '5': getSchoolDetails,
|
|
|
+ '6': getHospitalDetails,
|
|
|
+ '7': getGasolinestationDetails,
|
|
|
+ '8': getMiningcompanyDetails,
|
|
|
+ // '9': getChemicalcompanyDetails,
|
|
|
+ '10': getShipRealtilmePositionDetails,
|
|
|
+ '11': getChemicalcompanyDetails,
|
|
|
+ '12': getChemicalcompanyDetails,
|
|
|
+ '13': getChemicalcompanyDetails,
|
|
|
+ '14': getChemicalcompanyDetails,
|
|
|
+ '15': getUAVDetails,
|
|
|
+ '16': getRainbowDetails,
|
|
|
+ '17': getMidmapDzzhDetails,
|
|
|
+ '18': getMiningOperationsDetails,
|
|
|
+ '21': getBuildingProjectDetails,
|
|
|
+ '22': getChemicalWarehouseDetails,
|
|
|
+ '23': getMajorHazardSourceDetails,
|
|
|
+ '24': getStationInfoDetails,
|
|
|
+ '25': getYardSitesDetails,
|
|
|
+ '26': getTouristAttractionDetails,
|
|
|
+ '27': getConstructionSitesDetails,
|
|
|
+ '28': getEmergencyTransportResourcesDetails,
|
|
|
+ '29': getEmergencyDisasterInfoOfficerDetails
|
|
|
+ };
|
|
|
+ let titleList = {
|
|
|
+ '1': '专家信息',
|
|
|
+ '2': '物资与装备仓库信息',
|
|
|
+ '3': '避难所信息',
|
|
|
+ '4': '易涝点信息',
|
|
|
+ '5': '学校信息',
|
|
|
+ '6': '医院信息',
|
|
|
+ '7': '加油站信息',
|
|
|
+ '8': '非煤矿山企业信息',
|
|
|
+ '9': '危化企业信息',
|
|
|
+ '10': '船舶动态信息',
|
|
|
+ '11': '危险化学品经营企业信息',
|
|
|
+ '12': '危险化学品生产企业信息',
|
|
|
+ '13': '危险化学品使用企业(使用许可)信息',
|
|
|
+ '14': '化工企业(不发使用许可)信息',
|
|
|
+ '15': '无人机信息',
|
|
|
+ '16': '雨窝点',
|
|
|
+ '17': '地质灾害隐患点',
|
|
|
+ '18': '矿山施工',
|
|
|
+ '19': '工矿商贸',
|
|
|
+ '20': '气象灾害防御重点单位',
|
|
|
+ '21': '建筑工程',
|
|
|
+ '22': '储罐信息',
|
|
|
+ '23': '重大危险源',
|
|
|
+ '24': '客运站',
|
|
|
+ '25': '堆场',
|
|
|
+ '26': '旅游场所',
|
|
|
+ '27': '在建工地',
|
|
|
+ '28': '运输资源',
|
|
|
+ '29': '灾害信息员'
|
|
|
+ };
|
|
|
+ let method = methodList[data.dataType];
|
|
|
+ let title = !!titleList[data.dataType] ? titleList[data.dataType] : '信息';
|
|
|
+ if (!method) return;
|
|
|
+ method(data.id).then((res) => {
|
|
|
+ if (!!pointDetailTemplate[data.dataType]) {
|
|
|
+ let div = document.createElement('div');
|
|
|
+ // div.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
|
|
|
+ div.className = 'point-info';
|
|
|
+ let titleDom = document.createElement('div');
|
|
|
+ titleDom.className = 'title-box';
|
|
|
+ titleDom.innerHTML = '<div class="gradient-text">' + title + '</div></div>';
|
|
|
+ div.appendChild(titleDom);
|
|
|
+ if (data.dataType === 2) {
|
|
|
+ let btnBox = document.createElement('div');
|
|
|
+ let btn = document.createElement('div');
|
|
|
+ btnBox.className = 'flex';
|
|
|
+ btn.className = 'btn';
|
|
|
+ btn.innerHTML = '<div class="video-icon"></div><div>物资详情</div>';
|
|
|
+ btn.onclick = () => {
|
|
|
+ emits('handleShowWarehouse', data);
|
|
|
+ };
|
|
|
+ btnBox.appendChild(btn);
|
|
|
+ div.appendChild(btnBox);
|
|
|
+ } else if (data.dataType === 4) {
|
|
|
+ let btnBox = document.createElement('div');
|
|
|
+ let btn = document.createElement('div');
|
|
|
+ btnBox.className = 'flex';
|
|
|
+ btn.className = 'btn';
|
|
|
+ btn.innerHTML = '<div class="video-icon"></div><div>附近视频</div>';
|
|
|
+ btn.onclick = () => {
|
|
|
+ emits('handleShowVideo', data);
|
|
|
+ };
|
|
|
+ btnBox.appendChild(btn);
|
|
|
+ div.appendChild(btnBox);
|
|
|
+ }
|
|
|
+ let icon1 = document.createElement('div');
|
|
|
+ icon1.className = 'icon1';
|
|
|
+ let icon2 = document.createElement('div');
|
|
|
+ icon2.className = 'icon2';
|
|
|
+ let icon3 = document.createElement('div');
|
|
|
+ icon3.className = 'icon3';
|
|
|
+ let icon4 = document.createElement('div');
|
|
|
+ icon4.className = 'icon4';
|
|
|
+ div.appendChild(icon1);
|
|
|
+ div.appendChild(icon2);
|
|
|
+ div.appendChild(icon3);
|
|
|
+ div.appendChild(icon4);
|
|
|
+ let table = document.createElement('div');
|
|
|
+ table.className = 'table-box';
|
|
|
+ let content = '';
|
|
|
+ content += '<div class="table">';
|
|
|
+ const newData = filterTd(res.rows[0], data.dataType);
|
|
|
+ newData.forEach((item) => {
|
|
|
+ if (item.type === 'shortText') {
|
|
|
+ content += '<div class="tr">';
|
|
|
+ item.data.forEach((item2) => {
|
|
|
+ content += '<div class="point-item">';
|
|
|
+ content += '<div class="td1">' + item2.label + '</div><div class="td2">' + item2.value + '</div>';
|
|
|
+ content += '</div>';
|
|
|
+ });
|
|
|
+ content += '</div>';
|
|
|
+ } else {
|
|
|
+ content += '<div class="point-item2">';
|
|
|
+ content += '<div class="td1">' + item.data[0].label + '</div><div class="td2">' + item.data[0].value + '</div>';
|
|
|
+ content += '</div>';
|
|
|
+ }
|
|
|
+ });
|
|
|
+ content += '</div>';
|
|
|
+ table.innerHTML = content;
|
|
|
+ div.appendChild(table);
|
|
|
+ let closeBtn = document.createElement('div');
|
|
|
+ closeBtn.className = 'close';
|
|
|
+ closeBtn.onclick = hideInfo;
|
|
|
+ div.appendChild(closeBtn);
|
|
|
+ showInfo(div, [data.longitude, data.latitude], true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+const filterTd = (obj, dataType) => {
|
|
|
+ let data = [];
|
|
|
+ let tempData = {};
|
|
|
+ let i = 0;
|
|
|
+ for (let key in obj) {
|
|
|
+ let keyLabel = pointDetailTemplate[dataType][key];
|
|
|
+ if (!!keyLabel) {
|
|
|
+ if (i === 2) {
|
|
|
+ i = 0;
|
|
|
+ }
|
|
|
+ const value = !!obj[key] ? obj[key] : '';
|
|
|
+ if (value && value.length > 8) {
|
|
|
+ if (i === 0) {
|
|
|
+ data.push({ type: 'longText', data: [{ label: keyLabel, value: value }] });
|
|
|
+ i = 0;
|
|
|
+ } else {
|
|
|
+ tempData = { type: 'longText', data: [{ label: keyLabel, value: value }] };
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (i === 0) {
|
|
|
+ data.push({ type: 'shortText', data: [{ label: keyLabel, value: value }] });
|
|
|
+ } else {
|
|
|
+ data[data.length - 1].data.push({ label: keyLabel, value: value });
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ if (!!tempData && JSON.stringify(tempData) !== '{}') {
|
|
|
+ data.push(tempData);
|
|
|
+ tempData = {};
|
|
|
+ i = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!!tempData && JSON.stringify(tempData) !== '{}') {
|
|
|
+ data.push(tempData);
|
|
|
+ }
|
|
|
+ if (data[data.length - 1].data && data[data.length - 1].data.length === 1 && data[data.length - 1].type === 'shortText') {
|
|
|
+ data[data.length - 1].data[1] = { label: '', value: '' };
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+};
|
|
|
const handleClick = (item) => {
|
|
|
item.checked = !item.checked;
|
|
|
let path = [];
|
|
@@ -237,6 +544,21 @@ const handleClick = (item) => {
|
|
|
addMarker(data);
|
|
|
});
|
|
|
};
|
|
|
+// 搜索列表
|
|
|
+const getList = () => {
|
|
|
+ const params = {
|
|
|
+ dataType: queryParams.dataType,
|
|
|
+ keyword: queryParams.keyword,
|
|
|
+ distance: ''
|
|
|
+ };
|
|
|
+ if (checked1.value) {
|
|
|
+ params.distance = distance.value;
|
|
|
+ }
|
|
|
+ getEmergencyRescuePointInfoList(params).then((res) => {
|
|
|
+ dataList.value = res.rows;
|
|
|
+ total.value = res.total;
|
|
|
+ });
|
|
|
+};
|
|
|
const initData = () => {
|
|
|
getEventActiveList().then((res) => {
|
|
|
eventList.value = res.data;
|
|
@@ -253,6 +575,7 @@ onUnmounted(() => {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+@import '@/components/Map/map.scss';
|
|
|
.map-container {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
@@ -382,7 +705,7 @@ onUnmounted(() => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-.amap-icon img{
|
|
|
+.amap-icon img {
|
|
|
width: 25px;
|
|
|
height: 34px;
|
|
|
}
|