springboot-redis-geo经纬度坐标操作

redis-geo

前言

在涉及到经纬度定位点操作的时候,我们了解了GEO的概念

我们有时候也需要根据经纬度点进行一些业务开发,比如根据自己当前定位获取最近商家(美团)、获取最近车辆(打车软件)获取两个地点之间的距离等,这个时候,我们便可以使用redis中geo来简化我们的业务代码开发。

image-20230522200753820

但实际上,redis-geo并不是一种全新的数据结构,其底层是sorted set

redis-geo相关命令

image-20230522201343816

详细内容则可以直接参考官网:https://redis.io/commands/?group=geo

GEOADD

版本要求:3.2.0

将指定的空间元素(经度、纬度、元素名)添加到key对应的Sorted Set中

GEODIST

版本要求:3.2.0

返回两个给定元素之间的距离,距离支持 千米 米 英尺 英里

GEOHASH

版本要求:3.2.0

  • GEOADD命令会将经纬度编码为52bit,该命令返回GeoHash编码转换后的11位字符串表示形式,该字符串形式,与 **维基百科**描述一致,兼容 **geohash.org**规范
  • 使用该URL: http://geohash.org/,可以反向解析出命令返回的11位字符串对应的经纬度,例如http://geohash.org/wm6n8h9sef0。页面中显示对应的纬度和经度(九里堤农贸附近)

GEOPOS

版本要求:3.2.0

返回给定元素对应的经纬度 (使用GEOADD添加的元素,会被GeoHash转化为52位比特值,因此使用GEOPOS取出值并转为经纬度时,可能与添加的经纬度值有少许差异)

GEORADIUS

版本要求:3.2.0

指定元素的经纬度与半径(米 米 英尺 英里)得到一个圆形区域,返回圆形区域中的所有元素

GEORADIUSBYMEMBER

版本要求:3.2.0

指定元素与半径(米 米 英尺 英里)得到一个圆形区域,返回圆形区域中的所有元素

springboot整合

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

GEOADD

添加定位点元素至集合

point 包路径:org.springframework.data.geo.Point
    
redisTemplate.opsForGeo().add("geo", new Point(104.063037, 30.701011), "九里堤");org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation#GeoLocation

redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("北站西", new Point(104.072595, 30.700887)));



redisTemplate().add("geo", new RedisGeoCommands.GeoLocation<>("北站西", new Point(104.072595, 30.700887)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("九里堤农贸", new Point(104.064726, 30.699334)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("西北桥", new Point(104.064007, 30.692037)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("城北派出所", new Point(104.073386, 30.702136)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("人民北路", new Point(104.078345, 30.692168)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("哈啰酒店-成都西南交大店", new Point(104.052828, 30.699939)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("矮冬瓜红茶火锅", new Point(104.052936, 30.698899)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("沈跃全中医", new Point(104.052199, 30.698231)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("五丁小学", new Point(104.067169, 30.695763)));
redisTemplate.opsForGeo().add("geo", new RedisGeoCommands.GeoLocation<>("那屋网客", new Point(104.061456, 30.700576)));

image-20230522204216524

image-20230522205000944

GEODIST

获取指定两个元素间的距离 默认是m单位
Distance distance = redisTemplate.opsForGeo().distance("geo", "九里堤", "北站西");
Distance distance2 = redisTemplate.opsForGeo().distance("geo", "九里堤", "北站西", RedisGeoCommands.DistanceUnit.KILOMETERS);
// 913.8254 m
System.out.println(distance.getValue() + " " + distance.getUnit());
// 0.9138 km
System.out.println(distance2.getValue() + " " + distance2.getUnit());

image-20230522204452888

image-20230522204522387

GEOHASH

GeoHash编码转换后的11位字符串表示形式

List<String> hash = redisTemplate.opsForGeo().hash("geo", "九里堤农贸");
// [wm6n8h9sef0]
System.out.println(hash);

粘贴至网站

http://geohash.org/你的转码后的字符串

ex:

http://geohash.org/wm6n8h9sef0

image-20230522210046539

返回上边查看我们九里堤农贸定位点信息

GEOPOS

返回给定元素的经纬度信息(可能会有损耗)

List<Point> position = redisTemplate.opsForGeo().position("geo", "九里堤", "北站西");
// [Point [x=104.063039, y=30.701010], Point [x=104.072593, y=30.700886]]
System.out.println(position);

GEORADIUS

指定元素的经纬度与半径(米 米 英尺 英里)得到一个圆形区域,返回圆形区域中的所有元素

// 以指定元素(我这里是九里堤)为圆心,获取指定半径范围内的数据 (包含自身)
Circle circle = new Circle(new Point(104.063037, 30.701011), new Distance(1000, RedisGeoCommands.DistanceUnit.METERS));
GeoResults<RedisGeoCommands.GeoLocation<Object>> radius = redisTemplate.opsForGeo().radius("geo", circle);

结果

[GeoResult [content: RedisGeoCommands.GeoLocation(name=九里堤, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=北站西, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=城北派出所, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=五丁小学, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=九里堤农贸, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=那屋网客, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=矮冬瓜红茶火锅, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=哈啰酒店-成都西南交大店, point=null), distance: 0.0, ]]

GEORADIUSBYMEMBER

指定元素与半径(米 米 英尺 英里)得到一个圆形区域,返回圆形区域中的所有元素

GeoResults<RedisGeoCommands.GeoLocation<Object>> radius = redisTemplate.opsForGeo().radius("geo", "九里堤", 1000);
System.out.println(new ArrayList<>(radius.getContent()));

结果

[GeoResult [content: RedisGeoCommands.GeoLocation(name=九里堤, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=北站西, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=城北派出所, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=五丁小学, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=九里堤农贸, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=那屋网客, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=矮冬瓜红茶火锅, point=null), distance: 0.0, ], GeoResult [content: RedisGeoCommands.GeoLocation(name=哈啰酒店-成都西南交大店, point=null), distance: 0.0, ]]

定制化获取指定半径内的数据

// 定制化获取指定半径内的数据
RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
// 只获取最近的一个geo信息
geoRadiusCommandArgs.limit(1);
geoRadiusCommandArgs.includeCoordinates();
// 距给定经纬度由远及近的顺序
geoRadiusCommandArgs.sort(Sort.Direction.DESC);
// 指定圆心点、半径大小、距离单位
GeoResults<RedisGeoCommands.GeoLocation<Object>> radius2 = redisTemplate.opsForGeo().radius("geo", "九里堤",
                                                                                            new Distance(1, RedisGeoCommands.DistanceUnit.KILOMETERS), geoRadiusCommandArgs);
System.out.println(new ArrayList<>(radius2.getContent()));
[GeoResult [content: RedisGeoCommands.GeoLocation(name=城北派出所, point=Point [x=104.073387, y=30.702136]), distance: 0.0 KILOMETERS, ]]

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值