Java中利用redis实现一个LBS服务
创始人
2024-12-21 13:23:45
0次

GEOADD 和 GEORADIOUS

命令描述

GEOADD

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

这个命令将指定的地理空间位置(纬度、经度、名称)添加到指定的 key 中。

有效的经度从-180度到180度。

有效的纬度从-85.05112878度到85.05112878度。

当坐标位置超出上述指定范围时,该命令将会返回一个错误。

该命令可以一次添加多个地理位置点

GEORADIOUS

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

这个命令以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。范围可以使用以下其中一个单位:

m 表示单位为米。  km 表示单位为千米。  mi 表示单位为英里。  ft 表示单位为英尺。

在给定以下可选项时, 命令会返回额外的信息:

WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。  WITHCOORD: 将位置元素的经度和维度也一并返回。  WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。  ASC: 根据中心的位置, 按照从近到远的方式返回位置元素。  DESC: 根据中心的位置, 按照从远到近的方式返回位置元素。  在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。 虽然用户可以使用 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 radious(String type, GeoCoordinate center, Long distinct, Boolean asc);}

实现的接口

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 radious(String type, GeoCoordinate center, Long distinct, Boolean asc) {List postions = new ArrayList();Jedis jedis = redisConnection.getJedis();try {GeoRadiusParam geoRadiusParam = GeoRadiusParam.geoRadiusParam().withCoord().withDist();if (asc) {geoRadiusParam.sortAscending();} else {geoRadiusParam.sortDescending();}List 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;@Beforepublic 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);}@Testpublic void test10KMRadious() {List postions = lbsServiceRedis.radious(type, center, 1000 * 10L, true);Assert.assertTrue(postions.size() == 2 && exist(postions, "2017122802") && exist(postions, "2017122803"));}@Testpublic void test50KMRadious() {List 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 postions, String key) {if (postions != null) {for (Postion postion : postions) {if (postion.getId().equals(key)) {return true;}}}return false;}@Beforepublic void after() {RedisConnection redisConnection = RedisConnectionUtil.create();cacheService = new CacheServiceRedisImpl();cacheService.setDbIndex(15);cacheService.setRedisConnection(redisConnection);cacheService.delObject(type);}}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...