总结:react项目中使用地图——以腾讯地图为例

目录

准备工作

需求1:根据地址中文或者经纬度在地图显示对应的坐标点

需求2:搜索地址然后在地图上显示对应的大致路线

需求3:根据地址跳转到本机安装的对应地图APP中,并显示目标位置


由于项目中需要用到地图展示,之前也没用到过地图展示,所以记录一下自己的探索过程,共同成长,互勉!

准备工作

引用地图功能需要引用对应的js包,可以到对应官方文档查看例子,这里就不做多说明。附上链接(https://lbs.qq.com/),然后在官网注册一个账号,创建项目,生成对应的key值,这个时候就可以把对应的key值写在刚才引入的js包链接上,我们项目用到的是umi框架,引入js文件的地方是document.ejs,如果是别的项目自行百度引入的位置。

可以考虑把这个地图封装成组件,然后在需要的地方进引用即可,地图的组件需要用到一个对象TMap。首先,你需要在页面上编写一个div,然后创建地图对象的时候初始在对应的div上,即可展现地图。

// 初始化地图
  function setMap() {
    
    //初始化地图
      map = new TMap.Map(document.getElementById('addressMap'), {
        viewMode: '2D',
      });

      //初始化蒙层
      markerLayer = new TMap.MultiMarker({
        map: map, // 指定地图容器
        // 样式定义
        styles: {
          myStyle: new TMap.MarkerStyle({
            width: 18, // 点标记样式宽度(像素)
            height: 26, // 点标记样式高度(像素)
            anchor: { x: 16, y: 32 }
          }),
          startMarker: new TMap.MarkerStyle({
            width: 25,
            height: 35,
            anchor: { x: 16, y: 32 },
            src: start
          }),
          endMarker: new TMap.MarkerStyle({
            width: 25,
            height: 35,
            anchor: { x: 16, y: 32 },
            src: end
          })
        }
      });
  }

现在你打开页面,已经可以在页面上看到地图了。自此,准备工作已经完成。

需求1:根据地址中文或者经纬度在地图显示对应的坐标点

这个需求需要根据地址中文查询出对应的坐标值,然后在地图上标注出来,我们需要编写一个函数用来在地图上标注出对应的点,点的展示需要坐标值,所以我们还需要调用响应的接口,进行坐标值转换,可查看官方文档,这里就不做多介绍。

根据这个接口,会对应返回中文地址的坐标值。而后,我们还需要一个函数来在地图上描点,描点的样式在初始化的时候已经定义好了样式,直接引用即可,这个函数会先清除掉之前的标注点,如果你不想清除,则直接添加即可。

  // 加载标注点
  const setMarkerlayer =(item)=> {
    
    const _wait_to_clear_ = markerLayer.getGeometries();

    if (_wait_to_clear_.length > 0) {
      // 先清除旧标注点
      const str = _wait_to_clear_.map((item) => item.id);
      markerLayer.remove(str);
    }
    
    //设置对应的地图中心点
    map.setCenter({ lat: current.lat, lng: current.lng });

    //增加标注点
    markerLayer.add({
      styleId: 'endMarker',  //之前初始地图定义的样式
      id: item.id | 'endmarker',
      position: new TMap.LatLng(item.lat || 0, item.lng || 0)
    });
  
  }

需求2:搜索地址然后在地图上显示对应的大致路线

这个需求根据你搜索的地点,然后在地图上描绘出当前位置到搜索地点的大致路线,我们需要做的有两个,定位当前所在位置,然后将其标注成起点,把搜索的地点标注成终点,然后描绘出起点和终点的路线。根据官方文档的api,即可定位当前位置,并返回对应的坐标值。

function getLocationIp() {
    let url = `/map/ws/location/v1/ip?key=${window.mapkey}`;
    io.get(url).then(res=> {
      addMarkerlayer(res.result.location, 'startMarker'); //增加标注点
    })
  }

描绘路线根据你传入的两个坐标位置,返回对应的路线。然后根据官方给出的方法,即可描绘出路线。

  //初始化描线图层
  const setPolylineLayer = () => {
    polylineLayer = new TMap.MultiPolyline({
      id: 'polyline-layer', //图层唯一标识
      map: map,//绘制到目标地图
      //折线样式定义
      styles: {
        'style_blue': new TMap.PolylineStyle({
          'color': '#3777FF', //线填充色
          'width': 6, //折线宽度
          'borderWidth': 5, //边线宽度
          'borderColor': '#FFF', //边线颜色
          'lineCap': 'round' //线端头方式
        })
      }
    })
  }

  //查询路线
  const direcationPlan =() => {

    const copyCurrent = current;
    const copyPurpose = purpose;

    let url = '/map/ws/direction/v1/driving/' +
        '?from=' + current.lat + ',' + current.lng + '&to=' + purpose.lat + ',' + purpose.lng +
        '&output=json&callback=cb' +
        '&key=' + window.mapkey;
      io.get(url).then(res=>{
        cb(res);
      }).catch() 
  }

  //定义请求回调函数
  const cb =(ret) => {

    let coors = ret.result.routes[0].polyline, pl = [];

    //坐标解压(返回的点串坐标,通过前向差分进行压缩,因此需要解压)
    let kr = 1000000;
    for (let i = 2; i < coors.length; i++) {
      coors[i] = Number(coors[i - 2]) + Number(coors[i]) / kr;
    }
    //将解压后的坐标生成LatLng数组
    for (let i = 0; i < coors.length; i += 2) {
      pl.push(new TMap.LatLng(coors[i], coors[i+1]));
    }

    setMarkerPolyline(pl)//显示路线
  }

  // 增加描线点
  const setMarkerPolyline =(p1)=> {

    const _wait_to_clear_ = polylineLayer.getGeometries();

    if (_wait_to_clear_.length > 0) {
      // 先清除旧标注点
      const str = _wait_to_clear_.map((item) => item.id);
      polylineLayer.remove(str);
    }
    polylineLayer.add({
      'id': 'pl_1',//折线唯一标识,删除时使用
      'styleId': 'style_blue',//绑定样式名
      'paths': p1
    })
  }

效果如图:

需求3:根据地址跳转到本机安装的对应地图APP中,并显示目标位置

目前找不到检测移动端是否有安装对应的APP,所以把市面上主流的三大地图软件都做了点击跳转,效果如图:

如果本机有安装对应的地图APP,则直接跳转到对应软件,如果有安装,则跳转到对应的下载页面。各自地图的跳转链接附上:

<a href="androidamap://poi?sourceApplication=dingtalk&keywords=XXX">打开安卓高德地图</a><br>
<a href="iosamap://poi?sourceApplication=dingtalk&keywords=XXX">打开iOS高德地图</a><br>
<a href="baidumap://map/place/search?query=XXX">打开百度地图</a><br>
<a href="qqmap://map/search?keyword=XXXX">打开腾讯地图</a>

实现的具体代码如下:

 const toMoblieMap =(item)=> {

    if(item.label == '取消') {
      setIsShow(!isShow);
      return ;
    }

    if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i)) {
      var loadDateTime = new Date();
      window.location = (item?.openUrl1 || item?.openUrl) + address;//schema链接或者universal link
      window.setTimeout(function() { //如果没有安装app,便会执行setTimeout跳转下载页
        var timeOutDateTime = new Date();
        if (timeOutDateTime - loadDateTime < 5000) {
          let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden ||window.document.webkitHidden
          if(typeof hidden =="undefined" || hidden ==false) {
            window.location = item.download2; //ios下载地址
          }
        } else {
          window.close();
        }
      }, 4000);

    } else if (navigator.userAgent.match(/android/i)) {
      var state = null;
      try {
        window.location = item.openUrl + address; //schema链接或者universal link
        window.setTimeout(function() {
          let hidden = window.document.hidden || window.document.mozHidden || window.document.msHidden ||window.document.webkitHidden

          if(typeof hidden =="undefined" || hidden ==false) {
            window.location = item.download1; //android下载地址
          }
        }, 4000);
      } catch (e) {}
    }
  }

至此,基本的功能已经完成,有很多需要完善的地方,比如如何检测到本机安装的地图软件等,很多细节也处理的不是很好,希望各位指正,互相交流进步!!!

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值