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

如何在 Java 中利用 redis 實現(xiàn) LBS 服務

 更新時間:2019年06月11日 11:30:23   作者:阿土伯已經(jīng)不是我  
基于位置的服務,是指通過電信移動運營商的無線電通訊網(wǎng)絡或外部定位方式,獲取移動終端用戶的位置信息,在GIS平臺的支持下,為用戶提供相應服務的一種增值業(yè)務。下面我們來一起學習一下吧

前言

LBS(基于位置的服務) 服務是現(xiàn)在移動互聯(lián)網(wǎng)中比較常用的功能。例如外賣服務中常用的我附近的店鋪的功能,通常是以用戶當前的位置坐標為基礎,查詢一定距離范圍類的店鋪,按照距離遠近進行倒序排序。

自從 redis 4 版本發(fā)布后, lbs 相關命令正式內置在 redis 的發(fā)行版中。要實現(xiàn)上述的功能,主要用到 redis geo 相關的兩個命令

GEOADD 和 GEORADIOUS

命令描述

GEOADD

GEOADD key longitude latitude member [longitude latitude member ...]

這個命令將指定的地理空間位置(緯度、經(jīng)度、名稱)添加到指定的 key 中。

有效的經(jīng)度從-180度到180度。

有效的緯度從-85.05112878度到85.05112878度。

當坐標位置超出上述指定范圍時,該命令將會返回一個錯誤。

該命令可以一次添加多個地理位置點

GEORADIOUS

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

這個命令以給定的經(jīng)緯度為中心, 返回鍵包含的位置元素當中, 與中心的距離不超過給定最大距離的所有位置元素。
范圍可以使用以下其中一個單位:

  • m 表示單位為米。
  • km 表示單位為千米。
  • mi 表示單位為英里。
  • ft 表示單位為英尺。

在給定以下可選項時, 命令會返回額外的信息:

  • WITHDIST: 在返回位置元素的同時, 將位置元素與中心之間的距離也一并返回。 距離的單位和用戶給定的范圍單位保持一致。
  • WITHCOORD: 將位置元素的經(jīng)度和維度也一并返回。
  • WITHHASH: 以 52 位有符號整數(shù)的形式, 返回位置元素經(jīng)過原始 geohash 編碼的有序集合分值。 這個選項主要用于底層應用或者調試, 實際中的作用并不大。
  • ASC: 根據(jù)中心的位置, 按照從近到遠的方式返回位置元素。
  • DESC: 根據(jù)中心的位置, 按照從遠到近的方式返回位置元素。
  • 在默認情況下, GEORADIUS 命令會返回所有匹配的位置元素。 雖然用戶可以使用 COUNT <count> 選項去獲取前 N 個匹配元素

接口定義

package com.x9710.common.redis;
import com.x9710.common.redis.domain.GeoCoordinate;
import com.x9710.common.redis.domain.Postion;
import java.util.List;
public interface LBSService {
/**
* 存儲一個位置
*
* @param postion 增加的位置對象
* @throws Exception
*/
boolean addPostion(Postion postion);
/**
* 查詢以指定的坐標為中心,指定的距離為半徑的范圍類的所有位置點
*
* @param center 中心點位置
* @param distinct 最遠距離,單位米
* @param asc 是否倒序排序
* @return 有效的位置
*/
List<Postion> radious(String type, GeoCoordinate center, Long distinct, Boolean asc);
}

實現(xiàn)的接口

