目前基于LBS地理位置的搜索已经应用非常广了,的确是个很方便的东西。
我们做程序的就是要考虑如何通过这些功能,来做出更符合用户的内容来。
1,如何获取位置
例如微信,可以通过发送地理位置来获取到当前用户的经纬度。查看
在网页端,可以使用html5获取地理定位。查看
2,数据表设计
数据库中要预存自己的位置数据,如何获取数据请查看相关地图api。
字段:十进制数的纬度 latitude FLOAT(10,6) 十进制数的经度 longitude FLOAT(10,6)
假设我们数据库中已经存储大量酒店的位置信息
3,根据用户位置查询附近
如上图,假设当前用户所在的位置为坐标O,那么我们要查询附近的酒店,理想的范围应该是以O为原点的圆内,但是我们先不这样做,后面会讲到。
我们先以O为原点,在坐标上以0.3的差值标识了4个位置,其实这样就是一个正方形范围,大致应该符合我们的要求。
那么我们就要从数据库中查询范围在这个正方形之内的所有酒店了。
1 |
|
1 2 3 4 5 |
|
1 |
|
这样我们的附近搜索基本完成了
如果我们要筛选出最近的10个的话,用上面的语句来查询,可能会把稍远的先查出来,后面的就没有机会了,那么我们得做个排序了。
如上图,如果我们要获取E位置和F位置分别距离O点的长度,那么我们就需要计算OE和OF的长度分别为多少,这里我们要用到直角三角形的数学公式:C^2 = A^2 + B^2,知道A和B,那么C的值也就得到了。
注意:请首先在表中建立一个字段d,以作后面缓存距离使用,否则会报错
我们可以根据经纬度的差分别来获取到A和B的值,SQL语句是这样的:
1 |
|
SQRT(X):求X的平方根,POWER(X, Y):求X的Y次方
通过这样一步,我们的范围已经锁定在圆形之内了,并且按照由近及远的方式进行排序(在不考虑效率的情况下)。
经纬度小数点后与精确到米的误差
如下表所示
赤道周长(米) 度数(度)
40076000 360
111322.2222 1
11132.22222 0.1
1113.222222 0.01
111.3222222 0.001
11.13222222 0.0001
1.113222222 0.00001
0.111322222 0.000001
0.011132222 0.0000001
所以,只需要精确到小数点后7位,精度就是1CM,因此,数据库保存经纬度采用 decimal(10,7) 即可。
问题1:为什么不采用float?
答:float,double容易产生误差,对精确度要求比较高时,建议使用decimal来存,decimal在mysql内存是以字符串存储的,
问题2:为什么不用字符串?
答:字符串不方便数据库计算
如下表所示
赤道周长(米) 度数(度)
40076000 360
111322.2222 1
11132.22222 0.1
1113.222222 0.01
111.3222222 0.001
11.13222222 0.0001
1.113222222 0.00001
0.111322222 0.000001
0.011132222 0.0000001
所以,只需要精确到小数点后7位,精度就是1CM,因此,数据库保存经纬度采用 decimal(10,7) 即可。
问题1:为什么不采用float?
答:float,double容易产生误差,对精确度要求比较高时,建议使用decimal来存,decimal在mysql内存是以字符串存储的,
问题2:为什么不用字符串?
答:字符串不方便数据库计算