o2o业务,如何依据当前位置计算附近的点

1.前言

我叫外卖,10公里外的商户我相信他是不会送餐的。
我叫桶装水,3公里估计人家都嫌远。

这类对距离敏感的业务,也就是传说的o2o业务,都需要在一定的距离范围内开展工作。

2.涉及的问题

这类距离敏感型业务,涉及4个最基本的问题。

1、如何获取当前用户位置坐标
2、如何计算两个坐标点之间的直线距离
3、如何从全体商户集合中筛选出符合距离要求的一批商户
4、如何根据远近进行排序

3.解决问题的思路

一、或取当前用户坐标位置

这个客户端基本都提供现成的api,我们以微信小程序为例,通过调用wx.getLocation可以得到当前用户的经度坐标longitude,与纬度坐标latitude

//微信小程序
wx.getLocation({
  type: 'wgs84',
  success: function(res) {
    var latitude = res.latitude
    var longitude = res.longitude
    var speed = res.speed
    var accuracy = res.accuracy
  }
})

二、计算两点间直线距离

计算两点间距离,这个有固定的数学公式,示例代码如下,获得距离米数。(这个其实应该属于排序环节)

//计算距离(米)
$distance = getDistance(40.035076141357,116.3627243042,40.035076142357,116.3927243142);

var_dump($distance);

//计算公式
function getDistance($lat1, $lng1, $lat2, $lng2) 
{ 
    $earthRadius = 6367000; 

    $lat1 = ($lat1 * pi() ) / 180; 
    $lng1 = ($lng1 * pi() ) / 180; 

    $lat2 = ($lat2 * pi() ) / 180; 
    $lng2 = ($lng2 * pi() ) / 180; 

    $calcLongitude = $lng2 - $lng1; 
    $calcLatitude = $lat2 - $lat1; 
    $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2); 
    $stepTwo = 2 * asin(min(1, sqrt($stepOne))); 
    $calculatedDistance = $earthRadius * $stepTwo; 

    return round($calculatedDistance); 
} 

三、筛选附近的商户

1、首先要给数据库商户表家里索引,经度与纬度联合索引
2、依据当前点,范围反向计算出最大、最小经纬度
3、使用范围查询

//根据当前坐标,范围计算最大最小坐标点
function getAround($latitude,$longitude,$raidus)
{
    $PI = 3.14159265;
    $degree = (24901*1609)/360.0;
    $dpmLat = 1/$degree;
    $radiusLat = $dpmLat*$raidus;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;
    $mpdLng = $degree*cos($latitude * ($PI/180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng*$raidus;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    return array (minLat=>$minLat, maxLat=>$maxLat, minLng=>$minLng, maxLng=>$maxLng);
}

//范围查询
SELECT * FROM 商户表 WHERE (latitude BETWEEN minLat AND maxLat) and (longitude BETWEEN minLng and maxLng);

四、进行远近排序

对于整数数组我们可以方便的使用各类排序算法,但当数组元素是对象时,就平添了实现上的麻烦。

$shops = 已查询出的商户集合;//这是一个对象数组

$myspace = array('lat'=>40.035076141357,'lng'=>116.3627243042);

//计算各点与当前点的距离
for($i=0;$i<count($shops);$i++){

    $d = getDistance($myspace['lat'],$myspace['lng'],$shops[$i]['lat'],$shops[$i]['lng']);
    $shops[$i]['distance'] = $d;
}

//排序,一般而言周边商户数据量都比较小,这里用冒泡排序算法实现
bublleSort($shops);

//$shops已经按距离从近到远排序

function swap(&$arr,$i,$j){

    if($arr[$i]['distance']>$arr[$j]['distance']){

        $temp = $arr[$i];
        $arr[$i] = $arr[$j];
        $arr[$j] = $temp;
    }
}

function bubbleSort(&$arr){

    for($i=0;$i<count($arr)-1;$i++){

        for($j=$i+1;$j<count($arr);$j++){

            swap($arr,$i,$j);
        }
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值