水煮Redisson(二三)- GEO之地球一维化

前言

上一章介绍了Redisson地图索引接口的使用方式,这里介绍一下Geo内核-GeoHash的原理。

简单来说,GeoHash将三维的地球模型抽象成一维数据,每个节点代表了一个矩形区域,方便计算附近节点集合和相应的距离。

地球一维化

第一步:将地球二维化,并划分为32个大区域

第二步:细化矩形区域,每个节点代表一个小区域,并不断递归,矩形越小位置越精确

GeoHash用一个字符串表示经度和纬度两个坐标

拿一个地址举例说明【经纬度:33.762,38.465】,将经度和纬度两个数值,在下表中不断二分取值,最终会得到一串二进制编码。

经度

纬度

得到经纬度的二进制编码之后,将奇数为纬度,偶数为经度 进行整合,五位一组,返回0-31的十进制数据。

11001 -> 十进制为25,对应Base32为T

01110 -> 十进制为14,对应Base32为F
最终得到的GeoHash码为:tf

Base32编码参照,使用ezs42方案,丢弃ailo四个字母

GeoHash的精度问题

Geohash比直接用经纬度的高效很多,而且使用者可以发布地址编码,既能表明自己位于北海公园附近,又不至于暴露自己的精确坐标,有助于隐私保护。

GeoHash编码的前缀可以表示更大的区域。例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围,这个特性可以用于附近地点搜索。编码越长,表示的范围越小,位置也越精确。因此我们就可以通过比较GeoHash匹配的位数来判断两个点之间的大概距离。

GeoHash每个精度对应的矩形大小

前面例子得到的GeoHash码为tf,长度为2,那么其代表的矩形区域范围为1250KM * 625KM

GeoHash的长度对应的地理位置误差范围

前面例子得到的GeoHash码为tf,长度为2,其误差大概为630KM。

应用上的一些问题

GeoHash在使用过程中,会碰到一些实际问题,下面列举两个最常见的。

边缘问题

要计算黄点附近最近的目标,如果按区域来算的话,蓝点在同一个区域,数学上更接近,但是在图中可以直观的看出,绿点在物理上与其距离更小。

曲线突变

曲线突变问题比较直观,拿上面的一个图来展示

0111区块和1000在数学上更接近,只相差1,但是在物理上其实与0010距离更小。

解决方案

上面两个问题,可以用同一种方案来解决,就是计算自身位置附近8个区域内,所有候选目标与自己的实际距离,最后再决定展示效果。至于如何获取这8个区域的GeoHash值,可以直接修改自身GeoHash的最后一位或者两位,因为都是相邻区域,GeoHash是有规律可循的。

相关推荐
蛋蛋的就会顺顺的5 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
需要8265 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡5 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
骇客野人6 小时前
在麒麟操作系统上 分别安装 jdk1.8, 达梦数据库,redis ,memcache 的操作实施方案和步骤
数据库·redis·memcached
伯恩bourne7 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
silvamux_8 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
省钱兄--zs8 小时前
深圳24小时自助健身房软硬件解决方案实战指南与开发流程详解
java·数据仓库·spring boot·小程序·架构
顽疲8 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
用户21296835261689 小时前
开源了一个 Java 多智能体 LLM 框架 Baton:一个依赖,把 Agent 循环、工具调用、记忆、编排全配齐
java·llm