SpringBoot查询指定范围内的坐标点
  qrDKVBcFRU5H 2023年12月05日 14 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查询指定范围内的坐标点_spring boot

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());
        }
    }
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月05日 0

暂无评论

推荐阅读
qrDKVBcFRU5H