使用Redis存储和使用地理空间数据

2023-11-14

目录

让我们回到地理空间数据。什么是Geohash?

Redis如何存储地理空间数据?

用于处理地理空间数据的命令

通过地理空间数据读取和搜索呢?

结论


众所周知,处理地理空间数据非常困难,因为纬度和经度是浮点数,应该非常精确。此外,纬度和经度似乎可以表示为网格,但实际上它们不能,仅仅是因为地球不是平的,数学是一门复杂的科学。在本文中,我们将了解Redis如何帮助我们在处理地理空间数据时最大限度地减少计算。

众所周知,处理地理空间数据非常困难,因为纬度和经度是浮点数,应该非常精确。此外,纬度和经度似乎可以表示为网格,但实际上它们不能,仅仅是因为地球不是平坦的,数学很难。

例如,要根据球体上的两点之间的纬度和经度确定大圆的距离,请使用哈弗正弦公式,如下所示:

与纬度和经度相关的另一个常见任务是查找地球表面半径内的点数。也就是说,给定一个大球(地球),并且您正在尝试找到该球半径内的点。但地球,其实不是一个完美的球体,它仍然是一个椭球体。正如您可能猜到的那样,此类操作的数学计算变得非常复杂。

在本文中,我们将了解Redis如何帮助我们在处理地理空间数据时最大限度地减少计算。

Redis,代表远程字典服务器,是一个快速的开源键值数据存储。由于其速度,Redis是缓存、会话管理、游戏、分析、地理空间数据等的热门选择。

让我们回到地理空间数据。什么是Geohash

Geohash是一个将坐标表示为字符串的系统。Geohash使用Base32编码将纬度和经度转换为字符串。例如,圣彼得堡宫殿广场的Geohash将如下所示:udtscze2chgq。可变Geohash长度表示可变位置精度,换句话说,Geohash越短,它表示的坐标越不精确。也就是说,较短的Geohash将表示相同的地理位置,但准确性较低。您可以尝试在http://geohash.org 上在Geohash中编码坐标。

Redis如何存储地理空间数据?

地理空间数据存储在Redis中使用排序列表(ZSET)作为底层数据结构实现,但对位置数据以及新的API进行动态编码和解码。这意味着使用内置命令:GEOADDGEODISTGEORADIUSGEORADIUSBYMEMBERGEOSEARCH可以将按特定位置的索引,搜索和排序以最少的代码行和最少的工作量投入到Redis中。

Geo Set是在Redis中处理地理空间数据的基础——它是一种旨在管理地理空间索引的数据结构。每个地理集由一个或多个元素组成,每个元素由一个唯一标识符和一对坐标(经度和纬度)组成。

用于处理地理空间数据的命令

要在Redis存储中添加新列表(或向现有列表添加新元素),请使用GEOADD命令。为了清楚起见,我将给出Redis中的命令示例,以及Ruby客户端中用于使用Redis的示例:

# Redis example:
GEOADD "buses" -74.00020246342898 40.717855101298305 "Bus A"

# Ruby example:
RedisClient.geoadd("buses", -74.00020246342898, 40.717855101298305, "Bus A")   

这些命令将总线总线A”的位置坐标添加到名为总线的地理集。如果具有此名称的地理集尚未存储在Redis中,则将创建该地理集。仅当列表中尚不存在同名条目(总线A”)时,才会将新条目添加到索引中。也就是说,总线A是唯一标识符。

也可以通过一次GEOADD调用一次添加多个记录,这有助于减少网络和数据库负载。记录ID必须是唯一的:

# Redis example:
GEOADD "buses" -74.00020246342898 40.717855101298305 
"Bus A" -73.99472237472686 40.725856700515855 "Bus B"

# Ruby example:
RedisClient.geoadd("buses", -74.00020246342898, 40.717855101298305, "Bus A",
                           -73.99472237472686, 40.725856700515855, "Bus B")

相同的命令用于更新记录的索引。如果GEOADD调用时带有Geo Set中已经存在的条目,Redis只是更新这些条目的数据,只要总线A开始移动,它的位置就可以更新:

