lbs(查看附近的人),看看社交软件如何实现查看附近的人

最近在做一款移动端棋牌游戏,为了进一步提高用户体验、拉近玩家的距离,我们决定在游戏中加入好友功能,而对于体验好友功能的玩家来说,要是玩牌的时候可以看看附近都有谁在玩牌,跟他们交流交流玩牌心得什么的无疑是个不错的想法。而要实现查看附近的人就需要提提LBS(Location Based Service),他的意思就是基于位置的服务,就是通过移动终端获取到许多用户或者物体的经纬度坐标,通过这些位置信息所提供的服务。

好了,扯了这么多,我们来看看如何实现查看附近人的功能的:

首先要具备下面这些环境:

    1. php+MySQL(MySQL不是必须,本文中用的是redis来存储用户的信息)
    2. redis(本文用的是redis,当然你也可以用MySQL)
    3. geohash.class.php类(这个类是用来处理经纬度坐标的一些基本函数,当然这些东西完全可以自己去写,如果时间充裕的话)

好了,等这些环境都具备了之后,我来讲讲这个实现过程:

  • 首先介绍下GeoHash思想

   第一步.  编码

这个功能应用到了一个很好的算法GeoHash,也许有同学听过这个功能,没错GeoHash就是通过一个巧妙的算法(不由得惊叹前辈们真牛!)把经纬度转化为字符串,这样有什么好处呢,显而易见,将二维的数据转化为了一维,这样一来存储就方便了,搜索效率也会高很多,那么现在问题来了,GeoHash算法是如何把经纬度坐标转化为字符串的?

将经纬度编码为字符串的过程可以分为以下3个步骤:

首先就是编码,对于经纬度的编码通过折半比较法,当大于中值时该位编码为1(小于时编码为0),下次新的区间为中值到最大值(或者最小值到中值),这样一直比较下去,直到到达要求的精度,精度和纬度的方法是一样的,只不过一个原始区间是(-90,90),一个是(-180,180),光说不好理解,下面我们看看一个简单的例子:

对经度32.165进行编码:                                                                                                 对纬度89.156进行编码:


编码


min


mid


max


1


-90


0


90


0


0


45


90


1


0


22.5


45


0


22.5


033.75


45


1


22.5


28.125


33.75


1


28.125


30.9375


33.75


0


30.9375


32.34375


33.75


1


30.9375


31.640625


32.34375


1


31.640625


31.9921875


32.34375


0


31.9921875


32.16796875


32.34375


编码


min


mid


max


1


-180


0


180


0


0


90


180


1


0


45


90


1


45


67.5


90


1


67.5


78.75


90


1


78.75


84.375


90


1


84.375


87.1875


90


1


87.1875


88.59375


90


0


88.59375


89.296875


90


1


88.59375


88.9453125


89.296875

这样便可将(89.156,32.165) =>  (10101 10110,10111 11101)

这个时候就到了第二步骤——组码了,顾名思义,将第一步产生的编码组合起来为下一步产生字符串做准备,组码的方式是偶数位放置经度,奇数位放纬度(为什么要这么做呢,我猜可能是谷歌为了大家统一规范,仅此而已,其实奇偶数位互换也可以的),对于上面的经纬度编码后再组码如下:


经度:10101 11101


纬度:10111 11101


位置编码:11001 11011 11111 10011

图 3

对于上面的位置编码,为什么要这么编码呢,为什么要奇数位放纬度,偶数为方经度呢,我们看看下面这张图,用这张图模拟地图的经纬度,A点(-180,90),B点(180,90),C点(-180,-90),D点(180,-90);


A


B

 
010101


010111


011101


011111


110101


110111


111101


111111


010100


010110


011100


011110


110100


110110


111100


111110


010001


010011


011001


011011


110001


110011


111001


111011


010000


010010


011000


011010


110000


110010


111000


111010


000101


000111


001101


001111


100101


100111


101101


101111


000100


000110


001100


001110


100100


100110


101100


101110


000001


000011


001001


001011


100001


100011


101001


101011


000000


000010


