百度地图(坐标转换,自定义信息窗口)使用

1,433 阅读1分钟

百度地图引入(第一个script是引入百度地图,后2个是用到了自定义信息窗口才需要,第3个infobox.js官方文档上有)

    <script src="http://api.map.baidu.com/api?v=3.0&ak=放自己的AK" type="text/javascript"></script>
    <!--百度地图自定义信息窗口-->
    <script src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=放自己的AK" type="text/javascript"></script>
    <script src="static/InfoBox.js" type="text/javascript"></script>

Dom部分很简单,有个容器就行了,如下

  <div class="map-box" ref="mapContainer">
  </div>

Data定义部分(主要是map实例,其他的非必需)

  data () {
    return {
      map: null, // 地图实例
      projectIconList: [
        {id: 0, src: require('../../images/project-icon-blue.png')},
        {id: 1, src: require('../../images/project-icon-green.jpg')},
        {id: 2, src: require('../../images/project-icon-grey.jpg')},
        {id: 3, src: require('../../images/project-icon-orange.jpg')},
      ],
      projectIcon: null, // 项目icon
      airportIcon: require('../../images/airport-icon.png'), // 机场icon
      myProjectIcon: null, // 项目标注icon
      myAirportIcon: null, // 机场标注icon
      lastInfoBox: null, // 信息窗口
      markerList: [], // 所有覆盖物数组(便于清空)
      zoomNum: null, // 地图缩放级别
    };
  },

地图初始化的方法(此处增加了一些地图控件,不用可以去掉)

    /*
    * 地图初始化
    * */
    mapInit () {
      this.map = new BMap.Map(this.$refs.mapContainer); // 创建地图实例
      this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 8); // 初始化地图,用经纬度设置地图中心点,同时设置地图展示级别
      this.map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
      this.map.addControl(new BMap.NavigationControl({ anchor: BMAP_ANCHOR_TOP_RIGHT })); // 添加平移缩放控件
      this.map.addControl(new BMap.ScaleControl({ offset: new BMap.Size(10, 5) })); // 添加比例尺控件
      // this.map.addControl(new BMap.OverviewMapControl()); // 添加缩略图控件
      this.map.addControl(new BMap.MapTypeControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, offset: new BMap.Size(30, 20) })); // 添加地图类型控件(地图,卫星,混合)
      this.map.setCurrentCity('北京'); // 仅当设置城市信息时,MapTypeControl的切换功能才能可用

百度坐标转换方法(这里是wgs-84坐标转百度)

    /**
     * 百度坐标转换方法
     * @param x 需转换的坐标经度
     * @param y 需转换的坐标维度
     * @param translateCallback 转换方法的回调函数
     * 坐标常量说明:
     * COORDINATES_WGS84 = 1, WGS84坐标
     * COORDINATES_WGS84_MC = 2, WGS84的平面墨卡托坐标
     * COORDINATES_GCJ02 = 3,GCJ02坐标
     * COORDINATES_GCJ02_MC = 4, GCJ02的平面墨卡托坐标
     * COORDINATES_BD09 = 5, 百度bd09经纬度坐标
     * COORDINATES_BD09_MC = 6,百度bd09墨卡托坐标
     * COORDINATES_MAPBAR = 7,mapbar地图坐标
     * COORDINATES_51 = 8,51地图坐标
     */
    transformCoordinate (x, y, translateCallback) {
      let originalPoint = new BMapGL.Point(x, y);
      let convertor = new BMapGL.Convertor();
      let pointArr = [];
      pointArr.push(originalPoint);
      convertor.translate(pointArr, COORDINATES_WGS84, COORDINATES_BD09, translateCallback);
    },

算了,直接贴原码吧,不然也还是看不懂

<!--
* @Author : XuXing
* @Date :  2021/04/16
* @Version : 1.0
* @Content : 项目列表页地图
-->
<template>
  <div class="map-box" ref="mapContainer">
  </div>
</template>

<script>
import airportLocation from '../../../static/airportLocation';

