lg_frontend/components/Map.vue

242 lines
6.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="map-wrapper">
<div class="bg event-none"></div>
<div class="map-container" ref="mapRef" id="mars3dContainer"></div>
</div>
</template>
<script>
import { ms3dConfig } from '@/config/mapConfig'
import { mapState, mapActions } from 'vuex'
const mapLayerTypeToPointIcon = {
cems: require('@/assets/images/map/points/点位-CEMS.png'),
sdjcy: require('@/assets/images/map/points/点位-深度检测仪.png'),
zkz: require('@/assets/images/map/points/点位-质控站.png'),
gbz: require('@/assets/images/map/points/点位-国标站.png'),
ssc: require('@/assets/images/map/points/点位-洒水车.png'),
shisc: require('@/assets/images/map/points/点位-湿扫车.png'),
wz: require('@/assets/images/map/points/点位-微站.png'),
jkd: require('@/assets/images/map/points/点位-监控点.png'),
}
export default {
name: "Map",
data () {
return {
layerMap: new Map()
}
},
props: {
/**
* 地图类型
* @param { 'big' | 'small' } type
*/
type: {
type: String,
default: 'big'
}
},
watch: {
info: {
immediate: true,
deep: true,
handler (info) {
if (info) {
this.$nextTick(() => {
if (this.$refs.mapRef) {
this.initMap(info.home.center)
}
})
}
}
}
},
mounted() {
this.$evBus.$on('setVisibility', (layerType, show) => {
this.setVisibility(layerType, show)
})
},
computed: {
...mapState({
cems: state => state.map.cems,
sdjcy: state => state.map.sdjcy,
zkz: state => state.map.zkz,
gbz: state => state.map.gbz,
ssc: state => state.map.ssc,
shisc: state => state.map.shisc,
wz: state => state.map.wz,
jkd: state => state.map.jkd,
info: state => state.system.info
})
},
methods: {
...mapActions('system', ['setTitle', 'setInfo']),
//创建三维地球场景
initMap (center) {
const { lon, lat } = center
ms3dConfig.scene.center.lng = lon
ms3dConfig.scene.center.lat = lat
this.map = new mars3d.Map(this.$refs.mapRef, ms3dConfig)
this.map.on("load", () => {
Object.keys(mapLayerTypeToPointIcon).forEach(layerType => {
this.layerCreator(layerType)
})
/*this.map.on(mars3d.EventType.click, function (event) {
var point = mars3d.LngLatPoint.fromCartesian(event.cartesian); //转为经纬度
const [ longitude, latitude ] = point.toString().split(',')
console.log("鼠标单击坐标", JSON.stringify({
longitude: longitude,
latitude: latitude
}));
})*/
this.addPoints()
})
},
addPoints () {
this.addDataByLayerType('cems', this.cems)
this.addDataByLayerType('sdjcy', this.sdjcy)
this.addDataByLayerType('zkz', this.zkz)
this.addDataByLayerType('gbz', this.gbz)
this.addDataByLayerType('ssc', this.ssc)
this.addDataByLayerType('shisc', this.shisc)
this.addDataByLayerType('wz', this.wz)
this.addDataByLayerType('jkd', this.jkd)
},
/**
* 图层构造器
* @param { 'cems' | 'sdjcy' | 'zkz' | 'gbz' | 'ssc' | 'shisc' | 'wz' | 'jkd' } layerType 图层名称
*/
layerCreator (layerType) {
if (!this.layerMap.has(layerType)) {
const graphicLayer = new mars3d.layer.GraphicLayer({
/*clustering: {
enabled: true,
pixelRange: 20,
minimumClusterSize: 2,
clampToGround: true,
style: {
}
},*/
allowDrillPick: true, // 如果存在坐标完全相同的图标点可以打开该属性click事件通过graphics判断
flyTo: false
})
this.map.addLayer(graphicLayer)
graphicLayer.on(mars3d.EventType.click, ({ graphic }) => {
const position = graphic.positionShow
/*this.map.flyToPoint(position, {
radius: 5000, // 距离目标点的距离
duration: 4,
complete: function (e) {
// 飞行完成回调方法
// graphic.openPopup()
}
})*/
this.$emit('pointClick', { layerType, data: graphic.attr })
})
this.layerMap.set(layerType, graphicLayer)
}
},
/**
* 根据图层类型添加点位数据
* @param { 'cems' | 'sdjcy' | 'zkz' | 'gbz' | 'ssc' | 'shisc' | 'wz' | 'jkd' } layerType 图层名称
* @param { Array<{ longitude: string | number, latitude: string | number, name: string }> }data
*/
addDataByLayerType (layerType, data) {
const scale = this.type === 'middle' ? 4: 2
if (this.layerMap.has(layerType)) {
const graphicLayer = this.layerMap.get(layerType)
for (const datum of data) {
const graphic = new mars3d.graphic.BillboardEntity({
position: new mars3d.LngLatPoint( parseFloat(datum.longitude), parseFloat(datum.latitude), 1000),
id: datum.primaryKey,
style: {
image: mapLayerTypeToPointIcon[layerType],
scale: 1.0,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
clampToGround: true,
width: 290 / scale,
height: 426 / scale
},
attr: datum
})
if (datum.name) {
graphic.bindTooltip(datum.name, {
offsetY: -195,
className: 'point-tooltip'
})
}
graphicLayer.addGraphic(graphic) // 还可以另外一种写法: graphic.addTo(graphicLayer)
}
} else {
this.layerCreator(layerType)
this.addDataByLayerType(layerType, data)
}
},
/**
* 显示或隐藏图层
* @param { 'cems' | 'sdjcy' | 'zkz' | 'gbz' | 'ssc' | 'shisc' | 'wz' | 'jkd' } layerType 图层名称
* @param { boolean } show 显示/隐藏
*/
setVisibility (layerType, show) {
if (this.layerMap.has(layerType)) {
const layer = this.layerMap.get(layerType)
layer.show = show
}
}
}
}
</script>
<style lang="less">
.point-tooltip {
font-size: 35px;
text-align: center;
}
</style>
<style scoped lang="less">
.map-wrapper {
width: 100%;
height: 100%;
position: absolute;
transform: translateX(-50%);
left: 50%;
top: 0;
z-index: 1;
.bg {
background: radial-gradient(transparent, rgba(3, 5, 51, 0.19), rgba(3, 5, 51, 0.68), #020433);
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 2;
}
.map-container {
width: 100%;
height: 100%;
position: absolute;
transform: translateX(-50%);
left: 50%;
top: 0;
z-index: 1;
}
}
</style>