简单记录一下使用Redis的GEO命令,SpringDataRedis提供了十分简单的地理位置定位的功能,实现查找附近用户的功能。
(1)用法:GEOADD key [longitude][ latitude ][member]
(2)作用:用于存储地理位置信息,以便进行地理位置搜索和距离计算等操作。
(3)返回值:成功添加的成员数量。
(4)示例:
- redis > GEOADD cities 116.4074 39.9042 Beijing
- redis > GEOADD cities NX 121.4737 31.2304 Shanghai
(5)可选参数:
- NX:只在 key 不存在时才执行操作。
- XX:只在 key 存在时才执行操作。
- CH:修改成功的成员数量将被返回
(1)用法:GEORADIUS key longitude latitude radius
(2)作用:用于查询指定地理位置附近的其他地理位置的命令。
(3)返回值:返回成员列表。
(4)示例:
redis > GEORADIUS User-Location 116.4074 39.9042 100 km
(1)UserController.java
- /**
- * 更新用户位置信息
- * {
- * "longitude": 113.936099,
- * "latitude": 22.542364
- * }
- */
- @PostMapping("updateUserLocation")
- @ResponseBody
- @CrossOrigin
- public
T updateUserLocation(@RequestBody HashMap data) { - return userService.updateUserLocation(data);
- }
-
- /**
- * 更新用户位置信息
- * {
- * "longitude": 113.936099,
- * "latitude": 22.542364,
- * "radius": 10
- * }
- */
- @PostMapping("nearby")
- @ResponseBody
- @CrossOrigin
- public
T nearby(@RequestBody HashMap data) { - return userService.nearby(data);
- }
(1)IUserService.java
T updateUserLocation(HashMap data) ; -
T nearby(HashMap data) ;
(1)UserServiceImpl.java
- @Override
- public
T updateUserLocation(HashMap data) { - HashMap
responseObj = new HashMap<>(); - // 获取登录用户
- UserDTO userDTO = RequestHolder.getUser();
-
- // 获取经纬度
- Double longitude = (Double) data.get("longitude"); // 经度
- Double latitude = (Double) data.get("latitude"); // 维度
-
- String USER_LOCATION_KEY = "User-Location";
- String phone = userDTO.getPhone();
- stringRedisTemplate.opsForGeo().add(USER_LOCATION_KEY, new Point(longitude, latitude), phone);
- responseObj.put("code", 200);
- responseObj.put("success", true);
- responseObj.put("msg", "更新完成");
- return (T) responseObj;
- }
-
- @Override
- public
T nearby(HashMap data) { - HashMap
responseObj = new HashMap<>(); - // 获取登录用户
- UserDTO userDTO = RequestHolder.getUser();
-
- // 获取经纬度,以及半径
- Double longitude = (Double) data.get("longitude"); // 经度
- Double latitude = (Double) data.get("latitude"); // 维度
- Integer radius = (Integer) data.get("radius"); // 半径
-
- String USER_LOCATION_KEY = "User-Location";
- String phone = userDTO.getPhone();
- Distance distance = new Distance(radius, Metrics.KILOMETERS); // 距离,单位为千米
- Circle circle = new Circle(new Point(longitude, latitude), distance); // 圆心
-
- // 使用Redis的地理位置操作对象,在指定范围内查询附近的用户位置信息
- GeoResults
> geoResults = stringRedisTemplate.opsForGeo().radius(USER_LOCATION_KEY, circle); - List
- for (GeoResult
> geoResult : geoResults.getContent()) { - Object memberId = geoResult.getContent().getName();
- // 排除查询用户本身
- if (!memberId.equals(phone)) {
- nearbyUsers.add(memberId);
- }
- }
-
- responseObj.put("code", 200);
- responseObj.put("success", true);
- responseObj.put("msg", "更新完成");
- responseObj.put("data", nearbyUsers);
- return (T) responseObj;
- }