springboot利用Redis的Geo数据类型,获取附近店铺的坐标位置和距离列表

发布于:2024-05-09 ⋅ 阅读:(21) ⋅ 点赞:(0)

GEO介绍

在Redis 3.2版本中,新增了一种数据类型:GEO,它主要用于存储地理位置信息,并对存储的信息进行操作。

GEO实际上是一种有序集合(zset),它的每个元素都包含三个属性:经度(longitude)、纬度(latitude)和位置名称(member)。通过这些属性,我们可以在Redis中存储地理位置的坐标,并对它们进行一些有用的操作。

GEO命令行应用

添加地理坐标位置

语法

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

key: redis存储的KEY键值
longitude : 经度
latitude : 纬度
member : 该坐标的位置名称

demo

GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"

获取指定单位半径的全部地理位置列表

语法

GEORADIUS key longitude latitude radius <M | KM | FT | MI> [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC | DESC] [STORE key | STOREDIST key]

radius: 半径长度,必选项。后面的m、km、ft、mi、是长度单位选项,四选一。
WITHCOORD: 将位置元素的经度和维度也一并返回,非必选。
WITHDIST: 在返回位置元素的同时, 将位置元素与中心点的距离也一并返回。 距离的单位和查询单位一致,非必选。
WITHHASH: 返回位置的52位精度的Geohash值,非必选。这个我反正很少用,可能其它一些偏向底层的LBS应用服务需要这个。
COUNT: 返回符合条件的位置元素的数量,非必选。比如返回前10个,以避免出现符合的结果太多而出现性能问题。
ASC|DESC: 排序方式,非必选。默认情况下返回未排序,但是大多数我们需要进行排序。参照中心位置,从近到远使用ASC ,从远到近使用DESC。

demo

georadius cater 116.40 39.91 10 km withcoord withdist withhash count 10 asc

意思是:查询cater键值下的距离目标位置116.40 :39.91,
10 km:表示10公里半径内;
withcoord :表示地理坐标;
withdist :距离目标位置的距离;
count 10:表示限制前10条;
asc表示:由近到远排序

springboot 的实际应用

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
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.GeoOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.List;

@SpringBootTest(classes = GeoApplicationTest.class)
public class GeoApplicationTest {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;



	// 添加地理坐标
	@Test
	void geoadd(){
		GeoOperations<String, String> geo = stringRedisTemplate.opsForGeo();
		Point point = new Point(116.402661,39.907223);
		RedisGeoCommands.GeoLocation<String> geoLocation =
			new RedisGeoCommands.GeoLocation<>("beijing", point);
		geo.add("china", geoLocation);
	}

	//根据给定的地理坐标,取得半径内全部的缓存坐标,并取得距离和具体信息
	@Test
	void georadius(double longitude, double latitude, double radius){
		RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs
			.newGeoRadiusArgs() // 创建georadius命令参数对象
			.includeDistance() // 包含距离
			.includeCoordinates() // 包含坐标
			.sortAscending() // 按距离由近及远排序
			.limit(10); // 限制返回结果为10个
		GeoResults<RedisGeoCommands.GeoLocation<String>> locationGeoResults = stringRedisTemplate.opsForGeo()
			.radius("china",
				new Circle(new Point(longitude, latitude),
					new Distance(radius, RedisGeoCommands.DistanceUnit.KILOMETERS)),
				args
			);
		List<GeoResult<RedisGeoCommands.GeoLocation<String>>> geoResults = locationGeoResults.getContent();
		for (GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult : geoResults) {
			System.out.println("目标距离位置 :" + geoResult.getDistance().getValue());
			System.out.println("距离单位: " + geoResult.getDistance().getUnit());
			System.out.println("位置名称: " + geoResult.getContent().getName());
			System.out.println("经度: " + geoResult.getContent().getPoint().getX());
			System.out.println("纬度:" + geoResult.getContent().getPoint().getY());
		}
	}
}

网站公告

今日签到

点亮在社区的每一天
去签到