【每天5分钟,了解一个知识点】
一、GeoHash 算法概述
GeoHash 是一种地址编码方法,它能够把二维的空间经纬度数据编码成一个字符串。其基本原理如下:
地球上的经度范围是[-180, 180],纬度范围是[-90, 90]。设定西经为负,南纬为负,以本初子午线、赤道为界,地球可分成 4 个部分。若纬度范围[-90°, 0°)用二进制 0 代表,(0°, 90°]用二进制 1 代表,经度范围[-180°, 0°)用二进制 0 代表,(0°, 180°]用二进制 1 代表,则地球被初步划分。通过在小块范围内递归对半划分,可以得到更多更精确的区域。GeoHash 算法就是基于这种思想,通过不断划分区域,使区域面积更小,从而实现对地理位置的分区。
GeoHash 算法的具体步骤如下:
将经纬度变成二进制:
以一个点(39.923201, 116.390705)为例,对于纬度 39.923201,在区间(0,90)中,得到一个 1;(0,90)区间的中间值为 45 度,纬度 39.923201 小于 45,得到一个 0,依次计算下去,可得到纬度的二进制表示为 10111000110001111001。
同理可得经度 116.390705 的二进制表示为 11010010110001000100。
将经纬度合并:
经度占偶数位,纬度占奇数位,得到 1110011101001000111100000011010101100001。
按照 Base32 进行编码:
先将合并后的二进制转换为十进制数据,然后对应生成 Base32 码。以 0 - 9、b - z(去掉 a, i, l, o)这 32 个字母进行编码,每 5 个二进制位转换成一个 base32 码。上例最终得到的值为 wx4g0ec1。
GeoHash 算法具有以下优点:
比直接用经纬度高效很多。
使用者可以发布地址编码,既能表明自己位于北海公园附近,又不至于暴露自己的精确坐标,有助于隐私保护。
用一个字符串表示经度和纬度两个坐标,在数据库中可以实现在一列上应用索引(某些情况下无法在两列上同时应用索引)。
GeoHash 表示的是一个矩形区域,其编码的前缀可以表示更大的区域,这个特性可用于附近地点搜索。
编码越长,表示的范围越小,位置也越精确,可以通过比较 GeoHash 匹配的位数来判断两个点之间的大概距离。
二、GeoHash 算法存在的问题及解决方案
(一)边缘问题
问题描述:如图所示,如果车在红点位置,区域内还有一个黄点。相邻区域内的绿点明显离红点更近。但因为黄点的编码和红点一样,最终找到的将是黄点。
解决方案:只要再查找周边 8 个区域内的点,看哪个离自己更近即可。
方案优缺点:
优点:简单有效,能够解决边缘问题,提高查询的准确性。
缺点:增加了查询的范围和复杂度,可能会降低查询效率。
(二)曲线突变问题
问题描述:例如 0111 和 1000 两个编码非常相近,但它们的实际距离确很远。所以编码相近的两个单位,并不一定真实距离很近。
解决方案:实际计算两个点的距离。
方案优缺点:
优点:能够准确地确定两个点之间的实际距离,避免因编码相近而产生的误判。
缺点:计算两个点的距离需要一定的计算资源和时间,可能会降低查询效率。
【关联阅读】




