Java中如何使用Redis GEO测算经纬度距离

 更新时间:2023年11月21日 11:28:12   作者:www.Rui  
GEO也是Redis中提供的一种数据类型,可以将其理解成ZSet有序集合类型,本文给大家介绍Java-使用Redis GEO测算经纬度距离,感兴趣的朋友一起看看吧

一、Redis GEO相关命令操作

GEO也是Redis中提供的一种数据类型,可以将其理解成ZSet有序集合类型

  • GEOADD
GEOADD cars -115.17087 36.12306 my-car

向GEO集合cars中添加一个键为my-car,值为-115.17087 36.12306。

第一个参数为GEO集合名称,第二个参数为经度,第三个参数为纬度,第四个参数为成员名称。

GEOADD cars -115.171971 36.120609 robins-car

再向同一个集合cars中添加一个robins-car坐标。

GEO与ZSET相同,多次添加相同的成员KEY,将会覆盖以前的内容,即不允许重复的成员KEY。

GEODIST

GEODIST cars my-car robins-car

测算两个成员坐标的距离,即测算cars集合中,根据my-car与robins-car的经纬度计算两者相距的距离。默认返回的距离单位为米,比如"90.7082"米。

GEODIST cars my-car robins-car km

测算两个坐标的距离,返回值单位为km千米。

GEORADIUS

GEORADIUS cars -115.17258 36.11996 100 m

刷选出集合cars中距离经纬度-115.17258 36.11996的100米范围内的成员名称数据。会返回成员键,即robins-car、my-car。

GEORADIUSBYMEMBER

GEORADIUSBYMEMBER cars robins-car 100 m WITHDIST

刷选出集合内距离键robins-car 100米范围内的成员名称,并且一起返回距离该指定的键多少米。

ZREM

ZREM cars my-car

移除集合中某个键,与ZSET有序集合使用的相同命令。

二:Spring中RedisTemplate操作。

有了Redis GEO相关命令后,我们便可以轻松地来计算两个经纬度之间的距离、筛选出距离某个经纬度100米范围内的数据了。

@Component
public class GeoUtil {
    @Autowired
    private RedisTemplate redisTemplate;
    private static final String GEO_KEY = "DISTANCE";
    /**
     * 将经纬度信息添加到redis中
     * @param certId 标识
     * @param longitude 经度
     * @param latitude 纬度
     */
    public void geoAdd(String certId, double longitude, double latitude) {
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        Point point = new Point(longitude, latitude);
        RedisGeoCommands.GeoLocation geoLocation = new RedisGeoCommands.GeoLocation(certId, point);
        geoOperations.add(GEO_KEY, geoLocation);
    }
    /**
     * 两个人之间的距离
     * @param certId1
     * @param certId2
     * @return
     */
    public double distanceBetween(String certId1, String certId2) {
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        Distance distance = geoOperations.distance(GEO_KEY, certId1, certId2);
        return distance.getValue();
    }
    /**
     * 查询距离某个人指定范围内的人,包括距离多少米
     * @param certId
     * @param distance
     * @return
     */
    public Map<String, Double> distanceInclude(String certId, double distance) {
        Map<String, Double> map = new LinkedHashMap<>();
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = geoOperations.radius(GEO_KEY, certId, new Distance(distance), geoRadiusCommandArgs.includeDistance());
        if (geoResults != null) {
            Iterator<GeoResult<RedisGeoCommands.GeoLocation<String>>> iterator = geoResults.iterator();
            while (iterator.hasNext()) {
                GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult = iterator.next();
                // 与目标点相距的距离信息
                Distance geoResultDistance = geoResult.getDistance();
                // 该点的信息
                RedisGeoCommands.GeoLocation<String> geoResultContent = geoResult.getContent();
                map.put(geoResultContent.getName(), geoResultDistance.getValue());
            }
        }
        return map;
    }
}
GeoUtil geoUtil = springApplicationContext.getBean(GeoUtil.class);
geoUtil.geoAdd("北京西站", 116.328103,39.900835);
geoUtil.geoAdd("北京南站", 116.385488,39.87128);
geoUtil.geoAdd("北京西站-南广场", 116.327766,39.898944);
geoUtil.geoAdd("北京西站-南进站口", 116.327765,39.899347);
geoUtil.geoAdd("中铁设计大厦", 116.328628,39.896485);
geoUtil.geoAdd("瑞海大厦", 116.326661,39.903778);
// 计算北京南站与北京西站之间的距离
double distance = geoUtil.distanceBetween("北京西站", "北京南站");
// 5898.4001
System.out.println(distance);
// 查询距离北京西站5000米范围内的地方
Map<String, Double> distanceInclude = geoUtil.distanceInclude("北京西站", 5000);
System.out.println(distanceInclude);