001000


001010


100000


100010


101000


101010

 

C


D

图 4

如图4所示,这样就可以将地图(经度-180~180,纬度-90~90)分为很多很多多的小块,每一个小块都有唯一的二进制编码,当位数达到一定的长度时就可以表示很小的一块区域,这不就可以根据二进制编码定位一个唯一的位置了吗,对于划分的进一步理解可看下面的图。

图 5

如图5所示,左边是是对纬度(-180,180)的划分,可以看出通过划分可以确定(22.4,45)这一纬度区间的编码为1001,当然了位数越多精度越高,同理对经度进行划分,可以确定(-78.75,-67.5)这一经度范围的编码为0001,可以想象,当左右两张图合在一起时就可以确定一个唯一的矩形区域,当该区域足够小的时候就可一看做一个点。

  第二步.  组码

从图3可以看出我们对经纬度编码后可得二进制字符串11001 11011 11111 10011

最后使用用0-9、b-z(去掉a, i, l, o)这32个字母进行base32编码,首先将11001 11011 11111 10011转成十进制,对应着25、27、32、19,十进制对应的编码就是tvzm。同理,将编码转换成经纬度的解码算法与之相反,具体不再赘述。至此,我们的对geohash有了个大致的了解。

图 6

  • 如何具体的应用到程序中

首先思考一下查看附近的人的流程:

    1. 用户点击查看附近的人按钮,首先获取到该用户的选位置信息(经纬度),传给服务器。
    2. 服务器收到数据之后对该用户的位置信息进行geohash计算,获得该用户的位置hash字符串。
    3. 对该用户的位置信息hash串进行缓存(缓存时间长短根据具体情况而定)。
    4. 根据该hash串选出附近的人。
    5. 对hash进行解码,计算出附近用户的位置,返回给用户。

首先看看geohash.class.php这个公共类库里面的基本方法:

 
[public]Geohash()       初始化hash映射表


Geohash


[public]encode($lat,$long)       对经纬度进行编码

 
[public]decode()       对hash进行解码

图 7

如图7所示,显而易见这个类库里面有3个函数,第一个用来初始化hash映射表,其实就是把0123456789bcdefghjkmnpqrstuvwxyz字符串中的每个字符和它对应的二进制编码对应起来(左边补零至5位)。encode()是用来生成hash的,decode是用来解码hash得到hash对应的经纬度的。

下面我们看个例子,现在假设有图8中的几个用户查看附近的人:


mid


坐标


100


(42.61233,-5.61234)


101


(-20.25689, 50.56897)


102


(10.11233, 57.21234)


103


(49.26343, -123.26895)


104


(0.00534, -179.56732)


105


(-30.55555, 0.28958)


106


(5.00001, -140.63422)


107


(42.61234, -5.61234)


108


(5.00001, -140.63422)

图 8

图8的数据发送到服务器经过geohash计算得出下面的hash表:


mid


坐标


100


ezs42m34yfp_100


101


mh7uy8r5n6j_101


102


t3b9tbuu84u_102


103


c2b26bnk32b_103


104


80021bgp45m_104


105


k484ntdc58w_105


106


8bgury1r1jm_106


107


ezs42m34ygz_107


108


8bgury1r1jm_108

图 9

计算出这些hash值,将hash值存入redis中,存入redis中之后,那么问题来了,如何去获取一个用户附近的用户呢?当redis数据库中有了一些用户的记录之后,来一个用户,我们先对其进行编码,然后根据该用户的位置hash从redis中选出该用户附近的hash,选取附近的hash这一步很简单,对于redis只需这么做:

<?php
       $mid = 2014;
       $level = 7;    //获取的精度等级,数字越大,附近这个范围越小
        $redis = Redis::init();  //假设这样获取到redis实例
        $mykey = ‘8gur95yjmz‘;  //假设我的hash为这个
        $redis->setex($mykey.‘_‘.$mid,$_SERVER[‘REQUEST_TIME‘],86400);    //这里设置缓存1天,具体情况具体对待
