地理位置检索服务在日常生活中随处可见,小到共享单车、高德地图,大到飞行航线轨迹。上述服务中很多相关功能都可以通过GeoHash来实现,Lucene/Solr中也有应用到GeoHash,通过GeoHash创建索引、查询索引以及距离的计算等等。
GeoHash算法本质上是空间索引的一种方式。我们可以将整个地球设想为一个二维平面,将地球上所有区域展开平铺之后通过递归分解将该平面切分为32个模块。之后再将其中的模块再进行分块,随着范围不断缩小,位置精度也越来越高。每个分块都由一定的标识来表示该块。而地球上所有经纬度坐标都会通过GeoHash算法转变为一个唯一的base32标识,该标识对应上述分块的标识,一层一层的确定分块位置,最终便可通过标识找到具体的地理位置。
首先贴出base32编码表:
对于给定的一组经纬度数据(116.389550, 39.928167),使用二分法无限逼近。对纬度39.928167进行编码:
1)区间[-90,0),[0,90],39.928167在右区间内,取1;
2)区间 [0,45),[45,90],39.928167在左区间内,取0;
3)区间 [0,22.5),[22.5,45],39.928167在右区间内,取1;
4)不断递归进行二分拆解,慢慢缩小范围(最多缩小13次)...
5)最终纬度编码为1 1 0 1 0 0 1 0 1 1 0 0 0 1 0;
对经度116.389550做上述操作,可得经度编码1 0 1 1 1 0 0 0 1 1 0 0 0 1 1。
得到经纬度的二进制位后需要对其进行合并。奇数位取纬度,偶数位取经度,每次取其二进制位的一位(不足为取0),最终合并成一个新的二进制串:
11100 11101 00100 01111 0000 01101
每5位为一个10进制数,换算过来为28、29、4、15,0,13 。通过换算过来的