|
|
@@ -0,0 +1,325 @@ |
|
|
|
<template> |
|
|
|
<div class="map-container" :="getMapOptions" /> |
|
|
|
<div class="layer-management"> |
|
|
|
<div class="list-manage"> |
|
|
|
<p>列表</p> |
|
|
|
<n-switch v-model:value="listShow" /> |
|
|
|
</div> |
|
|
|
<div class="air-manage"> |
|
|
|
<p>机场</p> |
|
|
|
<n-switch v-model:value="airShow" @update:value="airShowHide" /> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div id="airOverlay" class="airport-overlay"> |
|
|
|
<span id="closeAir" class="close-overlay" @click="hideAirInfo">x</span> |
|
|
|
<air-info :data="airDetail" /> |
|
|
|
</div> |
|
|
|
<div class="task-question"> |
|
|
|
<n-card style="margin-bottom: 16px"> |
|
|
|
<n-tabs type="line" animated> |
|
|
|
<!-- <n-tab-pane name="task" tab="任务"> |
|
|
|
任务 |
|
|
|
</n-tab-pane> --> |
|
|
|
<n-tab-pane name="question" tab="问题"> |
|
|
|
<n-date-picker |
|
|
|
:on-update:formatted-value="abc" |
|
|
|
:default-formatted-value="efg" |
|
|
|
type="daterange" |
|
|
|
:default-value="[Date.now() - 6.048e8, Date.now()]" |
|
|
|
:is-date-disabled="disablePreviousDate" |
|
|
|
/> |
|
|
|
<!-- <n-checkbox-group :value="cities" @update:value="handleUpdateValue"> |
|
|
|
<n-space style="display: block;"> |
|
|
|
<n-checkbox value="Beijing" label="北京" /> |
|
|
|
<n-checkbox value="Shanghai" label="上海" /> |
|
|
|
<n-checkbox value="Guangzhou" label="广州" /> |
|
|
|
<n-checkbox value="Shenzen" label="深圳" /> |
|
|
|
</n-space> |
|
|
|
</n-checkbox-group> --> |
|
|
|
</n-tab-pane> |
|
|
|
</n-tabs> |
|
|
|
</n-card> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { Map, View, Feature, Overlay } from 'ol' |
|
|
|
import { XYZ, Vector as VectorSource } from 'ol/source' |
|
|
|
import { Tile, Vector as VectorLayer } from 'ol/layer' |
|
|
|
import { transform, fromLonLat } from 'ol/proj' |
|
|
|
import { Style, Icon, Text, Fill } from 'ol/style' |
|
|
|
import * as control from 'ol/control' |
|
|
|
import uav_icon from '@/assets/images/UAV.png' |
|
|
|
import { reactive, toRefs, onMounted, computed } from 'vue' |
|
|
|
import { Point } from 'ol/geom' |
|
|
|
import { airportList } from '@/api/dashboard/index.js' |
|
|
|
import { getQuestions } from '@/api/task/index.js' |
|
|
|
import { gcj02towgs84 } from '@/utils/coordinate-util.js' |
|
|
|
import AirInfo from './AirInfo.vue' |
|
|
|
export default { |
|
|
|
name: 'OneMap', |
|
|
|
components: { AirInfo }, |
|
|
|
props: { |
|
|
|
id: { |
|
|
|
type: String, |
|
|
|
default: 'map' |
|
|
|
} |
|
|
|
}, |
|
|
|
setup(props) { |
|
|
|
const data = reactive({ |
|
|
|
map: null, |
|
|
|
// 机场数组 |
|
|
|
airportsAll: [], |
|
|
|
// 机场显隐 |
|
|
|
airShow: true, |
|
|
|
// 机场要素集 |
|
|
|
airFeatures: [], |
|
|
|
// 机场图层 |
|
|
|
airLayer: null, |
|
|
|
// 机场信息容器 |
|
|
|
airOverlay: null, |
|
|
|
// 机场细节信息 |
|
|
|
airDetail: {}, |
|
|
|
listShow: false, |
|
|
|
// 时间范围是一周前至今天 |
|
|
|
efg: '' |
|
|
|
}) |
|
|
|
|
|
|
|
const getMapOptions = computed(() => { |
|
|
|
return { |
|
|
|
id: props.id |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
const initMap = () => { |
|
|
|
// 天地图影像图 |
|
|
|
const tdtImgMap = |
|
|
|
new Tile({ |
|
|
|
visible: true, |
|
|
|
source: new XYZ({ |
|
|
|
url: 'https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f634525a82da65f715d168d7ba1899c0' |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
data.map = new Map({ |
|
|
|
// 地图容器 |
|
|
|
target: props.id, |
|
|
|
view: new View({ |
|
|
|
center: transform([118.773136, 31.828065], 'EPSG:4326', 'EPSG:3857'), |
|
|
|
zoom: 11, |
|
|
|
maxZoom: 17 |
|
|
|
}), |
|
|
|
layers: [ |
|
|
|
tdtImgMap |
|
|
|
], |
|
|
|
controls: control.defaults({ |
|
|
|
attribution: false, |
|
|
|
rotate: false, |
|
|
|
zoom: false |
|
|
|
}) |
|
|
|
|
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @description: 获取机场数据 |
|
|
|
* @param {*} res |
|
|
|
* @return {*} |
|
|
|
*/ |
|
|
|
const loadAirport = (async function() { |
|
|
|
const res = await airportList({ page: 1, limit: 100 }) |
|
|
|
if (res.code === 0) { |
|
|
|
data.airportsAll = res.data |
|
|
|
showAirport() |
|
|
|
} |
|
|
|
})() |
|
|
|
|
|
|
|
/** |
|
|
|
* 展示机场 |
|
|
|
*/ |
|
|
|
const showAirport = () => { |
|
|
|
if (data.airportsAll.length > 0) { |
|
|
|
for (let i = 0; i < data.airportsAll.length; i++) { |
|
|
|
const airport = data.airportsAll[i] |
|
|
|
const lngLat = gcj02towgs84(parseFloat(airport.longitude), parseFloat(airport.latitude)) |
|
|
|
const feature = new Feature({ |
|
|
|
geometry: new Point(fromLonLat(lngLat)) |
|
|
|
}) |
|
|
|
// 要素设置样式 |
|
|
|
feature.setStyle( |
|
|
|
new Style({ |
|
|
|
image: new Icon({ |
|
|
|
src: uav_icon |
|
|
|
}), |
|
|
|
text: new Text({ |
|
|
|
// 文字内容 |
|
|
|
text: airport.name, |
|
|
|
// 位置 |
|
|
|
textAlign: 'center', |
|
|
|
// 基准线 |
|
|
|
textBaseline: 'top', |
|
|
|
offsetY: 30, |
|
|
|
// 文字样式 |
|
|
|
font: 'normal 20px Microsoft YaHei', |
|
|
|
// 文字颜色 |
|
|
|
fill: new Fill({ |
|
|
|
color: '#fff' |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
) |
|
|
|
// 要素设置id |
|
|
|
feature.setId(airport.id) |
|
|
|
// 要素设置属性 |
|
|
|
feature.setProperties({ |
|
|
|
id: airport.id, |
|
|
|
code: airport.code, |
|
|
|
name: airport.name, |
|
|
|
// 设置类别 |
|
|
|
type: 'airport', |
|
|
|
coordinate: fromLonLat(lngLat) |
|
|
|
}) |
|
|
|
|
|
|
|
data.airFeatures.push(feature) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
data.airLayer = new VectorLayer({ |
|
|
|
source: new VectorSource({ |
|
|
|
features: data.airFeatures |
|
|
|
}), |
|
|
|
visible: data.airShow |
|
|
|
}) |
|
|
|
data.map.addLayer(data.airLayer) |
|
|
|
|
|
|
|
// 机场信息覆盖物 |
|
|
|
data.airOverlay = new Overlay({ |
|
|
|
id: 'air_overlay', |
|
|
|
element: document.getElementById('airOverlay'), |
|
|
|
autoPan: true, |
|
|
|
offset: [10, 10] |
|
|
|
}) |
|
|
|
|
|
|
|
// 点击事件 |
|
|
|
data.map.on('click', (evt) => { |
|
|
|
showAirInfo(evt) |
|
|
|
}) |
|
|
|
|
|
|
|
console.log(new Date().getFullYear()) |
|
|
|
} |
|
|
|
/** |
|
|
|
* 展示机场信息 |
|
|
|
* @param {} e |
|
|
|
*/ |
|
|
|
const showAirInfo = (e) => { |
|
|
|
// 防止冒泡 |
|
|
|
e.stopPropagation() |
|
|
|
// 点击位置的经纬度 |
|
|
|
var feature = data.map.forEachFeatureAtPixel(e.pixel, (feature) => { |
|
|
|
return feature |
|
|
|
}) |
|
|
|
if (feature) { |
|
|
|
// 要素类别为机场 |
|
|
|
if (feature.getProperties().type === 'airport') { |
|
|
|
data.airDetail = feature.getProperties() |
|
|
|
|
|
|
|
// 为了overlay位置更加精确 |
|
|
|
const coord = feature.getProperties().coordinate |
|
|
|
data.airOverlay.setPosition(coord) |
|
|
|
data.map.addOverlay(data.airOverlay) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 关闭展示机场信息 |
|
|
|
*/ |
|
|
|
const hideAirInfo = () => { |
|
|
|
if (data.map.getOverlayById('air_overlay')) { |
|
|
|
data.airDetail = {} |
|
|
|
data.map.removeOverlay(data.airOverlay) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 机场图层控制显隐 |
|
|
|
* @param { } value |
|
|
|
*/ |
|
|
|
const airShowHide = (isShow) => { |
|
|
|
data.airLayer.setVisible(isShow) |
|
|
|
if (!isShow) { |
|
|
|
hideAirInfo() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const abc = (value) => { |
|
|
|
console.log(value) |
|
|
|
} |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
initMap() |
|
|
|
}) |
|
|
|
|
|
|
|
return { |
|
|
|
...toRefs(data), |
|
|
|
getMapOptions, |
|
|
|
loadAirport, |
|
|
|
airShowHide, |
|
|
|
hideAirInfo, |
|
|
|
disablePreviousDate(ts) { |
|
|
|
return ts > Date.now() |
|
|
|
}, |
|
|
|
abc |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
|
.map-container{ |
|
|
|
width: 100vw; |
|
|
|
height: 100vh; |
|
|
|
} |
|
|
|
|
|
|
|
.layer-management { |
|
|
|
height: calc(100vh - 84%); |
|
|
|
position: absolute; |
|
|
|
width: 100px; |
|
|
|
/* margin-right: 10px; */ |
|
|
|
left: 100px; |
|
|
|
top: 100px; |
|
|
|
background-color: rgba(0,0,0, 0.6); |
|
|
|
} |
|
|
|
|
|
|
|
.layer-management p{ |
|
|
|
color: #fff; |
|
|
|
} |
|
|
|
|
|
|
|
.airport-overlay { |
|
|
|
width: 400px; |
|
|
|
height: 200px; |
|
|
|
background-color: rgba(0, 0, 0, 0.5); |
|
|
|
} |
|
|
|
|
|
|
|
.close-overlay{ |
|
|
|
width: 28px; |
|
|
|
height: 28px; |
|
|
|
position: relative; |
|
|
|
color: #fff; |
|
|
|
font-size: 20px; |
|
|
|
cursor: pointer; |
|
|
|
float: right; |
|
|
|
text-align: center; |
|
|
|
line-height: 28px; |
|
|
|
} |
|
|
|
|
|
|
|
/* 任务-问题面板 */ |
|
|
|
.task-question { |
|
|
|
width: 500px; |
|
|
|
height: 800px; |
|
|
|
position: absolute; |
|
|
|
top: 100px; |
|
|
|
right: 10px; |
|
|
|
} |
|
|
|
|
|
|
|
</style> |