在数字化时代,地理位置信息的处理变得尤为重要。为了高效、准确地表示和查询地理位置,Geohash(经纬度哈希)应运而生。作为一种创新的地理位置编码方式,Geohash由Gustavo Niemeyer和G.M. Morton在2008年发明,它将二维的经纬度坐标转换为一串具有特定长度的字符串,极大地简化了地理位置的存储、传输和查询过程。
一句话概括就是:将经纬度采用二分法计算,划分找出0、1区间,计算后的值按照偶位放精度,奇位放纬度进行合并,合并之后的值转化为十进制,找到对应的base32编码的值,即为geohash值。
Geohash是地理编码系统,它将地球表面细分为矩形区域,并将每个单元编码为字母和数字的短串。它是一种分层数据结构,因此geohash字符串越长,地理位置就越精确。如果需要手动将地理坐标转换为geohash字符串,可以使用geohash.org。
一. 基本原理
Geohash是一种算法,能够将地球表面的任意位置通过一串字符来表示。这些字符组成的字符串最长可达12位,每增加一位字符,其表示的地理位置范围就越小,精度就越高。例如,当Geohash为12位时,它可以表示一个大约37毫米范围内的区域,而6位Geohash则对应一个约1.2公里宽的矩形区域。
我们知道,经度范围是东经180到西经180,纬度范围是南纬90到北纬90,我们设定西经为负,南纬为负,所以地球上的经度范围就是[-180, 180],纬度范围就是[-90,90]。如果以本初子午线、赤道为界,地球可以分成4个部分。
(1) 按照经度范围[-180°,180°],纬度范围[-90°,90°]对目标经纬度进行计算;二分经度和纬度范围区间,分别判断经度和纬度,在右侧集合则为1,在左侧集合则为0;循环进行此计算。
(2)将所得经纬度1和0结果,经度在偶数位(从0位计算),纬度在奇数位进行拼接,5位二进制结果为 一组,转换为十进制数后,再转换为对应Base32码表中数字,即得到对应GeoHash值。
二. 编码和解码
Geohash的编码过程是将经度和纬度值进行指定精度的划分,然后将每个划分结果编码为一位字符,最后合并所有字符得到Geohash字符串。解码过程则是通过字符串的每一位字符,逐步缩小范围,最终确定对应的经纬度坐标。
以经纬度值:(116.389550,39.924015)进行算法说明,对纬度39.924015进行逼近编码 (地球纬度区间是[-90,90])
区间[-90,90]进行二分为[-90,0),[0,90],称为左右区间,可以确定39.928167属于右区间[0,90],给标记为1
接着将区间[0,90]进行二分为 [0,45),[45,90],可以确定39.924015属于左区间 [0,45),给标记为0
递归上述过程39.928167总是属于某个区间[a,b]。随着每次迭代区间[a,b]总在缩小,并越来越逼近39.924015
如果给定的纬度x(39.924015)属于左区间,则记录0,如果属于右区间则记录1,序列的长度跟给定的区间划分次数有关,如下图;
同理,地球经度区间是[-180,180],可以对经度116.389550进行编码。通过上述计算,纬度产生的编码为1 1 0 1 0 0 1 0 1 1 0 0 0 1 0,经度产生的编码为1 0 1 1 1 0 0 0 1 1 0 0 0 1 1
合并:偶数位放经度,奇数位放纬度,把2串编码组合生成新串如下图:
将11100 11101 00100 01111 0000 01101五五为一组,转成十进制,对应着28、29、4、15,0,13 十进制对应的base32编码就是wx4g0e,如下
同理,将编码转换成经纬度的解码算法与之相反。
三. 精度说明
GeoHash使用5位计算结果(左右区间)作为一个精度,例如 wx4g0e共有6个Base32编码表的字母或数字,代表这个geoHash值的精度为6,GeoHash值越长,代表其精度越高。
四. GeoHash算法的特点
紧凑性:Geohash编码可以将经纬度坐标表示为较短的字符串,极大地节省了存储空间。
可排序性:Geohash编码的字符串可以按照字典序进行排序,这方便了范围查询和邻近搜索。
精度可控性:通过调整Geohash字符串的长度,可以控制其表示的地理位置精度,满足不同场景的需求。
邻近搜索:由于经纬度相近的地点,其Geohash字符串前缀相似,因此可以通过前缀匹配快速找到邻近的位置。
GeoHash用一个字符串表示经度和纬度两个坐标。在数据库中可以实现在一列上应用索引(某些情况下无法在两列上同时应用索引)
GeoHash表示的并不是一个点,而是一个矩形区域。
GeoHash编码的前缀可以表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。 这个特性可以用于附近地点搜索。
编码越长,表示的范围越小,位置也越精确。因此我们就可以通过比较GeoHash匹配的位数来判断两个点之间的大概距离。下表编码长度的误差:
五、Geohash的应用场景
Geohash在多个领域得到了广泛应用,包括但不限于:
位置搜索:通过Geohash编码,可以快速搜索附近的位置,如附近的商家、朋友等。
地理围栏:Geohash编码可用于表示地理围栏的范围,如电子围栏、地理推送等。
地理数据聚合:大量地理数据可以通过Geohash编码进行聚合和统计,生成热力图、地理分布图等。
缓存优化:在缓存系统中,可以使用Geohash作为key,将具有相同或相近地理位置的数据缓存在一起,提高缓存的命中率。
六、Geohash的局限性与解决方案
尽管Geohash具有诸多优势,但也存在一些局限性,如边界问题和突变性问题。边界问题指的是,在实际距离上相近的地点,其Geohash编码可能相差较远;突变性问题则是指在某些特定区域,相邻的Geohash编码可能相差很大。
为了解决这些问题,可以采用将附近8个Geohash考虑进去的方法,即在查询时不仅考虑目标位置的Geohash,还考虑其周围相邻的Geohash,以提高查询的准确性和可靠性。
七、总结
Geohash作为一种创新的地理位置编码方式,以其紧凑性、可排序性和精度可控性,在多个领域得到了广泛应用。它不仅简化了地理位置的存储和传输过程,还提高了位置搜索和邻近查询的效率。随着技术的不断发展,Geohash有望在更多领域发挥重要作用,为我们的生活带来更多便利。