zoukankan      html  css  js  c++  java
  • redis实现查找附近商户信息功能

    这个项目是使用thinkphp框架开发的,项目中需要用到查找附近商户,并显示距离的功能。以前通过sqlserver 函数实现了附近功能,代码如下

     1 CREATE  FUNCTION [dbo].[GetDistance]
     2 
     3 ( 
     4 --SELECT *,GetDistance(某一点的经度,某一点的纬度,数据库中经度,数据库中纬度)AS dis FROM 表名  where dis<5
     5 /*
     6 6371.004  地球半径
     7 
     8 6371.004*ACOS(SIN(@GPSLat/180*PI())*SIN(@Lat/180*PI())+COS(@GPSLat/180*PI())*COS(@Lat/180*PI())*COS((@GPSLng-@Lng)/180*PI()))  计算公式 可查球面弧长计算公式的详细解释
     9 */
    10 @GPSLng DECIMAL(12,6),
    11 @GPSLat DECIMAL(12,6),
    12 @Lng  DECIMAL(12,6),
    13 @Lat DECIMAL(12,6)
    14 )
    15 RETURNS DECIMAL(12,4)
    16 AS
    17 BEGIN
    18    DECLARE @result DECIMAL(12,4)
    19    SELECT @result=6371.004*ACOS(SIN(@GPSLat/180*PI())*SIN(@Lat/180*PI())+COS(@GPSLat/180*PI())*COS(@Lat/180*PI())*COS((@GPSLng-@Lng)/180*PI()))
    20    RETURN @result
    21 
    22 END
    View Code

    数据并不多,但是读取缓慢,现在随着数据的增加,打开的速度到了无法忍受的地步,于是通过寻找新的技术重写了该功能,修改过后,展现实现了秒开,具体使用技术为redis的GEO定位功能。

    Redis 在 3.2 版本以后增加了地理位置 GEO 模块,注意:如果phps要使用redis的GEO模块,版本必须要在7.0以上才能使用,因为php7.0以前并没有支持redis3.2以上的版本。点此下载windows php redis模块

    第一步: 将需要展示附近的数据, 通过GEOADD 命令 导入到redis:

    geoadd

    geoadd 用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

    geoadd 语法格式如下:

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

    添加数据  

    geoadd test 113.765 34.7275 "jx102" 113.61 34.783 "jx103" 113.424 34.348 

    第二步:通过使用georadius 来计算离你最近的商户

    GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
    GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
    

      

    参数说明:

      • m :米,默认单位。
      • km :千米。
      • mi :英里。
      • ft :英尺。
      • WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。
      • WITHCOORD: 将位置元素的经度和维度也一并返回。
      • WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
      • COUNT 限定返回的记录数。
      • ASC: 查找结果根据距离从近到远排序。
      • DESC: 查找结果根据从远到近排序。

    如定得到用户的经伟度后,计算离用户周边6km的商户,显示距离并根据距离排序,可以使用以下命令

    georadius test 113.671 34.7893 6 km  WITHDIST COUNT 5  ASC
    

      

    效果:其中 0.0002为离你的距离,单位为km

    使用GEODIST 计算两个位置之间的距离:

    语法:

    GEODIST key member1 member2 [m|km|ft|mi]

    member1 member2 为两个地理位置,key为GEOADD添加时设定的集合名称,如本文中的test

     /*通过GEOADD命令把得到的用户经纬度加入到集合*/
    self::$redis->geoAdd($long,$latitude,$this->tokens,'test');
    /*通过GEODIST计算两点之间的距离*/
     $info['path']=round(self::$redis->geoDist($this->tokens,'jx'.$info['id'],'test'),1);
    /*在集合中删除刚添加的用户定位信息*/
      self::$redis->zRem($this->tokens,'test');
    

      

     相关参考:https://www.runoob.com/redis/redis-geo.html

                     https://www.cnblogs.com/GreenForestQuan/p/14310434.html

  • 相关阅读:
    参数传递(值传递与引用传递)
    存入redis中的java对象都需要序列化
    windows环境Apache服务器启动失败的原因
    IDEA/Eclipse安装 Alibaba Java Coding Guidelines 插件
    使用freemarker对模板进行渲染
    java使用freemarker作为模板导出Excel表格
    mybatis 中 foreach collection的三种用法
    利用freemarker导出页面格式复杂的excel
    mysql limit和offset用法
    设计模式之二十一:中介者模式(Mediator)
  • 原文地址:https://www.cnblogs.com/fogwang/p/15022609.html
Copyright © 2011-2022 走看看