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

泪湿孤枕 提交于 2020-04-06 18:55:59

首先,经过测试,使用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')
    }
})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!