欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解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)采用左閉右開(kāi)的方式,即包括左邊界,不包括右邊界。

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)緯度周?chē)牟宛^

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)和半徑查找周?chē)牟宛^
     *
     * @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)和半徑查找周?chē)木包c(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í)際開(kāi)發(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)文章

  • 利用Redis實(shí)現(xiàn)防止接口重復(fù)提交功能

    利用Redis實(shí)現(xiàn)防止接口重復(fù)提交功能

    大家好,本篇文章主要講的是利用Redis實(shí)現(xiàn)防止接口重復(fù)提交功能,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 深入解析Redis的LRU與LFU算法實(shí)現(xiàn)

    深入解析Redis的LRU與LFU算法實(shí)現(xiàn)

    這篇文章主要重點(diǎn)介紹了Redis的LRU與LFU算法實(shí)現(xiàn),并分析總結(jié)了兩種算法的實(shí)現(xiàn)效果以及存在的問(wèn)題,并闡述其優(yōu)劣特性,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2023-07-07
  • 利用控制臺(tái)如何對(duì)Redis執(zhí)行增刪改查命令

    利用控制臺(tái)如何對(duì)Redis執(zhí)行增刪改查命令

    這篇文章主要給大家介紹了關(guān)于利用控制臺(tái)如何對(duì)Redis執(zhí)行增刪改查命令的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Redis IP地址的綁定的實(shí)現(xiàn)

    Redis IP地址的綁定的實(shí)現(xiàn)

    這篇文章主要介紹了Redis IP地址的綁定的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Redis持久化方式之RDB和AOF的原理及優(yōu)缺點(diǎn)

    Redis持久化方式之RDB和AOF的原理及優(yōu)缺點(diǎn)

    在Redis中,數(shù)據(jù)可以分為兩類,即內(nèi)存數(shù)據(jù)和磁盤(pán)數(shù)據(jù),Redis?提供了兩種不同的持久化方式,其中?RDB?是快照備份機(jī)制,AOF?則是追加寫(xiě)操作機(jī)制,本文將詳細(xì)給大家介紹Redis?持久化方式RDB和AOF的原理及優(yōu)缺點(diǎn),感興趣的同學(xué)可以跟著小編一起來(lái)學(xué)習(xí)
    2023-06-06
  • Redis有序集合類型的常用命令小結(jié)

    Redis有序集合類型的常用命令小結(jié)

    這篇文章先是給大家簡(jiǎn)單介紹了一下有序集合類型,然后詳細(xì)整理了關(guān)于Redis有序集合類型的常用命令,通過(guò)整理的這些命令相信會(huì)給大家的工作或?qū)W習(xí)帶來(lái)一定的幫助,有需要的朋友們下面來(lái)一起看看吧。
    2016-09-09
  • 解析高可用Redis服務(wù)架構(gòu)分析與搭建方案

    解析高可用Redis服務(wù)架構(gòu)分析與搭建方案

    我們按照由簡(jiǎn)至繁的步驟,搭建一個(gè)最小型的高可用的Redis服務(wù)。 本文通過(guò)四種方案給大家介紹包含每種方案的優(yōu)缺點(diǎn)及詳細(xì)解說(shuō),具體內(nèi)容詳情跟隨小編一起看看吧
    2021-06-06
  • Redis的9種數(shù)據(jù)類型用法解讀

    Redis的9種數(shù)據(jù)類型用法解讀

    這篇文章主要介紹了Redis的9種數(shù)據(jù)類型用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù)的教程

    Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù)的教程

    RediSearch提供了一種簡(jiǎn)單快速的方法對(duì) hash 或者 json 類型數(shù)據(jù)的任何字段建立二級(jí)索引,然后就可以對(duì)被索引的 hash 或者 json 類型數(shù)據(jù)字段進(jìn)行搜索和聚合操作,這篇文章主要介紹了Redis全文搜索教程之創(chuàng)建索引并關(guān)聯(lián)源數(shù)據(jù),需要的朋友可以參考下
    2023-12-12
  • Redis 緩存滿了如何解決

    Redis 緩存滿了如何解決

    Redis 緩存使用內(nèi)存來(lái)保存數(shù)據(jù),隨著需要緩存的數(shù)據(jù)量越來(lái)越大,有限的緩存空間不可避免地會(huì)被寫(xiě)滿,本文主要介紹了Redis 緩存滿了如何解決,感興趣的可以了解一下
    2023-08-08

最新評(píng)論