Spring Data Redis 中,Geo 类型的响应式接口为 ReactiveGeoOperations,该接口定义的方法和 GeoOperations、BoundGeoOperations 接口定义的方法非常类似。
我们可以通过 ReactiveRedisTemplate 的 opsForGeo() 方法获取获取,代码如下:
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
reactor.core.publisher.Mono<Long> add(K key, Iterable<RedisGeoCommands.GeoLocation<M>> locations) 将 RedisGeoCommands.GeoLocations 添加到 key
reactor.core.publisher.Mono<Long> add(K key, Map<M,org.springframework.data.geo.Point> memberCoordinateMap) 将 memberCoordinateMap 中的坐标批量添加到 key
reactor.core.publisher.Mono<Long> add(K key, org.springframework.data.geo.Point point, M member) 将具有给定成员名称的 Point 添加到 key
reactor.core.publisher.Flux<Long> add(K key, org.reactivestreams.Publisher<? extends Collection<RedisGeoCommands.GeoLocation<M>>> locations) 将 RedisGeoCommands.GeoLocations 添加到 key
reactor.core.publisher.Mono<Long> add(K key, RedisGeoCommands.GeoLocation<M> location) 将 RedisGeoCommands.GeoLocation 添加到 key
示例:
@Test
public void add() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 成都天府广场坐标
Point point = new Point(104.072206,30.663486);
ops.add("key", point, "chengdu")
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("添加成都坐标成功");
}
});
System.out.println(queue.take());
// 批量添加坐标
Map<String,Point> pointMap = new HashMap<>();
pointMap.put("beijing", new Point(116.403039,39.91513));
pointMap.put("beijing2", new Point(116.303039,39.81513));
ops.add("key", pointMap).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("批量添加坐标成功");
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
添加成都坐标成功 批量添加坐标成功
reactor.core.publisher.Mono<Boolean> delete(K key) 删除给定的键
示例:
@Test
public void delete() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 成都天府广场坐标
Point point = new Point(104.072206,30.663486);
ops.add("key", point, "chengdu")
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("添加成都坐标成功");
}
});
System.out.println(queue.take());
// 删除key
ops.delete("key").subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) {
if(aBoolean) {
queue.add("成功删除key");
} else {
queue.add("删除key失败");
}
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
添加成都坐标成功 成功删除key
reactor.core.publisher.Mono<org.springframework.data.geo.Distance> distance(K key, M member1, M member2) 获取 member1 和 member2 之间的距离
reactor.core.publisher.Mono<org.springframework.data.geo.Distance> distance(K key, M member1, M member2, org.springframework.data.geo.Metric metric) 使用 Metric 单位获取 member1 和 member2 之间的距离
示例:
@Test
public void distance() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 批量添加坐标
Map<String,Point> pointMap = new HashMap<>();
pointMap.put("beijing", new Point(116.403039,39.91513));
pointMap.put("chengdu", new Point(104.072206,30.663486));
ops.add("key", pointMap).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("批量添加坐标成功");
}
});
System.out.println(queue.take());
// 计算成都和北京的距离
ops.distance("key", "beijing", "chengdu")
.subscribe(new Consumer<Distance>() {
@Override
public void accept(Distance distance) {
queue.add("北京与成都距离:" + distance.getValue()
+ distance.getMetric().getAbbreviation());
}
});
System.out.println(queue.take());
ops.distance("key", "beijing", "chengdu", Metrics.KILOMETERS)
.subscribe(new Consumer<Distance>() {
@Override
public void accept(Distance distance) {
queue.add("北京与成都距离:" + distance.getValue()
+ distance.getMetric().getAbbreviation());
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
批量添加坐标成功 北京与成都距离:1517797.1972m 北京与成都距离:1517.7972km
reactor.core.publisher.Mono<List<String>> hash(K key, M... members) 获取一个或多个成员的位置的 Geohash 表示
reactor.core.publisher.Mono<String> hash(K key, M member) 获取指定成员的位置 Geohash 表示
示例:
@Test
public void hash() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 批量添加坐标
Map<String,Point> pointMap = new HashMap<>();
pointMap.put("beijing", new Point(116.403039,39.91513));
pointMap.put("chengdu", new Point(104.072206,30.663486));
ops.add("key", pointMap).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("批量添加坐标成功");
}
});
System.out.println(queue.take());
// 获取成都的 Geohash
ops.hash("key", "chengdu").subscribe(new Consumer<String>() {
@Override
public void accept(String s) {
queue.add(s);
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
批量添加坐标成功 wm6n2np5f00
reactor.core.publisher.Mono<List<org.springframework.data.geo.Point>> position(K key, M... members) 获取一个或多个成员位置的点表示
reactor.core.publisher.Mono<org.springframework.data.geo.Point> position(K key, M member) 获取指定成员位置的点表示
示例:
@Test
public void position() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 批量添加坐标
Map<String,Point> pointMap = new HashMap<>();
pointMap.put("beijing", new Point(116.403039,39.91513));
pointMap.put("chengdu", new Point(104.072206,30.663486));
ops.add("key", pointMap).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("批量添加坐标成功");
}
});
System.out.println(queue.take());
// 获取成都位置点表示
ops.position("key", "chengdu").subscribe(new Consumer<Point>() {
@Override
public void accept(Point point) {
queue.add("x=" + point.getX() + ", y=" + point.getY());
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
批量添加坐标成功 x=104.0722069144249, y=30.663486325924417
利用这些方法可以获取根据一个点计算半径圆圈范围内的地理位置信息,方法如下:
reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, org.springframework.data.geo.Circle within) 获取给定圈子边界内的成员。
reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, org.springframework.data.geo.Circle within, RedisGeoCommands.GeoRadiusCommandArgs args) 应用 RedisGeoCommands.GeoRadiusCommandArgs 获取给定 Circle 边界内的成员。
reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, M member, org.springframework.data.geo.Distance distance) 获取由成员坐标和给定半径应用公制定义的圆内的成员。
reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, M member, org.springframework.data.geo.Distance distance, RedisGeoCommands.GeoRadiusCommandArgs args) 获取由成员坐标定义的圆内的成员,并应用 Metric 和 RedisGeoCommands.GeoRadiusCommandArgs 给定半径。
reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, M member, double radius) 获取由成员坐标和给定半径定义的圆内的成员。
示例:
@Test
public void radius() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 添加多个坐标
Map<String,Point> pointMap = new HashMap<>();
pointMap.put("chengdu", new Point(104.07332,30.664768));
pointMap.put("chengdudong_railway_station", new Point(104.145184,30.636433));
pointMap.put("chengdubei_railway_station", new Point(104.145184,30.636433));
pointMap.put("beijing", new Point(116.400739,39.920885));
pointMap.put("wuhan", new Point(114.360454,30.588768));
ops.add("key", pointMap).subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("批量添加坐标成功 " + aLong);
}
});
System.out.println(queue.take());
// 获取成都附近 100 公里范围内的地理位置
Circle circle = new Circle(104.07332, 30.664768, 100*1000);
ops.radius("key", circle).collectList()
.subscribe(new Consumer<List<GeoResult<RedisGeoCommands.GeoLocation<String>>>>() {
@Override
public void accept(List<GeoResult<RedisGeoCommands.GeoLocation<String>>> geoResults) {
for(GeoResult<RedisGeoCommands.GeoLocation<String>> result : geoResults) {
RedisGeoCommands.GeoLocation<String> geo = result.getContent();
System.out.println(geo.getName());
}
queue.add("成都附近 100 公里范围内有" + geoResults.size() + "地理位置");
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
批量添加坐标成功 5 chengdubei_railway_station chengdudong_railway_station chengdu 成都附近 100 公里范围内有3地理位置
reactor.core.publisher.Mono<Long> remove(K key, M... members) 删除指定的一个或多个坐标
示例:
@Test
public void remove() throws Exception {
LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
// 成都天府广场坐标
Point point = new Point(104.072206,30.663486);
ops.add("key", point, "chengdu")
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("添加成都坐标成功");
}
});
System.out.println(queue.take());
// 删除成都坐标
ops.remove("key", "chengdu").subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) {
queue.add("删除成都坐标成功 " + aLong);
}
});
System.out.println(queue.take());
}运行示例,输出结果如下:
添加成都坐标成功 删除成都坐标成功 1