# Redis example:
GEOADD "buses" -76.99265963484487 38.87275545298483 "Bus A"

# Ruby example:
RedisClient.geoadd("buses", -76.99265963484487, 38.87275545298483, "Bus A")   

除了添加和更新之外,当然还可以从索引中删除条目。提供ZREM命令以从Redis中的地理集中删除条目。ZREM采用要从中删除记录的索引的名称和要删除的记录的ID

# Redis example:
ZREM buses "Bus A" "Bus B"

# Ruby example:
RedisClient.zrem("buses", "Bis A", "Bus B")

地理索引可以完全删除,并且由于它存储为Redis密钥,因此可以使用以下DEL命令:

# Redis example:
DEL buses

# Ruby example:
RedisClient.del("buses")

但是,为大列表使用DEL可能是一个坏主意,因为它可以长时间阻止Redis。因此,最好始终使用UNLINK而不是DEL非阻塞删除:

# Redis example:
UNLINK buses

# Ruby example:
RedisClient.unlink("buses")

请记住,Redis具有索引过期的机制,如果您不指定索引的过期日期,那么它将永远不会过期并且会占用内存。为了防止这种情况发生,您需要使用以下EXPIRE命令,传递索引的名称和过期的秒数:

# Redis example:
EXPIRE buses 1000

# Ruby example:
RedisClient.expire("buses", 1000)

Redis采用半延迟过期机制,这意味着索引直到不被读取才过期,如果事实证明读取操作过程中过期时间已经过去了,那么结果不会返回,对象本身也会从存储中删除。也就是说,在我们请求地理集之前,它将无限期地存储在内存中。

但是,Redis具有第二个过期级别——它是主动和随机的。它是一个随机读取不同密钥的垃圾回收器,当读取密钥时,将发生检查过期的标准机制。

遗憾的是,Redis无法直接使索引中的记录过期。这样的功能必须独立开发。

通过地理空间数据读取和搜索呢?

有几种方法可以从索引中读取条目。您可以使用ZRANGEZSCAN命令开始。这些命令循环访问索引中的所有条目。例如,要返回索引中的所有条目:

# Redis example:
ZRANGE buses 0 -1

# Ruby example:
RedisClient.zrange("buses", 0, -1)

对于地理空间数据,有两个命令可以从索引中获取条目的位置。第一个——GEOPOS命令返回索引中条目的坐标:

# Redis example:
GEOPOS buses "Bus A"

# Ruby example:
RedisClient.geopos("buses", "Bus A")

第二个命令——GEOHASH返回在Geohash中编码的条目的坐标:

# Redis example:
GEOHASH buses "Bus A"

# Ruby example:
RedisClient.geohash("buses", "Bus A")

要获取索引中两个条目之间的距离,可以使用以下GEODIST命令:

# Redis example:
GEODIST buses "Bus A" "Bus B"

# Ruby example:
RedisClient.geodist("buses", "Bus A", "Bus B", "km")

默认情况下,命令的结果将以米为单位返回。您可以通过将第四个参数传递给命令来指定所需的度量单位,例如:公里表示公里,m表示米,mi——表示英里,ft——表示英尺。

要搜索索引,还使用了GEORADIUSGEORADIUSBYMEMBER(对于低于6.2Redis版本)或GEOSEARCH(对于低于6.2的版本)命令。

GEORADIUSGEORADIUSBYMEMBER接受参数WITHDIST(显示结果 + 与指定点/记录的距离)和WITHCOORD(显示结果 + 记录坐标),以及ASCDESC排序选项(按与点的距离排序): 

# Redis example:
GEORADIUS buses -73 40 200 km WITHDIST

# returns:
1) 1) "Bus A"
  2) "190.4424"
2) 1) "Bus B"
  2) "56.4413"

GEORADIUS buses -73 40 200 km WITHCOORD

# returns:
1) 1) "Bus A"
  2) 1) "-74.00020246342898"
     2) "40.717855101298305"
2) 1) "Bus B"
  2) 1) "-73.99472237472686
     2) "40.725856700515855"

GEORADIUS buses -73 40 200 km WITHDIST WITHCOORD