从百度地图看北京西站与北京南站的距离为5.9公里,即5900米,与计算出的5898.4001相差无几。

到此这篇关于Java-使用Redis GEO测算经纬度距离的文章就介绍到这了,更多相关redis计算经纬度距离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring-DI依赖注入全过程

    Spring-DI依赖注入全过程

    Spring DI是核心特性,通过容器管理依赖注入,降低耦合度,实现方式包括组件扫描、构造器/设值/字段注入、自动装配及作用域配置,支持灵活的依赖管理与生命周期控制,提升代码可维护性与可测试性
    2025-08-08
  • Java课设案例之百行代码实现简易计算器

    Java课设案例之百行代码实现简易计算器

    下面这篇文章主要给大家介绍了关于Java课设案例之百行代码实现简易计算器的相关资料,这是一个关于java简单计算器的完整课程设计以及源码,需要的朋友可以参考下
    2023-06-06
  • Java 如何快速实现一个连接池

    Java 如何快速实现一个连接池

    有没有一个通用的库可以快速实现一个线程池呢?得益于 Java 完善的生态,前人们针对这种需要开发了一个通用库:Apache Commons Pool(下文简称 ACP)。本质上来说,ACP 库提供的是管理对象池的通用能力,当然也可以用来管理连接池了!
    2021-05-05
  • maven多moudle项目在idea里面显示多个root问题及解决

    maven多moudle项目在idea里面显示多个root问题及解决

    这篇文章主要介绍了maven多moudle项目在idea里面显示多个root问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • java如何分布式锁实现和选型

    java如何分布式锁实现和选型

    文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zookeeper的分布式锁实现示例,分析了每种方法的优点和缺点
    2025-01-01
  • SpringCloud网关Gateway功能实现

    SpringCloud网关Gateway功能实现

    本文介绍SpringCloud网关Gateway功能实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09
  • Java实现飞机大战游戏 附完整源码

    Java实现飞机大战游戏 附完整源码

    这篇文章主要介绍了Java实现飞机大战游戏,本文给大家分享完整源代码和效果图展示,对java飞机大战游戏实现代码感兴趣的朋友一起看看吧
    2022-05-05
  • Java使用Arthas查看接口方法的执行时间的步骤

    Java使用Arthas查看接口方法的执行时间的步骤

    在日常的开发和运维工作中,经常需要监控接口方法的执行时间,以便排查性能问题或优化代码,Arthas 是一款强大的 Java 诊断工具,可以帮助我们轻松地查看接口方法的执行时间,而无需修改代码或重启应用,本文将详细介绍如何使用 Arthas 来查看接口方法的执行时间
    2025-05-05
  • 在Spring Boot框架中使用AOP的正确姿势

    在Spring Boot框架中使用AOP的正确姿势

    aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案。下面这篇文章主要给大家介绍了如何在Spring Boot框架中使用AOP的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-08-08
  • Java:DocumentBuilderFactory调用XML的方法实例

    Java:DocumentBuilderFactory调用XML的方法实例

    Java:DocumentBuilderFactory调用XML的方法实例,需要的朋友可以参考一下
    2013-04-04

最新评论