Java整合Redis实现坐标附近查询

目录

一、GEO用法引入

二、引入依赖

三、实体类

四、添加位置信息

五、查询位置信息


一、GEO用法引入

  1. GEO,全称Geolocation,代表地理坐标。可以在其中存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有:
  2. GEOADD:添加一个或多个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)
  3. GEODIST:计算指定的两个点之间的距离并返回
  4. GEOHASH:将指定member的坐标转为hash字符串形式并返回
  5. GEOPOS:返回指定member的坐标
  6. GEORADIUS:指定圆心、半径,找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。(6.2以后已废弃)
  7. GEOSEARCH:在指定范围内搜索member,并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。(6.2以后新命令)
  8. GEOSEARCHSTORE:与GEOSEARCH功能一致,不过可以把结果存储到一个指定的key。(6.2以后新命令)

我们可以在redis服务器使用命令 help xxx 查看指令的具体用法~

二、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

三、实体类

1.返回实体

@Data
public class Geo<T> {

    private T object;

    private double distance;
}

2.添加的商户信息 


@Data
@ApiModel("商户信息DO")
public class CommercialDO implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(type = IdType.AUTO)
    /**
     * id
     */
    private Integer id;

    /**
     * 商户名称
     */
    private String name;

    /**
     * 商户类型
     */
    private String commercialType;

    /**
     * 门店名称
     */
    private String storeName;

    /**
     * 商户地址
     */
    private String address;

    /**
     * 项目code
     */
    private String itemCode;

    /**
     * 经度
     */
    private String longitude;

    /**
     * 纬度
     */
    private String latitude;

}

四、添加位置信息

    @ApiOperation("geo测试添加位置信息")
    @GetMapping("/geo/add")
    public String geoAdd(String key, double longitude, double latitude, CommercialDO commercialDO) throws Exception {
        redisUtils.geoAdd(key, longitude, latitude, commercialDO);
        return "添加成功";
    }
    public void geoAdd(String key, double longitude, double latitude, Object object) {
        redisTemplate.boundGeoOps(key).add(new Point(longitude, latitude),object);
    }

五、查询位置信息

    /**
     * 根据经纬度获取指定距离范围内的地理位置信息
     *
     * @param key           Redis中Geo操作的key
     * @param longitude     经度
     * @param latitude      纬度
     * @param distance      距离范围(单位:米)
     * @param limit         限制返回结果的数量
     * @param searchName    地点名称(可选)
     * @return              返回地理位置信息的列表
     */
    public List<Geo<T>> getNearbyByGeo(String key, double longitude, double latitude, int distance, int limit, String searchName) {
        List<Geo<T>> geos = new ArrayList<>();
        BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps(key);
        Point point = new Point(longitude, latitude);
        Circle within = new Circle(point, distance);
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        geoRadiusArgs = geoRadiusArgs.includeDistance();
        geoRadiusArgs.limit(limit);
        geoRadiusArgs.sortAscending();
        GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults = boundGeoOperations.radius(within, geoRadiusArgs);
        List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> geoResultList = geoResults.getContent();
        if (StringUtils.isNotBlank(searchName)) {
            geoResultList = geoResults.getContent()
                    .stream()
                    .filter(result -> result.getContent().getName().toString().contains(searchName))
                    .collect(Collectors.toList());
        }
        Geo geo;
        for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult : geoResultList) {
            geo = new Geo();
            geo.setObject(geoResult.getContent());
            geo.setDistance(geoResult.getDistance().getValue());
            geos.add(geo);
        }
        return geos;
    }

 结果:会根据距离自动排序,传递名称则模糊查询

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis GeoRedis提供的一种地理位置信息存储与查询的工具。通过Redis Geo,用户可以轻易地存储和查询地理位置信息,比如地理坐标、距离计算、范围查询等。 下面是一个Redis Geo工具类的示例代码: ``` import redis from typing import List, Tuple class RedisGeo: def __init__(self, host: str, port: int, db: int): self.redis = redis.Redis(host=host, port=port, db=db) def add_location(self, key: str, longitude: float, latitude: float, member_name: str): self.redis.geoadd(key, longitude, latitude, member_name) def get_location(self, key: str, member_name: str) -> Tuple[float, float]: return self.redis.geopos(key, member_name)[0] def get_distance(self, key: str, member1: str, member2: str, unit: str) -> float: return self.redis.geodist(key, member1, member2, unit=unit) def get_locations_in_radius(self, key: str, longitude: float, latitude: float, radius: float, unit: str) -> List[str]: return self.redis.georadius(key, longitude, latitude, radius, unit=unit, withdist=True, withcoord=False, sortasc=True, count=None) def get_locations_in_box(self, key: str, min_longitude: float, min_latitude: float, max_longitude: float, max_latitude: float) -> List[str]: return self.redis.georadiusbymember(key, member_name, radius, unit=unit, withdist=True, withcoord=False, sortasc=True, count=None) ``` 这个工具类封装了Redis Geo提供的常用操作,包括: - add_location:添加地理位置信息 - get_location:获取地理位置坐标 - get_distance:获取两个地理位置的距离 - get_locations_in_radius:获取某个地理位置周围一定范围内的所有地理位置信息 - get_locations_in_box:获取某个地理位置周围一个矩形范围内的所有地理位置信息 使用时,只需创建一个RedisGeo对象,并调用相应的方法即可,示例如下: ``` redis_geo = RedisGeo(host='127.0.0.1', port=6379, db=0) redis_geo.add_location('cities', 116.4074, 39.9042, 'Beijing') redis_geo.add_location('cities', 121.4737, 31.2304, 'Shanghai') redis_geo.add_location('cities', 113.2644, 23.1291, 'Guangzhou') print(redis_geo.get_location('cities', 'Beijing')) print(redis_geo.get_distance('cities', 'Beijing', 'Shanghai', 'km')) print(redis_geo.get_locations_in_radius('cities', 116.4074, 39.9042, 2000, 'km')) print(redis_geo.get_locations_in_box('cities', 110, 20, 120, 30)) ``` 这段代码将三个城市的地理位置信息存储在名为“cities”的Redis Geo Key中,并通过RedisGeo对象的方法获取了这些地理位置信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值