199 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			5.9 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()
 | 
						||
    }
 | 
						||
  },
 | 
						||
  props: {
 | 
						||
    /**
 | 
						||
     * 地图类型
 | 
						||
     * @param { 'big' | 'small' } type
 | 
						||
     */
 | 
						||
    type: {
 | 
						||
      type: String,
 | 
						||
      default: 'big'
 | 
						||
    }
 | 
						||
  },
 | 
						||
  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) {
 | 
						||
      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-container {
 | 
						||
    width: 100%;
 | 
						||
    height: 100%;
 | 
						||
    position: absolute;
 | 
						||
    transform: translateX(-50%);
 | 
						||
    left: 50%;
 | 
						||
    top: 0;
 | 
						||
    z-index: 1;
 | 
						||
  }
 | 
						||
</style>
 |