vue天地图开发实战,解决高德百度,无卫星图问题

6,869 阅读4分钟

在实际开发过程中,发现高德和百度地图等,无法使用卫星图查看乡镇问题,遂使用政府开发的天地图。写一份实(jiao)战(xue)记录,为开源精神做一份贡献。

讲解的功能有

  1. 天地图入门
  2. 地图渲染
  3. 添加地图控件
  4. 定位用户坐标,绘制城市边界,并通过移动标点重新定位经纬度
  5. 添加多个点,并且点击弹出信息框

天地图官方链接

项目使用vue-cli3,vue2开发

1、在public-index.html引入天地图cdn

<!--index.html-->
<script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=您的密钥"></script>

key申请地址 应用创建成功就能看到key

2、渲染dome

<!--创建dome容器-->
 <div id="mapDiv" style="position:absolute;width:100%; height:100%"></div>
  //生命周期 - 在挂载完成(可以访问DOM元素)
 mounted() {
   this.onLoad()
  },
  methods(){
   onLoad(){
    let that=this  //将方法放在mounted,会有指向问题,定义this使用就会正常
    let zoom = 12; //地图的初始化级别,及放大比例
    that.map = new T.Map("mapDiv");
    that.map.centerAndZoom(new T.LngLat(116.40769, 39.89945), zoom); //地图的初始化中心点,此为北京的经纬度
   }
  }

3、添加地图类型控件

 var ctrl = new T.Control.MapType([
        {
          title: "地图", //地图控件上所要显示的图层名称
          icon: "http://api.tianditu.gov.cn/v4.0/image/map/maptype/vector.png", //地图控件上所要显示的图层图标(默认图标大小80x80)
          layer: TMAP_NORMAL_MAP //地图类型对象,即MapType。
        },
        {
          title: "卫星混合",
          icon:
            "http://api.tianditu.gov.cn/v4.0/image/map/maptype/satellitepoi.png",
          layer: TMAP_HYBRID_MAP
        }
      ]);
       that.map.addControl(ctrl);

我只添加了两种类型的卫星,更多类型可以查看官方文档

值得注意的是:官方文档提供的代码格式错误,不能直接copy下来用

4、定位用户坐标,绘制城市边界,并通过移动标点重新定位经纬度

