PHP根据一个给定经纬度的点,进行附近地点查询–合理利用算法

实现原理先算出该点周围的矩形的四个点,然后使用经纬度去直接匹配数据库中的记录。

   //获取周围坐标
   public function returnSquarePoint($lng, $lat,$distance = 0.5){
         $earthRadius = 6378138;
        $dlng =  2 * asin(sin($distance / (2 * $earthRadius)) / cos(deg2rad($lat)));
        $dlng = rad2deg($dlng);
        $dlat = $distance/$earthRadius;
        $dlat = rad2deg($dlat);
        return array(
                       ‘left-top‘=>array(‘lat‘=>$lat + $dlat,‘lng‘=>$lng-$dlng),
                       ‘right-top‘=>array(‘lat‘=>$lat + $dlat, ‘lng‘=>$lng + $dlng),
                       ‘left-bottom‘=>array(‘lat‘=>$lat - $dlat, ‘lng‘=>$lng - $dlng),
                       ‘right-bottom‘=>array(‘lat‘=>$lat - $dlat, ‘lng‘=>$lng + $dlng)
        );
   }
   //计算两个坐标的直线距离
   
   public function getDistance($lat1, $lng1, $lat2, $lng2){      
          $earthRadius = 6378138; //近似地球半径米
          // 转换为弧度
          $lat1 = ($lat1 * pi()) / 180;
          $lng1 = ($lng1 * pi()) / 180;
          $lat2 = ($lat2 * pi()) / 180;
          $lng2 = ($lng2 * pi()) / 180;
          // 使用半正矢公式  用尺规来计算
        $calcLongitude = $lng2 - $lng1;
          $calcLatitude = $lat2 - $lat1;
          $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);  
       $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
          $calculatedDistance = $earthRadius * $stepTwo;
          return round($calculatedDistance);
   }
时间: 2024-10-16 07:25:27

PHP根据一个给定经纬度的点,进行附近地点查询–合理利用算法的相关文章

PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询–合理利用算法,效率提高2125倍

目前的工作是需要对用户的一些数据进行分析,每个用户都有若干条记录,每条记录中有用户的一个位置,是用经度和纬度表示的.还有一个给定的数据库,存储的是一些已知地点以及他们的经纬度,内有43W多条的数据.现在需要拿用户的经纬度和已知地点进行距离匹配,如果它们之间的距离小于一定的数据,比如说500米,就认为用户是在这个地点.MYSQL本身是支持空间索引的,但是在5.x的版本中,取消了对Distance()和Related()的支持,参考这里:MySQL 5.1参考手册 :: 19. 中的空间扩展 19.

Java,Mysql-根据一个给定经纬度的点,进行附近500米地点查询–合理利用算法

LBS 球面距离公式 http://wiki.myoa.info/zh-blog:20 最近做一个项目:需要查询一个站点(已知该站点经纬度)500米范围内的其它站点.所以,我首先想到的是,对每条记录,去进行遍历,跟数据库中的每一个点进行距离计算,当距离小于500米时,认为匹配.这样做确实能够得到结果,但是效率极其低下,因为每条记录都要去循环匹配n条数据,其消耗的时间可想而知. 于是我就想到一个先过滤出大概的经纬度范围再进行计算.比方说正方形的四个点,于是我在网上搜索,意外的,查询到了一个关于这个

给定经纬度定位某个城市

方案1 通过GEO HASH,抓取每个格子里的点的地址信息,然后把这个地址信息作为GEO中点坐标的一个信息,当查询给定经纬度是在哪个城市的时候,查询过程是查询距离这个经纬度最近的带有地址的点,认为给定经纬度和最近的这个点是同一个地址下的.通过不断完善GEO中的每个坐标下的地址信息,可以提高整个系统的精度.这种方法相当于一种间接获取的方法的. 方案2 我们知道每个地区是有一定区域的,可以认为是一个闭合的多边形,定位城市,可以理解为判断某个点,是否在某个区域内. 第一点:如何获取城市的区域边界 很幸

程序员面试100题之十:快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值(转)

能否快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值,为了简化起见,我们假设这个数组中肯定存在至少一组符合要求的解. 假如有如下的两个数组,如图所示: 5,6,1,4,7,9,8 给定Sum= 10 1,5,6,7,8,9 给定Sum= 10 分析与解法 这个题目不是很难,也很容易理解.但是要得出高效率的解法,还是需要一番思考的. 解法一 一个直接的解法就是穷举:从数组中任意取出两个数字,计算两者之和是否为给定的数字. 显然其时间复杂度为N(N-1)/2即O(N^2).这个算法很简

JavaScript面试题:重复输出一个给定的字符串

面试题 重复输出一个给定的字符串(str第一个参数)n 次 (num第二个参数),如果第二个参数num不是正数的时候,返回空字符串. function repeatStringNumTimes(str, num) { return str; } repeatStringNumTimes("abc", 3); 提供测试情况: repeatStringNumTimes("*", 3) //应该返回 "***". repeatStringNumTime

写一个函数,对于一个给定的整数,如果它的二进制模式从正向看和反向看是一样的,那么返回true;

写一个函数,对于一个给定的整数,如果它的二进制模式从正向看和反向看是一样的,那么返回true:也就是实现这样一个函数boolean isPalindrome(int x); 分析一下,该题目主要是通过移位来实现,二进制模式从正向看和反向看是一样的,说明这个二进制数两边是对称的, 画个图看看: 代码如下: boolean isPalindrome(int x){ int flag = 1,i,j,temp;    while(1){        if(num&(0x1<<flag)){

采用truelicense进行Java规划license控制 扩展可以验证后,license 开始结束日期,验证绑定一个给定的mac住址

采用truelicense进行Java规划license控制 扩展可以验证后,license 开始结束日期,验证绑定一个给定的mac住址. Truelicense 它是一个开源java license 检验项目. 使用truelicense实现用于JAVAprojectlicense机制(包含license生成和验证)请參考http://www.it165.net/pro/html/201404/11540.html 当中包含license授权机制的原理和制作license的详细步骤 本文主要是

问对于一个给定的n,怎样才能用最少的步骤将它变到1

如果n为偶数,则将它除以2,如果n为奇数,则将它加1或者减1.问对于一个给定的n,怎样才能用最少的步骤将它变到1.例如:n= 61n-- 60n/2 30n/2 15n++ 16n/2 8n/2 4n/2 2n/2 1 算法设计:首先想到的是递规算法,不过细想一下我们可以动态规划:设a(i)为整数i用最少步骤变成1的解,设n=i+1 那么我们考虑a(n),如果n为偶数,那么a(n) = a(n/2) +1; 如果为奇数,那么a(n) = Min(a( (n+1)/2+2 ),   a((n-1)

【转】重复输出一个给定的字符串的几种方法

方法1:通过 `while` 循环重复输出一个字符串 解题思路:while 语句只要指定的条件计算结果为true的时候,就执行其语句.while 语句的语法是这样的: 1 while (expression) 2 statement 在每次通过循环之前计算条件结果.如果条件为true,则执行语句.如果条件为false,则执行继续 while 循环之后的任何语句. 只要条件为true,语句就会执行. 这里是解决方案: function repeatString(str, times) { //空字