Redis使用Geo存储经纬度

Redis GEO 功能解析 Redis GEO 是 Redis 数据库提供的一个强大的地理位置信息处理功能。通过一系列的命令,Redis GEO 可以轻松地存储、查询和计算地理位置信息,适用于多种实际应用场景。尽管 Redis GEO 有一些限制,但它的性能和易用性使其成为处理地理位置信息的优秀选择。 阅读详情



Geo原理简单介绍

GeoHash 算法将 二维的经纬度 数据映射到 一维 的整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算 「附近的人时」,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。

它的核心思想就是把整个地球看成是一个 二维的平面,然后把这个平面不断地等分成一个一个小的方格,每一个 坐标元素都位于其中的 唯一一个方格 中,等分之后的 方格越小,那么坐标也就 越精确。

Redis 的 Geo 数据结构,它们将 全部放在一个 zset 集合中。在 Redis 的集群环境中,集合可能会从一个节点迁移到另一个节点,如果单个 key 的数据过大,会对集群的迁移工作造成较大的影响,在集群环境中单个 key 对应的数据量不宜超过 1M,否则会导致集群迁移出现卡顿现象,影响线上服务的正常运行。

所以,这里建议 Geo 的数据使用 单独的 Redis 实例部署,不使用集群环境,如果数据量过亿甚至更大,就需要对 Geo 数据进行拆分,按国家拆分、按省拆分,按市拆分。

Geo常用方法讲解:

这里使用的是spring boot项目。了解如何在spring boot中使用Redis.

add方法:添加地理位置坐标

Point point = new Point(112.24292267773436, 30.337854070185536);//使用point定位经纬度
GeoLocation<String> geo = new GeoLocation<String>("荆州", point);
opsForGeo.add(key, geo);

point = new Point(111.28711213085936, 30.688053698037617);
opsForGeo.add(key, point, "宜昌");

Map<String,Point> memberCoordinateMap = new HashMap<String, Point>();
memberCoordinateMap.put("武汉", new Point(114.29736603710936, 30.59352961254808));
memberCoordinateMap.put("襄阳", new Point(112.12207306835936, 32.00160906017225));
memberCoordinateMap.put("荆门", new Point(112.216009,31.027841));
opsForGeo.add(key, memberCoordinateMap);

pos方法:给定的 key 里返回所有指定名称(member)的位置(经度和纬度)

List<Point> position = opsForGeo.position(key, "荆州","宜昌");
position.forEach(System.out::println);

//dist方法:计算两个位置之间的距离。
Distance distance = opsForGeo.distance(key, "荆州", "宜昌",RedisGeoCommands.DistanceUnit.KILOMETERS);
System.out.println("荆州与宜昌的距离:"+distance.getValue()+"KM");


radius方法:根据给定的位置名称来获取指定范围内的地理位置集合。

GeoRadiusCommandArgs geoRadiusCommandArgs = GeoRadiusCommandArgs.newGeoRadiusArgs()
        .sortAscending()// 排序
        .limit(3)// 输出元素的个数
        .includeCoordinates()// 输出经纬度
        .includeDistance();// 距离
// 封装距离参数
distance = new Distance(100d, RedisGeoCommands.DistanceUnit.KILOMETERS);
GeoResults<GeoLocation<String>> radius = opsForGeo.radius(key, "荆州", distance, geoRadiusCommandArgs);
radius.getContent().forEach(s -> System.out.println("名称:" + s.getContent().getName() + "  经纬度:" + s.getContent().getPoint() + "  距离:" + s.getDistance()));

radius方法:根据给定的经纬度坐标来获取指定范围内的地理位置集合。

point = new Point(111.28711213085936, 30.688053698037617);
Circle circle = new Circle(new Point(112.24292267773436, 30.337854070185536), distance);
GeoResults<GeoLocation<String>> radius2 = opsForGeo.radius(key, circle,geoRadiusCommandArgs);
radius2.getContent().forEach(s -> System.out.println("名称:" + s.getContent().getName() + "  经纬度:" + s.getContent().getPoint() + "  距离:" + s.getDistance()));

hash方法:获取位置的hash值

List<String> hash = opsForGeo.hash(key, "荆州","宜昌");
hash.forEach(System.out::println);

