redis-Geo

Redis在3.2版本里面新增的一个功能就是对GEO(地理位置)的支持。

地理位置大概提供了6个命令,分别为:
1.GEOADD
2.GEODIST
3.GEOHASH
4.GEOPOS
5.GEORADIUS
6.GEORADIUSBYMEMBER
这个功能在现在互联网行业用处还是很多的,比如:
附近的人,网约车,外卖….
试验了一下,感觉非常好用,记录下来

package com.redis.geo;

import com.redis.util.RedisUtil;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.GeoCoordinate;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.geo.GeoRadiusParam;

import java.util.List;

/**
 * Geo
 */
public class GeoTest {


    /**
     * 向location中添加两个坐标信息
     */
    @Test
    public void geoAdd(){
        Jedis jedis = RedisUtil.getJedis();
        Long geoadd1 = jedis.geoadd("location", 121.377142, 31.180923, "local1");
        System.out.println("返回结果:"+geoadd1);
        Long geoadd2 = jedis.geoadd("location", 121.37686,31.176551, "local2");
        System.out.println("返回结果:"+geoadd2);
        Long geoadd3 = jedis.geoadd("location", 121.398156,31.180774, "local3");
        System.out.println("返回结果:"+geoadd3);
        Long geoadd4 = jedis.geoadd("location", 121.388814,31.187633, "local4");
        System.out.println("返回结果:"+geoadd4);
        Long geoadd5 = jedis.geoadd("location", 121.369698,31.180466, "local5");
        System.out.println("返回结果:"+geoadd5);
        Long geoadd6 = jedis.geoadd("location", 121.358775,31.177685, "local6");
        System.out.println("返回结果:"+geoadd6);
        Long geoadd7 = jedis.geoadd("location", 121.373148,31.16477, "local7");
        System.out.println("返回结果:"+geoadd7);
        Long geoadd8 = jedis.geoadd("location", 121.398444,31.167674, "local8");
        System.out.println("返回结果:"+geoadd8);
        Long geoadd9 = jedis.geoadd("location", 121.376885,31.203696, "local9");
        System.out.println("返回结果:"+geoadd9);
        Long geoadd10 = jedis.geoadd("location", 121.399306,31.186644, "local10");
        System.out.println("返回结果:"+geoadd10);
        Long geoadd11 = jedis.geoadd("location", 121.340665,31.169343, "local11");
        System.out.println("返回结果:"+geoadd11);

    }

    /**
     * 返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。
     * 指定单位的参数 unit 必须是以下单位的其中一个:
     * m 表示单位为米。
     * km 表示单位为千米。
     * mi 表示单位为英里。
     * ft 表示单位为英尺。
     */
    @Test
    public void geoDist(){
        Jedis jedis = RedisUtil.getJedis();
        Double geodist1 = jedis.geodist("location", "local1", "local2");
        System.out.println("获取两点的直线距离,默认单位m:"+geodist1);

        Double geodist2 = jedis.geodist("location", "local1", "local2", GeoUnit.M);
        System.out.println("获取两点的直线距离,指定单位m:"+geodist2);

        Double geodist3 = jedis.geodist("location", "local1", "local2", GeoUnit.KM);
        System.out.println("获取两点的直线距离,指定单位km:"+geodist3);
    }

    /**
     * 从key里返回所有给定位置元素的位置(经度和纬度)。
     * 返回值:GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成:
     *  第一个元素为给定位置元素的经度,
     *  第二个元素则为给定位置元素的纬度。
     *  当给定的位置元素不存在时, 对应的数组项为空值。
     */
    @Test
    public void geoPos(){
        Jedis jedis = RedisUtil.getJedis();
        List<GeoCoordinate> geopos1 = jedis.geopos("location", "local1","local2","local3","local4","local5","local6","local7","local8","local9","local10","local11");
        for (GeoCoordinate geopo : geopos1) {
            System.out.println("经度:"+geopo.getLongitude());
            System.out.println("纬度:"+geopo.getLatitude());
            System.out.println("==========================");
        }

    }


