Redis7高级之案例实战GEO(六)

ps:如果想要获取经纬度的话,可以去百度地图拾取坐标系统 (baidu.com)

6.1 附近的人、附近的美食店铺怎么实现的

  • 用mysql
    • 查询性能问题,并发高、数据量大这种查询要搞垮mysql数据库
    • 一般mysql查询的是一个平面矩形访问,而叫车服务要以我为中心N公里为半径的圆形覆盖
    • 精准度的问题,我们知道地球不是平面坐标系,而是一个圆球,这种矩形计算在长距离计算时会有很大误差,mysql不合适
  • 用GEO
    • 可以解决上述问题

6.2 命令复习

GEOADD添加经纬度坐标

在这里插入图片描述

会出现中文乱码

  • redis -cli -a 123456 – raw

GEOPOS 返回经纬度

在这里插入图片描述

GEOHASH返回坐标的 geohash 表示 (base32编码)

在这里插入图片描述

GEODIST 返回两个位置之间的距离

在这里插入图片描述

GEORADIUS 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

在这里插入图片描述

GEORADIUSBYMEMBER 找出指定范围内的元素,中心点是由给定的位置元素决定

在这里插入图片描述

6.3 案例景点附近的推送功能

GEORADIUS: 以给定的经纬度为中心,找出某一半径内的元素

  • GEOService

    /**
     * @author 晓风残月Lx
     * @date 2023/3/27 21:14
     */
    public interface GeoService {
          
          
        String geoAdd();
    
        Point position(String member);
    
        String hash(String member);
    
        Distance distance(String member1, String member2);
    
        GeoResults radiusByxy();
    
        GeoResults radiusMember();
    
    }
    
  • GEOServiceImpl

    import com.xfcy.service.GeoService;
    import lombok.extern.slf4j.Slf4j;
    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.stereotype.Service;
    
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author 晓风残月Lx
     * @date 2023/3/27 21:14
     */
    @Service
    @Slf4j
    public class GeoServiceImpl implements GeoService {
          
          
    
        public static final String CITY = "city";
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        @Override
        public String geoAdd() {
          
          
            Map<String, Point> map = new HashMap<>();
            map.put("白马寺", new Point(112.610356,34.728481));
            map.put("龙门石窟", new Point(112.484071,34.564375));
            map.put("老君山", new Point(111.663,33.75186));
            map.put("白马寺的公共厕所1", new Point(112.608311,34.726809));
            map.put("白马寺的公共厕所2", new Point(112.610356,34.728481));
            redisTemplate.opsForGeo().add(CITY, map);
            return null;
        }
    
        @Override
        public Point position(String member) {
          
          
            // 获取经纬度坐标
            List<Point> position = redisTemplate.opsForGeo().position(CITY, member);
            return position.get(0);
        }
    
        @Override
        public String hash(String member) {
          
          
            // geohash 算法生成的base32编码
            List<String> hash = redisTemplate.opsForGeo().hash(CITY, member);
            return hash.get(0);
        }
    
        @Override
        public Distance distance(String member1, String member2) {
          
          
            // 获取两个给定位置之间的距离
            Distance distance = redisTemplate.opsForGeo().distance(CITY, member1, member2,
                    RedisGeoCommands.DistanceUnit.KILOMETERS);
            return distance;
        }
    
        @Override
        public GeoResults radiusByxy() {
          
          
            // 通过经纬度查找附近的,白马寺的位置 112.610356,34.728481
            Circle circle = new Circle(112.610356, 34.728481, Metrics.KILOMETERS.getMultiplier());
            // 返回50条
            RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeCoordinates().sortDescending().limit(50);
    
            GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, circle, args);
            return geoResults;
        }
    
        @Override
        public GeoResults radiusMember() {
          
          
            // 通过地方查找附近,洛阳白马寺为例
            String member = "白马寺";
            // 返回10条
            RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending().limit(10);
            // 半径 10 公里内
            Distance distance = new Distance(10, Metrics.KILOMETERS);
            GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, member, distance, args);
    
            return geoResults;
        }
    }
    
  • GEOController

    import com.xfcy.service.GeoService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.geo.Distance;
    import org.springframework.data.geo.GeoResults;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    import org.springframework.data.geo.Point;
    
    /**
     * @author 晓风残月Lx
     * @date 2023/3/27 21:14
     */
    @Api(tags = "美团地图位置附近的酒店推送GEO")
    @Slf4j
    @RestController
    public class GeoController {
          
          
    
        @Resource
        private GeoService geoService;
    
        @ApiOperation("添加经纬度坐标")
        @RequestMapping(value = "/geoadd",method = RequestMethod.GET)
        public String geoAdd() {
          
          
            return geoService.geoAdd();
        }
    
        @ApiOperation("获取经纬度坐标geopos")
        @RequestMapping(value = "/geopos",method = RequestMethod.GET)
        public Point position(String member){
          
          
            return geoService.position(member);
        }
    
        @ApiOperation("获取经纬度生成的base32编码值geohash")
        @RequestMapping(value = "/geohash",method = RequestMethod.GET)
        public String hash(String member){
          
          
            return geoService.hash(member);
        }
    
        @ApiOperation("获取两个给定位置之间的距离")
        @RequestMapping(value = "/geodist",method = RequestMethod.GET)
        public Distance distance(String member1, String member2){
          
          
            return geoService.distance(member1,member2);
        }
    
        @ApiOperation("通过经纬度查找洛阳白马寺附近的")
        @RequestMapping(value = "/georadius",method = RequestMethod.GET)
        public GeoResults radiusByxy(){
          
          
            return geoService.radiusByxy();
        }
    
        @ApiOperation("通过地方查找附近,白马寺为例")
        @RequestMapping(value = "/georadiusByMember",method = RequestMethod.GET)
        public GeoResults radiusMember(){
          
          
            return geoService.radiusMember();
        }
    
    }
    
  • 测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

下拉还有字段注意
在这里插入图片描述

下拉还有字段注意
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_55993923/article/details/129869136