188 lines
5.7 KiB
Vue
188 lines
5.7 KiB
Vue
<template>
|
||
<div class="map-container" ref="mapRef" id="mars3dContainer"></div>
|
||
</template>
|
||
|
||
<script>
|
||
import { ms3dConfig } from '@/config/mapConfig'
|
||
import { mapState } 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()
|
||
}
|
||
},
|
||
mounted() {
|
||
this.$nextTick(() => {
|
||
if (this.$refs.mapRef) {
|
||
this.initMap()
|
||
}
|
||
})
|
||
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,
|
||
})
|
||
},
|
||
methods: {
|
||
//创建三维地球场景
|
||
initMap () {
|
||
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) {
|
||
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 / 2,
|
||
height: 426 / 2
|
||
},
|
||
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-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
transform: translateX(-50%);
|
||
left: 50%;
|
||
top: 0;
|
||
z-index: 1;
|
||
}
|
||
</style>
|