最近设计H5业务需求需要实现类似钉钉一样打卡获取当前定位得功能。反复研究了各大官网地图,这里分享一些经验,和遇到得问题。

首先是高德地图api,都说高德地图获取到得定位比较准确,但是在使用高德地图api的时候,发现高德地图现在通过官网提供的"AMap.Geolocation",插件根本获取不到精准定位。获取到的经纬度也是有偏差的,后来查阅很多资料才看到,现在的高德一个办法根本获取不到详细信息,还需要再调用别的方法。(有兴趣的小伙伴可以自己研究)

这里是高德地图我写的获取当前位置的方法。如果只是获取到当前城市的经纬度的话,这个是可以直接使用的。

温馨提醒:

1.记得再mounted里面去调用getLocation()方法

2.谷歌浏览器打开会报错,使用edge可以

3.使用本地路径是可以查看的。

使用地图的基本步骤就不说了,申请key去各大官网平台申请对应的key

我这里是用vue2写的

首先在html中引入cdn 记得要放在script 标签最前面。

  <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=申请的高德key"></script>
getLocation(){
      const self = this
      AMap.plugin('AMap.Geolocation',function(){
        var geolocation = new AMap.Geolocation({
          //是否使用高i精度定位,默认:true
          enableHighAccuracy: true,
          // 设置定位超时时间,默认:无穷大
          timeout: 10000,
        })
        geolocation.getCurrentPosition();
        AMap.event.addListener(geolocation, 'complete', onComplete);//返回定位信息
        AMap.event.addListener(geolocation, 'error', onError);      //返回定位出错信息
        function onComplete(data){
          //data 是具体定位信息
          console.log('定位成功信息:',data);
        }
        function onError(){
          //定位出错 
          console.log('帝国为失败错误:',data);
          //调用ip定位
          self.getLngLatLocation()
        }
      })
    },
    getLngLatLocation() {
      AMap.plugin('AMap.CitySearch', function () {
        var citySearch = new AMap.Citysearch();
        citySearch.getLocalcity(function (status, result) {
          if (status === 'complete' && result.info === 'OK') {
            //查询成功,result即为当前所在城市信息
            console.log('通过ip获取当前城市:', 'result')
            //逆向地理编码
            AMap.plugin('AMap.Geocoder', function () {
              var geocoder = new AMap.Geocoder({
                //city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
                city: result.adcode
              })
              var lnglat = result.rectangle.split(';')[0].split(',');
              geocoder.getAddress(lnglat, function (status, data) {
                if (status === 'complete' && data.info === 'OK') {
                  //result为对应的地理位置详细信息console.log(data)
                  console.log(data)
                }
              })
            })
          }
        })
      })
    },

这里是edge显示的返回结果

 因为这个获取不到详细定位,又研究了一下百度地图的api,这里分享一下使用百度地图api 的时候遇到的一些问题。百度地图是可以获取到详细街道的,但是有局限,在浏览器上获取定位是不准确的,需要使用测试域名 跑到服务上,从手机端去看,但是有浏览器限制,在uc,夸克,百度app上可以获取到精确定位,苹果自带的safari 和部分安卓自带的浏览器仍然是获取不到的。

这里也上一下代码,小伙伴们根据需求合理使用、

首先也是引入cdn

    <script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=申请的百度ak"></script>

代码片段,百度地图三种获取当前定位的方法

      var geolocation = new BMap.Geolocation();
        geolocation.getCurrentPosition(function(r){
          console.log('我是浏览器定位' + '-------------');
          console.log(r);
          if(this.getStatus() == BMAP_STATUS_SUCCESS){
            console.log('您的位置:'+r.point.lng+','+r.point.lat);
            console.log('您的位置:'+r.address.province +','+ r.address.city+','+ r.address.district+','+r.address.street);
          }
          else {
            console.log('failed'+this.getStatus());
          }        
        })
      // //ip 定位
      var myCity = new BMap.LocalCity();
      myCity.get(  
       result=>{
        let geoc = new BMap.Geocoder();  
          geoc.getLocation(result.center,res=>{
            console.log('我是ip定位'+ '----------------');
            console.log(result.center);
            console.log(res);
          },
          { enableHighAccuracy: true })
      }); 
      //定位SDK辅助定位
    var geolocation = new BMap.Geolocation();
    // 开启SDK辅助定位
    geolocation.enableSDKLocation();
    geolocation.getCurrentPosition(function(r){
      console.log('我是开启SDK'+'--------------');
      console.log(r);
      if(this.getStatus() == BMAP_STATUS_SUCCESS){
        // console.log('您的位置:'+r.point.lng+','+r.point.lat);
      }
    })

