当前位置:首页 > PHP教程 > php应用 > 列表

PHP实现搜索地理位置及计算两点地理位置间距离的实例

发布:smiling 来源: PHP粉丝网  添加日期:2021-07-04 13:58:50 浏览: 评论:0 

这篇文章主要介绍了PHP实现搜索地理位置及计算两点地理位置间距离的实例,地理位置搜寻的例子中使用到了MongoDB数据库,需要的朋友可以参考下。

地理位置搜寻

LBS,存储每个地点的经纬度坐标,搜寻附近的地点,建立地理位置索引可提高查询效率。

mongodb地理位置索引,2d和2dsphere,对应平面和球面。

1.创建lbs集合存放地点坐标

  1. use lbs;  
  2.    
  3. db.lbs.insert(  
  4.   {  
  5.     loc:{  
  6.       type: "Point",  
  7.       coordinates: [113.332264, 23.156206]  
  8.     },  
  9.     name: "广州东站" 
  10.   }  
  11. )  
  12.    
  13. db.lbs.insert(  
  14.   {  
  15.     loc:{  
  16.       type: "Point",  
  17.       coordinates: [113.330611, 23.147234]  
  18.     },  
  19.     name: "林和西" 
  20.   }  
  21. )  
  22.    
  23. db.lbs.insert(  
  24.   {  
  25.     loc:{  
  26.       type: "Point",  
  27.       coordinates: [113.328095, 23.165376]  
  28.     },  
  29.     name: "天平架" 
  30.   }  
  31. )  

2.创建地理位置索引

  1. db.lbs.ensureIndex(  
  2.   {  
  3.     loc: "2dsphere" 
  4.   }  
  5. )  

3.查询附近的坐标

当前位置为:时代广场,

坐标:

113.323568, 23.146436

搜寻附近一公里内的点,由近到远排序

  1. db.lbs.find(  
  2.   {  
  3.     loc: {  
  4.       $near:{  
  5.         $geometry:{  
  6.           type: "Point",  
  7.           coordinates: [113.323568, 23.146436]  
  8.         },  
  9.         $maxDistance: 1000  
  10.       }  
  11.     }  
  12.   }  
  13. )  

搜寻结果:

{ "_id" : ObjectId("556a651996f1ac2add8928fa"), "loc" : { "type" : "Point", "coordinates" : [ 113.330611, 23.147234 ] }, "name" : "林和西" }

php代码如下:

  1. <?php  
  2. // 连接mongodb  
  3. function conn($dbhost$dbname$dbuser$dbpasswd){  
  4.   $server = 'mongodb://'.$dbuser.':'.$dbpasswd.'@'.$dbhost.'/'.$dbname;  
  5.   try{  
  6.     $conn = new MongoClient($server);  
  7.     $db = $conn->selectDB($dbname);  
  8.   } catch (MongoException $e){  
  9.     throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);  
  10.   }  
  11.   return $db;  
  12. }  
  13.    
  14. // 插入坐标到mongodb  
  15. function add($dbconn$tablename$longitude$latitude$name){  
  16.   $index = array('loc'=>'2dsphere');  
  17.   $data = array(  
  18.       'loc' => array(  
  19.           'type' => 'Point',  
  20.           'coordinates' => array(doubleval($longitude), doubleval($latitude))  
  21.       ),  
  22.       'name' => $name 
  23.   );  
  24.   $coll = $dbconn->selectCollection($tablename);  
  25.   $coll->ensureIndex($index);  
  26.   $result = $coll->insert($dataarray('w' => true));  
  27.   return (isset($result['ok']) && !emptyempty($result['ok'])) ? true : false;  
  28. }  
  29.    
  30. // 搜寻附近的坐标  
  31. function query($dbconn$tablename$longitude$latitude$maxdistance$limit=10){  
  32.   $param = array(  
  33.     'loc' => array(  
  34.       '$nearSphere' => array(  
  35.         '$geometry' => array(  
  36.           'type' => 'Point',  
  37.           'coordinates' => array(doubleval($longitude), doubleval($latitude)),   
  38.         ),  
  39.         '$maxDistance' => $maxdistance*1000  
  40.       )  
  41.     )  
  42.   );  
  43.    
  44.   $coll = $dbconn->selectCollection($tablename);  
  45.   $cursor = $coll->find($param);  
  46.   $cursor = $cursor->limit($limit);  
  47.      
  48.   $result = array();  
  49.   foreach($cursor as $v){  
  50.     $result[] = $v;  
  51.   }   
  52.    
  53.   return $result;  
  54. }  
  55.    
  56. $db = conn('localhost','lbs','root','123456');  
  57.    
  58. // 随机插入100条坐标纪录  
  59. for($i=0; $i<100; $i++){  
  60.   $longitude = '113.3'.mt_rand(10000, 99999);  
  61.   $latitude = '23.15'.mt_rand(1000, 9999);  
  62.   $name = 'name'.mt_rand(10000,99999);  
  63.   add($db'lbs'$longitude$latitude$name);  
  64. }  
  65.    
  66. // 搜寻一公里内的点  
  67. $longitude = 113.323568;  
  68. $latitude = 23.146436;  
  69. $maxdistance = 1;  
  70. $result = query($db'lbs'$longitude$latitude$maxdistance);  
  71. print_r($result);  
  72. ?>  

