基于PHP+MongoDB的LBS附近的人应用-初探
来源:互联网 发布:网络畅销书排行榜 编辑:程序博客网 时间:2024/04/30 00:17
写这篇文章是基于兴趣,早之前好奇一些社交APP、O2O应用可能会带有“附近的人”类似的功能,到底他们是如何做的呢?下面我简单的分析下用到的技术,小学生的分析欢迎批评指正。在线体验:http://182.92.217.161/map/index.php (H5+PHP+Mongo 请使用 手机打开,最好是在非WIFI 环境下,那样定位更加准确)。
基于 GeoHash + (B Tree + R tree 储存,最好是 R tree)技术,详细关于GeoHash深度技术可阅读以下文章:
http://www.cnblogs.com/LBSer/p/3310455.html
http://iamzhongyong.iteye.com/blog/1399333
依旧沿用简单粗暴的解决问题的方案,直接使用空间索引的 DB,这里我就折中选择 MongoDB,提供空间索引的DB 很多,例如 Redis 3.2 以上,MongoDB 、PostgreSQL、MySQL,关于这几款的性能测评,详情参照: http://www.cnblogs.com/zhenbianshu/p/6817569.html.
上代码套餐:
<?phpini_set("display_errors", "On");error_reporting(E_ALL | E_STRICT);$mongo_config = [ 'host'=>'127.0.0.1', 'port'=>27017, 'dbname'=>'my_app', 'user'=>'', 'pwd'=>''];$host_port = $mongo_config['host'] . ":" . $mongo_config['port'];try { $mongoDB = new MongoClient($host_port); $mongo_model = $mongoDB->selectDB($mongo_config['dbname']);} catch(\Exception $e) { echo responseJson(0, 'MongoDB connection was fail.'); exit();}$lbs = new LBS();$lbs->setKvDB($mongo_model);$method = trim($_POST['method']);switch($method) { case 'join': $longitude = $_POST['lng']; $latitude = $_POST['lat']; $uid = $_POST['uuid']; $r = $lbs->geoAdd($longitude, $latitude, $uid); if($r) { $users = $lbs->geoSearch($longitude, $latitude); if(!empty($users)) { echo responseJson(1, '已经找到附近的小伙伴了.', $users); } else { echo responseJson(0, '你附近没有小伙伴.'); } } else { echo responseJson(0, '上报地理位置失败'); exit(); } break; case 'search': echo georadiusbymember($redis); break; default: echo responseJson(0,'未知操作'); break;}class LBS{ private $kvDB; private $index_type = '2dsphere'; private $table_name = 'user_lbs'; /** * 设置储存媒介,限定 mongoDB,所有操作基于mongo * @param object $mongoDB * */ public function setKvDB(MongoDB $mongoDB) { $this->kvDB = $mongoDB; } /** * 设置 lbs 表名称 * @param double $longitude 经度 * @param double $latitude 维度 * @param string/int $uid 用户ID * @param array $data 其他数据,k v 形式, example: $data = ['username' => 'kevin','geo' => 'center']; */ public function geoAdd($longitude, $latitude, $uid, $data = []) { $d = [ 'loc' => [ 'type' => 'Point', 'coordinates' => [doubleval($longitude), doubleval($latitude)] ], 'uid' => $uid ]; if($this->checkData($data)) { $d = array_merge($d, $data); } $collection = $this->kvDB->selectCollection($this->table_name); //查询 该uid 是否存在,存在则更新 //$collection->remove(['uid' => $uid], ['justOne' => true]); // test $exist = $collection->findOne(['uid' => $uid]); $collection->ensureIndex(['loc' => $this->index_type]); if($exist) { $r = $collection->update(['uid' => $uid], ['$set' => $d]); } else { $r = $collection->insert($d); } return (isset($r['ok']) && !empty($r['ok'])) ? true : false; } /** * 根据 经纬度查询附近人 * @param double $longitude 经度 * @param double $latitude 维度 * @param int $maxdistance 默认 2000 Mi(米) * @param int $limit 默认拉取100 * @return array 附近的人集合 */ public function geoSearch($longitude, $latitude, $maxdistance = 1000, $limit = 100) { $coll = $this->kvDB->selectCollection($this->table_name); $r = $this->kvDB->command( [ 'geoNear' => $this->table_name, 'near' => [ 'type' => 'Point','coordinates' =>[doubleval($longitude), doubleval($latitude)]], 'spherical' => true, 'maxDistance' => $maxdistance, 'num' => $limit, ] ); if(isset($r['ok']) && !empty($r['ok'])) { return $r['results']; } else { return false; } } /** * 安全监测 如需严格,则需要判断经纬度在范围 * @param array $data * @return bool|array */ public function checkData($data) { if(empty($data)) return false; if(isset($data['loc'])) unset($data['loc']); if(isset($data['uid'])) unset($data['uid']); return $data; } /** * 设置 lbs 表名称 * @param string $table_name default value "user_lbs" * */ public function setTableName($table_name) { $this->table_name = $table_name; } /** * 获取 lbs 表名称 * @return string table name */ public function getTableName() { return $this->table_name; } /** * 返回json * @param int $state 状态 * @param string $message 消息 * @param array $data 数据 * @return json string json 数据 */ function responseJson($state = 0, $message = '', $data = null) { $r['state'] = $state; $r['message'] = $message; if(!is_null($data)) { $r['data'] = $data; } return json_encode($r); }}/** * 返回json * @param int $state 状态 * @param string $message 消息 * @param array $data 数据 * @return json string json 数据 */function responseJson($state = 0, $message = '', $data = null) { $r['state'] = $state; $r['message'] = $message; if(!is_null($data)) { $r['data'] = $data; } return json_encode($r);}
效果图
阅读全文
0 0
- 基于PHP+MongoDB的LBS附近的人应用-初探
- 结合MongoDB开发LBS应用——附近的人
- LBS 附近的人
- mongodb实现lbs地理位置查找附近的商家
- 【LBS】基于地理位置的搜索之微信 附近的人 简单实现
- LBS 查询附近的方法
- Mongodb获取附近的人
- php附近的人
- 基于LBS功能应用的Geohash方案
- 构建基于LBS的大数据应用
- 基于LBS功能应用的Geohash方案
- mongodb的lbs功能
- 基于MongoDB的php应用开发
- 基于MongoDB的php应用开发
- 基于MongoDB的php应用开发
- 基于MongoDB的php应用开发
- 基于LBS的地理位置附近的搜索以及由近及远的排序
- 基于LBS的地理位置附近的搜索以及由近及远的排序(MYSQL)
- 最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器
- React 认知 四 Props 属性
- linux中增加swap分区文件的步骤方法
- spark存储,缓存,断点模块
- 设计模式六大原则(一)-- 接口隔离原则(ISP)
- 基于PHP+MongoDB的LBS附近的人应用-初探
- 欢迎使用CSDN-markdown编辑器
- 自定义注解校验
- 解析:中国大数据发展呈现十大发展趋势
- 【计算机视觉】OpenCV人脸识别facerec源码分析2——LBPH概述
- UFLDL教程:数据预处理
- Spring的整体架构
- css布局(上下固定,中间自适应)
- 剑指offer——孩子们的游戏