目录
- 一、前言
- 二、Redis GEO 常用命令介绍
- 三、Redis GEO 获取两个坐标的直线距离
- 四、Redis GEO 给定坐标获取半径不超过指定距离的元素
一、前言
在做快递外卖等配送业务时经常需要使用到,计算配送员距离商家的直线距离,和检索商家坐标给定一个半径内全部的配送员,要想实现这两个功能可以直接使用Redis GEO进行坐标计算,这里会使用Redis命令演示和Java代码演示,Java代码会使用Spring Boot
环境RedisTemplate
操作Redis。
-
需要集成文章可以查看:
SpringBoot集成Lettuce客户端操作Redis:https://blog.csdn.net/weixin_44606481/article/details/133907103 -
准备SpringBoot测试类,下面Java代码演示统一使用:
java">import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class RedisGeoTest { @Autowired private RedisTemplate<String, Object> redisTemplate; }
二、Redis GEO 常用命令介绍
# 添加坐标信息 可以一次性添加多个,member:城市名称
geoadd <key> <longitude> <latitude> <member> ...
# 用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),可以一次性指定多个member
geopos <key> <member> ...
# 用于返回两个给定位置之间的直线距离距离单位可选m|km|ft|mi,withdist:加上可以返回间隔距离
geodist <key> <member1> <member2> m|km|ft|mi withdist
# 根据给定的经纬度,返回半径不超过指定距离的元素 距离单位可选m|km|ft|mi
georadius <key> <longitude> <latitude> <radius> m|km|ft|mi
# 根据给定元素的经纬度,返回半径不超过指定距离的元素
georadiusbymember <key> <member> <radius> m|km|ft|mi
# 用于获取一个或多个位置元素的 geohash 值,可以一次性获取多个
geohash <key> <member> ...
三、Redis GEO 获取两个坐标的直线距离
- Redis命令演示
127.0.0.1:6379> geoadd geo_01 114.057939 22.543527 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo_01 114.171203 22.277468 xianggang
(integer) 1
127.0.0.1:6379> geodist geo_01 shenzhen xianggang km
"31.8021"
- Java代码演示
java"> @Test
public void t1() {
String redisKey = "geo_01";
redisTemplate.delete(redisKey);
// 设置深圳市政府的坐标
redisTemplate.opsForGeo().add(redisKey,new Point(114.057939,22.543527),"shenzhen");
// 设置香港的坐标
redisTemplate.opsForGeo().add(redisKey,new Point(114.171203,22.277468),"xianggang");
// 获取两个城市之间的距离
Distance distance = redisTemplate.opsForGeo().distance(redisKey, "shenzhen", "xianggang", RedisGeoCommands.DistanceUnit.KILOMETERS);
System.out.println("获取两个城市之间的距离:"+distance.getValue()+" 千米");
// 输出结果:获取两个城市之间的距离:31.8021 千米
}
四、Redis GEO 给定坐标获取半径不超过指定距离的元素
- Redis命令演示
127.0.0.1:6379> geoadd geo_02 114.057939 22.543527 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo_02 113.751884 23.021016 donguan
(integer) 1
127.0.0.1:6379> geoadd geo_02 114.415587 23.112368 huizhou
(integer) 1
127.0.0.1:6379> geoadd geo_02 114.171203 22.277468 xianggang
(integer) 1
127.0.0.1:6379> georadius geo_02 113.264499 23.130061 100 km
1) "donguan"
127.0.0.1:6379> georadius geo_02 113.264499 23.130061 110 km withdist
1) 1) "donguan"
2) "51.3264"
2) 1) "shenzhen"
2) "104.2642"
- Java代码演示
java"> @Test
public void t2() {
String redisKey = "geo_02";
redisTemplate.delete(redisKey);
// 设置深圳市政府的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(114.057939, 22.543527), "shenzhen");
// 设置东莞市政府的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.751884, 23.021016), "donguan");
// 设置惠州市政府的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(114.415587, 23.112368), "huizhou");
// 设置香港的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(114.171203, 22.277468), "xianggang");
// 以广州市政府经纬度为中心,获取半径不超过最大距离的所有元素
Point point = new Point(113.264499,23.130061);
// 半径为110km
Distance distance = new Distance(110, RedisGeoCommands.DistanceUnit.KILOMETERS);
Circle circle = new Circle(point, distance);
// 构造 GeoRadiusCommandArgs 对象
RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
.includeDistance() // 设置为 true,表示返回距离信息
.sortAscending(); // 设置为 true,表示按距离升序排列
GeoResults<RedisGeoCommands.GeoLocation<Object>> radius = redisTemplate.opsForGeo().radius(redisKey, circle,geoRadiusArgs);
List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content= radius.getContent();
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult:content){
RedisGeoCommands.GeoLocation<Object> geoResultContent = geoResult.getContent();
System.out.println("广州市政府110KM半径范围内城市:"+geoResultContent.getName() + " 相隔:" +geoResult.getDistance().getValue()+ " 千米");
}
// 输出结果:
// 广州市政府110KM半径范围内城市:donguan 相隔:51.3264 千米
// 广州市政府110KM半径范围内城市:shenzhen 相隔:104.2642 千米
}