$search = substr($makey,0,$level);
       $nearbys = $redis->keys("{$search}*");
?>

程序 1

上面的几句代码就可以选出我附近的人的hash,当然,其中的level来设置精度的,这个数字越大,附近的人范围越小,具体参考图10中的值,这个表中的值是从我的导师李伟(weickly)那里获取到的。要注意,这个地方搜索完之后要排除自己。还有一点要注意,就是在缓存时键名的最后一定要加上_{$mid},这样做可以避免多个用户在同一位置是互相覆盖的情况(就像图9中mid为106和108的用户),放在最后是为了不影响搜索。


1


2500000m


2


630000m


3


78000m


4


20000m


5


2400m


6


610m


7


76m


8


19m


9


2m

图 10

例如mid为109,经纬度为(42.61236, -5.61234)的用户,当他点击获取附近的人按钮式,我获取到他的经纬度并计算出他的hash,$mykey=‘ezs42m34yzx‘,然后通过程序段1可以获取到他附近的hash:


100


ezs42m34yfp_100


(42.61233,-5.61234)


3.3m


107


ezs42m34ygz_107


(42.61234, -5.61234)


2.2m


109


ezs42m34yzx_109


(42.61236, -5.61234)


0m

图 11

图11中获取到了用户109附近的用户hashs,获取到hash值还并没有完成,首先排除掉自己109那条记录,然后通过Geohash类中的decode将hash解码为经纬度,通过每个用户的经纬度计算出和109用户的距离,然后按距离等级返回,比如说小于100,小于200……

至此,获取附近的人就完成了,当然了具体实践的时候还要随机应变具体情况具体对待,我写这篇文章只是想起到抛砖引玉的效果,本文中可能会存在很多不足,还望斧正。

  本文版权归作者([email protected])和博客园共有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

时间: 2024-10-14 13:44:52

lbs(查看附近的人),看看社交软件如何实现查看附近的人的相关文章

微信肆虐,社交软件路在何方?

在2011年1月,那个智能机才刚刚开始普及,千元低端安卓手机还留在计划之中,人们还沉迷于微博大V互动的鼎盛时期之中,腾讯微信悄悄地来了. 在微信出现之前,除去使用米聊的用户之外,当时绝大多数人都不知道微信是何许方物,是干吗用的?但是也就是这么一个出现的有些突然的微信,着实吊足了不少人的胃口.微信的出现彻底改变了之前的网络社交方式,也直接或间接的堵死了国内其他社交软件的移动入口,甚至连同门兄弟手机QQ都无法抵挡阻挡微信的攻势,那么夹缝中的其他社交软件未来之路到底该如何走下去? 疯狂的"微信&quo

为什么用了这么多社交软件,你还是要回家相亲

美国杂志纽约客曾经在情人节前夕邀请一些撰稿人讲述他们自己的恋爱经历,其中有一个很有意思的故事,一位 37 岁的大龄女青年坚持不懈地在社交网站 JDate(一家创立超过 10 年的犹太人交友社区,致力于为犹太男女提供交友及约会的机会)上相亲,虽然见识了很多奇葩,不过也遇到了三段无疾而终的感情,为了证明自己是有魅力的,她在这个平台上花了 1000 多美元,为每一次的赴约精心准备,「必须要在 JDate 上找到一个老公 ,哪怕我们是在别的地方遇见的,我也会说我们在 JDate 认识的!」 最终,她还是

[Android分享] 社交软件开发解决方案

一个简单的社交软件解决方案应该解决的问题: 通信/共享/空间(朋友圈)/用户/好友/动态/聊天记录. 社交主要是交流.朋友圈(空间).通信又分为文本.表情.语音.视频.朋友圈主要包含自己和好友动态,有些还包含系统推荐的信息. 这是我使用Bmob提供的解决方案案例: 通信:建立Bmob推送服务基础上,有消息需要将通知或者信息推送到参与者端,文本可以直接推送,对于视频,语音推送的是存储连接地址,当参与者收到推送消息,根据地址下载该消息.对于表情来说有两种方法,一种是在本地存储表情包,另一种是和视频,