完整的demo

/**
	 * GeoHash 算法将 二维的经纬度 数据映射到 一维 的整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。
	 * 当我们想要计算 「附近的人时」,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。
	 * 参考:https://www.it610.com/article/1288713480500748288.htm
	 * @描述:
	 * @作者:严磊
	 * @时间:2020年11月25日 下午11:11:15
	 */
	public void GeoHash(){
		String key = "湖北";
		GeoOperations<String, String> opsForGeo = redisTemplate.opsForGeo();
		
		//add方法:添加地理位置坐标
		Point point = new Point(112.24292267773436, 30.337854070185536);//使用point定位经纬度
		GeoLocation<String> geo = new GeoLocation<String>("荆州", point);
		opsForGeo.add(key, geo);
		
		point = new Point(111.28711213085936, 30.688053698037617);
		opsForGeo.add(key, point, "宜昌");
		
		Map<String,Point> memberCoordinateMap = new HashMap<String, Point>();
		memberCoordinateMap.put("武汉", new Point(114.29736603710936, 30.59352961254808));
		memberCoordinateMap.put("襄阳", new Point(112.12207306835936, 32.00160906017225));
		memberCoordinateMap.put("荆门", new Point(112.216009,31.027841));
		opsForGeo.add(key, memberCoordinateMap);
		
		//pos方法:给定的 key 里返回所有指定名称(member)的位置(经度和纬度)
		List<Point> position = opsForGeo.position(key, "荆州","宜昌");
		position.forEach(System.out::println);
		
		//dist方法:计算两个位置之间的距离。
		Distance distance = opsForGeo.distance(key, "荆州", "宜昌",RedisGeoCommands.DistanceUnit.KILOMETERS);
		System.out.println("荆州与宜昌的距离:"+distance.getValue()+"KM");
		
		//radius方法:根据给定的位置名称来获取指定范围内的地理位置集合。
	    GeoRadiusCommandArgs geoRadiusCommandArgs = GeoRadiusCommandArgs.newGeoRadiusArgs()
	            .sortAscending()// 排序
	            .limit(3)// 输出元素的个数
	            .includeCoordinates()// 输出经纬度
	            .includeDistance();// 距离
	    // 封装距离参数
	    distance = new Distance(100d, RedisGeoCommands.DistanceUnit.KILOMETERS);
	    GeoResults<GeoLocation<String>> radius = opsForGeo.radius(key, "荆州", distance, geoRadiusCommandArgs);
	    radius.getContent().forEach(s -> System.out.println("名称:" + s.getContent().getName() + "  经纬度:" + s.getContent().getPoint() + "  距离:" + s.getDistance()));
	    
	    //radius方法:根据给定的经纬度坐标来获取指定范围内的地理位置集合。
	    point = new Point(111.28711213085936, 30.688053698037617);
	    Circle circle = new Circle(new Point(112.24292267773436, 30.337854070185536), distance);
	    GeoResults<GeoLocation<String>> radius2 = opsForGeo.radius(key, circle,geoRadiusCommandArgs);
	    radius2.getContent().forEach(s -> System.out.println("名称:" + s.getContent().getName() + "  经纬度:" + s.getContent().getPoint() + "  距离:" + s.getDistance()));
	    
	    //hash方法:获取位置的hash值
	    List<String> hash = opsForGeo.hash(key, "荆州","宜昌");
	    hash.forEach(System.out::println);
	    
	}

参考: https://www.it610.com/article/1288713480500748288.html.

【Redis7】10大数据类型之GEO类型 GEO数据类型非常适合需要处理地图、定位服务或者任何与地理位置相关的应用程序,比如餐饮外卖服务的门店定位、出行应用中的路线规划等场景。Redis的GEO(地理空间)数据类型是一种特殊的数据结构,用于存储地理位置信息并执行地理位置相关的操作。由于这里的数据比很少,示例效果不太好.大家明白熟悉命令就行.感兴趣的话,可以自己去添加一些数据.:将地理位置的坐标转化为一个唯一的字符串编码(GeoHash),这有助于快速索引和查询。:查询指定位置周围的地点,基于给定的最大距离(半径)。 阅读详情

