GeoHash简介

参考文档:html

 

http://blog.csdn.net/wangxiafghj/article/details/9014363geohash  算法原理及实现方式
http://blog.charlee.li/geohash-intro/  geohash:用字符串实现附近地点搜索
http://blog.sina.com.cn/s/blog_7c05385f0101eofb.html    查找附近点--Geohash方案讨论
http://www.wubiao.info/372        查找附近的xxx 球面距离以及Geohash方案探讨
http://en.wikipedia.org/wiki/Haversine_formula       Haversine formula球面距离公式
http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe   球面距离公式代码实现
http://developer.baidu.com/map/jsdemo.htm#a6_1   球面距离公式验证  
http://www.wubiao.info/470     Mysql or Mongodb LBS快速实现方案算法

 

如今不少APP都有搜索附近的功能,好比附近的人、附近的店铺等。要实现这样的功能,咱们能够用最笨的方法:根据经纬度计算距离,而后划定一个阈值,只要小于该阈值就算是附近的。这种方法在数据量小时基本没问题,可是,若是数据量特别大,那服务器就须要进行大量的计算,负担很重!为了解决这一类问题,一个比较经常使用的方法就是利用GeoHash。 
1、简介 
GeoHash是一种地址编码方法。他可以把二维的空间经纬度数据编码成一个字符串。GeoHash具备如下特色: 
一、GeoHash用一个字符串表示经度和纬度两个坐标。在数据库中能够实如今一列上应用索引 
二、GeoHash表示的并非一个点,而是一个区域; 
三、GeoHash编码的前缀能够表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。 这个特性能够用于附近地点搜索 
2、计算方法: 
GeoHash的计算过程分为三步: 
一、将经纬度转换成二进制: 
好比这样一个点(39.923201, 116.390705) 
纬度的范围是(-90,90),其中间值为0。对于纬度39.923201,在区间(0,90)中,所以获得一个1;(0,90)区间的中间值为45度,纬度39.923201小于45,所以获得一个0,依次计算下去,便可获得纬度的二进制表示,以下表: 
这里写图片描述 
最后获得纬度的二进制表示为: 
10111000110001111001 
同理能够获得经度116.390705的二进制表示为: 
11010010110001000100 
二、合并纬度、经度的二进制: 
合并方法是将经度、纬度二进制按照奇偶位合并: 
11100 11101 00100 01111 00000 01101 01011 00001 
三、按照Base32进行编码: 
Base32编码表(其中一种): 
这里写图片描述
将上述合并后二进制编码后结果为: 
wx4g0ec1 
3、GeoHash的精度 
这里写图片描述
编码越长,表示的范围越小,位置也越精确。所以咱们就能够经过比较GeoHash匹配的位数来判断两个点之间的大概距离。 
4、不足之处及解决方法 
一、边缘附近的点,黄色的点要比黑色的点更加靠近红点,可是因为黑点跟红点的GeoHash前缀匹配数目更多,所以获得黑点更加靠近红点的结果 
这里写图片描述 
解决方法: 
能够经过筛选周围8个区域内的全部点,而后计算距离获得知足条件结果。 
二、由于现有的GeoHash算法使用的是Peano空间填充曲线(可感兴趣的可本身查看),这种曲线会产生突变,形成了编码虽然类似但距离可能相差很大的问题,所以在查询附近的时候,首先筛选GeoHash编码类似的点,而后进行实际距离计算。sql

相关文章
相关标签/搜索