最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Redis中地理位置功能Geospatial的應(yīng)用

 更新時(shí)間:2023年06月01日 09:46:04   作者:蜀山劍客李沐白  
Geospatial?Indexes?是?Redis?提供的一種數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)和查詢地理位置信息,這篇文章就來(lái)和大家詳細(xì)講講Geospatial的具體應(yīng)用吧

Geospatial Indexes 是 Redis 提供的一種數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)和查詢地理位置信息。它可以將地理位置的經(jīng)度和緯度編碼為二維平面上的點(diǎn),并支持根據(jù)距離或矩形區(qū)域查詢附近的地理位置點(diǎn),這使得它在很多場(chǎng)景下被廣泛應(yīng)用,比如 LBS(Location Based Service)、智能推薦、出行規(guī)劃等。

Redis 中 Geospatial Indexes 是通過(guò)有序集合實(shí)現(xiàn)的,其內(nèi)部使用 zset 數(shù)據(jù)類型來(lái)存儲(chǔ)地理位置點(diǎn)的經(jīng)緯度和成員信息。其中,經(jīng)緯度以浮點(diǎn)數(shù)表示,成員信息則可以是用戶 ID、商鋪名稱等。

在使用 Geospatial Indexes 時(shí),我們需要注意以下幾個(gè)方面:

  • 地理位置點(diǎn)的經(jīng)緯度采用 WGS-84 坐標(biāo)系表示;
  • 距離單位默認(rèn)為米,可以通過(guò)參數(shù)設(shè)置為其他單位;
  • 矩形區(qū)域查詢默認(rèn)采用左閉右開的方式,即包括左邊界,不包括右邊界。

Geospatial Indexes 的數(shù)據(jù)結(jié)構(gòu)

Geospatial Indexes 在 Redis 中是通過(guò) zset 實(shí)現(xiàn)的,其中地理位置點(diǎn)的經(jīng)緯度被編碼為 zset 中每個(gè) member 的分?jǐn)?shù)。具體來(lái)說(shuō),Redis 在將經(jīng)緯度編碼為分?jǐn)?shù)時(shí),使用了 zset 的有序性質(zhì),將其轉(zhuǎn)化為一個(gè)唯一的、不可重復(fù)的浮點(diǎn)數(shù)。

例如,如果我們要存儲(chǔ)以下三個(gè)地理位置點(diǎn):

39.9042° N, 116.4074° E
上海 31.2304° N, 121.4737° E
廣州 23.1291° N, 113.2644° E

則可以將經(jīng)緯度編碼為分?jǐn)?shù),存入 zset 中,如下圖所示:

ZADD city_geo_location 116.4074 39.9042 "北京"
ZADD city_geo_location 121.4737 31.2304 "上海"
ZADD city_geo_location 113.2644 23.1291 "廣州"

此時(shí),zset 中的每個(gè) member 都代表了一個(gè)地理位置點(diǎn),其分?jǐn)?shù)則代表了該點(diǎn)的唯一標(biāo)識(shí),在進(jìn)行距離或矩形區(qū)域查詢時(shí)將會(huì)用到。

常用命令

Redis 中的 Geospatial Indexes 提供了一組命令來(lái)管理和查詢地理位置數(shù)據(jù),包括以下命令:

1.GEOADD:向有序集合中添加一個(gè)或多個(gè)地理位置元素。

語(yǔ)法:GEOADD key longitude latitude member [longitude latitude member ...]

參數(shù):

  • key:必需,要添加元素的有序集合的鍵名。
  • longitude:必需,要添加元素的經(jīng)度值,范圍為 -180 到 180 度。
  • latitude:必需,要添加元素的緯度值,范圍為 -90 到 90 度。
  • member:必需,要添加元素的成員名,必須為字符串類型。

示例:GEOADD restaurants 139.7329 35.6634 "Sushi Dai" 139.7712 35.7100 "Afuri Ramen" 139.7198 35.7101 "Komoro Soba"

2.GEOPOS:獲取指定成員在有序集合中的經(jīng)緯度坐標(biāo)。

語(yǔ)法:GEOPOS key member [member ...]

參數(shù):

  • key:必需,要獲取經(jīng)緯度坐標(biāo)的有序集合的鍵名。
  • member:必需,要獲取經(jīng)緯度坐標(biāo)的元素的成員名,可以指定多個(gè)成員名。

