什么是 Geohash 编码?

简介: Geohash编码将经纬度转换为字符串,通过不断二分地球坐标区间,交叉合并经纬编码,再转为Base32简化表示。它用短字符串标识位置,支持高效空间索引与查询,广泛应用于Redis、MySQL等系统。

说到这,你可能会有疑问了,在实际工作中,用户对应的都是实际的地理位置坐标,那它和二维空间的区域编码又是怎么联系起来的呢?别着急,我们慢慢说。

实际上,我们会将地球看作是一个大的二维空间,那经纬度就是水平和垂直的两个切分方向。在给出一个用户的经纬度坐标之后,我们通过对地球的经纬度区间不断二分,就能得到这个用户所属的区域编码了。这么说可能比较抽象,我来举个例子。

我们知道,地球的纬度区间是[-90,90],经度是[-180,180]。如果给出的用户纬度(垂直方向)坐标是 39.983429,经度(水平方向)坐标是 116.490273,那我们求这个用户所属的区域编码的过程,就可以总结为 3 步:

  1. 在纬度方向上,第一次二分,39.983429 在[0,90]之间,[0,90]属于空间的上半边,因此我们得到编码 1。然后在[0,90]这个空间上,第二次二分,39.983429 在[0,45]之间,[0,45]属于区间的下半边,因此我们得到编码 0。两次划分之后,我们得到的编码就是 10。
  2. 在经度方向上,第一次二分,116.490273 在[0,180]之间,[0,180]属于空间的右半边,因此我们得到编码 1。然后在[0,180]这个空间上,第二次二分,116.490273 在[90,180]之间,[90,180]还是属于区间的右半边,因此我们得到的编码还是 1。两次划分之后,我们得到的编码就是 11。
  3. 我们把纬度的编码和经度的编码交叉组合起来,先是经度,再是纬度。这样就构成了区域编码,区域编码为 1110。

你会发现,在上面的例子中,我们只二分了两次。实际上,如果区域划分的粒度非常细,我们就要持续、多次二分。而每多二分一次,我们就需要增加一个比特位来表示编码。如果经度和纬度各二分 15 次的话,那我们就需要 30 个比特位来表示一个位置的编码。那上面例子中的编码就会是 11100 11101 00100 01111 00110 11110。

这样得到的编码会特别长,那为了简化编码的表示,我们可以以 5 个比特位为一个单位,把长编码转为 base32 编码,最终得到的就是 wx4g6y。这样 30 个比特位,我们只需要用 6 个字符就可以表示了。

这样做不仅存储会更简单,而且具有相同前缀的区域属于同一个大区域,看起来也非常直观。这种将经纬度坐标转换为字符串的编码方式,就叫作 Geohash 编码。大多数应用都会使用 Geohash 编码进行地理位置的表示,以及在很多系统中,比如,Redis、MySQL 以及 Elastic Search 中,也都支持 Geohash 数据的存储和查询。

那在实际转换的过程中,由于不同长度的 Geohash 代表不同大小的覆盖区域,因此我们可以结合 GeoHash 字符长度和覆盖区域对照表,根据自己的应用需要选择合适的 Geohash 编码长度。这个对照表让我们在使用 Geohash 编码的时候方便很多。

不过,Geohash 编码也有缺点。由于 Geohash 编码的一个字符就代表了 5 个比特位,因此每当字符长度变化一个单位,区域的覆盖度变化跨度就是 32 倍(2^5),这会导致区域范围划分不够精细。

因此,当发现粒度划分不符合自己应用的需求时,我们其实可以将 Geohash 编码转换回二进制编码的表示方式。这样,编码长度变化的单位就是 1 个比特位了,区域覆盖度变化跨度就是 2 倍,我们就可以更灵活地调整自己期望的区域覆盖度了。实际上,在许多系统的底层实现中,虽然都支持以字符串形式输入 Geohash 编码,但是在内存中的存储和计算都是以二进制的方式来进行的。

相关文章
|
前端开发 JavaScript Java
酒店管理|基于Springboot+Vue前后端分离实现酒店管理系统
酒店管理|基于Springboot+Vue前后端分离实现酒店管理系统
705 52
|
1月前
|
人工智能 PHP Android开发
PHP 现在可以零成本构建原生 iOS 和 Android 应用 NativePHP for Mobile v3 发布
NativePHP for Mobile v3(即NativePHP Air)正式发布!核心框架MIT协议免费开源,Laravel开发者可零成本构建原生iOS/Android应用。全新插件化架构,按需加载功能;内置Jump真机即时调试、Mimi AI辅助编码,PHP≥8.3即可快速上手。(239字)
343 1
PHP 现在可以零成本构建原生 iOS 和 Android 应用 NativePHP for Mobile v3 发布
|
7月前
|
存储 Java 数据库
如何开发人事及OA管理系统的会议管理板块?(附架构图+流程图+代码参考)
人事及OA系统是现代企业管理的重要工具,整合人力资源与办公流程,提升效率。其会议管理板块可优化会议室预约、冲突检测、审批流程及数据统计,助力企业高效协作。本文详解功能设计、开发技巧与实现方案。
|
6月前
|
Java 开发工具
JDK多版本设置并且切换
本文介绍了如何在不卸载旧版本的前提下,配置并切换多个JDK版本。通过统一安装路径、设置环境变量(如JAVA_HOME、JAVA_HOME8、JAVA_HOME17),并调整系统PATH顺序,实现快速切换。最终通过CMD和开发工具验证切换是否生效。
JDK多版本设置并且切换
|
10月前
|
机器学习/深度学习 自然语言处理 数据可视化
⼤模型驱动的DeepInsight Copilot在蚂蚁的技术实践
本文整理自潘兰天(蚂蚁数据智能团队数据分析平台技术专家)在DA数智大会2025·上海站的演讲实录。
|
XML Java 数据安全/隐私保护
企业微信接收回调
企业微信接收回调
837 0
|
12月前
|
Java 调度
ThreadPoolExecutor解析
本文深入解析了Java中`ThreadPoolExecutor`的实现原理,帮助理解线程池的工作机制。核心内容包括任务队列`workQueue`、线程工厂`ThreadFactory`、拒绝策略`RejectedExecutionHandler`等关键成员的作用。通过`submit`和`execute`方法的执行流程,展示了线程池如何根据`corePoolSize`和`maximumPoolSize`动态调整线程数量,并结合`keepAliveTime`管理空闲线程。最后分析了`Worker`类的`run`方法,揭示线程池通过循环从队列中获取任务并执行的核心逻辑。
330 0
|
IDE Java 开发工具
python缩进错误(IndentationError)
【7月更文挑战第12天】
2950 10
|
机器学习/深度学习 数据采集 存储
使用Python实现智能农业灌溉系统的深度学习模型
使用Python实现智能农业灌溉系统的深度学习模型
925 6

热门文章

最新文章