REDIS10_GEO添加距离半径命令美团附近酒店推送案例
Posted 所得皆惊喜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了REDIS10_GEO添加距离半径命令美团附近酒店推送案例相关的知识,希望对你有一定的参考价值。
文章目录
- ①. 添加元素 - GEOADD
- ②. 返回经纬度 - GEOPOS
- ③. 返回距离 - GEODIST
- ④. 返回哈希 - GEOHASH
- ⑤. 半径 - GEORADIUS
- ⑥. GEORADIUSBYMEMBER
- ⑦. 美团地图位置附近的酒店推送
①. 添加元素 - GEOADD
-
①. 添加:GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member …]
-
②. 该命令的参数格式是固定的,即(longitude latitude member),经度要在纬度之前
-
③. GEOADD 坐标是有限的: 非常接近两极的区域是无法被索引的。坐标被 EPSG:900913 / EPSG:3785 / OSGEO:41001规范限制, 合法值如下:
- 有效的经度介于-180度至180度之间
- 有效的纬度介于-85.05112878度至85.05112878度之间
# 当给定的经纬度超出上述合法范围时,会返回error
127.0.0.1:6379> geoadd city 89.0 99 nanji
(error) ERR invalid longitude,latitude pair 89.000000,99.000000
- ④. Redis GEO没有删除命令 GEODEL,因为底层使用的是Sorted Set,所以完全可以使用ZREM 命令删除
127.0.0.1:6379> geoadd city 116.41667 39.91667 beijing 121.43333 34.50000 shanghai 117.20000 39.13333 tianjin
(integer) 3
②. 返回经纬度 - GEOPOS
-
①. 命令格式:GEOPOS key member [member …]
-
②. 返回给定元素对应的经纬度
-
③. 使用GEOADD添加的元素,会被GeoHash转化为52位比特值,因此使用GEOPOS取出值并转为经纬度时,可能与添加的经纬度值有少许差异
-
④. 命令接收多个可变参数,返回值始终是数组形式
数组:存在的元素返回经纬度,不存在的元素返回nil
127.0.0.1:6379> geoadd city 116.41667 39.91667 beijing 121.43333 34.50000 shanghai 117.20000 39.13333 tianjin
(integer) 3
127.0.0.1:6379> geopos city beijing nanjing
1) 1) "116.41667157411575317"
2) "39.91667095273589183"
2) (nil)
③. 返回距离 - GEODIST
-
①. 命令格式:GEODIST key member1 member2 [m|km|ft|mi]
-
②. 返回两个给定元素之间的距离
-
③. 距离度量支持如下参数
- m: 米(默认值)
- km: 千米
- ft: 英尺
- mi:英里
-
④. 在计算距离时会假设地球为完美的球形,在极限情况下最大会造成 0.5%的误差
-
⑤. 如果给定的元素中,有元素不存在,返回nil
127.0.0.1:6379> geoadd city 116.41667 39.91667 beijing 121.43333 34.50000 shanghai 117.20000 39.13333 tianjin
(integer) 3
127.0.0.1:6379> geodist city beijing shanghai
"748346.9287"
127.0.0.1:6379> geodist city beijing shanghai km
"748.3469"
④. 返回哈希 - GEOHASH
-
①. 命令格式:GEOHASH key member [member …]
-
②. 返回给定元素,GeoHash编码值对应的字符串表示
127.0.0.1:6379> geohash city beijing
1) "wx4g14s53n0"
⑤. 半径 - GEORADIUS
-
①. georadius:以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素
-
②. 命令:GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]
- WITHDIST: 在返回位置元素的同时,将位置元素与中心之间的距离也一并返回。距离的单位和用户给定的范围单位保持一致
- WITHCOORD: 将位置元素的经度和维度也一并返回
- WITHHASH: 以52位有符号整数的形式,返回位置元素经过原始geohash编码的有序集合分值这个选项主要用于底层应用或者调试,实际中的作用并不大
- COUNT限定返回的记录数
GEORADIUS city 116.418017 39.914402 10 km withdist withcoord count 10 withhash desc
127.0.0.1:6379> GEORADIUS city 116.418017 39.914402 10 km withdist withcoord count 10 withhash desc
1) 1) "beijing"
2) "0.2772"
3) (integer) 4069885649163649
4) 1) "116.41667157411575317"
2) "39.91667095273589183"
- ③. 简单来说就是查询指定位置一定距离内的元素,例如查询当前位置5公里内的银行
⑥. GEORADIUSBYMEMBER
-
①. 命令格式:GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]
-
②. 该命令与GEORADIUS命令基本一样,唯一不同的是:GEORADIUSBYMEMBER给定的是Sorted Set中的一个元素,而GEORADIUS给定的是具体经纬度。通过给定元素,其实就可以得到存储的经纬度,进而进行查询
127.0.0.1:6379> geoadd city 116.408 39.904 beijing 116.298 39.959 haidian 116.443 39.922 chaoyang 121.445 31.213 shanghai 121.23 31.07 minhang 117.246 39.117 tianjin
(integer) 6
127.0.0.1:6379> GEORADIUSBYMEMBER city beijing 500 km withdist asc
1) 1) "beijing"
2) "0.0000"
2) 1) "chaoyang"
2) "3.5948"
3) 1) "haidian"
2) "11.2004"
4) 1) "tianjin"
2) "113.2837"
⑦. 美团地图位置附近的酒店推送
- ①. 需求分析:
- 微信附近的人或者一公里以内的各种营业厅、加油站、理发店、超市…
- 附近的酒店
- 某公司附近三公里药店查询
@RestController
public class GeoController
public static final String CITY ="city";
@Autowired
private RedisTemplate redisTemplate;
@ApiOperation("新增天安门故宫长城经纬度")
@RequestMapping(value = "/geoadd",method = RequestMethod.POST)
public String geoAdd()
Map<String, Point> map= new HashMap<>();
map.put("天安门",new Point(116.403963,39.915119));
map.put("故宫",new Point(116.403414 ,39.924091));
map.put("长城" ,new Point(116.024067,40.362639));
redisTemplate.opsForGeo().add(CITY,map);
return map.toString();
@ApiOperation("获取地理位置的坐标")
@RequestMapping(value = "/geopos",method = RequestMethod.GET)
public Point position(String member)
//获取经纬度坐标
List<Point> list= this.redisTemplate.opsForGeo().position(CITY,member);
return list.get(0);
@ApiOperation("geohash算法生成的base32编码值")
@RequestMapping(value = "/geohash",method = RequestMethod.GET)
public String hash(String member)
//geohash算法生成的base32编码值
List<String> list= this.redisTemplate.opsForGeo().hash(CITY,member);
return list.get(0);
@ApiOperation("计算两个位置之间的距离")
@RequestMapping(value = "/geodist",method = RequestMethod.GET)
public Distance distance(String member1, String member2)
Distance distance= this.redisTemplate.opsForGeo().distance(CITY,member1,member2, RedisGeoCommands.DistanceUnit.KILOMETERS);
return distance;
/**
* 通过经度,纬度查找附近的
* 北京王府井位置116.418017,39.914402,这里为了方便讲课,故意写死
*/
@ApiOperation("通过经度,纬度查找附近的")
@RequestMapping(value = "/georadius",method = RequestMethod.GET)
public GeoResults radiusByxy()
//这个坐标是北京王府井位置
Circle circle = new Circle(116.418017, 39.914402, Metrics.MILES.getMultiplier());
//返回50条
RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(10);
GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults= this.redisTemplate.opsForGeo().radius(CITY,circle, args);
return geoResults;
/**
* 通过地方查找附近
*/
@ApiOperation("通过地方查找附近")
@RequestMapping(value = "/georadiusByMember",method = RequestMethod.GET)
public GeoResults radiusByMember()
String member="天安门";
//返回50条
RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(10);
//RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortDescending().limit(10);
//半径10公里内
Distance distance=new Distance(10, Metrics.KILOMETERS);
GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults= this.redisTemplate.opsForGeo().radius(CITY,member, distance,args);
return geoResults;
以上是关于REDIS10_GEO添加距离半径命令美团附近酒店推送案例的主要内容,如果未能解决你的问题,请参考以下文章