geohash:附近坐标点的查询

637 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

geohash

geohash可以解决什么问题

GeoHash是一种地址编码方法,他能够把二维的空间经纬度数据编码成一个字符串。

可以解决范围搜索的问题。现在又很多APP都有搜索附近的功能,比如附近的人,附近的店。

geohash的表示

geohash由经度和维度,通过运算,base32转换,组合成的一个字符串。一个geohash表示的是一个区域,而不是一个点。

geohash值的计算

(39.923201, 116.390705)为例子

  1. 经度转换计算。(纬度范围[-90,90])

    首先将纬度范围(-90, 90)平分成两个区间(-90, 0)、(0, 90),如果目标纬度位于前一个区间,则编码为0,否则编码为1。

    将区间二分,第一次分为[-90,0]和(0,90]。39.923201在右区间,得到编码1,

    继续二分,区间为[0,45],(45,90],39.923201在左区间,得到编码0,

    继续二分,区间为[0,23.5],(23.5,45],39.923201在右区间,得到编码1,

    以此多次划分,划分次数越多,越精确。

    细分了16次后,得到字符串1011 1000 1100 0111

  2. 纬度转换计算。(经度范围[-180,180])

​ 定义临时变量log存储计算的字符。

​ 将区间二分,第一次分为[-180,0]和(0,180]。116.390705在右区间,得到编码1,

​ 继续二分,区间为[0,90],(90,180],116.390705在右区间,得到编码1,

​ 继续二分,区间为[90,135],(135,180],116.390705在左区间,得到编码0,

​ 以此多次划分,划分次数越多,越精确。

​ 细分了16次后,得到字符串1101 0010 1100 0100,转为10进制为

  1. 组合后转base32

    两个字符串组合,基数位是纬度,偶数位是经度,得到组合后的32位字符串11100 11101 00100 01111 00000 01101 01011 00001四个位为一个字符,转为十进制然后按base32编码表转换,得到结果为:wx4g0ec1

base32.png

这个字符串的意义

这个字符串的两个部分都是通过区间逐渐逼近得到的一个结果,字符越往前部分区间越大,包括的范围越大。对于两个坐标geohash来说,如果前缀匹配的位数越多,那么就说明两个坐标越相近。

网上找到一张表,标明了字符串位数与偏差的几组对于关系

2.jpg

如何查询坐标附近的其他坐标呢?

  1. 先计算坐标点geohash

  2. 根据业务需要精确到几位。通过左缀匹配模糊查询即可

    select * from table_name where geohash like 'wx4g0%';

参考文献

github.com/CloudSide/g…

zhuanlan.zhihu.com/p/75480946