这里是打印结果。在谷歌上只显示一种ip定位的结果,当然也是有误差的结果

 下面是edge的打印结果,可以看到在pc浏览器上三种方法都打印出来了。但是这里显示的是有偏差的结果。

 这里是详细信息,可以看到,浏览器定位跟开启sdk定位获取到的位置是一样的。但是同一个地址,ip定位和浏览器,sdk都有误差。 

百度地图的详细信息是出来了,但是在pc端仍然是有问题的。但是使用测试地址发布在移动端通过浏览器和sdk是可以获取当详细地址并且能展现出来的,这里我因为用的是本地,就没办法给发打印结果了。但是上面也说了。他是在部分浏览器上才可以打印出来结果,获取详细信息的。

上面高德和百度都有各自的缺陷,百度虽然获取到了,但是不符合业务需求,所以研究资料之后,我最后去看了,微信js-sdk ,在vue中调用微信的sdk 获取位置。最后把功能实现了。分享一下成功的办法吧。因为我使用的是vue的框架 

首先在vue 中下载js-sdk 的node

1. npm i weixin-js-sdk 引入js-sdk

2.引入之后根据微信开发平台,请求后端接口获取参数。

3.调用wx-sdk方法。 使用wx-getLocation()

4.获取到经纬度,然后根据腾讯地图cdn逆编码转换成详细地址。

代码如下:

    getLocation(){
        //定位,获取用户经纬度
        let url =  location.href.split('#')[0];
         //截取当前地址栏的URL,(不带#hash部分)
          let _this = this
          this.axios.get(this.url.getSignMsg+'?url='+url).then(res=>{
           if(res){
            wx.config({
              beta: true,
              debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
              appId: res.appId, // 必填,公众号的唯一标识
              timestamp: res.timestamp, // 必填,生成签名的时间戳
              nonceStr: res.nonceStr, // 必填,生成签名的随机串
              signature: res.signature, // 必填,签名
              jsApiList:['getLocation'],//必填,需要使用的JS接口列表,如我要用的是wx.getLocation,那么我的jsApiList里的就是getLocation
            });
            wx.ready(() => {
              // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
              // config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
              // 则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
              wx.getLocation({
                type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
                success: res=> {
                  // _this.latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
                  // _this.longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
                  // var speed = res.speed; // 速度,以米/每秒计
                  // var accuracy = res.accuracy; // 位置精度
                  let latLng = new qq.maps.LatLng(res.latitude,res.longitude)
                  getAddr.getAddress(latLng)
                },
                fail: function(err) {
                  if(err.errMsg == 'getLocation:fail'){
                    _this.form.address = '获取定位失败,请检查您的授权!'
                  }
                },
                cancel: function (res) {
                 console.log('用户拒绝授权获取地理位置');
                }
              });
            });
             let getAddr = new qq.maps.Geocoder({
                complete: function (res) {
                  console.log(res);
                  _this.form.address = res.detail.address
                  // let allAddress = res.detail.addressComponents
                  // _this.address = res.detail.nearPois
                  // let address = res.detail.address
                  // alert('地址:' + JSON.stringify(_this.address))
                  // console.log('地址:', address, allAddress.province, allAddress.city, allAddress.district)
                  console.log('地址:' + address + allAddress.province + allAddress.city + allAddress.district)
                }
          })
        }
      })
    },

记得还是在html中引入腾讯地图的cdn

    <script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=申请的腾讯地图key"></script>

  我们的项目一个是在企业微信,一个是在小程序上线的,所以我还特地看了一下企业微信的文档,跟微信公众号是一样的方法。就不多说了。但是如果小伙伴们,在企业微信或者微信公众号测试得时候,如果碰到报错invalid url domain得问题,记得看一下企业微信或者公众号有没有配置你本地得接口域名。

最后,因为没有权限问题,成功得截图没有办法展现给大家,回头我会再补一下成功得图。

总结一下,高德地图获取地位虽然准确,但是最新得地图,需要https域名,使用起来比较麻烦。百度地图根据官网方法比较简单能获取到,但是局限性太强了,需要再固定得浏览器使用。腾讯地图不多评价,最好结合微信sdk使用。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