<!--添加点击按钮-->
 <button
    style="position: absolute;
    z-index: 500;
    border: 1px solid;
    right: 7%;
    bottom: 10%;
    color: red;
    background: green;
    padding: 10px;"
      @click="positionBtn"
    >定位坐标</button>
  data() {
    //这里存放数据
    return {
        cityName:""  //暂存城市名称
    };
  },
  positionBtn() {
        let that =this
      // this.map.clearOverLays();   //清理地图上的覆盖物
      let lc = new T.LocalCity();  //创建一个获取本地城市位置的实例
      lc.location(function(e) {  //利用ip进行定位
        alert(e.cityName);
        let marker = new T.Marker(e.lnglat);  //e.lnglat,标注点的地理坐标
        that.map.addOverLay(marker);  //addOverLay方法,将覆盖物添加到地图中,一个覆盖物实例只能向地图中添加一次。
        that.getMap(); //创建地图对象

        marker.addEventListener("dragend", overlay_style); //添加事件监听函数。
        marker.enableDragging(); //开启标注拖拽功能

        function overlay_style(e) {
          let p = e.target;
          alert(
            "该地区经纬度是:" + p.getLngLat().lng + "," + p.getLngLat().lat
          );
        }
      });
    },
   

    getMap() {
        let that= this
      //创建对象
      let administrative = new T.AdministrativeDivision(); //创建一个获取行政区划的实例
      let config = {
        needSubInfo: false, //是否需要下一级信息
        needAll: false, //是否需要所有子节点。
        needPolygon: true,//是否需要行政区划范围。
        needPre: true,//是否需要上一级所有信息。
        searchType: 1,//查询类型。0表示根据code查询,1表示根据名称查询。
        searchWord: this.cityName//查询行政区划的名称。
      };
      administrative.search(config, searchResult);//方法:根据检索词发起检索,searchResult:回调参数
      function searchResult(result) {
        if (result.getStatus() == 100) {
          let data = result.getData();
          that.showMsg(data);
        } else {
          result.getMsg();
        }
      }
      //具体内容详见AdministrativeDivisionResult类。
    },
    showMsg(data) {
      for (let i = 0; i < data.length; i++) {
        //解释上级行政区划
        if (data[i].parents) {
          let upLevel = "";
          if (data[i].parents.country) {
            upLevel += data[i].parents.country.name;
          }
          if (data[i].parents.province) {
            upLevel += data[i].parents.province.name;
          }
        }

        if (data[i].points) {
          //绘制行政区划
          this.polygon(data[i].points);
        }

        //解释下级行政区划
        if (data[i].child) {
          showMsg(data[i].child);
          console.log(data[i].child.points);
          if (data[i].child.points) {
            //绘制行政区划
            this.polygon(data[i].child.points);
          }
        }
      }
    },

    polygon(points) {
        let that=this
      let pointsArr = [];
      for (let i = 0; i < points.length; i++) {
        let regionLngLats = [];
        let regionArr = points[i].region.split(",");
        for (let m = 0; m < regionArr.length; m++) {
          let lnglatArr = regionArr[m].split(" ");
          let lnglat = new T.LngLat(lnglatArr[0], lnglatArr[1]);
          regionLngLats.push(lnglat);
          pointsArr.push(lnglat);
        }
        //创建面对象,样式
        let polygon = new T.Polygon(regionLngLats, {
          color: "#fd737a",
          weight: 3,
          opacity: 1,
          fillColor: "#FFFFFF", //填充颜色。
          fillOpacity: 0.3 //填充透明度
        });
        //向地图上添加行政区划面
        that.map.addOverLay(polygon);
      }
      //显示最佳比例尺
      that.map.setViewport(pointsArr);
      alert(
        "当前地图中心点:" +
          that.map.getCenter().getLng() +
          "," +
          that.map.getCenter().getLat()
      );
    },

5、添加多个点,并且点击弹出信息框

<!--添加点击按钮-->
  <button
      style="position: absolute;
    z-index: 500;
    border: 1px solid;
    right: 7%;
    bottom: 5%;
    color: red;
    background: green;
    padding: 10px;"
      @click="pointsBtn"
    >添加多个点</button>
pointsBtn() {
        let that=this
      let data_info = [
        [
          116.417854,
          39.921988,
          "地址:北京市东城区王府井大街88号乐天银泰百货八层"
        ],
        [116.406605, 39.921585, "地址:北京市东城区东华门大街"],
        [116.412222, 39.912345, "地址:北京市东城区正义路甲5号"]
      ];

      for (let i = 0; i < data_info.length; i++) {
        let marker = new T.Marker(
          new T.LngLat(data_info[i][0], data_info[i][1])
        ); // 创建标注
        let content = data_info[i][2];
        that.map.addOverLay(marker); // 将标注添加到地图中
        that.addClickHandler(content, marker);
      }
     
   
    },
 addClickHandler(content, marker) {
        marker.addEventListener("click", function(e) {
          that.openInfo(content, e);
        });
      },
 openInfo(content, e) {
        let point = e.lnglat;
        that.marker = new T.Marker(point); // 创建标注
        let markerInfoWin = new T.InfoWindow(content, {
          offset: new T.Point(0, -30)
        }); // 创建信息窗口对象
        that.map.openInfoWindow(markerInfoWin, point); //开启信息窗口
      },

使用自定义信息框,会涉及到利用三目运算符,根据数字转换成对应字符的问题,记得用()把三木运算符括起来,否则会导致前面的html无法渲染

结语

网上写天地图的文章挺少,其实只要把坑踩过了还是挺好用的。 觉得有用的小伙伴,可以请我喝杯奶茶以资鼓励。