是一种地址编码、能把二维的经纬度编码成一维的字符串。

有以下几个特点:

  1. 用一个字符串表示经度和纬度两个坐标。某些情况下无法在两列上同时应用索引,利用 Geohash,只需在一列上应用索引即可。
  2. Geohash 表示的并不是一个点,而是一个矩形区域。
  3. 编码的前缀可以表示更大的区域。例如 wx4g0ec1,前缀 wx4g0e 表示包含编码 wx4g0ec1 在内的更大范围。这个特性可以用于附近地点搜索。

Geohash 的算法

算法的主要思想是对某一数字通过二分法进行无限逼近。

下面以(39.92324, 116.3906)为例,介绍一下Geohash的编码算法。首先将纬度范围(–90, 90)平分成两个区间(–90, 0)、(0, 90), 如果目标纬度位于前一个区间,则编码为0,否则编码为1。由于39.92324属于(0, 90),所以取编码为1。然后再将(0, 90)分成 (0, 45), (45, 90)两个区间,而39.92324位于(0, 45),所以编码为0。以此类推,直到精度符合要求为止,得到纬度编码为1011 1000 1100 0111 1001。

img

经度也用同样的算法,对(–180, 180)依次细分,得到116.3906的编码为1101 0010 1100 0100 0100。

经度范围 划分区间0 划分区间1 116.3906所属区间img接下来将经度和纬度的编码合并,奇数位是纬度,偶数位是经度。得到编码 11100 11101 00100 01111 00000 01101 01011 00001。

最后,用0–9,b-z(去掉 a,i,l,o)这32个数字进行 base32编码,得到(39.92324, 116.3906)的编码为wx4g0ec1。img

Base32简介

将5个 ASCII 字符编码转为8个 Base32 字符,对二进制来说就是把40个二进制位,编码成8个 Base32 字符。

Java版:github wiki介绍:Geohash