# returns:
1) 1) "Bus A"
  2) "190.4424"
  3) 1) "-74.00020246342898"
     2) "40.717855101298305"
2) 1) "Bus B"
  2) "56.4413"
  3) 1) "-73.99472237472686
     2) "40.725856700515855"

# Redis example:
GEORADIUSBYMEMBER buses "Bus A" 100 km

# returns:
1) "Bus B"

# Ruby example:
RedisClient.georadiusbymember("buses", "Bus A", 100, "km")

新版本RedisGEOSEARCH命令具有类似的语法并执行相同的操作。命令语法如下所示:

# Redis examples:
GEOSEARCH buses FROMMEMBER "Bus A" BYRADIUS 100 km ASC WITHCOORD WITHDIST WITHHASH
# returns all entries in 100km radius from Bus A with coordinates, 
# distances and geohashes

GEOSEARCH buses FROMLONLAT -74.00020246342898 40.717855101298305" 
BYRADIUS 200 mi DESC COUNT 2
# returns maximum 2 entries sorted from the farest to the closest within 
# 200 miles from the center
# with given coordinates 

结论

Redis中使用地理空间数据实现位置应用程序的简单性不仅可以轻松处理大量地理空间数据,还允许您对数据进行一些复杂的处理。例如,查询半径内的条目可以帮助您实现对附近兴趣点的搜索,方法是仅为用户提供最接近的兴趣点的选项。如果您的应用程序以任何方式使用地理空间数据,请考虑将复杂的计算移动到Redis,这可能会提高应用程序的效率。

https://www.codeproject.com/Articles/5337573/Using-Redis-for-Storing-and-Working-with-Geospatia

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Redis存储和使用地理空间数据 的相关文章

