Redis GEODIST 命令 - 返回两个给定位置之间的距离
程序员文章站
2022-07-13 13:54:52
...
前言
基于LBS服务的需求已常态化,其中一个非常常见的需求就是给点两个位置,要计算返回这两位位置间的距离。比较简单做法,是根据这两个位置的经纬度,计算出它们之间的直线距离。
实践
redis 客户端登录,脚本执行
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEODIST Sicily Palermo Catania
"166274.15156960039"
redis> GEODIST Sicily Palermo Catania km
"166.27415156960038"
redis> GEODIST Sicily Palermo Catania mi
"103.31822459492736"
redis> GEODIST Sicily Foo Bar
(nil)
redis>
Sicily 是自定义的组名,同Sicily 把Palermo与Catania分为一对。
GEOADD 加入数据到redis
GEODIST 对加入的数据进行计算
km、mi是单位
注意点
指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。
GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。
计算出的距离会以双精度浮点数的形式被返回。 如果给定的位置元素不存在, 那么命令返回空值。
如果两个位置之间的其中一个不存在, 那么命令返回空值。
java中应用
Jedis类关键源码:
@Resource
private JedisPool jedisPool;
/**
* 单个点位置加入
*/
public Long geoAdd(String key, double longitude, double latitude, String member){
Jedis jedis=null;
Long result=null;
try {
jedis=jedisPool.getResource();
result=jedis.geoadd(key ,longitude,latitude,member);
} catch (Exception e) {
log.error("redis异常,异常信息:",e);
}finally {
release(jedis);
}
return result;
}
/**
* 批量加入多个点位置
*/
public Long geoadd(String key, Map<String, GeoCoordinate> memberCoordinateMap) {
Jedis jedis=null;
Long result=null;
try {
jedis=jedisPool.getResource();
result=jedis.geoadd(key ,memberCoordinateMap);
} catch (Exception e) {
log.error("redis异常,异常信息:",e);
}finally {
release(jedis);
}
return result;
}
/**
* 计算距离
*/
public Double geoDist(String key , String member1, String member2, GeoUnit unit){
Jedis jedis=null;
Double result=null;
try {
jedis=jedisPool.getResource();
result=jedis.geodist(key,member1,member2,unit);
} catch (Exception e) {
log.error("redis异常,异常信息:",e);
}finally {
release(jedis);
}
return result;
}
对照上面的例子,在java代码中如下调用:
geoAdd(“Sicily”,13.361389,38.115556,“Palermo”);
geoAdd(“Sicily”,15.087269,37.502669,“Catania”);
geoDist(“Sicily”,“Palermo”,“Catania”,GeoUnit.KM);
总结
调用步骤很简单:
1、在某个总key下,加入子key及对应位置信息。
2、计算某个总key下,某两个子key 位置信息的距离,默认单位是m,可以在单位常量中选择。
以上只是简单应用,实际投产需考虑多线程、并发及缓存时效等场景处理。