一、GEO
Redis 3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。
有效纬度从-85.05112878度到85.05112878度
注意:当坐标位置超出上述指定范围时,将会返回一个错误。
二、实现方式
- 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。
geoadd命令
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
- geodist命令
如果两个位置之间的其中一个不存在, 那么命令返回空值。
指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 geodist默认使用米作为单位。
注意:GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。
返回值:
计算出的距离会以双精度浮点数的形式被返回。 如果给定的位置元素不存在, 那么命令返回空值。
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEODIST Sicily Palermo Catania //默认米
"166274.15156960039"
redis> GEODIST Sicily Palermo Catania km //指定了单位
"166.27415156960038"
redis> GEODIST Sicily Palermo Catania mi //英里
"103.31822459492736"
redis> GEODIST Sicily Foo Bar
(nil)
- 代码实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;
import redis.clients.jedis.params.GeoRadiusParam;
import java.util.List;
import java.util.Map;
@Component
public class RedisGEO {
//表示是存储geo的key
public final static String RS_GEO_NS = "rg:";
@Autowired
private JedisPool jedisPool;
/**
*
* @param key
* @param longitude 经度
* @param latitude 纬度
* @param member 成员名
* @return
*/
public Long addLocation(String key, double longitude, double latitude, String member) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.geoadd(RS_GEO_NS+key,longitude,latitude,member);
} catch (Exception e) {
return null;
} finally {
jedis.close();
}
}
/**
*
* @param key
* @param memberCoordinateMap 成员为key,经纬度为value的map
* @return
*/
public Long addLocations(String key, Map<String, GeoCoordinate> memberCoordinateMap) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.geoadd(RS_GEO_NS+key,memberCoordinateMap);
} catch (Exception e) {
return null;
} finally {
jedis.close();
}
}
public List<GeoRadiusResponse> nearbyMore(String key, String member, double radius,
boolean withDist, boolean isASC) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
GeoRadiusParam geoRadiusParam = new GeoRadiusParam();
if (withDist) geoRadiusParam.withDist();
if(isASC) geoRadiusParam.sortAscending();
else geoRadiusParam.sortDescending();
return jedis.georadiusByMember(RS_GEO_NS+key, member, radius, GeoUnit.KM,geoRadiusParam);
} catch (Exception e) {
return null;
} finally {
jedis.close();
}
}
}
不是重点,其他的geo功能不做赘述。