演示php代码,首先需要在mongodb的lbs中创建用户和执行auth,方法如下:

  1. use lbs;  
  2. db.createUser(  
  3.   {  
  4.     "user":"root",  
  5.     "pwd":"123456",  
  6.     "roles":[]  
  7.   }  
  8. )  
  9.    
  10. db.auth(  
  11.   {  
  12.     "user":"root",  
  13.     "pwd":"123456" 
  14.   }  
  15. )  

计算两点地理坐标的距离

功能:根据圆周率和地球半径系数与两点坐标的经纬度,计算两点之间的球面距离。

获取两点坐标距离:

  1. <?php 
  2. /** 
  3.  * 计算两点地理坐标之间的距离 
  4.  * @param Decimal $longitude1 起点经度 
  5.  * @param Decimal $latitude1 起点纬度 
  6.  * @param Decimal $longitude2 终点经度  
  7.  * @param Decimal $latitude2 终点纬度 
  8.  * @param Int   $unit    单位 1:米 2:公里 
  9.  * @param Int   $decimal  精度 保留小数位数 
  10.  * @return Decimal 
  11.  */ 
  12. function getDistance($longitude1$latitude1$longitude2$latitude2$unit=2, $decimal=2){ 
  13.  
  14.   $EARTH_RADIUS = 6370.996; // 地球半径系数 
  15.   $PI = 3.1415926; 
  16.  
  17.   $radLat1 = $latitude1 * $PI / 180.0; 
  18.   $radLat2 = $latitude2 * $PI / 180.0; 
  19.  
  20.   $radLng1 = $longitude1 * $PI / 180.0; 
  21.   $radLng2 = $longitude2 * $PI /180.0; 
  22.  
  23.   $a = $radLat1 - $radLat2
  24.   $b = $radLng1 - $radLng2
  25.  
  26.   $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2))); 
  27.   $distance = $distance * $EARTH_RADIUS * 1000; 
  28.  
  29.   if($unit==2){ 
  30.     $distance = $distance / 1000; 
  31.   } 
  32.  
  33.   return round($distance$decimal); 
  34.  
  35.  
  36. // 起点坐标 
  37. $longitude1 = 113.330405; 
  38. $latitude1 = 23.147255; 
  39.  
  40. // 终点坐标 
  41. $longitude2 = 113.314271; 
  42. $latitude2 = 23.1323; 
  43.  
  44. $distance = getDistance($longitude1$latitude1$longitude2$latitude2, 1); 
  45. echo $distance.'m'// 2342.38m 
  46.  
  47. $distance = getDistance($longitude1$latitude1$longitude2$latitude2, 2); 
  48. echo $distance.'km'// 2.34km 
  49.  
  50. ?>

Tags: PHP搜索地理位置及

分享到: