小程序距离计算解决记

calculateDistance(options:Object)

我在写微信小程序的时候需要用到腾讯位置服务,场景如下:

需要在一堆店铺地址中筛选出距离起点5公里以内的店铺,用到的API是calculateDistance(options:Object)。那正常思路就是把这些店铺的经纬度按官方的要求放在一个数组里,然后去批量查询,获得距离后再筛选出5公里以内的地址,看似很完美的思路,但其实是一个大坑,一跑代码就报错{"status": 373, "message": "起终点距离超长"}原来它只能计算10公里以内的距离,一旦终点列表数组中有一个地址超过10公里,那就全盘皆输,它直接报错,没得商量。

好吧,那我不批量查了,一个个查,报"起终点距离超长"的就丢弃。但是人家腾讯位置又说了"对每个key的每个服务接口的调用量做了如下限制:并发数:5次 / key / 秒" 。几个for循环后它就又报错{"status": 120, "message": "此key每秒请求量已达到上限"}

生无可恋...

难道就没办法了吗?当然有!那就只能曲线救国了。我只要测5公里以内的距离,可以先用公式计算两个点的直线距离,把范围缩小在5公里(直线距离5km)以内。然后再调用calculateDistance对筛选后的终点计算实际距离不就OK了吗?

贴上代码

//先引入腾讯位置的js
var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');
var qqmapsdk;
qqmapsdk = new QQMapWX({
  key: '你的key'
});
//通过经纬度计算两点距离
function getDistFromTwoPoint (lat1, lon1, lat2, lon2) {
  var p = 0.017453292519943295;    // Math.PI / 180
  var c = Math.cos;
  var a = 0.5 - c((lat2 - lat1) * p) / 2 +
    c(lat1 * p) * c(lat2 * p) *
    (1 - c((lon2 - lon1) * p)) / 2;

  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}
//设置起点和终点
var start = {latitude: 40.04215, longitude: 116.29471};
var end = [{
                latitude: 40.03731665,
                longitude: 116.31489942
            },
            {  
                latitude:40.03895454,
                longitude:116.31947467
            },
            {
                latitude:39.06835611,
                longitude:116.31365596
            }, 
            {
                latitude:39.801202,
                longitude:116.31365596
            }];
var nearRestaurants = [];
//计算每个终点与起点的直线距离,筛选出与起点的距离小于5km的点,放入nearRestaurants
for (let item of end) {
  var lat = item.latitude
  var lng = item.longitude
  if (getDistFromTwoPoint(start.latitude, start.longitude, lat, lng) >= 5) {
    continue
  }
  nearRestaurants.push(item)
}
//再调用calculateDistance API去测距
qqmapsdk.calculateDistance({
    mode: 'driving',
    from: start,
    to: nearRestaurants,
    success: function (res) {
       var distanceList = res.result.elements;
       var newDistanceList = distanceList.filter(item => item.distance <= 5000)
       console.log(newDistanceList)
    }
})
//最后的newDistanceList就是距离起点5km以内的店铺地址

完美~

不过最后还是真心希望腾讯能自己把这个坑填了。。。

Comments
Write a Comment