使用redis實現附近的人功能
前言
Redis自3.2版本開始提供瞭GEO(geograph)功能,支持地理位置相關操作,以實現諸如附近的人這類依賴於地理位置信息的功能。
工具
百度經緯度拾取器
拾取坐標系統
一、測試數據
120.70012 28.00135 溫州
120.207686 30.253359 杭州
121.482537 31.238034 上海
118.793117 32.068407 南京
二、基本命令
1. geoadd
為瞭進行地理位置相關操作,我們首先需要將具體的地理位置記錄起來,可以通過執行geoadd 命令來完成 命令格式如下
GEOADD 集合名稱 經度 緯度 名稱 [longitude latitude name...] //添加集合 geoadd citys 120.70012 28.00135 wenzhou 120.207686 30.253359 hanghzou
查看已添加集合
2.geopos
此命令根據輸入的位置名稱獲取位置的信息坐標,語法如下
GEOPOS 集合名稱 位置 [name...] geopos address wuyue
查看坐標信息
3.geodist
此命令用於計算兩個位置之間的距離,語法如下
geodist 集合名稱 位置1 位置2 [unit] //計算杭州到南京之間的距離 geodist citys hanghzredis:0>ou nanjing km
可選參數:unit用於指定計算距離時的單位,他的值可以是以下單位的其中一個
m :表示米
km:表示千米
mi:表示英裡
ft:表示英尺。
4.georadius
georadius使用用戶給定的經緯度作為計算范圍時的中心點,
georadius 集合名稱 精度 緯度 radius m|km|ft|mi| [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count] //查詢據我100km之內的城市 georadius citys 120.754274 27.983296 100 km
radius:距離
WITHCOORD:返回坐標
由於版本原因可能為空
WITHDIST:同時返回距離
ASC|DESC:排序
count:取多少長度
5. georadiusbymember
georadiusbymember使用存儲在位置集合裡的某個地點作為中心點
georadiusbymember 地址集合 地點名稱 距離 單位 //查詢距離wuyue五公裡之內的地點 georadiusbymember address wuyue 5 km
三、javaApi
實體類
package com.jiale.web.controller.pojo; import lombok.Data; import java.io.Serializable; /** * @Author: Hello World * @Date: 2021/9/16 16:12 * @Description: */ @Data public class AddressInfo implements Serializable { /**網點名稱*/ private String title; /**網點地址*/ private String address; /**網點聯系方式*/ private String phone; /**網點坐標-精度*/ private double x; /**網點坐標-緯度*/ private double y; }
package com.jiale; import com.jiale.common.config.JialeGlobal; import com.jiale.web.controller.pojo.AddressInfo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.geo.*; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import java.math.BigDecimal; import java.util.List; /** * @Author: Hello World * @Date: 2021/9/15 17:47 * @Description: */ @SpringBootTest public class JialeTests { @Autowired RedisTemplate redisTemplate; @Test public void test1(){ System.out.println(JialeGlobal.getUploadPath()); } /** * 一.向redis中添加位置信息 * 1.網店位置信息-geo * 2.網點詳細信息 */ @Test public void geoAdd(){ //1.網點位置信息存儲120.653208,28.032606 Point point = new Point(120.653208, 28.032606); redisTemplate.boundGeoOps("outlets").add(point,"江心嶼"); //2.網點詳細信息 AddressInfo addressInfo = new AddressInfo(); addressInfo.setTitle("江心嶼"); addressInfo.setAddress("浙江省溫州市鹿城區江心嶼景區內"); addressInfo.setPhone("(0577)88201281"); addressInfo.setX(120.653208); addressInfo.setY(28.032606); redisTemplate.boundHashOps("outletsInfo").put("江心嶼",addressInfo); } /** * 二.獲取位置坐標信息 */ @Test public void geoPos(){ //傳入位置名稱查詢位置信息 List<Point> position = redisTemplate.boundGeoOps("outlets").position("南塘五組團"); for (Point point : position) { System.out.println(point); } } /** * 三.計算兩個位置信息 */ @Test public void geoDist(){ /** Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心嶼", "溫州樂園"); //距離 double value = distance.getValue(); //單位 String unit = distance.getUnit(); System.out.println("兩點相距:"+value+unit); */ //以km展示 /** Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心嶼", "溫州樂園", Metrics.KILOMETERS); //距離 double value = distance.getValue(); //單位 String unit = distance.getUnit(); System.out.println("兩點相距:"+value+unit);*/ //保留兩位小數 Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心嶼", "溫州樂園", Metrics.KILOMETERS); //距離 double value = distance.getValue(); //單位 String unit = distance.getUnit(); System.out.println("兩點相距:"+new BigDecimal(value).setScale(2,BigDecimal.ROUND_HALF_UP) +unit); } /** * 四.按照給定的經緯度查找指定范圍的位置 */ @Test public void geoRadius(){ //指定位置 Point point = new Point(120.754274, 27.983296); //構建條件-10km Distance distance = new Distance(10, Metrics.KILOMETERS); Circle circle = new Circle(point,distance); //RedisGeoCommands RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs(); //包含位置信息 args.includeDistance(); //存放的是查詢到的網址位置信息 GeoResults<RedisGeoCommands.GeoLocation<String>> outlets = redisTemplate.boundGeoOps("outlets").radius(circle, args); for (GeoResult<RedisGeoCommands.GeoLocation<String>> outlet : outlets) { //獲取距離信息 Distance outletDistance = outlet.getDistance(); //距離 double value = outletDistance.getValue(); //單位 String unit = outletDistance.getUnit(); System.out.println("當前坐標距離:"+outlet.getContent().getName()+value+unit); } } /** * 五.按照指定元素(必須在集合中存在)查找指定范圍位置 */ @Test public void geoRadiusByMember(){ //構建條件 Distance distance = new Distance(10, Metrics.KILOMETERS); //構建條件-包含位置信息 RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs(); args.includeDistance(); //參數 key 構建的條件 其他條件 GeoResults<RedisGeoCommands.GeoLocation<String>> outlets = redisTemplate.boundGeoOps("outlets").radius("江心嶼", distance,args); for (GeoResult<RedisGeoCommands.GeoLocation<String>> outlet : outlets) { //獲取距離信息 Distance outletDistance = outlet.getDistance(); //距離 double value = outletDistance.getValue(); //單位 String unit = outletDistance.getUnit(); System.out.println("江心嶼距離:"+outlet.getContent().getName()+value+unit); } } }
到此這篇關於使用redis實現附近的人的文章就介紹到這瞭,更多相關redis實現附近的人內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringBoot集成Redis的思路詳解
- SpringBoot集成Redis並實現主從架構的實踐
- springboot整合使用雲服務器上的Redis方法
- Spring中RedisTemplate的基本使用淺析
- spring使用RedisTemplate操作Redis數據庫