当前位置: 首页 > ai >正文

Redis GEO 52 位整数的经纬分布

文章目录

      • Geohash 编码的位排列规则
      • 编码过程原理(源码解析)
      • 为什么采用交错存储?
      • 解码过程
      • 精度说明

在 Redis 的 GEO 实现中,经度和纬度的编码方式是 交错存储而不是分离存储的。在 52 位的 Geohash 编码中,经度(longitude)和纬度(latitude)的比特位是 交替排列的,而不是物理上分开的区块。

具体结构如下:

Geohash 编码的位排列规则

位位置(从最高位开始)012345051
对应坐标经度纬度经度纬度经度经度纬度
  • 偶数索引位(0,2,4,…,50):存储经度信息(共 26 位)
  • 奇数索引位(1,3,5,…,51):存储纬度信息(共 26 位)

编码过程原理(源码解析)

Redis 的 Geohash 编码实现在 geohash.c 文件中,核心逻辑在 geohashEncode() 函数中:

// redis/src/geohash.c
void geohashEncode(...) {// ...for (i = 0; i < step; i++) {double lat_offset, lng_offset;uint64_t bits = 0;// 交替处理经度和纬度if (i % 2 == 0) {// 偶数位:处理经度lng_offset = (lng_range[0] + lng_range[1]) / 2;if (longitude >= lng_offset) {bits |= 1;lng_range[0] = lng_offset;} else {lng_range[1] = lng_offset;}} else {// 奇数位:处理纬度lat_offset = (lat_range[0] + lat_range[1]) / 2;if (latitude >= lat_offset) {bits |= 1;lat_range[0] = lat_offset;} else {lat_range[1] = lat_offset;}}hash->bits = (hash->bits << 1) | bits;}
}

为什么采用交错存储?

  1. 空间局部性保留
    • 经纬度交错排列保持了地理位置的连续性
    • 相邻地理位置的 Geohash 值会有更长的公共前缀(临界特性)
  2. 范围查询优化
// redis/src/geo.c
void georadiusGetAreasByShape(geoRange *r) {// 范围查询时会自动对齐Z阶曲线geohashBoundingBox(r->longitude, r->latitude, r->radius);
}

这种排列使得经度/纬度联合查询可以直接通过位操作实现

  1. 与Z阶曲线的兼容
    交错存储本质上实现了莫顿码(Morton Code),将二维坐标映射到一维曲线时能最小化空间跳跃

解码过程

当需要反向获取坐标时,Redis 会分离这些位:

// redis/src/geohash.c
int decodeGeohash(uint64_t bits, double *xy) {double lat_range[] = {-90, 90};double lng_range[] = {-180, 180};// 交替处理52位for (int i = 51; i >= 0; i--) {uint64_t bit = (bits >> i) & 1;if (i % 2 == 0) { // 经度位double mid = (lng_range[0] + lng_range[1]) / 2;if (bit) lng_range[0] = mid;else lng_range[1] = mid;} else { // 纬度位double mid = (lat_range[0] + lat_range[1]) / 2;if (bit) lat_range[0] = mid;else lat_range[1] = mid;}}xy[0] = (lng_range[0] + lng_range[1]) / 2;xy[1] = (lat_range[0] + lat_range[1]) / 2;
}

精度说明

坐标轴比特位数理论精度
经度26 bits约 0.0000429° (赤道约 4.78m)
纬度26 bits约 0.0000215° (约 2.39m)

这种交错编码方式虽然增加了编解码的复杂性,但使 Redis 的 GEO 查询性能达到了 O(log N) 的优异水平,是空间与时间的完美平衡。

http://www.xdnf.cn/news/13361.html

相关文章:

  • 【基于阿里云上Ubantu(x86-64)系统部署配置K8s】
  • Docker环境安装Kafka、Flink、ClickHouse镜像
  • 海外打车代驾app评价系统框架搭建
  • 获取RadioButton的text,更换textview的text
  • C++笔记-C++11(二)
  • 【Unity优化】提高热更新和打包速度
  • Centos与RockLinux设置静态ip
  • 数据库管理与高可用-PostgreSQL日常维护
  • MongoDB入门指南:环境安装与基本操作
  • QGIS新手教程4:相交、缓冲区与合并操作详解(含实战案例)
  • 多头与空头:市场博弈的两面
  • 【2025最新】Adobe Illustrator下载保姆级安装教程(附官方下载链接)
  • ThinkPad 交换 Ctrl 键和 Fn 键
  • Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘xxx’)
  • RK3588开发笔记-GNSS-RTK模块调试
  • YOLO-World 部署踩坑记录
  • Linux611 libvirtb ;FTP vsftpd.conf部分配置文件
  • React 元素的生命周期
  • 从硬件视角审视Web3安全:CertiK CTO主持Proof of Talk圆桌论坛
  • GO 入门小项目-博客-结合Gin Gorm
  • 【面板数据】中国与世界各国农产品进出口贸易数据(2015-2024年)
  • 国内外数据要素标准有何不同?
  • K8S项目需求分析
  • 火山引擎发布豆包大模型 1.6 与视频生成模型 Seedance 1.0 pro
  • ABP vNext + Spark on Hadoop:实时流处理与微服务融合
  • 嵌入式学习笔记 - C语言访问地址的方式,以及指针的进一步理解
  • JMeter 处理 UTF-16 转 UTF-8 乱码问题解决方案(deepseek)
  • AnythingLLM配置Milvus后,上传文档提示向量数据库标识符错误的解决办法
  • 鹰盾Win播放器作为专业的视频安全解决方案,除了硬件翻录外还有什么呢?
  • 微信小程序分享带参数地址