目录
一、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;
}
结果:会根据距离自动排序,传递名称则模糊查询