随机推荐

  • java List集合转Excel表格文档

    前阵子有朋友问我java将excel转成文档的方法 用此方法需要引入jxl包 而最近公司刚好有个需求需要将数据转成excel文档 所以我就写了一个工具类 将数据对象转成excel文档 考虑到可能要传入不同类型的对象集合 为了能配合我那个朋友
  • java编写机器人_用JAVA编写自己的机器人一起“厮杀”

    什么是Robocode 最近我在阅读一个关于极限编程 XP 的邮件列表 有人提议为对学习更多的XP方法学知识感兴趣的开发人员构建一个工作间 这位作者还建议 把一群人凑到一起 分成小组研究该方法学 然后要有一个经验丰富的XP教练对工作间进行管
  • Oracle导入导出数据库(exp/imp和expdp/impdp的区别)

    Oracle导入导出数据库 exp imp和expdp impdp的区别 目录索引 1 exp和expdp的区别 2 expdp导出数据库流程 一 exp和expdp的区别 1 exp和expdp最明显的区别就是导出速度的不同 expdp导
  • libevent介绍

    libevent介绍 1 事件驱动 高性能 轻量级 专注于网络 2 源代码精炼 易读 3 跨平台 4 支持多种I O多路复用技术 如epoll select poll等 5 支持I O和信号等事件 libevent的安装 登录官方网站 ht
  • ORA-00923: 未找到要求的 FROM 关键字

    ORA 00923 未找到要求的 FROM 关键字 注意 别名不能是数字和使用
  • ps长阴影插件_PS插件Long Shadow Generator 安装步骤

    软件 下载 软件名称 Long Shadow Generator 软件大小 536KB 软件语言 简体中文 系统要求 Win10 Win8 Win7 支持版本 PS CC 2015及以上版本 下载链接 https pan baidu com
  • DSP和RAM的区别

    DSP顾名思义就是数字信号处理 厂家主要是德州仪器 TI 主要用于数字型号处理等对运算速度有特殊要求的场合 诸如音频视频算法 军工等领域 但同时dsp有2000 5000 6000等系列也可满足不场合需要 ARM 是一类内核的称谓 就像51
  • HOOK与注入

    HOOK和注入技术经常被恶意代码使用 利用HOOK和注入技术 恶意代码提高了执行隐蔽性 增加了恶意代码分析难度 在某些情况下还能实现权限提升和内存常驻 HOOK技术 挂钩 HOOK 就是在来往信息间安装 钩子 钩取来往信息 在用户层 常见的
  • Canoe 安装流程

    硬件 VN5620 软件 CANoe V15 0 软件 Vector License Client 6 2 驱动 Vector Driver Setup license 购买硬件时 vector会分配 参考文档 First Steps to
  • 理想方波的频谱

    1 理想方波的频谱 时域到频域 理想方波为频率1G 50 占空比 幅度为1v 上升时间为0 把理想方波通过离散傅里叶变换 DFT 就可以知道各个频率分量的幅度 如下图所示 偶次谐波如2G 4G 6G 8G 的幅度都为零 奇次谐波有如下关系式
  • 概率论--数学期望与方差--协方差(详解)

    目录 数学期望与方差 离散型随机变量的数学期望 注意 连续型随机变量的数学期望 方差 常用随机变量服从的分布 二项分布 正态分布 随机向量与随机变量的独立性 随机向量 随机变量的独立性 协方差 协方差的定义 协方差的意义 协方差矩阵 数学期
  • 软件工程专业学生的自我反思

    迷茫时的反思 我现在是一名大三的学生 有时候还是会处在一种很迷茫的状态 这种状态体现在 自己会不自觉的打开王者荣耀 打开BiliBili刷视频 熬夜看剧 慢慢地陷入一个漩涡 越陷越深 你是否经常对自己的行为感到怀疑 对自己做的事感到后悔 那
  • 关于“由于找不到MSVCP140.dll,无法继续执行代码,重新安装程序可能会解决此问题等”解决方案

    首先说明一下该问题 该问题就是表示你们的操作系统中现在确实一些必要的文件 具体是啥我也不是很清楚 然后 你现在要安装的这个软件正好要调用这些文件的一些函数 就可以简单理解为使用这些文件 需要你去安装一下这些文件 解决方案 首先 你自己去从一
  • unity点乘和叉乘的使用

    本文从http blog csdn net yupu56 article details 53609028转载而来 Unity当中经常会用到向量的运算来计算目标的方位 朝向 角度等相关数据 下面咱们来通过实例学习下Unity当中最常用的点乘
  • 星星之火-38:20M的LTE带宽,为什么是1200个子载波?

    先给个结论 在LTE中 单个小区最大的频谱带宽为20M 每个子载波的间隔为15K 带宽为30K 一共可以分为1200个子载波 那这个数据是怎么来得呢 1 15K子载波间隔的由来 如果子载波的带宽30K 那么按照频分复用FDM的规则 频谱利用
  • 春招,进阿里了....

    个人背景是东北某 985 科班本硕 做的 测试开发 有两个自己写的小项目 下面是一些印象比较深刻的面试题 阿里一面 什么是软件测试 软件测试过程中会面向哪些群体 开发一个软件都要经过哪些阶段 什么是黑盒测试 什么是白盒测试 一个测试工程师应
  • 招聘小程序制作:连接人才与企业

    随着人才市场的竞争日益激烈 招聘小程序成为了企业寻找优秀人才和求职者找到理想工作的重要工具 通过招聘小程序 企业可以发布招聘信息 筛选简历 而求职者可以浏览职位 提交简历等 招聘小程序的好处 精准匹配人才 招聘小程序通过智能推荐算法分析求职
  • 2018最新area.json(智行火车票)

    ids 5876 level 1 level4Useing name 广东省 names 广东省 notvalid pid 0 tid 5876 ids 5876 6131 level 2 level4Useing name 东莞市 nam
  • SpringBoot中搭建thymeleaf网页遇到Cannot resolve MVC View ‘###‘的问题

    原因是配置文件pom xml中thymeleaf版本与springBoot版本有冲突 要引入的thymeleaf依赖是这个
  • 使用Redis存储和使用地理空间数据

    目录 让我们回到地理空间数据 什么是Geohash Redis如何存储地理空间数据 用于处理地理空间数据的命令 通过地理空间数据读取和搜索呢 结论 众所周知 处理地理空间数据非常困难 因为纬度和经度是浮点数 应该非常精确 此外 纬度和经度似