目录
一、GEO用法引入
二、引入依赖
三、实体类
四、添加位置信息
五、查询位置信息
一、GEO用法引入
- GEO,全称Geolocation,代表地理坐标。可以在其中存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有:
- GEOADD:添加一个或多个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)
- GEODIST:计算指定的两个点之间的距离并返回
- GEOHASH:将指定member的坐标转为hash字符串形式并返回
- GEOPOS:返回指定member的坐标
- GEORADIUS:指定圆心、半径,找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。(6.2以后已废弃)
- GEOSEARCH:在指定范围内搜索member,并按照与指定点之间的距离排序后返回。范围可以是圆形或矩形。(6.2以后新命令)
- 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;}
结果:会根据距离自动排序,传递名称则模糊查询