export default {
  name: 'projectList',
  components: {},
  props: ['dataList', 'clickedProject'],
  data () {
    return {
      map: null, // 地图实例
      projectIconList: [
        {id: 0, src: require('../../images/project-icon-blue.png')},
        {id: 1, src: require('../../images/project-icon-green.jpg')},
        {id: 2, src: require('../../images/project-icon-grey.jpg')},
        {id: 3, src: require('../../images/project-icon-orange.jpg')},
      ],
      projectIcon: null, // 项目icon
      airportIcon: require('../../images/airport-icon.png'), // 机场icon
      myProjectIcon: null, // 项目标注icon
      myAirportIcon: null, // 机场标注icon
      lastInfoBox: null, // 信息窗口
      markerList: [], // 所有覆盖物数组(便于清空)
      zoomNum: null, // 地图缩放级别
    };
  },
  created () {
    window.goDetail = this.goDetail;// 解决字符串模板@click无效的问题
    // this.$set(this.dataList);
  },
  mounted () {
    this.mapInit();
  },
  computed: {
    formatStatus () {
      return (value) => {
        return value === 0 ? '待开始' : value === 1 ? '进行中' : value === 2 ? '已完成' : '已延期';
      };
    }
  },
  watch: {
    dataList: {
      handler (newValue, oldValue) {
        // console.log('mapnewValue:', newValue);
        if (this.dataList.length > 0 && this.zoomNum >= 9) {
          this.createProjectMarker();
        }
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    /*
    * 地图初始化
    * */
    mapInit () {
      this.map = new BMap.Map(this.$refs.mapContainer); // 创建地图实例
      this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 8); // 初始化地图,用经纬度设置地图中心点,同时设置地图展示级别
      this.map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
      this.map.addControl(new BMap.NavigationControl({ anchor: BMAP_ANCHOR_TOP_RIGHT })); // 添加平移缩放控件
      this.map.addControl(new BMap.ScaleControl({ offset: new BMap.Size(10, 5) })); // 添加比例尺控件
      // this.map.addControl(new BMap.OverviewMapControl()); // 添加缩略图控件
      this.map.addControl(new BMap.MapTypeControl({ anchor: BMAP_ANCHOR_BOTTOM_RIGHT, offset: new BMap.Size(30, 20) })); // 添加地图类型控件(地图,卫星,混合)
      this.map.setCurrentCity('北京'); // 仅当设置城市信息时,MapTypeControl的切换功能才能可用
      this.myAirportIcon = new BMap.Icon(this.airportIcon, new BMap.Size(34, 40)); // 机场标注icon
      this.createProjectMarker();
      // 监听地图缩放级别
      this.map.addEventListener('zoomend', e => {
        this.zoomNum = this.map.getZoom();
        // console.log('ZoomNum:', this.zoomNum);
        if (this.zoomNum < 5) { // 缩放级别小于5时,不展示
          this.remove(this.markerList);
          this.markerList = [];
        } else {
          this.createProjectMarker();
        }
      });
    },
    /**
     * 百度坐标转换方法
     * @param x 需转换的坐标经度
     * @param y 需转换的坐标维度
     * @param translateCallback 转换方法的回调函数
     * 坐标常量说明:
     * COORDINATES_WGS84 = 1, WGS84坐标
     * COORDINATES_WGS84_MC = 2, WGS84的平面墨卡托坐标
     * COORDINATES_GCJ02 = 3,GCJ02坐标
     * COORDINATES_GCJ02_MC = 4, GCJ02的平面墨卡托坐标
     * COORDINATES_BD09 = 5, 百度bd09经纬度坐标
     * COORDINATES_BD09_MC = 6,百度bd09墨卡托坐标
     * COORDINATES_MAPBAR = 7,mapbar地图坐标
     * COORDINATES_51 = 8,51地图坐标
     */
    transformCoordinate (x, y, translateCallback) {
      let originalPoint = new BMapGL.Point(x, y);
      let convertor = new BMapGL.Convertor();
      let pointArr = [];
      pointArr.push(originalPoint);
      convertor.translate(pointArr, COORDINATES_WGS84, COORDINATES_BD09, translateCallback);
    },
    /**
     * 标识项目
     */
    createProjectMarker () {
      this.remove(this.markerList);
      this.markerList = [];
      this.dataList.forEach(item => {
        let translateCallback = (data) => {
          if (data.status === 0) {
            this.createMarker(data.points[0], item);
          }
        };
        // 数据原因,这里centerLatitude=>经度,centerLongitude=>纬度
        this.transformCoordinate(item.defaultPosition.centerLatitude, item.defaultPosition.centerLongitude, translateCallback);
      });
    },
    /**
     * 项目打点及创建覆盖物
     * @param point 百度bd09经纬度坐标
     * @param projectInfo 项目信息
     */
    createMarker (point, projectInfo) {
      // console.log(projectInfo);
      let pt = new BMap.Point(point.lng, point.lat);
      this.projectIcon = this.projectIconList.find(icon => icon.id === projectInfo.status).src;
      this.myProjectIcon = new BMap.Icon(this.projectIcon, new BMap.Size(34, 40)); // 项目标注icon
      let marker = new BMap.Marker(pt, { icon: this.myProjectIcon });
      this.markerList.push(marker);
      this.map.addOverlay(marker);
      let opts = {
        position: point, // 指定文本标注所在的地理位置
        offset: new BMap.Size(-10, -20) // 设置文本偏移量
      };
      let label = new BMap.Label(projectInfo.project_name, opts); // 创建文本标注对象
      label.setStyle({ // label样式
        color: '#333333',
        fontSize: '16px',
        lineHeight: '20px',
        border: 'none',
        background: '#ffffff',
        textStrokeWidth: '2px', // 不生效
        textStrokeColor: '#FFFFFF', // 不生效
        textShadow: '2px 2px 2px #FFFFFF;' // 不生效
      });
      marker.setLabel(label); // 设置项目名称,设置覆盖物的文字标签
      let projectStatus = this.formatStatus(projectInfo.status);
      let arr = [projectInfo.id,projectInfo.project_name,projectInfo.tempId]; // 解决onClick无法传对象
      // 点击标注,打开自定义信息窗口
      marker.addEventListener('click', () => {
        let html = `<div style="cursor: default">
          <div style="display: flex;justify-content: space-between">
              <span style="font-size: 18px;font-family: Source Han Sans CN;color: #333333;line-height: 30px;cursor: pointer" onClick="goDetail('${arr}')">${ projectInfo.project_name }</span>
              <div style="background: #367BF1;border-radius: 4px;padding: 6px 12px;text-align: center;color: #ffffff;font-size: 14px;cursor: pointer">数据总览</div>
          </div>
          <div style="margin-top: 12px">
            <p style="font-size: 14px;
      font-family: Source Han Sans CN;
      font-weight: 400;
      color: #666666;">项目类型:${ projectInfo.templateTypeName }</p>
            <p style="font-size: 14px;
      font-family: Source Han Sans CN;
      font-weight: 400;
      color: #666666;">项目状态:${ projectStatus }</p>
          </div>
        </div>`;
        let infoBox = new BMapLib.InfoBox(this.map, html, {
          boxStyle: {
            background: '#FFFFFF',
            width: '300px',
            height: '120px',
            borderRadius: '4px',
            boxShadow: '0 2px 4px 0 rgba(0, 0, 0, 0.2)',
            padding: '17px 11px',
            zIndex: 999
          },
          enableAutoPan: false, // 是否启动自动平移功能
          align: INFOBOX_AT_TOP, // 基于哪个位置进行定位
          offset: new BMap.Size(0, 30)
        });
        if (this.lastInfoBox) {
          //判断上一个窗体是否存在,若存在则执行close
          this.lastInfoBox.close();
          this.lastInfoBox = null;
        } else {
          infoBox.open(marker); // 开启信息窗口
          this.lastInfoBox = infoBox;
        }
      });
    },
    /**
     * 根据选择的项目改变地图中心
     */
    changeCenter () {
      // 转换方法的回调函数
      let translateCallback = (data) => {
        if (data.status === 0) {
          let pt = new BMap.Point(data.points[0].lng, data.points[0].lat);
          this.map.centerAndZoom(pt, 9); // 把点击的点设置为地图中心点,同时设置地图展示级别
        }
      };
      this.$nextTick(() => {
        // 数据原因,这里centerLatitude=>经度,centerLongitude=>纬度
        this.transformCoordinate(this.clickedProject.defaultPosition.centerLatitude, this.clickedProject.defaultPosition.centerLongitude, translateCallback);
      });
    },
    /**
     * 清空覆盖物
     * @param list 覆盖物数组
     */
    remove (list) {
      if (list && list.length > 0) {
        [...list].every(x => (!this.map.removeOverlay(x)));
      }
    },
    /**
     * 标识机场
     */
    createAirportMarker () {
      this.remove(this.markerList);
      this.markerList = [];
      airportLocation.forEach(item => {
        // 转换方法的回调函数
        let translateCallback = (data) => {
          if (data.status === 0) {
            let pt = new BMap.Point(data.points[0].lng, data.points[0].lat);
            let marker = new BMap.Marker(pt, { icon: this.myAirportIcon });
            this.markerList.push(marker);
            this.map.addOverlay(marker);
            let opts = {
              position: data.points[0], // 指定文本标注所在的地理位置
              offset: new BMap.Size(-33, -20) // 设置文本偏移量
            };
            let label = new BMap.Label(item.name, opts); // 创建文本标注对象
            label.setStyle({ // label样式
              color: '#333333',
              fontSize: '16px',
              lineHeight: '20px',
              border: 'none',
              background: '#ffffff',
            });
            marker.setLabel(label); // 设置项目名称,设置覆盖物的文字标签
          }
        };
        this.transformCoordinate(item.longitude, item.latitude, translateCallback);
      });
    },
    /**
     * 跳转项目详情
     */
    goDetail(project) {
      setTimeout(() => {
        this.$router.push({
          path: "projectEdit",
          query: {
            pid: project.split(',')[0],
            pname: project.split(',')[1],
            tempid: project.split(',')[2]
          }
        });
      }, 100);
    },
  }
};
</script>

<style lang="less" scoped>
@deep: ~'>>>';
@import "../../styles/common";
.map-box {
  width: 100%;
  height: 100%;
}

/*下面两段是去掉百度地图水印的css*/
@{deep}.BMap_cpyCtrl {
  display: none !important;
}

@{deep}.anchorBL {
  a {
    display: none !important;
  }
}

/*隐藏地图类型控件的三维地图按钮(百度已废弃三维)*/
@{deep}.anchorBR {
  div:nth-child(3) {
    display: none !important;
  }
}
</style>