相关推荐

Redis --- 使用GEO实现经纬度距离计算

Spring Boot 项目中可以通过 Spring Data Redis 来使用 Redis GEO 功能,主要通过 RedisTemplate 和 GeoOperations 接口来操作地理位置数据。

记得开心一点嘛的博客 1158

Redis Geospatial地理位置

Redis 在 3.2 推出 Geo 类型,该功能可以推算出地理位置信息,两地之间的距离。 文档:https://www.redis.net.cn/order/3687.html 只有六个命令 geoadd:添加地理位置的坐标。 geopos:获取地理位置的坐标。 geodist:计算两个位置之间的距离。 georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。 georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。 geohash:返回一

MW 801

Android开发Intent详解

本文详解Android开发Intent。

qq_30725967的博客 2414

redis GEO 类型原理及命令详解

我们有一个需求是用户搜索附近的店铺,就是所谓的位置信息服务(Location-Based Service,LBS)的应用。这样的相关服务我们每天都在接触,用滴滴打车,中午去美团订外卖等等。当我们用这些服务方便我们的生活的时候,大家有没有想过是怎么实现的。目前市场上很多软件比如Es,Redis 都提供了类似的功能,他们底层都是用的GeoHash 编码,只不过底层的数据结构不同。今天主要讲的是Redis 的 Geo 如何实现这个功能。

擅长后端研发 5131

避开这些坑!STM32H750 IAP升级实战:从Bootloader设计到APP接收的完整避坑指南

本文深入探讨STM32H750 IAP升级的完整避坑指南,从Bootloader设计到APP接收的全流程实践。特别针对QSPI Flash运行限制、SRAM跳转机制和固件校验等核心问题,提供工业级解决方案,帮助开发者提升升级成功率和系统稳定性。

weixin_30471561的博客 275

用workbuddy自定义Skill:手把手搭建AI炒股分析助手

AI Agent正成为个人投资研究的重要工具,而Skill作为行为规范,能让AI输出保持稳定与专业。在AI Agent应用中,很多人分不清Skill与Agent的区别:Agent负责目标拆解与执行,Skill则固化分析流程与输出模板。借助本地工作台workbuddy,用户可自定义Skill,实现从市场环境检查到财务排雷的五段式分析。通过调低温度参数、设定数据验证规则,该方案能有效避免大模型凭空编造数据,帮助个人投资者快速完成基本面体检、资金面观察与风险清单生成。本文基于一套可直接套用的配置与一个月实测,展示

weixin_29038537的博客 520

redis 使用geo来存储地理经纬度信息

geo geo用于地理信息 没有删除api type类型是zset geoadd key longitude latitude element… 添加key 经纬度坐标和地名 geopos key element … 获取地名的经纬度 geodist key element element [unit] 获取两个地名的距离,unit可以是千米,米等单位 georadius key longitude latitude … 使用

大头讲架构的博客 776

TPS65987D USB PD控制器:从原理到实战的完整设计指南

USB PD(Power Delivery)协议是USB Type-C接口实现高功率快充和数据传输的核心技术标准。其工作原理基于CC(Configuration Channel)引脚的双相标记编码(BMC)通信,通过协商电压和电流,实现高达100W的功率传输。这项技术的核心价值在于统一了充电标准,简化了设备间的互操作性,广泛应用于笔记本电脑、移动电源、扩展坞等设备。TPS65987D作为一款高度集成的USB PD控制器,将复杂的协议处理、电源路径管理和多重保护电路集成于单芯片,显著降低了设计复杂度。通过其可

weixin_30983965的博客 338

一篇文章搞懂Redis Geo:地理位置存储与距离计算的底层原理

Redis 的 Geo 模块用于存储和查询地理位置信息(如经纬度坐标),其核心原理结合了 ​有序集合(ZSET)​​ 和 ​Geohash 编码,并通过 ​Haversine 公式​ 计算球面距离。本文从存储结构、编码方式和距离计算三个方面详细解析其原理。

weixin_42148384的博客 1488

github创建账号第一步始终出错

