踩坑!!!vue3获取当前位置经纬度(浏览器自带、百度地图、高德地图、腾讯地图)


前言

一把辛酸史,折磨死人了!!!!!!!!!!!!!!!!!我要用到的百度地图的展示,所以会将所有数据转成百度地图的百度坐标系 (BD-09)


一、使用浏览器自带定位navigator.geolocation.getCurrentPosition

浏览器自带经纬度是wgs84坐标系,注意坐标系的数据转换


// 浏览器
const getLocation = () => {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition, showError);
  } else {
    alert("浏览器不支持地理定位。");
  }
}

// 获取用户经纬度
function showPosition(position) {
  //GPS经纬度
  let x = position.coords.latitude;
  let y = position.coords.longitude;
  var gpsPoint = new BMap.Point(y, x);

  setTimeout(function () {
    var convertor = new BMap.Convertor();
    var pointArr = [];
    pointArr.push(gpsPoint);
    convertor.translate(pointArr, 1, 5, translateCallback)
  }, 1000);
}

// 将GPD经纬度转为百度地图经纬度
function translateCallback(data) {
  // 结果获取
  let obj = wgs84tobd09(data.points[0].lng, data.points[0].lat);
  submitForm.value.location.longitude = obj.lng
  submitForm.value.location.latitude = obj.lat

}

// 转换方法
function wgs84tobd09(){
// 先转GCJ-02再转BD-09
  const gcj = wgs84_to_gcj02(lng, lat);
  const z = Math.sqrt(gcj[0] * gcj[0] + gcj[1] * gcj[1]) + 0.00002 * Math.sin(gcj[1] * Math.PI * 3000.0 / 180.0);
  const theta = Math.atan2(gcj[1], gcj[0]) + 0.000003 * Math.cos(gcj[0] * Math.PI * 3000.0 / 180.0);
  return {lng:z * Math.cos(theta) + 0.0065, lat:z * Math.sin(theta) + 0.006};
}

// wgs84转GCJ-02
function wgs84_to_gcj02(lng, lat) {
  // 简化的坐标偏移算法(实际需要更复杂的纠偏)
  const ee = 0.006693421622965943; // 偏心率平方
  const a = 6378245.0; // 长半轴
  
  // 判断是否在国内
  if (lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271) {
    return [lng, lat];
  }
  
  let dlat = transform_lat(lng - 105.0, lat - 35.0);
  let dlng = transform_lng(lng - 105.0, lat - 35.0);
  
  const radlat = lat / 180.0 * Math.PI;
  let magic = Math.sin(radlat);
  magic = 1 - ee * magic * magic;
  
  const sqrtmagic = Math.sqrt(magic);
  dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * Math.PI);
  dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * Math.PI);
  
  return [lng + dlng, lat + dlat];
}
// 报错信息
function showError(error) {
  switch (error.code) {
    case error.PERMISSION_DENIED:
      alert("定位失败,用户拒绝请求地理定位");
      break;
    case error.POSITION_UNAVAILABLE:
      alert("定位失败,位置信息是不可用");
      break;
    case error.TIMEOUT:
      alert("定位失败,请求获取用户位置超时");
      break;
    case error.UNKNOWN_ERROR:
      alert("定位失败,定位系统失效");
      break;
  }
}

提示:坑来了!!!!!!!!!!
1、转变之后我发现和我实际定位还是有偏差,转换方法没错,那就是这个方法定位不准...
2、本地测试只有localhost是能用的,其他的会报错“定位失败,用户拒绝请求地理定位”。应该是要求安全环境,但是用到该功能的项目不会变成https的安全网址,所以我要放弃了!

二、百度地图BMap.Geolocation

官网链接

index.html引入

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

使用:

