坐标距离算法

Posted 啄木鸟¥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了坐标距离算法相关的知识,希望对你有一定的参考价值。

  经过这两天的研究,我想有些东西有必要写一下,同时也帮助需要的人

  这是一个查找附近的人的一个算法,在网上找了这篇文章 http://blog.csdn.net/dyllove98/article/details/9795815,他的算最小正方形的四个顶点有点问题。

    
   第一步 ,我们试想一下,如果我们要查找附近五公里的人,是不是最先想到根据自己的经纬度(如果连经纬度都不知道怎么回事,我想你应该知道度娘),再往数据库里面获取其他人的经纬度,根据两个经纬度获取他们的距离,

如果距离小于5公里的话,那就符合条件。 

  获取距离用两种情况,第一种就是全部查出来在代码里面进行算,第二种情况就是在sql 里面写个函数,在数据库里面算

      代码算距离算法:

 

    public static double GetDistance(Degree Degree1, Degree Degree2)
         {
             double radLat1 = radians(Degree1.Y);
             double radLat2 = radians(Degree2.Y);
             double a = radLat1 - radLat2;
             double b = radians(Degree1.X) - radians(Degree2.X);
 
             double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
              Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
             s = s * EARTH_RADIUS;
             s = Math.Round(s * 10000) / 10000;
             return s;
         }

      radians是个角度转弧度的算法

     private static double degrees(double d)
         {
             return d * (180 / Math.PI);
         }

     如果不知道里面的算法是个怎样的原理,你可以百度相关的三角函数公式

      sql 距离算法

  

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[fnGetDistance](@LatBegin float, @LngBegin float, @LatEnd float, @LngEnd float) returns float  
as
begin
  --距离(千米)  
  declare @Distance float;
  declare @EARTH_RADIUS float;
  set @EARTH_RADIUS = 6378.137;
  
  declare @RadLatBegin float, 
          @RadLatEnd float,
          @RadLatDiff float,
          @RadLngDiff float;
  set @RadLatBegin = @LatBegin * pi()/180.0;
  set @RadLatEnd = @LatEnd * pi()/180.;
  set @RadLatDiff = @RadLatBegin - @RadLatEnd;
  set @RadLngDiff = @LngBegin * pi()/180.0 - @LngEnd * pi()/180.0;
  set @Distance = 2 * asin(sqrt(power(sin(@RadLatDiff/2), 2) + cos(@RadLatBegin)
                  * cos(@RadLatEnd) * power(sin(@RadLngDiff/2), 2)));
  set @Distance = @Distance * @EARTH_RADIUS;
  --set @Distance = Round(@Distance * 10000) / 10000    
  return @Distance 
end

 

 

  如果你跟我上面的想法一致的话,我只能对你说处理小数据量还可以。

  例如:我们现在要做一个停车管理系统,需车位的可以查附近的供车位的,供车位的可以查附近需车位的,如果数据库里面有一万条供车位的经纬度,需车位访问服务器,服务器要进行十万次距离换算,如果同时有十个人进行访问的话,那服务器被你轻而易举的百万数据量访问了。

    那有什么办法可以解决呢?

  

 先看这张图,我们知道原点的坐标也就是我们的经纬度,也在知道半径(附近几公里),就可以得到圆的最小正方形,从而根据公式可以得到 正方形的四个顶点 就晓得了 最小经纬度和最大经纬度

把我们得到的经纬度往数据库里面一查 ,就能轻然一举的把符合范围内的人查

 

出来。

根据经纬度和距离,得到四个顶点的距离算法

 private static void GetlatLon(double GLON, double GLAT, double distance, double angle, out double newLon,out double newLat)
         {
             double Ea = 6378137;     //   赤道半径  
             double Eb = 6356725;     //   极半径
             double dx = distance  * Math.Sin(angle * Math.PI / 180.0);
             double dy = distance  * Math.Cos(angle * Math.PI / 180.0);
             //double ec = 6356725 + 21412 * (90.0 - GLAT) / 90.0;

             // 21412 是赤道半径与极半径的差
             double ec = Eb + (Ea - Eb) * (90.0 - GLAT) / 90.0;
             double ed = ec * Math.Cos(GLAT * Math.PI / 180);
             newLon = (dx / ed + GLON * Math.PI / 180.0) * 180.0 / Math.PI;
             newLat = (dy / ec + GLAT * Math.PI / 180.0) * 180.0 / Math.PI;
           
         }
         public static Degree[] GetRectRange(double centorLogitude,double centorlatitude, double distance)
         {

             double temp = 0.0;
             double maxLatitude;
             double minLatitude;
             double maxLongitude;
             double minLongitude;
             GetlatLon(centorLogitude, centorlatitude, distance, 0, out temp, out maxLatitude);

             GetlatLon(centorLogitude, centorlatitude, distance, 180, out temp, out minLatitude);

             GetlatLon(centorLogitude, centorlatitude, distance, 90, out maxLongitude, out temp);

             GetlatLon(centorLogitude, centorlatitude, distance, 270, out minLongitude, out temp);
             maxLatitude = Math.Round(maxLatitude,6);
             minLatitude = Math.Round(minLatitude,6);
             maxLongitude = Math.Round(maxLongitude,6);
             minLongitude = Math.Round(minLongitude,6);
             return new Degree[] {
                new Degree(minLongitude,maxLatitude),//left-top
                new Degree(minLongitude,minLatitude),//left-bottom
                new Degree(maxLongitude,maxLatitude),//right-top
                new Degree(maxLongitude,minLatitude)  //right-bottom
             };

         }

这些东西经过测试的 相差不到 1,2米

还是那就话如有不懂的地方 请联系我 QQ:209229923,或在下发为我留言

 

以上是关于坐标距离算法的主要内容,如果未能解决你的问题,请参考以下文章

通过距离和方位从已知位置查找点坐标的地理算法

数据结构与算法之深入解析“二指输入的的最小距离”的求解思路与算法示例

寻找像素和像素组之间最小距离的算法

用C语言和分治算法 求最近的两点的距离~

偏移 GPS 坐标的公式/算法

两坐标直线距离