使用Redis GEO计算两地理坐标之间的距离

本文介绍如何利用Redis的GEO功能精确计算两个地理坐标的距离,并且结果保留2位小数,同时展示如何按照距离远近进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

并且保留2位小数,而且按距离远近进行排序

public List<HouseGeoDto> getHouseGeoDistance( String currentLongitude, String currentLatitude) {
       
        List<HouseGeoDto> houseGeoList = infoHouseMapper.getHouseGeoList();
        if (CollectionUtil.isNotEmpty(houseGeoList)){
            for (HouseGeoDto dto : houseGeoList) {
                double distance = getDistance(currentLongitude, currentLatitude, dto.getLongitude(), dto.getLatitude());
                dto.setGeoDistance(distance);
            }
        }
        //匿名比较器排序
//        List<HouseGeoDto> collect = houseGeoList.stream().sorted(Comparator.comparing(HouseGeoDto::getGeoDistance,Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
        //匿名比较器排序
    /*    Collections.sort(houseGeoList, new Comparator<HouseGeoDto>() {
            @Override
            public int compare(HouseGeoDt
<think>嗯,用户问为什么大多数情况下使用RedisGEO模块来存储地位置。首先,我需要回忆一下Redis GEO的相关知识。Redis是一个内存数据库,支持多种数据结构,而GEO是专门处空间数据的。 那用户可能想知道Redis GEO的优势在哪里。首先,内存存储应该是一个关键点,因为内存访问速度快,适合高并发场景。比如,实时应用需要快速响应,比如打车软件里的附近司机查询,或者外卖App里的餐厅定位,这些都需要低延迟。 然后,Redis GEO底层使用了Sorted Set,也就是有序集合,用Geohash编码将经纬度转换成分数。这样的结构支持高效的范围查询,比如查找某个半径内的地点。用户可能关心查询效率,毕竟传统数据库如果没索引的话,查询速度可能不够。 另外,Redis本身支持持久化,虽然它是内存数据库,但可以通过RDB或AOF持久化到磁盘,这样数据不会丢失。用户可能担心内存数据库的持久性问题,需要说明这一点。 还有,Redis的高可用性和扩展性。通过集群模式,可以横向扩展,处更大的数据量和更高的请求量。比如,大型应用可能需要分布式的解决方案,Redis Cluster能提供这样的支持。 Geohash的编码方式也是一个点,它把二维的经纬度转换成一维的字符串,方便存储和比较,附近的位置会有相似的前缀,这样查询时可以利用这种特性优化搜索速度。 不过,用户可能存在的疑问是,为什么不用传统的关系型数据库,比如MySQL的空间索引?这里需要对比一下,关系型数据库虽然支持空间索引,但在高并发下的性能可能不如Redis,尤其是需要实时响应的场景。 还有,Redis GEO提供的命令是否足够方便?比如GEOADD添加位置,GEORADIUS查询半径内的点,这些操作是否简单易用。对于开发者来说,API的友好程度也很重要。 可能需要考虑的是数据量的问题,如果数据量特别大,全部放在内存里成本会不会很高?不过Redis有压缩和优化,或者可以分片存储,所以需要权衡内存成本和性能需求。 另外,应用场景的典型例子,比如共享经济中的地位置服务,社交应用中的附近好友,物流中的位置追踪,这些场景适合用Redis GEO,因为需要频繁更新和查询位置。 可能还要提到与其他地位置数据库的比较,比如PostGIS,MongoDB的地空间索引,但Redis的优势在于性能和简单性,特别是在已经使用Redis作为缓存或数据库的情况下,集成GEO模块会更方便。 总结起来,用户可能是在选择地位置存储方案,需要了解Redis GEO的优势和适用场景,所以回答时要突出性能、易用性、高效的查询命令、持久化和扩展性,以及适用的高并发实时应用场景。</think>Redis 的 **GEO 模块**被广泛用于存储和查询地位置信息,主要得益于其高性能、易用性和针对性设计。以下是它在多数场景中被优先选择的几个关键原因: --- ### 1. **基于内存的高性能** - Redis 是内存数据库,所有数据存储在内存中,读写速度极快(微秒级响应),适合需要**实时查询**的场景(如附近的人、附近的车辆、实时物流追踪)。 - 传统关系型数据库(如 MySQL)的磁盘 I/O 在高并发或大数据量时可能成为性能瓶颈,而 Redis 能轻松支持每秒数十万次的地位置查询。 --- ### 2. **优化的地空间数据结构** - Redis GEO 底层使用 **Sorted Set(有序集合)** 存储数据,通过 **Geohash 算法**将经纬度编码为一维的分数值,将二维地位置映射到一维空间,从而高效支持以下操作: - **添加位置**:`GEOADD` 直接存储经度、纬度、名称。 - **查询附近点**:`GEORADIUS` 或 `GEORADIUSBYMEMBER` 快速查找半径范围内的位置。 - **计算距离**:`GEODIST` 直接返回两点间距离。 - 这种设计使得范围查询(如“附近 5 公里内的餐厅”)的时间复杂度接近 O(log N),远高于传统数据库的全表扫描。 --- ### 3. **简化的开发流程** - Redis 提供了**开箱即用的 GEO API**,无需开发者手动实现 Geohash 编码或空间索引逻辑,显著降低开发复杂度。 - 示例:添加一个位置并查询附近点仅需几行命令: ```bash GEOADD cities 116.405285 39.904989 "北京" GEORADIUS cities 116.40 39.90 100 km WITHDIST ``` --- ### 4. **高扩展性与持久化** - **集群支持**:Redis Cluster 允许横向扩展,应对海量地位置数据(如全球数百万个点位)。 - **数据持久化**:通过 RDB(快照)或 AOF(日志)将内存数据保存到磁盘,避免数据丢失。 --- ### 5. **适用场景广泛** - **社交应用**:查找附近用户、共享位置。 - **物流与出行**:实时追踪车辆、计算配送距离。 - **本地服务**:搜索附近的餐厅、酒店、加油站。 - **物联网(IoT)**:管设备的地分布。 --- ### 6. **与其他方案的对比优势** - **对比关系型数据库(如 MySQL)**: - MySQL 虽然支持空间索引(R-Tree),但写入和查询性能低于 Redis,尤其在频繁更新的场景(如车辆实时位置)。 - **对比专用地数据库(如 PostGIS)**: - PostGIS 功能更强大(支持复杂地计算),但 Redis 在简单查询场景下性能更高,且更轻量易集成。 --- ### 何时可能不适用 Redis GEO? - **需要复杂地计算**:如多边形区域判断、地围栏等,需结合 PostGIS 或 MongoDB。 - **数据量远超内存容量**:内存成本较高,需权衡是否分片或降级存储。 --- ### 总结 Redis GEO 凭借**内存速度、高效数据结构、易用性**,成为处**实时地位置查询**的首选方案,尤其适合需要低延迟、高并发的场景。对于更复杂的地空间需求,可结合其他专业工具互补使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值