redis版本需要大于3.2 此代码测试于windows(5.0.14) centos(6.2.1)
用到的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
redisUtil类
@Component
@RequiredArgsConstructor
public class RedisUtil {
private final StringRedisTemplate redisTemplate;
/**
* 向指定key中添加经纬度信息
* @param key 存储的键值
* @param longitude 经度
* @param latitude 纬度
* @param member 成员名称(数据的标识 比如userID)
* @return 添加成功的条数
*/
public long geoAdd(String key,Double longitude,Double latitude,String member){
return redisTemplate.opsForGeo().add(key,new Point(longitude,latitude),member);
}
/**
* 向指定key中添加经纬度信息
* @param key
* @param locations
* @return
*/
public long geoAddList(String key, List<RedisGeoCommands.GeoLocation<String>> locations){
return redisTemplate.opsForGeo().add(key,locations);
}
/**
* 获取成员之间的距离
* @param key 存储的键值
* @param member1 成员名称
* @param member2 成员名称
* @return
*/
public Distance geoDist(String key, String member1, String member2){
return redisTemplate.opsForGeo().distance(key,member1,member2);
}
/**
* 获取指定key值的所有成员列表
* @param key
* @return
*/
public List<String> geoHash(String key){
return redisTemplate.opsForGeo().hash(key);
}
/**
* 获取指定成员的位置信息
* @param key 存储的键值
* @param member 成员名称
* @return
*/
public Point geoPos(String key, String member){
return (redisTemplate.opsForGeo().position(key,member)).get(0);
}
/**
* 获取指定成员 范围内的位置信息
* @param key 存储的键值
* @param member 成员名称
* @param distance 距离
* @return
*/
public GeoResults<RedisGeoCommands.GeoLocation<String>> geoRadius(String key, String member, double distance){
RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending();
return redisTemplate.opsForGeo().radius(key,member,new Distance(distance,Metrics.KILOMETERS),args);
}
}
使用测试类TestController
@RestController
@RequestMapping("test")
@RequiredArgsConstructor
public class TestController {
private final RedisUtil redisUtil;
@PostMapping("a_geo")
public Result addGeo(String ln, String lat) {
List<RedisGeoCommands.GeoLocation<String>> list = new ArrayList<>();
double [] points = {104.75558360809327,30.683943274847753,
103.87427409881593,30.867270286581444,
103.89573177093507,30.872279951526178,
103.9498051046753,30.86005001477394,
104.01743968719484,30.847523763824523,
104.06584819549562,30.828510210939427,
104.10155376190187,30.798582032501155,
104.12678798431398,30.77793647809215,
104.16506847137452,30.760236761209416,
104.33896144622804,30.75227082663582};
for (int i = 0; i < 20; i += 2) {
RedisGeoCommands.GeoLocation location = new RedisGeoCommands.GeoLocation("name_"+i/2,new Point(points[i],points[i+1]));
list.add(location);
}
long count = redisUtil.geoAddList(RKey.USER_ONLINE_LOCATION,list);
return ResultUtil.successResult(count);
}
@GetMapping("q_geo")
public Result getGeo(String member, double distance) {
GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisUtil.geoRadius(RKey.USER_ONLINE_LOCATION, member, distance);
return ResultUtil.successResult(geoResults);
}
@GetMapping("geo_dist")
public Result distMember(String member1,String member2){
Distance distance = redisUtil.geoDist(RKey.USER_ONLINE_LOCATION, member1, member2);
return ResultUtil.successResult(distance);
}
}
接口调用结果示例
// 添加位置信息 返回成功添加的条数
url:test/a_geo
{
"code": 200,
"msg": "SUCCESS",
"data": 10
}
// 获取指定成员间的距离
url:/test/geo_dist?member1=name_3&member2=name_2
{
"code": 200,
"msg": "SUCCESS",
"data": {
"value": 5338.7572,
"metric": "METERS"
}
}
// RedisGeoCommands.GeoRadiusCommandArgs 中可以指定排序和返回条数limit
url:/test/q_geo?member=name_3&distance=10
{
"code": 200,
"msg": "SUCCESS",
"data": {
"averageDistance": {
"value": 4.80035,
"metric": "KILOMETERS"
},
"content": [
{
"content": {
"name": "name_3",
"point": {
"x": 103.94980698823929,
"y": 30.86004888238883
}
},
"distance": {
"value": 0.0,
"metric": "KILOMETERS"
}
},
{
"content": {
"name": "name_2",
"point": {
"x": 103.89573365449905,
"y": 30.872278911982647
}
},
"distance": {
"value": 5.3388,
"metric": "KILOMETERS"
}
}
]
}
}