基于LBS的地理位置附近的搜索以及由近及远的排序


Nosql学习之Redis资料(一)php

http://redis.io/downloadhtml

 

目前基于LBS地理位置的搜索已经应用很是广了,的确是个很方便的东西。html5

咱们作程序的就是要考虑如何经过这些功能,来作出更符合用户的内容来。git

1,如何获取位置

例如微信,能够经过发送地理位置来获取到当前用户的经纬度。查看redis

在网页端,可使用html5获取地理定位。查看sql

2,数据表设计

数据库中要预存本身的位置数据,如何获取数据请查看相关地图api。数据库

字段:十进制数的纬度 latitude FLOAT(10,6) 十进制数的经度 longitude FLOAT(10,6)api

假设咱们数据库中已经存储大量酒店的位置信息缓存

3,根据用户位置查询附近

如上图,假设当前用户所在的位置为坐标O,那么咱们要查询附近的酒店,理想的范围应该是以O为原点的圆内,可是咱们先不这样作,后面会讲到。微信

咱们先以O为原点,在坐标上以0.3的差值标识了4个位置,其实这样就是一个正方形范围,大体应该符合咱们的要求。

那么咱们就要从数据库中查询范围在这个正方形以内的全部酒店了。

一,获取到用户的经纬度坐标:

$latitude;$longitude

  

二,定义一个差值,设置经度和纬度的范围:

$i = 0.3; //差值可自定义,值越大,范围就越大
$min_latitude = $latitude - $i; //纬度最小值
$max_latitude = $latitude + $i; //纬度最大值
$min_longitude = $longitude - $i; //经度最小值
$max_longitude = $longitude + $i; //经度最大值

  

三,数据库中查询在这个范围以内的酒店:

SELECT * FROM table WHERE (latitude BETWEEN $min_latitude AND $max_latitude) AND (longitude BETWEEN $min_longitude AND $max_longitude);

  

这样咱们的附近搜索基本完成了

四,以地理位置由远及近的排序:

若是咱们要筛选出最近的10个的话,用上面的语句来查询,可能会把稍远的先查出来,后面的就没有机会了,那么咱们得作个排序了。

如上图,若是咱们要获取E位置和F位置分别距离O点的长度,那么咱们就须要计算OE和OF的长度分别为多少,这里咱们要用到直角三角形的数学公式:C^2 = A^2 + B^2,知道A和B,那么C的值也就获得了。

注意:请首先在表中创建一个字段d,以做后面缓存距离使用,不然会报错

咱们能够根据经纬度的差分别来获取到A和B的值,SQL语句是这样的:

SELECT *,SQRT(POWER($latitude - latitude, 2) + POWER($longitude  - longitude, 2)) AS d FROM table WHERE (latitude BETWEEN $min_latitude AND $max_latitude) AND (longitude BETWEEN $min_longitude AND $max_longitude) AND d < $i ORDER BY d ASC LIMIT 10;

  

SQRT(X):求X的平方根,POWER(X, Y):求X的Y次方

经过这样一步,咱们的范围已经锁定在圆形以内了,而且按照由近及远的方式进行排序(在不考虑效率的状况下)。

相关文章
相关标签/搜索