欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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类关键源码:
Redis GEODIST 命令 - 返回两个给定位置之间的距离

 @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,可以在单位常量中选择。
以上只是简单应用,实际投产需考虑多线程、并发及缓存时效等场景处理。