github创建账号总结:第一次注册GitHub,填好用户名邮箱密码后进入下一步就卡在哪里,上面还提示Unable to verify your captcha response等,进入网址的解决办法以及下载其他的浏览器也无法解决,用手机浏览器抱着试一试的心态竟然成功了,分享给大家。手机下载谷歌浏览器,进入GitHub正常注册,能向下继续,邮箱验证完以后再用电脑登陆就ok啦

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 4376

软件需求规格说明书(SRS)标准模板

《软件需求规格说明书(SRS)框架解析》摘要: 本文档系统阐述了SRS的标准结构,包含7大核心部分:1)引言(目的、背景和术语);2)总体描述(产品定位与用户特征);3)功能需求(模块化功能说明);4)非功能需求(性能、安全等指标);5)接口需求(用户/硬件/软件接口);6)其他技术要求;7)附录(图表与参考资料)。重点突出了功能需求模块的标准化描述模板(FR-01),以及安全需求中的HTTPS通信、SHA-256加密等关键指标。该框架为软件开发提供了明确的需求基准,涵盖从业务背景到技术实现的完整链条,是确

moton2017的博客 2886

Redis GEO 底层实现(结合源码分析)

Redis GEO功能通过Sorted Set存储地理位置数据,其中经纬度经Geohash编码为52位整数作为score。纬度范围被限制在[-85°,85°],以避免极地区域Geohash编码失效和投影变形问题。底层实现上,GEO命令最终调用zset操作,如GEOADD对应zadd,并利用Geohash算法计算位置范围。这种设计兼顾了查询效率和地理计算的准确性。

NeoLshu的博客 1030

在 SAP 里玩转 FTP:标准程序 RSFTP00x 全景解析与落地实践

摘要:SAP系统通过封装的标准FTP程序(RSFTP001-008)提供便捷的文件传输能力,适用于各类集成场景。关键点包括:1)依赖SAPFTP可执行程序和RFC目的地;2)使用RSFTP005进行前置检查并生成RFC配置;3)标准报表各司其职,如RSFTP002用于命令测试、RSFTP007/008提供参考实现;4)开发时组合FTP_CONNECT/COMMAND/DISCONNECT等函数模块。特别注意前台(SAPFTP)与后台(SAPFTPA)的环境差异,这是常见故障点。该方案通过标准化工具链显著降低

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 210

Redis系列:Geo 类型赋能亿级地图位置计算

我们在篇深刻理解高性能Redis的本质动态字符串(REDIS_STRING):整数(REDIS_ENCODING_INT)、字符串(REDIS_ENCODING_RAW)双端列表(REDIS_ENCODING_LINKEDLIST)压缩列表(REDIS_ENCODING_ZIPLIST)跳跃表(REDIS_ENCODING_SKIPLIST)哈希表(REDIS_HASH)整数集合(REDIS_ENCODING_INTSET)

Ly768768的博客 1603

UNet + Shuffle Attention:一种轻量高效的医学图像分割注意力机制

本文提出了一种轻量高效的医学图像分割方法,将Shuffle Attention模块嵌入UNet的上采样路径中。Shuffle Attention通过通道分组注意力机制增强关键特征,同时保持计算轻量化。该方法在上采样后应用注意力模块,有效融合高层语义与低层细节,计算开销小且易于部署。实验表明,该模型在保持UNet原有优势的基础上,通过注意力机制提升了特征聚焦能力,适用于多种图像分割任务。未来可进一步结合空间注意力或Transformer模块以增强模型性能。

Henry的博客 240

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

php reids的geo功能,php使用redis的GEO地理信息类型

redis3.2中增中了对GEO类型的支持,该类型存储经纬度,提供了经纬设置,查询,范围查询,距离查询,经纬度hash等操作。$redis = new Redis();$redis->connect(‘127.0.0.1‘, 6379, 60);$redis->auth(‘‘);//添加成员的经纬度信息$redis->rawCommand(‘geoadd‘, ‘citys‘, ‘...

weixin_35882650的博客 339

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Redis GEO使用

Redis GEO使用【地理位置计算】

王文萱的博客 1337

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

附近零工岗位怎么找?我用了 Redis GEO,5 公里内秒出结果