const getLocation = () => {
  var geolocation = new BMap.Geolocation();
  geolocation.enableSDKLocation()
  geolocation.getCurrentPosition(function (r) {
    if (this.getStatus() == BMAP_STATUS_SUCCESS) {
      let obj = r.point
      submitForm.value.location.longitude = obj.lng
      submitForm.value.location.latitude = obj.lat
    }
    else {
      //关于状态码    
      //BMAP_STATUS_SUCCESS   检索成功。对应数值“0”。    
      //BMAP_STATUS_CITY_LIST 城市列表。对应数值“1”。    
      //BMAP_STATUS_UNKNOWN_LOCATION  位置结果未知。对应数值“2”。    
      //BMAP_STATUS_UNKNOWN_ROUTE 导航结果未知。对应数值“3”。    
      //BMAP_STATUS_INVALID_KEY   非法密钥。对应数值“4”。    
      //BMAP_STATUS_INVALID_REQUEST   非法请求。对应数值“5”。    
      //BMAP_STATUS_PERMISSION_DENIED 没有权限。对应数值“6”。(1.1 新增)    
      //BMAP_STATUS_SERVICE_UNAVAILABLE   服务不可用。对应数值“7”。(1.1 新增)    
      //BMAP_STATUS_TIMEOUT   超时。对应数值“8”。(1.1 新增)    
      switch (this.getStatus()) {
        case 2:
          alert('位置结果未知,获取位置失败。');
          break;
        case 3:
          alert('导航结果未知,获取位置失败。');
          break;
        case 4:
          alert('非法密钥,获取位置失败。');
          break;
        case 5:
          alert('对不起,非法请求位置,获取位置失败。');
          break;
        case 6:
          alert('对不起,当前没有权限,获取位置失败。');
          break;
        case 7:
          alert('对不起,服务不可用,获取位置失败。');
          break;
        case 8:
          alert('对不起,请求超时,获取位置失败。');
          break;
      }
    }
  }, { enableHighAccuracy: true });
}

提示:坑来了!!!!!!!!!!
1、手机设备在wifi和流量下获取的经纬度数据是不一样的。wifi环境下数据精准,流量环境下定位在了市政府...
2、IOS不可用,直接报错"对不起,当前没有权限,获取位置失败"。
还有其他坑:
历史踩坑记录

三、高德地图AMap.Geolocation

官网链接

index.html引入

  <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=你的key"></script>

使用:


  <div id="container"></div>

// 高德
const getLocation = () => {
  var map = new AMap.Map('container', {
    resizeEnable: true
  });
  AMap.plugin('AMap.Geolocation', function () {
    var geolocation = new AMap.Geolocation({
      enableHighAccuracy: true,//是否使用高精度定位,默认:true
      timeout: 10000,          //超过10秒后停止定位,默认:5s
      buttonPosition: 'RB',    //定位按钮的停靠位置
      buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
      zoomToAccuracy: true,   //定位成功后是否自动调整地图视野到定位点
    });
    map.addControl(geolocation);
    geolocation.getCurrentPosition(function (status, result) {
      if (status == 'complete') {
        onComplete(result)
        console.log(result);
      } else {
        onError(result)
      }
    });
  });
}

//解析定位结果
function onComplete(data) {
  showLocationDetail.value = true
  let obj = gcj02tobd09(data.position.lng, data.position.lat)
  submitForm.value.location.longitude = obj.lng
  submitForm.value.location.latitude = obj.lat
}
//解析定位错误信息
function onError(data) {
  alert(data.message)
}

和百度地图的问题差不多

四、腾讯地图qq.maps.Geolocation

官网链接

用法1

index.html

  <script type="text/javascript" src="https://apis.map.qq.com/tools/geolocation/min?key=你的key&referer=test(项目名,必填)"></script>
  <script type="text/javascript" src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>

使用:

// 腾讯
const getLocation = () => {
  var geolocation = new qq.maps.Geolocation('你的key', 'test(项目名,必填)');
  geolocation.getLocation(function success(position) {
    let obj = gcj02tobd09(position.lng, position.lat);
    console.log(obj);
    submitForm.value.location.longitude = obj.lng
    submitForm.value.location.latitude = obj.lat

  }, function error(result) {
    console.log('获取定位失败', JSON.stringify(result));
  }, {
    timeout: 15000, // 默认值为10s;
    failTipFlag: true
  });
}
}

用法2

这个会一直调用

 <iframe id="geoPage" width=0 height=0 frameborder=0 style="display:none;" scrolling="no" src="https://apis.map.qq.com/tools/geolocation?key=你的key&referer=test(项目名,必填)">
  </iframe>

window.addEventListener('message', function (event) {
  // 接收位置信息 你的其他操作
  var loc = event.data;
  let obj = gcj02tobd09(loc?.lng, loc?.lat);
  //   console.log(obj);
  //   console.log('location', loc);
    submitForm.value.location.longitude = obj.lng
    submitForm.value.location.latitude = obj.lat
  
}, false);


总结

微信jdk要做很多准备工作,而且只能在微信里面打开网页,所以放弃尝试。最后是先将项目部署成https的环境,测试百度地图方法是精准的(因为我要用百度地图坐标系的数据,所以直接用的百度地图方法)。至于定位权限,我发现是我的手机设置问题,safari浏览器直接给我禁止了,可能我设置了不允许获取地址,最后在别的同事手机(无论是安卓机还是苹果)都是好用的。
所以就是:1.首先确保环境为https的安全环境。2.查看你的浏览器是否禁止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值