缘由

本周技术群有一个同学说我们该怎么实现 由近到远的基于地理位置的搜索,我创业做电商的系统做过类似这样的服务,我把我们以前的操作给大家分享下

什么是LBS

LBS 全称是 Location  Based Service ,基于位置的服务。我们可以使用到这种服务,真是由于我国移动设备的大量增加,让我们加速进入了 移动互联网的时代。

由近到远的基于地理位置的搜索  其实就是 通过当前使用用户的经纬度,然后从我们自己的数据库中查出指定范围内(例如5km)的数据,按照由近到远的顺序 进行展示。

这句话中有四个条件

用户的经纬度,我们定义 用户维度为:$lat 、经度:$lng

指定范围,定义范围:distince

数据库中商家的经纬度字段,定义 维度为:lat,经度:lng

计算 用户经纬度 与 数据库中商家的经纬度 距离,由远及近进行排序

接下来,我们一起来用两种方案实现

实现方案一:

这种方案会比较挫,

理想模型计算阀值点

计算某个经纬度的周围某段距离的正方形的四个点

为什么这么计算,我给大家举个例子,如果我们把我们的地球仪中国区域直接摁平,是不是地球仪就灭有弧度了 ,我们理想方式就是在一定距离上这么计算的。计算代码如下

/**

* php代码

*计算某个经纬度的周围某段距离的正方形的四个点

*@param float $lng  经度

*@param float $lat  纬度

*@param float $distance  该点所在圆的半径,该圆与此正方形内切,默认值为5千米

*@return array 正方形的四个点的经纬度坐标

*/

function squarePoint($lat, $lng,$distance = 5.0){

$earth_radius = 6371;//地球半径

$dlng =  2 * asin(sin($distance / (2 * $earth_radius)) / cos(deg2rad($lat)));

$dlng = rad2deg($dlng);

$dlat = $distance/$earth_radius;

$dlat = rad2deg($dlat);

return [

'left-top'    =>['lat'=>$lat + $dlat, 'lng'=>$lng - $dlng],

'right-top'   =>['lat'=>$lat + $dlat, 'lng'=>$lng + $dlng],

'left-bottom' =>['lat'=>$lat - $dlat, 'lng'=>$lng - $dlng],

'right-bottom'=>['lat'=>$lat - $dlat, 'lng'=>$lng + $dlng],

];

}

取出用户指定距离的数据

根据上面的方法,我们计算出来了4个点,接下来我们直接从数据库取出符合条件的数据

$geo_data = squarePoint($lat,$lng,$distance);

$left_bottom =  $geo_data['left-bottom'];

$right_top = $geo_data['right-top'];

$lat_min = $left_bottom['lat'];

$lat_max = $right_top['lat'];

$lng_min = $left_bottom['lng'];

$lng_max = $right_top['lng'];

$sql = "SELECT * FROM table_name

WHERE lat > {$lat_min} lat  {$lng_min} and lng

按照距离远近排序

这个将 上面的符合条件的结果集取出来,在代码中排序,计算 两个经纬度之间距离的方法如下

/**

*

* 根据经纬度计算距离 单位(公里)

* @param  $lng1 float 经度1

* @param  $lat1 float 纬度2

* @param  $lng2 float 经度1

* @param  $lat2 float 纬度2

* @return float

*/

function getdistance($lng1,$lat1,$lng2,$lat2)

{

$dx = $lng1 - $lng2; // 经度差值

$dy = $lat1 - $lat2; // 纬度差值

$b = ($lat1 + $lat2) / 2.0; // 平均纬度

$Lx = deg2rad($dx) * cos(deg2rad($b)); // 东西距离

$Ly = deg2rad($dy); // 南北距离

return round(6371*sqrt($Lx * $Lx + $Ly * $Ly),4);  // 用平面的矩形对角距离公式计算总距离

}

按照方法一计算出来,基本问题不大,但是在数据量大(第二步结果集)到一定程度了是有很严重的效率问题的。这里给出一个衍生版本,直接计算距离

SELECT *,SQRT( POWER( $lat - lat, 2) + POWER($lng  - lng, 2) ) AS d

FROM table_name

WHERE (lat BETWEEN $lat_min AND $lat_max ) AND (lng BETWEEN $lng_min AND $lng_max ) AND d

ORDER BY d ASC LIMIT 10;

实现方案二

这个方法很快,直接可以SQL实现,由于数据库本身也支持很多函数的,我们直接在数据库本身计算就可以了。具体计算代码如下:

/**

* $lat:用户维度

* $lng:用户精度

* $as_name:查询出来的SQL字段名称

*/

get_distance_sql($lat,$lng,$as_name='distance')

{

return sprintf('round(6371*sqrt( pow((PI()*(abs(`lat`-%f))/180) * cos(PI()*(`lat`+%f)/360),2)

+ pow((PI()*abs(`lng`-%f)/180),2)),4) as %s',$lat,$lat,$lng,$as_name);

}

具体SQL如下:

/**

* shop_id 商家id

*/

$sql = "SELECT shop_id,lat,lng,".get_distance_sql( $lat,$lng)." FROM table_name