本文分享了零工平台“附近5公里岗位”查询的优化实践:从慢速的MySQL经纬度计算,升级为基于Redis GEO的高效方案。通过将岗位坐标存入Redis GEO(仅存ID),查询时按半径快速筛选并返回距离排序的结果,结合城市分片与异步更新机制,实现毫秒级响应。关键踩坑点包括:避免序列化对象、同步删除下架岗位、注意经纬度顺序、版本控制防重复灌入。最终系统稳定在5ms内完成查询,显著提升用户体验。

yzb20082009的专栏 251

如何在项目当中使用redis进行范围搜索

Redis GEO 本质上是在 Redis 中保存地理位置数据(使用经纬度 + key + member 的形式),然后通过。这是一个 Redis 的 Key,表示你所有帖子位置都保存在这个 key 下的 GEO 类型中。这是搜索的“附加参数”,你可以在里面设置返回什么信息、是否排序、返回几个等。→ Redis GEO 中的 member(这里是帖子 ID),“我现在的位置是 (经度, 纬度),请查我附近的 member”这是 Redis 中用于保存 GEO 数据的键名(key)

gege_0606的博客 1256

PHP 加Redis 根据经纬度实现附近的人查询功能

1、业务需求:用户信息存储经纬度,根据某个经纬度查询附近的人,已圆为中心,可根据距离从近到远排序。 2、使用技术:php,redis geo(geoadd,georadius) 3、相关文档:http://redisdoc.com/geo/georadius.html 实现: <?php /** * @author * @since */ header("Content-ty...

༺墨༒眉༻ 908

Redis——GeoHash

方格越 小,坐标越精确。我们知道,经度范围是东经180到西经180,纬度范围是南纬90到北纬90,我们设定西经为负,南纬为负,所以地球上的经度范围就是[-180, 180],纬度范围就是[-90,90]。这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点。命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。

吴声子夜歌的博客 1223

Redis的GEO的使用以及应用场景

在日常生活中,我们越来越依赖搜索“附近的餐馆”、在打车软件上叫车,这些都离不开基于位置信息服务(Location-Based Service,LBS)的应用。LBS 应用访问的数据是和人或物关联的一组经纬度信息,而且要能查询相邻的经纬度范围,GEO 就非常适合应用在 LBS 服务的场景中。其实这个服务用es也可以做,但是学习以及维护成本太高了,因此我们使用Redis来做。

qq_61039408的博客 798

php redis 根据经纬度 计算当前用户附近店铺信息

php redis 根据经纬度 计算当前用户附近店铺信息 1.redis 版本:Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能了 2.Redis GEO实现主要包含了以下两项技术: 2.1、使用geohash保存地理位置的坐标。 2.2、使用有序集合(zset)保存地理位置的集合。 3.gaoadd 添加 经纬度 到 数据集 redis> GEOADD redis_key 经

m0_37678007的博客 943

Redis - Redis GEO实现经纬度测算距离,附近搜索范围

Redis主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。

MinggeQingchun的博客 4525

图解Redis 08 | GEO数据类型的原理及应用场景

在我们的日常生活中,我们越来越依赖于位置服务(Location-Based Service, LBS),例如查找附近的商场、餐厅,或者在出行时使用打车软件。这些服务都离不开精确的地理位置信息。LBS应用主要是根据目标人物或物体相关的一组经纬度等地理位置信息,然后根据这些经纬度数据查询目标附近的位置。Redis GEO 就是专门用于存储和操作地理位置信息的数据类型,它是 Redis 3.2 版本新增的功能,提供了高效的方式来处理和查询这些地理位置信息。

大厂小码农的博客 1745

Redis(十一) -- Redis数据结构(八) -- Geo

简介 GEO,geographic的缩写,即地理信息。该类型,就是元素的二维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度hash等操作。 两极无法添加,一般会下载城市数据,直接通过java程序一次性导入。 有效的经度从-180°到180°。有效的纬度从-85.05112878°到85.05112878°。 当坐标位置超出指定范围时,该命令会返回一个错误。 已经添加的数据,无法再次添加。 原理,工作方式 这些数据将会存储到sorted set这样的目的

weixin_39724194的博客 1076
上一篇: mybatis常用知识点笔记
下一篇: Redis使用HyperLogLog统计海量数据的基数
村口老师傅
博客等级 码龄9年 67粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值