今天看到redis 再3.2以上版本支持GEO数据类型,了解下原来和LBS(Location Based Service ) 不由得想起来,当初2两年前作位置定位,需求场景是根据用户当前定位,匹配最近一公里内为半径所有可能用设备,设备实时上传信息,那时redis2.6,根据半径进行画⚪,现在georadius完全匹配;
一、geo概念
- redis的GEO特性在Redis3.2版本发布,这个功能可以将用户给定的地理位置信息储存起来,并对这些信息进行操作。
- GEO常用语LBS(Location Based Service),基于位置的服务。
二、GEO相关操作方法有:
- geoadd:添加地理位置的坐标。
- geopos:获取地理位置的坐标。
- geodist:计算两个位置之间的距离。
- georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
- georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
- geohash:返回一个或多个位置对象的 geohash 值。
--2020了人一上了年纪不由自主回顾一下,
@Override
public List<GridStation> queryListByPosition(StationEntity stationEntity) {
//先计算查询点的经纬度范围
double r = 6371;//地球半径千米
double dis = stationEntity.getRadius();//0.5千米距离
double dlng = 2*Math.asin(Math.sin(dis/(2*r))/Math.cos(stationEntity.getLatitude()*Math.PI/180));
dlng = dlng*180/Math.PI;//角度转为弧度
double dlat = dis/r;
dlat = dlat*180/Math.PI;
double minlat = stationEntity.getLatitude()-dlat;
double maxlat = stationEntity.getLatitude()+dlat;
double minlng = stationEntity.getLongitude()-dlng;
double maxlng = stationEntity.getLongitude() + dlng;
Map<String, Object> map=new HashMap<String,Object>();
map.put("areaCode", stationEntity.getAreaCode());
map.put("cityCode", stationEntity.getCityCode());
map.put("stationName", stationEntity.getStationName());
map.put("stationSeq", stationEntity.getStationSeq());
map.put("userId", stationEntity.getUserId());
map.put("updatetime", stationEntity.getUpdatetime());
map.put("minlat", minlat);
map.put("maxlat", maxlat);
map.put("minlng", minlng);
map.put("maxlng", maxlng);
return gridStationMapper.queryListByPosition(map);
}
<!-- 查询充电站静态数据 (根据用户位置坐标或选择的中心点坐标,定位周围的网点) -->
<![CDATA[ and s.LONGITUDE >= #{minlng,jdbcType=DOUBLE} and s.LONGITUDE <= #{maxlng,jdbcType=DOUBLE}
and s.LATITUDE >= #{minlat,jdbcType=DOUBLE} and s.LATITUDE <= #{maxlat,jdbcType=DOUBLE} ]]>
GROUP BY s.GRID_STATION_SEQ
ORDER BY updatetime DESC
) t1