社交软件开发,直播系统开发,区块链IM社交app系统开发

社交软件的出现,不仅仅为我们提供了一个平台,它还最大限度地聚集各类资源,为我们认识其他地域.不同领域的人提供了各种可能性.社交软件开发 Tel: 前面138中间2315后面3201 一款社交软件的间接交流怎么做才算好? 首先就是内容来源的丰富性:用户在任意一个地方看到的内容都能轻松分享到这款社交软件上,新闻.视频.音乐.文章.图片等等,无论从哪里看到可以一键分享是非常重要的诉求. 其次是互动性:如果你分享的内容没有办法被回应,那也就没有了之前提到的间接交流具有发起方期望得到多个接收方反馈的特点,

银钻娱乐客服15687949443浅谈社交软件

提起中国的社交软件,比较厉害的两个那就应该是QQ与微信.这两个产品可是腾讯的摇钱树,聚宝盆.归结其原因,也就是居高不下的活跃用户量了.现在各种外卖APP,打车APP,购物APP等疯狂补贴用户,不都是为了用户量和市场占有率吗! 今天要说的就是QQ与微信这两款社交软件.曾在15年11月份的时候看到过一条新闻,说的是微信的月活跃用户量6.5亿,同比增长百分之三十九,超越移动QQ.期间竟然还有人说,微信必将取代移动QQ.我想了想后,却很不以为然,因为数据只是数据,你要根据数据去理智的进行分析判断. 首先

一直在使用一个职场社交软件

15年年末,大家的话题都聚焦在了"社群"上,关于社群的建设.运营,已经有很多成功的案例,周围的一些朋友也有做的风生水起期的,这个时候,我觉得应该做点事情了.因为一直在使用一个职场社交软件脉脉,做为脉脉的一个深度用户,当知道"脉友会"这个事情的时候,也就自然加入了长春脉友会筹备和运营当中.作为一个地方性社群,长春脉友会相比其他城市,无论是在用户基数.用户的活跃度.用户结构等都不具备其他一线城市的先天条件.

三行代码接入,社交软件打字时底下弹出的表情布局,自定义ViewPager+页面点标+各种功能的android小框架。

(转载请声明出处:http://www.cnblogs.com/linguanh/) 前言: 接上次分享的 ListView 动态加载类,入口:http://www.cnblogs.com/linguanh/p/4645115.html  这次分享给大家的是,刚些写好的类似社交软件打字时地下弹出的表情布局. 先看下我的默认效果图. 该效果图里面使用的图片资源,是默认的IC_lanucher,在我的类里面,你可以自定义,包括布局,几行几列,什么的,都可以自定义.底下的是小点标. 下集预告:我将在使

为什么你还把时间浪费在无效人脉社交上?

有两项技能是一个人终身受用的,第一是学习,第二就是社交. 谁都知道人脉很重要,所以有些人非常勤奋的“做人脉”:他们往往会这样做——积极的参与各类线下活动,逢人就换名片.加微信.可是这样的做法往往非常不讨喜. 在这个大数据时代里,圈子小到你意想不到,口碑传播的速度也快到你意想不到.还在做无效的“人脉”?你该看看真正懂人脉的人是怎么做的. 反面教材往往是这样的: 见到名人或者重要人物必合影,而且他们还会掏出手机来给你看. 逢年过节,给所有他觉得重要的人发一条相同的祝福微信,比较有心的会在复制的时候改

ios 开发之个人appStore上线项目分享-即时通讯社交软件项目拆解0

分享一个appStore即时通讯上线作品的代码!本人的早期作品中,做过 几个上线的项目;目前对于我来说已经没有太大的用处;闲暇之余,写写博客,看看当时的我是怎么写出这个 应用的,下载地址 蜜聊Love  https://itunes.apple.com/cn/app/mi-liaolove/id939936656?mt=8 说明一下:聊天服务器用的是 阿里云的服务器,现在已到期 目前已无法聊天,但其他功能还在! 原文博主地址http://blog.csdn.net/yangbingbinga转载