    /**
     * GEOHASH key member [member ...]
     * 命令描述:返回一个或多个位置元素的 Geohash 表示。
     * 通常使用表示位置的元素使用不同的技术,使用Geohash位置52点整数编码。
     * 由于编码和解码过程中所使用的初始最小和最大坐标不同,编码的编码也不同于标准。此命令返回一个标准的Geohash
     * 返回值:一个数组, 数组的每个项都是一个 geohash 。
     * 命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。
     */
    @Test
    public void geoHash(){
        Jedis jedis = RedisUtil.getJedis();
        List<String> geohash = jedis.geohash("location", "local1","local2","local3","local4","local5","local6","local7","local8","local9","local10","local11");
        for (String s : geohash) {
            System.out.println("geoHash值:"+s);
        }
    }

    /**
     * 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
     * 范围可以使用以下其中一个单位:
     * m 表示单位为米。
     * km 表示单位为千米。
     * mi 表示单位为英里。
     * ft 表示单位为英尺。
     * 在给定以下可选项时, 命令会返回额外的信息:
     *
     * WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
     * WITHCOORD: 将位置元素的经度和维度也一并返回。
     * WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。这个选项主要用于底层应用或者调试, 实际中的作用并不大。
     * 命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:
     *
     * ASC: 根据中心的位置, 按照从近到远的方式返回位置元素。
     * DESC: 根据中心的位置, 按照从远到近的方式返回位置元素。
     * 在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。
     *      虽然用户可以使用 COUNT <count> 选项去获取前 N 个匹配元素,
     *      但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时,
     *      即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。
     *      但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。
     *
     * 返回值:
     * 在没有给定任何 WITH 选项的情况下, 命令只会返回一个像 [“New York”,”Milan”,”Paris”] 这样的线性(linear)列表。
     * 在指定了 WITHCOORD 、 WITHDIST 、 WITHHASH 等选项的情况下, 命令返回一个二层嵌套数组, 内层的每个子数组就表示一个元素。
     * 在返回嵌套数组时, 子数组的第一个元素总是位置元素的名字。 至于额外的信息, 则会作为子数组的后续元素, 按照以下顺序被返回:
     *
     * 以浮点数格式返回的中心与位置元素之间的距离, 单位与用户指定范围时的单位一致。
     * geohash 整数。
     * 由两个元素组成的坐标,分别为经度和纬度。
     *
     * GeoRadiusParam使用的是链式写法:
     * 不加GeoRadiusParam.geoRadiusParam().withCoord()参数返回的coordinate为null
     * 不加GeoRadiusParam.geoRadiusParam().withDist()参数返回的distance为0
     * 不加GeoRadiusParam.geoRadiusParam().sortAscending()或者sortDescending()参数返回值是不排序的(按照distance排序)
     */
    @Test
    public void geoRadius(){
        Jedis jedis = RedisUtil.getJedis();
        List<GeoRadiusResponse> location = jedis.georadius("location",121.375735,31.184914,1, GeoUnit.KM,GeoRadiusParam.geoRadiusParam().withCoord().withDist().sortDescending());
        System.out.println("==指定范围内的数量为:"+location.size());
        for (GeoRadiusResponse geoRadiusResponse : location) {
            System.out.println("distance:"+geoRadiusResponse.getDistance());
            System.out.println("coordinate:"+geoRadiusResponse.getCoordinate());
            System.out.println("lon:"+geoRadiusResponse.getCoordinate().getLongitude());
            System.out.println("lat:"+geoRadiusResponse.getCoordinate().getLatitude());
            System.out.println("memberByString:"+geoRadiusResponse.getMemberByString());
            System.out.println("==================================================");
        }

    }

    /**
     * georadiusByMember方法与georadius类似,只不过这里指定的不是坐标,而是member
     */
    @Test
    public void geoRadiusByMember(){
        Jedis jedis = RedisUtil.getJedis();
        List<GeoRadiusResponse> locations = jedis.georadiusByMember("location", "local2", 2, GeoUnit.KM,GeoRadiusParam.geoRadiusParam().withCoord().withDist());
        System.out.println("==指定范围内的数量为:"+locations.size());
        for (GeoRadiusResponse rr : locations) {
            System.out.println("distance:"+rr.getDistance());
            System.out.println("coordinate:"+rr.getCoordinate());
            System.out.println("lon:"+rr.getCoordinate().getLongitude());
            System.out.println("lat:"+rr.getCoordinate().getLatitude());
            System.out.println("memberByString:"+rr.getMemberByString());
            System.out.println("==================================================");
        }
    }


}

猜你喜欢

转载自blog.csdn.net/jinjin603/article/details/80772542
GEO