目录
- 一、简介
- 二、常用方法
- 2.1、GEOADD、GEOPOS
- 2.2、GEODIST
- 2.3、GEORADIUS
- 2.4、GEORADIUSBYMEMBER
- 2.5、GEOHASH
一、简介
RedisTemplate对象,后面例子里就不一一引入了。大家理解就行,如果大家还不知道如何通过Spring Boot 整合redis则可以查看我之前的文章:SpringBoot整合redis(redis支持单节点和集群)。
package com.alian.datastruct;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
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;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class RedisGeoTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
}
二、常用方法
2.1、GEOADD、GEOPOS
- GEOADD 用于存储指定的地理空间位置的经度和纬度
- GEOPOS 用于从给定的 key 里返回所有指定名称(member)的位置(经度和纬度)
语法
ZADD KEY_NAME SCORE1 MEMBER1... SCOREn MEMBERn
GEOADD KEY_NAME longitude latitude member
命令操作
127.0.0.1:6379> geoadd geo1 113.883078 22.553291 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo1 113.273241 23.157921 guangzhou
(integer) 1
127.0.0.1:6379> geopos geo1 shenzhen guangzhou
1) 1) "113.88307839632034302"
2) "22.55329111565713873"
2) 1) "113.27324062585830688"
2) "23.1579209662846921"
Java操作
@Test
public void geoAddAndGeoPos() {
String redisKey = "geo1";
redisTemplate.delete(redisKey);
// 设置深圳的坐标
redisTemplate.opsForGeo().add(redisKey,new Point(113.883078,22.553291),"shenzhen");
// 设置广州的坐标
redisTemplate.opsForGeo().add(redisKey,new Point(113.273241,23.157921),"guangzhou");
// 获取深圳的坐标
List<Point> list = redisTemplate.opsForGeo().position(redisKey, "shenzhen","guangzhou");
log.info("获取深圳的坐标:{}", list.get(0));
log.info("获取广州的坐标:{}", list.get(1));
}
获取深圳的坐标:Point [x=113.883078, y=22.553291]
获取广州的坐标:Point [x=113.273241, y=23.157921]
2.2、GEODIST
- GEODIST 用于返回两个给定位置之间的直线距离
语法
GEODIST KEY_NAME member1 member2
命令操作
127.0.0.1:6379> geoadd geo2 113.883078 22.553291 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo2 113.273241 23.157921 guangzhou
(integer) 1
127.0.0.1:6379> geodist geo2 shenzhen guangzhou km
"91.8118"
Java操作
@Test
public void geoDist() {
String redisKey = "geo2";
redisTemplate.delete(redisKey);
// 设置深圳的坐标
redisTemplate.opsForGeo().add(redisKey,new Point(113.883078,22.553291),"shenzhen");
// 设置广州的坐标
redisTemplate.opsForGeo().add(redisKey,new Point(113.273241,23.157921),"guangzhou");
// 获取两个城市之间的距离
Distance distance = redisTemplate.opsForGeo().distance(redisKey, "shenzhen", "guangzhou", RedisGeoCommands.DistanceUnit.KILOMETERS);
log.info("获取两个城市之间的距离:{} 千米", distance.getValue());
}
获取两个城市之间的距离:91.8118 千米
2.3、GEORADIUS
- GEORADIUS 根据给定的经纬度,返回半径不超过指定距离的元素
语法
GEORADIUS KEY_NAME longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
命令操作
127.0.0.1:6379> geoadd geo3 113.883078 22.553291 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo3 113.273241 23.157921 guangzhou
(integer) 1
127.0.0.1:6379> geoadd geo3 113.751791 23.020672 dongguan
(integer) 1
127.0.0.1:6379> geoadd geo3 113.392616 22.515951 zhongshan
(integer) 1
127.0.0.1:6379> georadius geo3 113.273241 23.157921 80 km
1) "guangzhou"
2) "dongguan"
3) "zhongshan"
127.0.0.1:6379> georadius geo3 113.273241 23.157921 80 km withdist
1) 1) "guangzhou"
2) "0.0000"
2) 1) "dongguan"
2) "51.2880"
3) 1) "zhongshan"
2) "72.4447"
Java操作
@Test
public void geoRadius() {
String redisKey = "geo3";
redisTemplate.delete(redisKey);
// 设置深圳的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.883078, 22.553291), "shenzhen");
// 设置广州的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.273241, 23.157921), "guangzhou");
// 设置东莞的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.751791, 23.020672), "dongguan");
// 设置中山的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.392616, 22.515951), "zhongshan");
// 以经纬度为中心,获取半径不超过最大距离的所有元素
Point point = new Point(113.273241, 23.157921);
// 半径为80km
Distance distance = new Distance(80, RedisGeoCommands.DistanceUnit.KILOMETERS);
Circle circle = new Circle(point, distance);
GeoResults<RedisGeoCommands.GeoLocation<Object>> radius = redisTemplate.opsForGeo().radius(redisKey, circle);
List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content= radius.getContent();
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult:content){
RedisGeoCommands.GeoLocation<Object> geoResultContent = geoResult.getContent();
log.info("获取半径不超过最大距离的所有元素:{}", geoResultContent.getName());
}
}
获取半径不超过最大距离的所有元素:guangzhou
获取半径不超过最大距离的所有元素:dongguan
获取半径不超过最大距离的所有元素:zhongshan
2.4、GEORADIUSBYMEMBER
- GEORADIUSBYMEMBER 根据给定元素的经纬度,返回半径不超过指定距离的元素
语法
GEORADIUSBYMEMBER KEY_NAME member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
命令操作
127.0.0.1:6379> geoadd geo4 113.883078 22.553291 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo4 113.273241 23.157921 guangzhou
(integer) 1
127.0.0.1:6379> geoadd geo4 113.751791 23.020672 dongguan
(integer) 1
127.0.0.1:6379> geoadd geo4 113.392616 22.515951 zhongshan
(integer) 1
127.0.0.1:6379> georadiusbymember geo4 guangzhou 100 km withdist
1) 1) "guangzhou"
2) "0.0000"
2) 1) "dongguan"
2) "51.2880"
3) 1) "zhongshan"
2) "72.4447"
4) 1) "shenzhen"
2) "91.8118"
Java操作
@Test
public void geoRadiusByMember() {
String redisKey = "geo4";
redisTemplate.delete(redisKey);
// 设置深圳的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.883078, 22.553291), "shenzhen");
// 设置广州的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.273241, 23.157921), "guangzhou");
// 设置东莞的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.751791, 23.020672), "dongguan");
// 设置中山的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.392616, 22.515951), "zhongshan");
// 定义距离
Distance distance = new Distance(100, RedisGeoCommands.DistanceUnit.KILOMETERS);
// 广州为中心点半径100km的元素
GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults = redisTemplate.opsForGeo().radius(redisKey, "guangzhou", distance);
List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content = geoResults.getContent();
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult : content) {
RedisGeoCommands.GeoLocation<Object> geoResultContent = geoResult.getContent();
log.info("广州为中心点半径100km的元素:{}", geoResultContent.getName());
}
}
广州为中心点半径100km的元素:guangzhou
广州为中心点半径100km的元素:dongguan
广州为中心点半径100km的元素:zhongshan
广州为中心点半径100km的元素:shenzhen
2.5、GEOHASH
- GEOHASH 用于获取一个或多个位置元素的 geohash 值
语法
GEOHASH KEY_NAME member [member ...]
命令操作
127.0.0.1:6379> geoadd geo5 113.883078 22.553291 shenzhen
(integer) 1
127.0.0.1:6379> geoadd geo5 113.273241 23.157921 guangzhou
(integer) 1
127.0.0.1:6379> geoadd geo5 113.751791 23.020672 dongguan
(integer) 1
127.0.0.1:6379> geoadd geo5 113.392616 22.515951 zhongshan
(integer) 1
127.0.0.1:6379> geohash geo5 shenzhen guangzhou dongguan zhongshan
1) "ws0br3xnkn0"
2) "ws0e9xg09v0"
3) "ws0fuqz90u0"
4) "ws08h6cuzm0"
Java操作
@Test
public void geoHash() {
String redisKey = "geo5";
redisTemplate.delete(redisKey);
// 设置深圳的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.883078, 22.553291), "shenzhen");
// 设置广州的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.273241, 23.157921), "guangzhou");
// 设置东莞的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.751791, 23.020672), "dongguan");
// 设置中山的坐标
redisTemplate.opsForGeo().add(redisKey, new Point(113.392616, 22.515951), "zhongshan");
// 定义距离
Distance distance = new Distance(100, RedisGeoCommands.DistanceUnit.KILOMETERS);
// 获取各个城市的hash
List<String> hashList = redisTemplate.opsForGeo().hash(redisKey, "shenzhen", "guangzhou", "dongguan", "zhongshan");
log.info("获取各个城市的hash:{}", hashList);
}
取各个城市的hash:[ws0br3xnkn0, ws0e9xg09v0, ws0fuqz90u0, ws08h6cuzm0]