精华内容
下载资源
问答
  • 使用Redis进行经纬度距离

    千次阅读 2019-08-27 15:38:50
    业务需求: 客户端传入用户的经纬度,后端计算出该经纬度与指定经纬度之间的距离; 在面向百度之后,发现Redis在3.2之后推出GEO特性可以简单就...再获取到两个地点的经纬度,在代码中使用redis geo 进行计算,获取出距...

    业务需求:
    客户端传入用户的经纬度,后端计算出该经纬度与指定经纬度之间的距离;

    在面向百度之后,发现Redis在3.2之后推出GEO特性可以简单就解决这个需求;
    为了验证其的可用性(误差不要太多),这里来写个demo,与在高德地图上获取的距离进行对比;
    先获取某两个地点的距离及经纬度,这里获取的是北京西站和南站的,距离大概是5927米;
    再获取到两个地点的经纬度,在代码中使用redis geo 进行计算,获取出距离与高德地图的进行对比
    在这里插入图片描述
    代码部分:
    先引入依赖

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

    配置连接redis信息

    spring:
    	redis:
        	host: localhost   
        	port: 6379
    

    测试代码:

      @Autowired
        private RedisTemplate redisTemplate;
    
        @Test
        public void getDistance(){
            GeoOperations geoOperations = redisTemplate.opsForGeo();
            //首先存入客户端上传的经纬度和指定地点的经纬度
            Map<String,Object> map = new HashMap<>();
            // 假如客户端的传的是北京西站的经纬度,指定地点是北京南站
            map.put("BJXZ",new Point(116.321275,39.895096));
            map.put("BJNZ",new Point(116.378438,39.864666));
            // 将这些地址数据保存到redis中
            geoOperations.geoAdd("GET_DISTANCE",map);
            // 调用方法,计算北京西站与北京南站之间的距离;
            double value = geoOperations.geoDist("GET_DISTANCE", "BJXZ", "BJNZ", RedisGeoCommands.DistanceUnit.METERS).getValue();
            System.out.println("北京西站到南站的距离是"+value+"米");
            System.out.println("与高德地图的误差是:"+(5927-value)+"米");
        }
    

    最终得出结果是:
    在这里插入图片描述

    展开全文
  • php redis 根据经纬度 计算当前用户附近店铺信息 1.redis 版本:Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能...

    php redis 根据经纬度 计算当前用户附近店铺信息

    1.redis 版本:Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能了

    2.Redis GEO实现主要包含了以下两项技术:
    2.1、使用geohash保存地理位置的坐标。
    2.2、使用有序集合(zset)保存地理位置的集合。

    3.gaoadd 添加 经纬度 到 数据集

    redis> GEOADD  redis_key  经度1 纬度1 "位置名称1"   经度2 纬度2  "位置名称2"
     
    redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
    

    4.php 批量插入数据集

    //伪数据   
     $data = [
           [
               'lng' => '116.1021',
               'lat' => '39.5928',
               'name'=> '阿里小贩'
            ],
            [
                'lng' => '112.5607',
                'lat' => '34.2331',
                'name'=> '腾讯小贩'
            ]
        ];
     
    $obj = new Redis();
    $obj->connect('127.0.0.1', '6379');
     $redis_key = "redis:test:2020":   
     $obj->pipeline();
     foreach ($data as $k => value) {
    		$obj->geoadd($redis_key,$value['lng'],$value['lat'],$value['name']);       
      }
     $obj->->exec();
    

    5.php 获取用户:lng:116.514202 lat:39.90540 附近20km 的商户

    $list = $obj->georadius($redis_key,116.514202,39.90540,20,'km');
    

    参考:1:https://www.cnblogs.com/wt645631686/p/8454497.html

    展开全文
  • 1、业务需求:用户信息存储经纬度,根据某个经纬度查询附近的人,已圆为中心,可根据距离从近到远排序。 2、使用技术:php,redis geo(geoadd,georadius) 3、相关文档:http://redisdoc.com/geo/georadius.html...

    1、业务需求:用户信息存储经纬度,根据某个经纬度查询附近的人,已圆为中心,可根据距离从近到远排序。

    2、使用技术:php,redis geo(geoadd,georadius),存储格式为:zset(有序集合)

    3、相关文档:http://redisdoc.com/geo/georadius.html

    实现:

    <?php
    /**
     * @author
     * @since
     */
    header("Content-type: text/html; charset=utf-8"); //编码
    ini_set('date.timezone', 'Asia/Shanghai');  //定义时间地点
    ini_set('memory_limit', '2024M'); //扩展php内存
    
    class statistics
    {
        protected $redis;
    
        public function __construct()
        {
            $this->redis = new Redis();
            $this->redis->connect('127.0.0.1', 6379);
        }
    
        public function index()
        {
            $total = 500000; //总数
    
            //模拟生成坐标,循环写入
            for ($i = 0; $i < $total; $i++) {
    
                //有效的经度介于 -180 度至 180 度之间。
                //有效的纬度介于 -85.05112878 度至 85.05112878 度之间。
    
                $num      = $this->randomFloat(-85, 85);
                $latitude = sprintf("%.6f", $num); //维度
    
                $num       = $this->randomFloat(-180, 180);
                $longitude = sprintf("%.6f", $num); //经度
    
                $this->redis->rawCommand('geoadd', 'user_info', $longitude, $latitude, 'user_id_' . $i);
            }
    
            echo '>>>>>' . date('Y-m-d H:i:s', time()) . '>>>>>';
    
        }
    
        function randomFloat($min = 0, $max = 1)
        {
            return $min + mt_rand() / mt_getrandmax() * ($max - $min);
        }
    
        public function __destruct()
        {
            $cx = '39.90'; //纬度
            $cy = '116.40'; //经度
    
            //获取本经纬度坐标100km内容的信息并根据距离从近到远排序显示5条
            $rediss = $this->redis->rawCommand('georadius', 'user_info', $cy, $cx, '100', 'km', 'WITHCOORD', 'WITHDIST', 'ASC', 'COUNT', 5);
            echo json_encode($rediss);
    
        }
    
    }
    
    $tg = new  statistics();
    $tg->index();

    查看数据,redis存储方式:

    打印结果:

    展开全文
  • redis计算两地经纬度

    2020-07-13 20:20:01
    通过Redis拓展的GEO数据类型查询两地之间的距离 最近了解到redis还有几种拓展数据类型,GEO,hyperLogLog,bitmaps GEO GEOADD locations 116.419217 39.921133 beijin GEOPOS locations beijin GEODIST locations...

    通过Redis拓展的GEO数据类型查询两地之间的距离

    最近了解到redis还有几种拓展数据类型,GEO,hyperLogLog,bitmaps

    GEO

    GEOADD locations 116.419217 39.921133 beijin
    GEOPOS locations beijin
    GEODIST locations tianjin beijin km 	计算距离
    GEORADIUSBYMEMBER locations beijin 150 km  通过距离计算城市
    注意:没有删除命令  它的本质是zset  (type locations)
    所以可以使用zrem key member  删除元素
    zrange key  0   -1  表示所有   返回指定集合中所有value
    

    hyperLogLog

    Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
    Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的
    在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
    PFADD 2017_03_06:taibai 'yes' 'yes' 'yes' 'yes' 'no'
    PFCOUNT 2017_03_06:taibai    统计有多少不同的值
    1.PFADD 2017_09_08:taibai uuid9 uuid10 uu11
    2.PFMERGE 2016_03_06:taibai 2017_09_08:taibai   合并
    注意:本质还是字符串 ,有容错率,官方数据是0.81%
    

    bitmaps

    setbit taibai 500000 0
    getbit taibai 500000
    bitcount taibai
    Bitmap本质是string,是一串连续的2进制数字(01),每一位所在的位置为偏移(offset)。
    string(Bitmap)最大长度是512 MB,所以它们可以表示2 ^ 32=4294967296个不同的位。
    

    代码部分

    1.pom.xml

    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
        </dependencies>
    

    2.application.yml

    spring:
      redis:
        host: localhost
        port: 6379
    

    3.测试代码

    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.geo.Distance;
    import org.springframework.data.geo.Point;
    import org.springframework.data.redis.connection.RedisGeoCommands;
    import org.springframework.data.redis.core.GeoOperations;
    import org.springframework.data.redis.core.RedisTemplate;
    
    import javax.annotation.Resource;
    
    @SpringBootTest
    class SpringbootDemoApplicationTests {
    
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
    
        @Test
        void testGetDistance() {
    
            GeoOperations<String, Object> geoOperations = redisTemplate.opsForGeo();
            //首先存入客户端上传的经纬度和指定地点的经纬度
            // 将这些地址数据保存到redis中
            geoOperations.add("GET_DISTANCE", new Point(116.40, 39.90), "beijing");
            geoOperations.add("GET_DISTANCE", new Point(117.20, 39.12), "tianjin");
            // 调用方法,计算天津与北京之间的距离;单位为KM
            Distance distance = geoOperations.distance("GET_DISTANCE", "tianjin", "beijing", RedisGeoCommands.DistanceUnit.KILOMETERS);
            double value = distance == null ? 0 : distance.getValue();
            System.out.println(value);
    
        }
    
    }
    

    redis :

    在这里插入图片描述

    结果:

    在这里插入图片描述

    网上使用工具查询接口

    在这里插入图片描述

    展开全文
  • 类型为简单的zset类型 #添加 geoadd key longitude latitude member [longitude ...#获取地址位置的经纬度坐标 geopos key member [member ...] 参数为 集合名称 成员名称 例如: geopos area xxxx 结果: “116.415
  • radius方法:根据给定的经纬度坐标来获取指定范围内的地理位置集合。 hash方法:获取位置的hash值 完整的demo Geo原理简单介绍 GeoHash 算法将 二维的经纬度 数据映射到 一维 的整数,这样所有的元素都将在挂载到一...
  • $redis = new \Redis(); //增加两个位置的经纬度 a,b $redis->geoadd('demo',114.03587211582945,22.663998990300417,'a'); $redis->geoadd('demo',114.03435934994505,22....

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 283
精华内容 113
关键字:

redis经纬度

redis 订阅