坐標距離算法


  經過這兩天的研究,我想有些東西有必要寫一下,同時也幫助需要的人

  這是一個查找附近的人的一個算法,在網上找了這篇文章 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,或在下發為我留言

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM