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

原文地址:https://www.cnblogs.com/fogwang/p/15022609.html