WHERE distance

这样就可以直接查出结果并排序了

结论

以上两种方案中,第二个是我我们当时使用的,我们当时数据库几十万,效率还可以。上百万乃至更高的需要大家去实现了

微信lbs开发 php,【LBS】基于地理位置的搜索之微信 附近的人 简单实现相关推荐

  1. Elasticsearch 基于地理位置的搜索查询

    ES为用户提供了基于地理位置的搜索功能.它主要支持两种类型的地理查询:一种是地理点(geo_point),即经纬度查询,另一种是地理形状查询(geo_shape),即支持点,线,圆形和多边形等查询. ...

  2. ElasticSearch之基于地理位置的搜索

    在某些时候,我们希望搜索到某个区域内的特定目标建筑物,或者说要查询某个城市某个区内的楼盘等,诸如此类的需求,还有我们看到的在百度地图或者高德地图上,在某个区域内显示出我们关心的数据,都可以算是一种基于 ...

  3. 【微信小程序AR】基于Kivicube零代码实现微信小程序AR

    话不多说,先看实现效果 作者之前尝试过Apple公司的ARkit.Google公司的ARCore以及国产的EasyAR和SenseAR.Apple公司和Google公司的AR产品是市面上的主流,功能非 ...

  4. java 微信转账 ca_error_C#关于微信红包开发问题:CA证书出错,请登录微信支付商户平台下载证书...

    看你的 MMC 的截图,是"个人", X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachin ...

  5. 【微信小程序】基于JavaScript的花店商城小程序微信云开发

    [微信小程序]基于JavaScript的花店商城小程序微信云开发 用Java Script语言进行一次微信小程序开发 文章目录 前言 一.功能总览 二.功能显示 1.搜索框 2.轮播图 3.主题导航栏 ...

  6. 微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示

    微信公众号开发系列-13.基于RDIFramework.NET框架整合微信开发应用效果展示 1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为 ...

  7. 微信接口开发-初级体验

    目录: 1. 微信接口的注册 2. 申请成为开发者 3. 申请测试账号 4. 获取access_token值 5. 调用接口 6. 自己编写程序 7. 总结 1. 微信接口的注册 进入到微信开发的官网 ...

  8. 微信红包 开发前的准备

    今天的开发目标是实现微信红包功能.先记录需要进行微信红包开发前的准备工作. 1.进行微信支付:需要注册认证的服务号或者认证的企业号 2.若要进行红包开发,前置准备条件 入住时间超过90天: 连续交易正 ...

  9. 微信企业号开发(6)--发送消息

    [本文所描述的内容具有一定的时效性,请以实际开发所处环境为准] 今天我们介绍我们日常使用最频繁的发送消息功能,在企业号中,由于移除了诸多的限制,消息的发送量几乎没有限制.但是,在此,特别提醒大家,千万 ...

最新文章

  1. java for 两个条件_for循环条件里定义2个变量为什么会报错
  2. python中删除对象方法的区别_python中delattr删除对象方法的代码分析
  3. MP4大文件虚拟HLS分片技术,避免服务器大量文件碎片
  4. Mac下Android studio 之NDK配置教程(二)
  5. java.两个例子充分阐述多态的可拓展性
  6. 章鱼扫描仪:Java构建工具和恶意软件
  7. oracle11 处理器数,11G AWR中%Total CPU与%Busy CPU指标的疑问
  8. idea 上传文件 java,IntelliJ IDEA如何上传和下载文件
  9. adb指令通过uid控制_图文教程:PC利用adb工具通过CMD命令控制手机动作(备忘笔记)...
  10. 学霸机器人“拼”高考 将成国内人工智能里程碑
  11. jQuery的Select操作集合
  12. [Java] 蓝桥杯BASIC-29 基础练习 高精度加法
  13. SQL Server 用SSMS查看依赖关系有时候不准确,改用代码查
  14. 汽车诊断协议,(K线/CAN总线、kwp2000、ISO14230、ISO1575...)转载
  15. rep( )函数--R语言
  16. 最新款电影程序源码 影院网站源码 在线采集多资源播放器去广告
  17. 折合分数的公式计算机,高考分数换算公式(高考分数折合怎么算)
  18. OCR通用文字识别接口
  19. yocto-poky下目录结构分析
  20. java的枚举类型是什么_什么是枚举(java枚举类型enum用法)

热门文章

  1. 给Sublime Text2安装GraphQL语法高亮插件
  2. 隐藏SAP CRM WebClient UI personalization 里某个field
  3. rxjs的一个例子:什么是rxjs的OperatorFunction?
  4. CRM product ID format相关配置
  5. SAP UI5是如何从浏览器读取语言设置并按照优先级排序的
  6. SAP移动解决方案之Cordova技术架构综述
  7. SAP CRM Contact和Account的从属关系
  8. SAP Cloud for Customer用ABSL消费Restful Mashup API
  9. 如何使用事务码SMICM分析ABAP代码发起的HTTP请求的错误
  10. java数据跑不出来,6000条数据,java下跑了20多分钟了还没跑完,求教怎么改进