IOS 計算兩個經緯度之間的距離

來源:互聯網
上載者:User

標籤:

IOS 計算兩個經緯度之間的距離

一 丶
-(double)distanceBetweenOrderBy:(double) lat1 :(double) lat2 :(double) lng1 :(double) lng2{           CLLocation *curLocation = [[CLLocation alloc] initWithLatitude:lat1 longitude:lng1];           CLLocation *otherLocation = [[CLLocation alloc] initWithLatitude:lat2 longitude:lng2];            double  distance  = [curLocation distanceFromLocation:otherLocation];            return  distance;}

 

二丶

//將角度轉為弧度

+ (float)radians:(float)degrees{

return (degrees*3.14159265)/180.0;

}

//根據經緯度換算出直線距離

+ (float)getDistance:(float)lat1 lng1:(float)lng1 lat2:(float)lat2 lng2:(float)lng2

{         

//地球半徑

int R = 6378137;

//將角度轉為弧度

float radLat1 = [self radians:lat1];

float radLat2 = [self radians:lat2];

float radLng1 = [self radians:lng1];

float radLng2 = [self radians:lng2];

//結果

float s = acos(cos(radLat1)*cos(radLat2)*cos(radLng1-radLng2)+sin(radLat1)*sin(radLat2))*R;

//精度

s = round(s* 10000)/10000;

return  round(s);

}

 

經緯度簡介這些經緯線是怎樣定出來的呢?地球是在不停地繞地軸旋轉(地軸是一根通過地球南北兩極和地球中心的假想線),在地球中腰畫一個與地軸垂直的大圓圈,使圈上的每一點都和南北兩極的距離相等,這個圓圈就叫作“赤道”。在赤道的南北兩邊,畫出許多和赤道平行的圓圈,就是“緯圈”;構成這些圓圈的線段,叫做緯線。我們把赤道定為緯度零度,向南向北各為90度,在赤道以南的叫南緯,在赤道以北的叫北緯。北極就是北緯90度,南極就是南緯90度。緯度的高低也標誌著氣候的冷熱,如赤道和低緯度地地區無冬,兩極和高緯度地區無夏,中緯度地區四季分明。 其次,從北極點到南極點,可以畫出許多南北方向的與地球赤道垂直的大圓圈,這叫作“經圈”;構成這些圓圈的線段,就叫經線。公元1884平面座標圖年,國際上規定以通過英國倫敦近郊的格林尼治天文台的經線作為計算經度的起點,即經度零度零分零秒,也稱“本初子午線”。在它東面的為東經,共180度;在它西面的為西經,共180度。因為地球是圓的,所以東經180度和西經180度的經線是同一條經線。各國公定180度經線為“國際日期變更線”。為了避免同一地區使用兩個不同的日期,國際日期變線在遇陸地時略有偏離。   每一經度和緯度還可以再細分為60分,每一分再分為60秒以及秒的小數。利用經緯線,我們就可以確定地球上每一個地方的具體位置,並且把它在地圖或地球儀上表示出來。例如問北京的經緯度是多少?我們很容易從地圖上查出來是東經116度24分,北緯39度54分。在大海中航行的船隻,只要把所在地的經度測出來,就可以確定船在海洋中的位置和前進方向。 緯度共有90度。赤道為0度,向兩極排列,圈子越小,度數越大。橫線是緯度,豎線是經度。 當然可以計算,四元二次方程。 經度和緯度都是一種角度。經度是個兩面角,是兩個經線平面的夾角。因所有經線都是一樣長,為了度量經度選取一個起點面,經1884年國際會議協商,決定以通過英國倫敦近郊、泰晤士河南岸的格林尼治皇家天文台(舊址)的一台主要子午儀十字絲的那條經線為起始經線,稱為本初子午線。本初子午線平面是起點面,終點面是本地經線平面。某一點的經度,就是該點所在的經線平面與本初子午線平面間的夾角。在赤道上度量,自本初子午線平面作為起點面,分別往東往西度量,往東量值稱為東經度,往西量值稱為西經度。由此可見,一地的經度是該地對於本初子午線的方向和角距離。本初子午線是0°經度,東經度的最大值為180°,西經度的最大值為180°,東、西經180°經線是同一根經線,因此不分東經或西經,而統稱180°經線。   緯度是個線面角。起點面是赤道平面,線是本地的地面法線。所謂法線,即垂直於參考扁球體表面的線。某地的緯度就是該地的法線與赤道平面之間的夾角。緯度在本地經線上度量,由赤道向南、北度量,向北量值稱為北緯度,向南量值稱為南緯度。由此可見,一地的緯度是該地對於赤道的方向和角距離。赤道是0°緯線,北緯度的最大值為90°,即北極點;南緯度的最大值為90°,即南極點。經緯度互換度換算成度分秒度(DDD):E 108.90593度    N 34.21630度 如何將度(DDD):: 108.90593度換算成度分秒(DMS)東經E 108度54分22.2秒?轉換方法是將108.90593整數位不變取108(度),用0.90593*60=54.3558,取整數位54(分),0.3558*60=21.348再取整數位21(秒),故轉化為108度54分21秒.同樣將度分秒(DMS):東經E 108度54分22.2秒 換算成度(DDD)的方法如下:108度54分22.2秒=108+(54/60)+(22.2/3600)=108.90616度因為計算時小數位保留的原因,導致正反計算存在一定誤差,但誤差影響不是很大。1秒的誤差就是幾米的樣子。GPS車友可以用上述方法換算成自己需要的單位座標。  關於經緯度十進位標記法
對於兩個點,在緯度相等的情況下:
經度每隔0.00001度,距離相差約1米;每隔0.0001度,距離相差約10米;每隔0.001度,距離相差約100米;每隔0.01度,距離相差約1000米;每隔0.1度,距離相差約10000米。