返回值:一個(gè)二維數(shù)組,每個(gè)子數(shù)組表示一個(gè)成員的經(jīng)緯度坐標(biāo),每個(gè)子數(shù)組包含兩個(gè)元素,分別表示經(jīng)度和緯度。

示例:GEOPOS restaurants "Sushi Dai" "Komoro Soba",返回值為 [["139.7329","35.6634"],["139.7198","35.7101"]]

3.GEODIST:獲取有序集合中兩個(gè)成員之間的距離。

語(yǔ)法:GEODIST key member1 member2 [unit]

參數(shù):

  • key:必需,要計(jì)算距離的有序集合的鍵名。
  • member1:必需,第一個(gè)成員的名字。
  • member2:必需,第二個(gè)成員的名字。
  • unit:可選,默認(rèn)為米,表示要返回的距離單位,可以是以下四種單位之一:"m"(米)、"km"(千米)、"mi"(英里)、"ft"(英尺)。

返回值:兩個(gè)成員之間的距離值,以指定的單位表示。

示例:GEODIST restaurants "Sushi Dai" "Komoro Soba" km,返回值為 "2.0499"

4.GEORADIUS:按照給定的經(jīng)緯度坐標(biāo)和半徑范圍查找有序集合中符合條件的元素。

語(yǔ)法:GEORADIUS key longitude latitude radius m|km|mi|ft [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]

參數(shù):

  • key:必需,要查詢的有序集合的鍵名。
  • longitude:必需,中心點(diǎn)的經(jīng)度值,范圍為 -180 到 180 度。
  • latitude:必需,中心點(diǎn)的緯度值,范圍為 -90 到 90 度。
  • radius:必需,半徑范圍,可以是以下格式之一:m(米)、km(千米)、mi(英里)或 ft(英尺)
  • m|km|mi|ft:必需,半徑范圍的單位,可以是以下四種單位之一:"m"(米)、"km"(千米)、"mi"(英里)、"ft"(英尺)。
  • WITHCOORD:可選,指示返回結(jié)果是否包含元素的經(jīng)緯度坐標(biāo)。如果指定了該參數(shù),則結(jié)果將包含經(jīng)緯度坐標(biāo),否則不包含經(jīng)緯度坐標(biāo)。
  • WITHDIST:可選,指示返回結(jié)果是否包含元素與中心點(diǎn)之間的距離值。如果指定了該參數(shù),則結(jié)果將包含距離值,否則不包含距離值。
  • ASC|DESC:可選,指示返回結(jié)果是否按照距離值(從小到大)排序。如果指定了該參數(shù),則結(jié)果將按距離值排序,否則默認(rèn)按有序集合中的順序返回結(jié)果。
  • COUNT count:可選,指示返回結(jié)果的數(shù)量限制。如果指定了該參數(shù),則結(jié)果將最多包含 count 個(gè)元素,否則返回所有符合條件的元素。

返回值:若干個(gè)符合條件的元素(根據(jù)查詢參數(shù)而定),每個(gè)元素由成員名、經(jīng)度坐標(biāo)和緯度坐標(biāo)組成。如果指定了 WITHDIST 參數(shù),則每個(gè)元素還包含距離值。如果指定了 WITHCOORD 參數(shù),則每個(gè)元素還包含經(jīng)緯度坐標(biāo)。

示例:GEORADIUS restaurants 139.7329 35.6634 5 km WITHCOORD WITHDIST,表示查找以經(jīng)緯度 (139.7329, 35.6634) 為中心,半徑為 5 公里范圍內(nèi)的所有元素,并返回它們與中心點(diǎn)之間的距離值和經(jīng)緯度坐標(biāo)。

5.GEORADIUSBYMEMBER:按照給定的成員名和半徑范圍查找有序集合中符合條件的元素。

語(yǔ)法:GEORADIUSBYMEMBER key member radius m|km|mi|ft [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]