package com.x9710.common.redis.impl;
import com.x9710.common.redis.LBSService;
import com.x9710.common.redis.RedisConnection;
import com.x9710.common.redis.domain.GeoCoordinate;
import com.x9710.common.redis.domain.Postion;
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.ArrayList;
import java.util.List;
public class LBSServiceRedisImpl implements LBSService {
private RedisConnection redisConnection;
private Integer dbIndex;

public void setRedisConnection(RedisConnection redisConnection) {
this.redisConnection = redisConnection;
}
public void setDbIndex(Integer dbIndex) {
this.dbIndex = dbIndex;
}
public boolean addPostion(Postion postion) {
Jedis jedis = redisConnection.getJedis();
try {
return (1L == jedis.geoadd(postion.getType(),
postion.getCoordinate().getLongitude(),
postion.getCoordinate().getLatitude(),
postion.getId()));
} finally {
if (jedis != null) {
jedis.close();
}
}
}
public List<Postion> radious(String type, GeoCoordinate center, Long distinct, Boolean asc) {
List<Postion> postions = new ArrayList<Postion>();
Jedis jedis = redisConnection.getJedis();
try {
GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam().withCoord().withDist();
if (asc) {
geoRadiusParam.sortAscending();
} else {
geoRadiusParam.sortDescending();
}
List<GeoRadiusResponse> responses = jedis.georadius(type,
center.getLongitude(),
center.getLatitude(),
distinct.doubleValue(),
GeoUnit.M,
geoRadiusParam);
if (responses != null) {
for (GeoRadiusResponse response : responses) {
Postion postion = new Postion(response.getMemberByString(),
type,
response.getCoordinate().getLongitude(),
response.getCoordinate().getLatitude());
postion.setDistinct(response.getDistance());
postions.add(postion);
}
}
} finally {
if (jedis != null) {
jedis.close();
}
}
return postions;
}
}

測試用例

package com.x9710.common.redis.test;
import com.x9710.common.redis.RedisConnection;
import com.x9710.common.redis.domain.GeoCoordinate;
import com.x9710.common.redis.domain.Postion;
import com.x9710.common.redis.impl.CacheServiceRedisImpl;
import com.x9710.common.redis.impl.LBSServiceRedisImpl;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* LBS服務測試類
*
* @author 楊高超
* @since 2017-12-28
*/
public class RedisLBSTest {
private CacheServiceRedisImpl cacheService;
private LBSServiceRedisImpl lbsServiceRedis;
private String type = "SHOP";
private GeoCoordinate center;
@Before
public void before() {
RedisConnection redisConnection = RedisConnectionUtil.create();
lbsServiceRedis = new LBSServiceRedisImpl();
lbsServiceRedis.setDbIndex(15);
lbsServiceRedis.setRedisConnection(redisConnection);
Postion postion = new Postion("2017122801", type, 91.118970, 29.654210);
lbsServiceRedis.addPostion(postion);
postion = new Postion("2017122802", type, 116.373472, 39.972528);
lbsServiceRedis.addPostion(postion);
postion = new Postion("2017122803", type, 116.344820, 39.948420);
lbsServiceRedis.addPostion(postion);
postion = new Postion("2017122804", type, 116.637920, 39.905460);
lbsServiceRedis.addPostion(postion);
postion = new Postion("2017122805", type, 118.514590, 37.448150);
lbsServiceRedis.addPostion(postion);
postion = new Postion("2017122806", type, 116.374766, 40.109508);
lbsServiceRedis.addPostion(postion);
center = new GeoCoordinate();
center.setLongitude(116.373472);
center.setLatitude(39.972528);
}
@Test
public void test10KMRadious() {
List<Postion> postions = lbsServiceRedis.radious(type, center, 1000 * 10L, true);
Assert.assertTrue(postions.size() == 2 && exist(postions, "2017122802") && exist(postions, "2017122803"));
}
@Test
public void test50KMRadious() {
List<Postion> postions = lbsServiceRedis.radious(type, center, 1000 * 50L, true);
Assert.assertTrue(postions.size() == 4
&& exist(postions, "2017122802")
&& exist(postions, "2017122803")
&& exist(postions, "2017122806")
&& exist(postions, "2017122804"));
}
private boolean exist(List<Postion> postions, String key) {
if (postions != null) {
for (Postion postion : postions) {
if (postion.getId().equals(key)) {
return true;
}
}
}
return false;
}
@Before
public void after() {
RedisConnection redisConnection = RedisConnectionUtil.create();
cacheService = new CacheServiceRedisImpl();
cacheService.setDbIndex(15);
cacheService.setRedisConnection(redisConnection);
cacheService.delObject(type);
}
}