對於兩個點,在經度相等的情況下:
緯度每隔0.00001度,距離相差約1.1米;每隔0.0001度,距離相差約11米;每隔0.001度,距離相差約111米;每隔0.01度,距離相差約1113米;每隔0.1度,距離相差約11132米。     根據地球上任意兩點的經緯度計算兩點間的距離 方法1:由於地球是橢球體,這個太難算了,如果假設地球是球體,可以使用以下公式:設地球上某點的經度為A,緯度為B, 則這點的空間座標是 x=cos(B)*cos(A) y=cos(B)*sin(A) z=sin(B) 設地球上兩點的空間座標分別為(x1,y1,z1),(x2,y2,z2) 則它們的夾角為 C=acos(x1*x2+y1*y2+z1*z2),C是角度 則兩地距離為 C/180*pi*R,其中R為地球平均半徑6371 誤差不超過1%  地球是一個近乎標準的橢球體,它的赤道半徑為6378.140千米,極半徑為 6356.755千米,平均半徑6371.004千米。如果我們假設地球是一個完美的球體,那麼它的半徑就是地球的平均半徑,記為R。如果以0度經線為基 准,那麼根據地球表面任意兩點的經緯度就可以計算出這兩點間的地表距離(這裡忽略地球表面地形對計算帶來的誤差,僅僅是理論上的估算值)。設第一點A的經 緯度為(LonA, LatA),第二點B的經緯度為(LonB, LatB),按照0度經線的基準,東經取經度的正值(Longitude),西經取經度負值(-Longitude),北緯取90-緯度值(90- Latitude),南緯取90+緯度值(90+Latitude),則經過上述處理過後的兩點被計為(MLonA, MLatA)和(MLonB, MLatB)。那麼根據三角推導,可以得到計算兩點距離的如下公式:C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB)Distance = R*Arccos(C)*Pi/180 這裡,R和Distance單位是相同,如果是採用6371.004千米作為半徑,那麼Distance就是千米為單位,如果要使用其他單位,比如mile,還需要做單位換算,1千米=0.621371192mile如果僅對經度作正負的處理,而不對緯度作90-Latitude(假設都是北半球,南半球只有澳洲具有應用意義)的處理,那麼公式將是:C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)*cos(MLonA-MLonB)Distance = R*Arccos(C)*Pi/180以上通過簡單的三角變換就可以推出。如果三角函數的輸入和輸出都採用弧度值,那麼公式還可以寫作: C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)Distance = R*Arccos(C)*Pi/180也就是:C = sin(LatA/57.2958)*sin(LatB/57.2958) + cos(LatA/57.2958)*cos(LatB/57.2958)*cos((MLonA-MLonB)/57.2958)Distance = R*Arccos(C) = 6371.004*Arccos(C) kilometer = 0.621371192*6371.004*Arccos(C) mile = 3958.758349716768*Arccos(C) mile[java] view plain copy
  1. <span style="font-size:14px;font-weight: normal;">  private static final  double EARTH_RADIUS = 6378137;//赤道半徑(單位m)  
  2.       
  3.     /** 
  4.      * 轉化為弧度(rad) 
  5.      * */  
  6.     private static double rad(double d)  
  7.     {  
  8.        return d * Math.PI / 180.0;  
  9.     }  
  10.       
  11.     /** 
  12.      * 基於餘弦定理求兩經緯度距離 
  13.      * @param lon1 第一點的精度 
  14.      * @param lat1 第一點的緯度 
  15.      * @param lon2 第二點的精度 
  16.      * @param lat3 第二點的緯度 
  17.      * @return 返回的距離,單位km 
  18.      * */  
  19.     public static double LantitudeLongitudeDist(double lon1, double lat1,double lon2, double lat2) {  
  20.         double radLat1 = rad(lat1);  
  21.         double radLat2 = rad(lat2);  
  22.   
  23.         double radLon1 = rad(lon1);  
  24.         double radLon2 = rad(lon2);  
  25.   
  26.         if (radLat1 < 0)  
  27.             radLat1 = Math.PI / 2 + Math.abs(radLat1);// south  
  28.         if (radLat1 > 0)  
  29.             radLat1 = Math.PI / 2 - Math.abs(radLat1);// north  
  30.         if (radLon1 < 0)  
  31.             radLon1 = Math.PI * 2 - Math.abs(radLon1);// west  
  32.         if (radLat2 < 0)  
  33.             radLat2 = Math.PI / 2 + Math.abs(radLat2);// south  
  34.         if (radLat2 > 0)  
  35.             radLat2 = Math.PI / 2 - Math.abs(radLat2);// north  
  36.         if (radLon2 < 0)  
  37.             radLon2 = Math.PI * 2 - Math.abs(radLon2);// west  
  38.         double x1 = EARTH_RADIUS * Math.cos(radLon1) * Math.sin(radLat1);  
  39.         double y1 = EARTH_RADIUS * Math.sin(radLon1) * Math.sin(radLat1);  
  40.         double z1 = EARTH_RADIUS * Math.cos(radLat1);  
  41.   
  42.         double x2 = EARTH_RADIUS * Math.cos(radLon2) * Math.sin(radLat2);  
  43.         double y2 = EARTH_RADIUS * Math.sin(radLon2) * Math.sin(radLat2);  
  44.         double z2 = EARTH_RADIUS * Math.cos(radLat2);  
  45.   
  46.         double d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)+ (z1 - z2) * (z1 - z2));  
  47.         //餘弦定理求夾角  
  48.         double theta = Math.acos((EARTH_RADIUS * EARTH_RADIUS + EARTH_RADIUS * EARTH_RADIUS - d * d) / (2 * EARTH_RADIUS * EARTH_RADIUS));  
  49.         double dist = theta * EARTH_RADIUS;  
  50.         return dist;  
  51.     }</span>  


  方法2:google地圖提供的方法:對上面的公式解釋如下:
1.Lat1 Lung1 表示A點經緯度,Lat2 Lung2 表示B點經緯度;
2.a=Lat1 – Lat2 為兩點緯度之差  b=Lung1 -Lung2 為兩點經度之差;
3.6378.137為地球半徑,單位為千米;
計算出來的結果單位為千米,若將半徑改為米為單位則計算的結果單位為米。
計算精度與Google地圖的距離精度差不多,相差範圍在0.2米以下。
[java] view plain copy
  1. <span style="font-size:14px;">  private static final  double EARTH_RADIUS = 6378137;//赤道半徑(單位m)  
  2.       
  3.     /** 
  4.      * 轉化為弧度(rad) 
  5.      * */  
  6.     private static double rad(double d)  
  7.     {  
  8.        return d * Math.PI / 180.0;  
  9.     }  
  10.     /** 
  11.      * 基於googleMap中的演算法得到兩經緯度之間的距離,計算精度與Google地圖的距離精度差不多,相差範圍在0.2米以下 
  12.      * @param lon1 第一點的精度 
  13.      * @param lat1 第一點的緯度 
  14.      * @param lon2 第二點的精度 
  15.      * @param lat3 第二點的緯度 
  16.      * @return 返回的距離,單位km 
  17.      * */  
  18.     public static double GetDistance(double lon1,double lat1,double lon2, double lat2)  
  19.     {  
  20.        double radLat1 = rad(lat1);  
  21.        double radLat2 = rad(lat2);  
  22.        double a = radLat1 - radLat2;  
  23.        double b = rad(lon1) - rad(lon2);  
  24.        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)));  
  25.        s = s * EARTH_RADIUS;  
  26.        //s = Math.round(s * 10000) / 10000;  
  27.        return s;  
  28.     }</span>  

IOS 計算兩個經緯度之間的距離

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.