微信小程序中使用地图和定位的一些坑和经验

本站所有文章均为博主人工写作,绝无AI辅助成分,请放心参阅。

首先,经过测试,使用GCJ02(火星坐标)比WGS84(GPS)的坐标在计算距离的时候更为精确。在微信小程序中使用内置接口获取用户坐标,代码放在app.js里:

App({
  getLocation: function () {
    var that = this
    wx.getLocation({
      //type: 'wgs84',
      type: 'gcj02',
      success: function (res) {
        that.globalData.latitude = res.latitude
        that.globalData.longitude = res.longitude
        //var speed = res.speed
        //var accuracy = res.accuracy
      }
    })
  }
 
})

关于坐标系的拓展知识,我看了这篇文章http://blog.sina.com.cn/s/blog_80a9926b0101ktoa.html

项目中,我一开始用百度坐标工具获取了自家小区正门坐标,结果在微信小程序里这个坐标变成的是小区后门之外,大约有1公里的误差。之后改用腾讯地图坐标获取工具重新获取坐标,才消除了这个误差。原来百度地图坐标是经过加密的,有一些偏移,只能用在百度自家产品上。微信小程序开发,还是用腾讯自家地图比较好。另外,高德地图和腾讯地图坐标也是通用的。

接下来是判断两个坐标之间的距离:

var EARTH_RADIUS = 6378.137; //地球半径
function rad(d) {
    return d * Math.PI / 180.0;
}
function getDistance(lng1, lat1, lng2, lat2) {
  var radLat1 = rad(lat1);
  var radLat2 = rad(lat2);
  var a = radLat1 - radLat2;
  var b = rad(lng1) - rad(lng2);
  var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
    + Math.cos(radLat1) * Math.cos(radLat2)
    * Math.pow(Math.sin(b / 2), 2)));
  s = s * EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000;
  return s;//返回数值单位:公里
}

另一个据说是精度更好的函数,目前尚未验证,留待备用:

function getFlatternDistance(lat1,lng1,lat2,lng2){
    var f = getRad((lat1 + lat2)/2);
    var g = getRad((lat1 - lat2)/2);
    var l = getRad((lng1 - lng2)/2);
 
    var sg = Math.sin(g);
    var sl = Math.sin(l);
    var sf = Math.sin(f);
 
    var s,c,w,r,d,h1,h2;
    var a = EARTH_RADIUS;
    var fl = 1/298.257;
 
    sg = sg*sg;
    sl = sl*sl;
    sf = sf*sf;
 
    s = sg*(1-sl) + (1-sf)*sl;
    c = (1-sg)*(1-sl) + sf*sl;
 
    w = Math.atan(Math.sqrt(s/c));
    r = Math.sqrt(s*c)/w;
    d = 2*w*a;
    h1 = (3*r -1)/2/c;
    h2 = (3*r +1)/2/s;
 
    return d*(1 + fl*(h1*sf*(1-sg) - h2*(1-sf)*sg));
}

此外还踩到一个坑,在小程序开发工具中没有表现出来,在真机调试才发现,地图marker的坐标如果想通过JS修改,光修改绑定坐标数据是无效的,必须通过小程序的地图组件控制接口wx.createMapContext,用translateMarker方法修改标记坐标才行。
首先在页面onReady创建对象

onReady: function (e) {
    // 使用 wx.createMapContext 获取 map 上下文
    this.mapCtx = wx.createMapContext('restaurantMap')
},

然后在需要修改坐标的时候用此方法

this.mapCtx.translateMarker({
    markerId: 0,//所要操作的标记ID,在data中已预先定义
    autoRotate: false,
    rotate: 0,
    duration: 100,
    destination: {//新的坐标值
        latitude: ***,
        longitude: ***,
    },
    animationEnd() {
    console.log('animation end')
    }
})

2018年3月30日更新一篇博客
微信小程序地图相关的开发经验补充

本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.brain1981.com/1696.html。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

关注我们的微信公众号-JennyStudio 本站记录了近几年的工作中遇到的一些技术问题和解决过程,“作品集”还收录了本人的大部分作品展示。除了本博客外,我们的工作室网站 – JennyStudio,内有更多作品回顾和展示。
您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。

10 关于 “微信小程序中使用地图和定位的一些坑和经验” 的评论

  1. JerryZhang

    官方示例 translateMarker 一直报错:渲染层错误 VM7412:2 TypeError: Cannot read property ‘map’ of undefined

    不知道你有没有遇到过。

    回复
  2. jin

    博主 你好 我做微信小程序时发现用map原生组件定位不准的问题 type: ‘gcj02′, type:’wgs84’ 这个2个type 我都改过 不知道为什么不准 想差2公里,请博主有空解答下,十分感谢

    回复
    1. Brain 文章作者

      有时候是地图在你这个区域本身不准,你可以多定位几个地方,距离远一些,看看是不是都相差同样的距离和方向。
      有时候可能是因为自己坐标算法的原因,这就很难说了

      回复
      1. jin

        理论上来说 获取当前位置 只需调用 wx.getLocation({
        type: ‘gcj02’,
        success: (res)=> {
        console.log(res)
        this.setData({
        latitude: res.latitude,
        longitude: res.longitude,
        这个方法就行了 里面就有经纬度是吗? 我是怕我自己写错了

        回复
  3. dimtai

    博主你好!文章有启发。关于经纬度的翻译成地图位置的问题,经纬度本身应当是准确的,地图错位与地图供应商有关吧?另外,请教如何能提高微信小程序获取位置的精度?

    回复

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注