測試結果

LBS 服務測試結果

后記

這樣,我們通過 redis 就能簡單實現(xiàn)一個我附近的小店的功能的 LBS服務。

代碼同步發(fā)布在 GitHub 倉庫

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • java實現(xiàn)json字符串格式化處理的工具類

    java實現(xiàn)json字符串格式化處理的工具類

    這篇文章主要為大家詳細介紹了如何使用java實現(xiàn)json字符串格式化處理的工具類,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • JAVA實現(xiàn)圖書管理系統(tǒng)項目

    JAVA實現(xiàn)圖書管理系統(tǒng)項目

    相信每一個學生學編程的時候,應該都會寫一個小項目——圖書管理系統(tǒng)。為什么這么說呢?我認為一個學校的氛圍很大一部分可以從圖書館的氛圍看出來,而圖書管理系統(tǒng)這個不大不小的項目,接觸的多,也比較熟悉,不會有陌生感,能夠練手,又有些難度,所以我的小項目也來了
    2021-10-10
  • 解決使用@Component會導致spring.factories中的EnableAutoConfiguration無效問題

    解決使用@Component會導致spring.factories中的EnableAutoConfiguration無效

    這篇文章主要介紹了解決使用@Component會導致spring.factories中的EnableAutoConfiguration無效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Shiro+Cas微服務化及前后端完全分離

    Shiro+Cas微服務化及前后端完全分離

    這篇文章主要為大家詳細介紹了Shiro+Cas微服務化及前后端完全分離,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Java生成Jar包方法步驟

    Java生成Jar包方法步驟

    在Java開發(fā)中,打包成JAR文件是一種常見的方式,本文主要介紹了Java生成Jar包方法步驟,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • 基于idea解決springweb項目的Java文件無法執(zhí)行問題

    基于idea解決springweb項目的Java文件無法執(zhí)行問題

    這篇文章給大家介紹了基于idea解決springweb項目的Java文件無法執(zhí)行問題,文中通過圖文結合的方式給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • 三道MySQL新手入門面試題,通往自由的道路

    三道MySQL新手入門面試題,通往自由的道路

    這篇文章主要為大家分享了最有價值的3道MySQL面試題,,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 一篇文中細看Java多線程的創(chuàng)建方式

    一篇文中細看Java多線程的創(chuàng)建方式

    隨著計算機的配置越來越高,我們需要將進程進一步優(yōu)化,細分為線程,充分提高圖形化界面的多線程的開發(fā),這篇文章主要給大家介紹了如何通過一篇文中細看Java多線程的創(chuàng)建方式,需要的朋友可以參考下
    2021-07-07
  • Spring 中@Validated 分組校驗的使用解析

    Spring 中@Validated 分組校驗的使用解析

    這篇文章主要介紹了Spring 中@Validated 分組校驗的使用解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java集合之Disruptor操作示例

    Java集合之Disruptor操作示例

    這篇文章主要為大家介紹了Java集合之Disruptor操作示例介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08

最新評論

德清县| 新建县| 甘德县| 方城县| 刚察县| 揭阳市| 广汉市| 得荣县| 新安县| 兴文县| 龙岩市| 集贤县| 梁河县| 九台市| 睢宁县| 娄烦县| 合山市| 丹东市| 合水县| 蓬溪县| 隆化县| 栾川县| 肥乡县| 合江县| 会理县| 白水县| 高雄县| 隆安县| 马鞍山市| 兴和县| 平和县| 尤溪县| 沙坪坝区| 九龙城区| 巫溪县| 盱眙县| 余姚市| 巢湖市| 乐清市| 安庆市| 新乐市|