SpringBoot查询指定范围内的坐标点

44 篇文章 0 订阅
27 篇文章 0 订阅

使用Redis geo实现

redis geo是基于Sorted Set来实现的

Redis 3.2 版本新增了geo相关命令,用于存储和操作地理位置信息。提供的命令包括添加、计算位置之间距离、根据中心点坐标和距离范围来查询地理位置集合等,说明如下:

geoadd:添加地理位置的坐标。

geopos:获取地理位置的坐标。

geodist:计算两个位置之间的距离。

georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。

georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。

geohash:返回一个或多个位置对象的 geohash 值

测试:

添加坐标点: geoadd region 117.130313 31.84504 "shuxihu" 117.143635 31.838962 "chanyeyuan" 117.143635 31.838962 "shiyanxiaoxue" 117.123423 31.842912 "aolai" 117.207504 31.879882 "zhiwuyuan"

// 查询距离117.130313 31.84504半径1000米地点信息

georadius region 117.130313 31.84504 1000 m

执行结果:

SpringBoot与redis geo整合

springframework中已经加入了对redis geo的支持,相关的类都在org.springframework.data.geo包下。而对redis的命令行交互,也提供了org.springframework.data.redis相关的类来支持相关开发。

为了在项目中方便使用,整理工具代码如下,主要封装了:

1、添加元素到redisgeo;

2、计算某指定集合下,给定中心和查询范围,获取区域内成员的方法;

3、计算两个成员的距离

4、查询某指定成员(数组)的位置信息

package com.octv.cloud.ota.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author xiaoss
 * @since 1.0, 2023年02月27日 11:31:45
 */
@RestController
@RequestMapping("test")
public class TestController {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 添加节点及位置信息
     * @param geoKey 位置集合
     * @param pointName 位置点标识
     * @param longitude 经度
     * @param latitude 纬度
     */
    public void geoAdd(String geoKey, double longitude, double latitude,String pointName){
        Point point = new Point(longitude, latitude);
        redisTemplate.opsForGeo().add(geoKey, point, pointName);
    }

    /**
     *
     * @param longitude
     * @param latitude
     * @param radius
     * @param geoKey
     * @param metricUnit 距离单位,例如 Metrics.KILOMETERS
     * @param metricUnit
     * @return
     */
    public List<GeoResult<RedisGeoCommands.GeoLocation<String>>> findRadius(String geoKey
            , double longitude, double latitude, double radius, Metrics metricUnit, int limit){
        // 设置检索范围
        Point point = new Point(longitude, latitude);
        Circle circle = new Circle(point, new Distance(radius, metricUnit));
        // 定义返回结果参数,如果不指定默认只返回content即保存的member信息
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs
                .newGeoRadiusArgs().includeDistance().includeCoordinates()
                .sortAscending()
                .limit(limit);
        GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().radius(geoKey, circle, args);
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> list = results.getContent();
        return list;
    }

    /**
     * 计算指定key下两个成员点之间的距离
     * @param geoKey
     * @param member1
     * @param member2
     * @param unit 单位
     * @return
     */
    public Distance calDistance(String geoKey, String member1, String member2
            , RedisGeoCommands.DistanceUnit unit){
        Distance distance = redisTemplate.opsForGeo()
                .distance(geoKey, member1, member2, unit);
        return distance;
    }

    /**
     * 根据成员点名称查询位置信息
     * @param geoKey geo key
     * @param members 名称数组
     * @return
     */
    public List<Point> geoPosition(String geoKey, String[] members){
        List<Point> points = redisTemplate.opsForGeo().position(geoKey, members);
        return points;
    }

    @GetMapping("test")
    public void test(){
        geoAdd("region",117.130313, 31.84504,"shuxihu");
        geoAdd("region",117.143635,31.838962,"chanyeyuan");
        geoAdd("region",117.143635,31.838962,"shiyanxiaoxue");
        geoAdd("region", 117.123423,31.842912,"aolai");
        geoAdd("region",117.207504,31.879882,"zhiwuyuan");
        List<GeoResult<RedisGeoCommands.GeoLocation<String>>> list=findRadius("region",117.130313 ,31.84504 ,0.5,Metrics.KILOMETERS,5);
        for(GeoResult<RedisGeoCommands.GeoLocation<String>> object:list){
            System.out.println(object.getContent().getName());
        }
    }
}

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中判断GIS坐标是否在某地理区域内,你可以使用Java的Geometry库来实现。下面是一个简单的示例代码: 首先,你需要引入相关的依赖: ```xml <dependency> <groupId>org.locationtech.jts</groupId> <artifactId>jts-core</artifactId> <version>1.18.0</version> </dependency> ``` 然后,你可以创建一个方法来判断坐标是否在指定的地理区域内: ```java import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; public class GisUtils { public static boolean isPointInPolygon(double lat, double lon, double[] polygonCoordinates) { GeometryFactory geometryFactory = new GeometryFactory(); // 创建坐标 Coordinate coordinate = new Coordinate(lon, lat); Point point = geometryFactory.createPoint(coordinate); // 创建多边形 Coordinate[] coordinates = new Coordinate[polygonCoordinates.length / 2]; for (int i = 0; i < polygonCoordinates.length; i += 2) { coordinates[i / 2] = new Coordinate(polygonCoordinates[i + 1], polygonCoordinates[i]); } Polygon polygon = geometryFactory.createPolygon(coordinates); // 判断是否在多边形内 return polygon.contains(point); } } ``` 在上面的代码中,`isPointInPolygon`方法接受一个纬度(lat)、经度(lon)以及地理区域的坐标数组(polygonCoordinates)。它会创建一个坐标和一个多边形,并使用JTS库的`contains`方法来判断是否在多边形内部。 你可以在Spring Boot应用中使用该方法来判断坐标是否在指定的地理区域内。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值