參數(shù):

  • key:必需,要查詢的有序集合的鍵名。
  • member:必需,中心點(diǎn)的成員名。
  • radius:必需,半徑范圍,可以是以下格式之一:m(米)、km(千米)、mi(英里)或 ft(英尺)
  • m|km|mi|ft:必需,半徑范圍的單位,可以是以下四種單位之一:"m"(米)、"km"(千米)、"mi"(英里)、"ft"(英尺)。
  • WITHCOORD:可選,指示返回結(jié)果是否包含元素的經(jīng)緯度坐標(biāo)。如果指定了該參數(shù),則結(jié)果將包含經(jīng)緯度坐標(biāo),否則不包含經(jīng)緯度坐標(biāo)。
  • WITHDIST:可選,指示返回結(jié)果是否包含元素與中心點(diǎn)之間的距離值。如果指定了該參數(shù),則結(jié)果將包含距離值,否則不包含距離值。
  • ASC|DESC:可選,指示返回結(jié)果是否按照距離值(從小到大)排序。如果指定了該參數(shù),則結(jié)果將按距離值排序,否則默認(rèn)按有序集合中的順序返回結(jié)果。
  • COUNT count:可選,指示返回結(jié)果的數(shù)量限制。如果指定了該參數(shù),則結(jié)果將最多包含 count 個(gè)元素,否則返回所有符合條件的元素。

返回值:若干個(gè)符合條件的元素(根據(jù)查詢參數(shù)而定),每個(gè)元素由成員名、經(jīng)度坐標(biāo)和緯度坐標(biāo)組成。如果指定了 WITHDIST 參數(shù),則每個(gè)元素還包含距離值。如果指定了 WITHCOORD 參數(shù),則每個(gè)元素還包含經(jīng)緯度坐標(biāo)。

示例:GEORADIUSBYMEMBER restaurants "Sushi Dai" 5 km WITHCOORD WITHDIST,表示查找以成員名 "Sushi Dai" 對(duì)應(yīng)的經(jīng)緯度為中心,半徑為 5 公里范圍內(nèi)的所有元素,并返回它們與中心點(diǎn)之間的距離值和經(jīng)緯度坐標(biāo)。

6.GEOHASH:獲取指定成員在有序集合中的 Geohash 值。

語(yǔ)法:GEOHASH key member [member ...]

參數(shù):

  • key:必需,要獲取 Geohash 值的有序集合的鍵名。
  • member:必需,要獲取 Geohash 值的元素的成員名,可以指定多個(gè)成員名。

返回值:一個(gè)數(shù)組,每個(gè)元素表示一個(gè)成員的 Geohash 值。

示例:GEOHASH restaurants "Sushi Dai" "Komoro Soba",返回值為 ["xn7743","xn773w"]

7.GEOINTERSECTS:檢查指定的兩個(gè)成員之間是否存在任何交集。

語(yǔ)法:GEOINTERSECTS key member1 member2

參數(shù):

  • key:必需,要檢查交集的有序集合的鍵名。
  • member1:必需,第一個(gè)成員的名字。
  • member2:必需,第二個(gè)成員的名字。

返回值:一個(gè)整數(shù)值,如果兩個(gè)成員之間存在交集,則返回 1,否則返回 0。

示例:GEOINTERSECTS restaurants "Sushi Dai" "Komoro Soba",如果 "Sushi Dai" 和 "Komoro Soba" 代表的位置之間存在任何交集,則返回 1,否則返回 0。

實(shí)用場(chǎng)景示例

1. 找出某一經(jīng)緯度周圍的餐館

import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
import java.util.List;
public class RestaurantFinder {
    private final static String HOST = "localhost";
    private final static int PORT = 6379;
    private final static int TIMEOUT = 5000;
    private final static String PASSWORD = "";
    private static final String KEY_RESTAURANT_LOCATION = "restaurant_location";
    private static Jedis jedis = null;
    static {
        try {
            jedis = new Jedis(HOST, PORT, TIMEOUT);
            if (!PASSWORD.isEmpty()) {
                jedis.auth(PASSWORD);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 添加餐館的經(jīng)緯度信息
     *
     * @param longitude 經(jīng)度
     * @param latitude  緯度
     * @param name      餐館名稱
     * @return
     */
    public Long addRestaurant(double longitude, double latitude, String name) {
        return jedis.geoadd(KEY_RESTAURANT_LOCATION, longitude, latitude, name);
    }
    /**
     * 根據(jù)給定的坐標(biāo)和半徑查找周圍的餐館
     *
     * @param longitude 經(jīng)度
     * @param latitude  緯度
     * @param radius    半徑,單位為米
     * @return
     */
    public List<GeoRadiusResponse> findNearbyRestaurants(double longitude, double latitude, double radius) {
        return jedis.georadius(KEY_RESTAURANT_LOCATION, longitude, latitude, radius, GeoUnit.M);
    }
    /**
     * 測(cè)試
     *
     * @param args
     */
    public static void main(String[] args) {
        RestaurantFinder finder = new RestaurantFinder();
        finder.addRestaurant(121.451087, 31.228591, "麥當(dāng)勞");
        finder.addRestaurant(121.454987, 31.227568, "星巴克");
        finder.addRestaurant(121.455831, 31.225719, "肯德基");
        List<GeoRadiusResponse> restaurants = finder.findNearbyRestaurants(121.453289, 31.228032, 500);
        for (GeoRadiusResponse restaurant : restaurants) {
            System.out.println(restaurant.getMemberByString() + " " + restaurant.getDistance());
        }
    }
}

2. 按照距離排序查詢景點(diǎn)

import redis.clients.jedis.GeoRadiusParam;
import redis.clients.jedis.GeoRadiusResponse;
import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
import java.util.List;
public class ScenicSpotFinder {
    private final static String HOST = "localhost";
    private final static int PORT = 6379;
    private final static int TIMEOUT = 5000;
    private final static String PASSWORD = "";
    private static final String KEY_SPOT_LOCATION = "spot_location";
    private static Jedis jedis = null;
    static {
        try {
            jedis = new Jedis(HOST, PORT, TIMEOUT);
            if (!PASSWORD.isEmpty()) {
                jedis.auth(PASSWORD);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 添加景點(diǎn)的經(jīng)緯度信息
     *
     * @param longitude 經(jīng)度
     * @param latitude  緯度
     * @param name      景點(diǎn)名稱
     * @return
     */
    public Long addScenicSpot(double longitude, double latitude, String name) {
        return jedis.geoadd(KEY_SPOT_LOCATION, longitude, latitude, name);
    }
    /**
     * 根據(jù)給定的坐標(biāo)和半徑查找周圍的景點(diǎn),并按照距離排序
     *
     * @param longitude 經(jīng)度
     * @param latitude  緯度
     * @param radius    半徑,單位為米
     * @return
     */
    public List<GeoRadiusResponse> findNearbyScenicSpots(double longitude, double latitude, double radius) {
        GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam().sortAscending();
        return jedis.georadius(KEY_SPOT_LOCATION, longitude, latitude, radius, GeoUnit.M, geoRadiusParam);
    }
    /**
     * 測(cè)試
     *
     * @param args
     */
    public static void main(String[] args) {
        ScenicSpotFinder finder = new ScenicSpotFinder();
        finder.addScenicSpot(121.451087, 31.228591, "東方明珠");
        finder.addScenicSpot(121.454987, 31.227568, "外灘");
        finder.addScenicSpot(121.455831, 31.225719, "人民廣場(chǎng)");
        List<GeoRadiusResponse> spots = finder.findNearbyScenicSpots(121.453289, 31.228032, 500);
        for (GeoRadiusResponse spot : spots) {
            System.out.println(spot.getMemberByString() + " " + spot.getDistance());
        }
    }
}

3. 根據(jù)經(jīng)緯度計(jì)算兩點(diǎn)距離

import redis.clients.jedis.GeoUnit;
import redis.clients.jedis.Jedis;
public class DistanceCalculator {
    private final static String HOST = "localhost";
    private final static int PORT = 6379;
    private final static int TIMEOUT = 5000;
    private final static String PASSWORD = "";
    private static Jedis jedis = null;
    static {
        try {
            jedis = new Jedis(HOST, PORT, TIMEOUT);
            if (!PASSWORD.isEmpty()) {
                jedis.auth(PASSWORD);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 計(jì)算兩個(gè)經(jīng)緯度之間的距離
     *
     * @param longitude1 經(jīng)度1
     * @param latitude1  緯度1
     * @param longitude2 經(jīng)度2
     * @param latitude2  緯度2
     * @return
     */
    public Double calculateDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        return jedis.geodist("distance", longitude1, latitude1, longitude2, latitude2, GeoUnit.M);
    }
    /**
     * 測(cè)試
     *
     * @param args
     */
    public static void main(String[] args) {
        DistanceCalculator calculator = new DistanceCalculator();
        double distance = calculator.calculateDistance(121.453289, 31.228032, 121.451087, 31.228591);
        System.out.println(distance);
    }
}

在實(shí)際開發(fā)中,需要注意以下幾點(diǎn):

  • 每個(gè)位置都需要一個(gè)唯一的標(biāo)識(shí)符。
  • 經(jīng)度和緯度的值需要使用正確的格式。
  • 半徑的單位為米。
  • Redis 地理位置功能支持多種查詢方式,例如矩形查詢、關(guān)鍵字查詢等,需要根據(jù)實(shí)際需求進(jìn)行選擇。

以上就是詳解Redis中地理位置功能Geospatial的應(yīng)用的詳細(xì)內(nèi)容,更多關(guān)于Redis Geospatial的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 搭建Caffeine+Redis多級(jí)緩存機(jī)制

    搭建Caffeine+Redis多級(jí)緩存機(jī)制

    本文主要介紹了搭建Caffeine+Redis多級(jí)緩存機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • Redis哨兵模式實(shí)現(xiàn)一主二從三哨兵

    Redis哨兵模式實(shí)現(xiàn)一主二從三哨兵

    本文主要介紹了Redis哨兵模式實(shí)現(xiàn)一主二從三哨兵,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • redis.config配置文件

    redis.config配置文件

    在使用Redis時(shí),我們通常需要對(duì)Redis進(jìn)行一些配置,以確保其能夠正常運(yùn)行并滿足我們的需求,本文主要介紹了redis.config配置文件,感興趣的可以了解一下
    2023-11-11
  • Linux、Windows下Redis的安裝即Redis的基本使用詳解

    Linux、Windows下Redis的安裝即Redis的基本使用詳解

    Redis是一個(gè)基于內(nèi)存的key-value結(jié)構(gòu)數(shù)據(jù)庫(kù),Redis 是互聯(lián)網(wǎng)技術(shù)領(lǐng)域使用最為廣泛的存儲(chǔ)中間件,這篇文章主要介紹了Linux、Windows下Redis的安裝即Redis的基本使用詳解,需要的朋友可以參考下
    2022-09-09
  • Window server中安裝Redis的超詳細(xì)教程

    Window server中安裝Redis的超詳細(xì)教程

    這篇文章主要介紹了Window server中安裝Redis的教程,本文通過(guò)圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Redis緩存預(yù)熱的概念及方法詳解

    Redis緩存預(yù)熱的概念及方法詳解

    文章解釋了什么是緩存預(yù)熱,為什么邏輯過(guò)期必須預(yù)熱,并提供了三種簡(jiǎn)單的方法來(lái)實(shí)現(xiàn)緩存預(yù)熱,同時(shí)介紹了saveShop2Redis方法的作用和角色,感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • Redis配置文件redis.conf詳細(xì)配置說(shuō)明

    Redis配置文件redis.conf詳細(xì)配置說(shuō)明

    本文列出了Redis的配置文件redis.conf的各配置項(xiàng)的詳細(xì)說(shuō)明,簡(jiǎn)單易懂
    2018-03-03
  • redis隊(duì)列和秒殺應(yīng)用方式

    redis隊(duì)列和秒殺應(yīng)用方式

    這篇文章主要介紹了redis隊(duì)列和秒殺應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • redis如何取hash的值

    redis如何取hash的值

    這篇文章主要介紹了redis如何取hash的值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Redis超詳細(xì)分析分布式鎖

    Redis超詳細(xì)分析分布式鎖

    在單體應(yīng)用中,如果我們對(duì)共享數(shù)據(jù)不進(jìn)行加鎖操作,會(huì)出現(xiàn)數(shù)據(jù)一致性問(wèn)題,我們的解決辦法通常是加鎖。下面我們一起聊聊使用redis來(lái)實(shí)現(xiàn)分布式鎖
    2022-07-07

最新評(píng)論

六盘水市| 南和县| 壤塘县| 颍上县| 崇礼县| 金秀| 西青区| 方山县| 收藏| 高青县| 洛阳市| 伊通| 雷波县| 镇宁| 新丰县| 阿克苏市| 秦安县| 博客| 江都市| 镇远县| 天气| 竹溪县| 外汇| 江华| 安顺市| 化州市| 双峰县| 铜梁县| 黑水县| 长汀县| 林口县| 盘锦市| 门头沟区| 亚东县| 五指山市| 河池市| 勐海县| 高要市| 隆子县| 南城县| 隆尧县|