日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

根据两点经纬度坐标计算距离

發布時間:2023/12/20 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 根据两点经纬度坐标计算距离 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考博客
http://www.jb51.net/article/34520.htm
http://www.douban.com/note/326431282/?type=like

問題提出


目前手頭的一個項目要用到GPS地理定位信息,很自然的就需要知道兩個地點之間的距離,于是上網找了一下。

背景知識


這些經緯線是怎樣定出來的呢?

地球是在不停地繞地軸旋轉(地軸是一根通過地球南北兩極和地球中心的假想線),在地球中腰畫一個與地軸垂直的大圓圈,使圈上的每一點都和南北兩極的距離相等,這個圓圈就叫作“赤道”

在赤道的南北兩邊,畫出許多和赤道平行的圓圈,就是“緯圈”;構成這些圓圈的線段,叫做緯線。我們把赤道定為緯度零度,向南向北各為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車友可以用上述方法換算成自己需要的單位坐標。

##經緯度換算成米

緯度分為60分,每一分再分為60秒以及秒的小數。

緯度線投射在圖上看似水平的平行線,但實際上是不同半徑的圓。有相同特定緯度的所有位置都在同一個緯線上。

赤道的緯度為0°,將行星平分為南半球和北半球。

緯度是指某點與地球球心的連線和地球赤道面所成的線面角,其數值在0至90度之間。位于赤道以北的點的緯度叫北緯,記為N,位于赤道以南的點的緯度稱南緯,記為S。

緯度數值在0至30度之間的地區稱為低緯地區,緯度數值在30至60度之間的地區稱為中緯地區,緯度數值在60至90度之間的地區稱為高緯地區。
赤道、南回歸線、北回歸線、南極圈和北極圈是特殊的緯線。

緯度1秒的長度

地球的子午線總長度大約40008km。
平均:
緯度1度 = 大約111km
緯度1分 = 大約1.85km
緯度1秒 = 大約30.9m

根據地球上任意兩點的經緯度計算兩點間的距離


地球是一個近乎標準的橢球體,它的赤道半徑為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

綜上我們得出公式

其中latitude是緯度,longitude是經度
a=latitude1 - latitude2為兩點緯度之差 b=longitude1-longitude2 為兩點經度之差;
6378.137(KM) 為地球半徑
結果是km……

在實際應用當中,一般是通過一個個體的郵政編碼來查找該郵政編碼對應的地區中心的經緯度,然 后再根據這些經緯度來計算彼此的距離,從而估算出某些群體之間的大致距離范圍(比如酒店旅客的分布范圍-各個旅客的郵政編碼對應的經緯度和酒店的經緯度所 計算的距離范圍-等等),所以,通過郵政編碼查詢經緯度這樣一個數據庫是一個很有用的資源。
附:C代碼

// 時間標識 typedef struct tagDate {int m_year; //int m_month; //int m_day; //int m_hour; // ?int m_minute; //int m_second; // }GoToDate;// GPS位置信息 typedef struct tagLocation {struct tagDate m_date; // 時間char m_status; // 狀態double m_latitude; // 緯度double m_longitude; // 經度char m_NS; // 南北緯度標識 char m_EW; // 東西經度標識double m_speed; // 速度標識 double m_high; // 高速 }GoToLocation;// 兩坐標之間的距離信息 typedef struct tagPosition {double m_xdistance; // 東西經度距離double m_ydistance; // 南北緯度距離double m_zdistance; // 高度距離double m_tdistance; // 坐標直線距離double m_angle; // 偏角 }GoToPosition;void ShowPosition(GoToPosition *position) {printf("兩地水平距離%lf\n", position->m_xdistance);printf("兩地垂直距離%lf\n", position->m_ydistance);printf("兩地高度相差%lf\n", position->m_zdistance);printf("兩地直線距離%lf\n", position->m_tdistance);printf("兩地偏角%lf\n", position->m_angle); }const double EARTH_RADIUS = 6378.137; //地球半徑 const double EARTH_RADIUS_C = 6378137; // 赤道半徑 const double EARTH_RADIUS_J = 6356725; // 極半徑 const double PI = 3.141592654; // PIdouble Rad(double d) {return d * PI / 180.0; }/*地球是一個近乎標準的橢球體,它的赤道半徑為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 */ /* 同一緯度上經度差一度實際距離差,與緯度有關 πRcosφ/180 π=3.1415926 R=6371 km φ為緯度 =111.319491*cosφ緯度差一度就簡單了,因為經線是大圓,和緯度無關= πR/180=111.319491 km */ // 獲取兩個位置點之間的相對距離 // 單位KM double GetDistance(GoToLocation *left, GoToLocation *right, GoToPosition *position) {double a = Rad(left->m_latitude) - Rad(right->m_latitude);double b = Rad(left->m_longitude) - Rad(right->m_longitude);printf("a = %lf, b = %lf\n", a, b);double s = 2 * asin(sqrt(pow(sin(a/2), 2) + cos(Rad(left->m_latitude))*cos(Rad(right->m_latitude))*pow(sin(b/2),2)));s = s * EARTH_RADIUS;//double angle = atan(cos(Rad(right->m_latitude)) * abs(right->m_longitude - left->m_longitude) / abs(right->m_latitude - left->m_latitude));//printf("%lf\n", angle);if(position != NULL){printf("***********************************\n");ShowLocation(left);ShowLocation(right);position->m_xdistance = 111.319491 * cos (Rad(left->m_latitude)) * (left->m_longitude - right->m_longitude) / 2; // 經度差position->m_ydistance = 111.319491 * (left->m_latitude - right->m_latitude); // 維度差position->m_zdistance = right->m_high - left->m_high;position->m_tdistance = s;position->m_angle = atan(position->m_ydistance / position->m_xdistance) * 180 / PI;if(position->m_angle < 0){position->m_angle *= -1; } /*position->m_xdistance = 111.319491 * cos (Rad(left->m_latitude)) * b; // 經度差position->m_ydistance = 111.319491 * (a); // 維度差position->m_zdistance = right->m_high - left->m_high;position->m_tdistance = s; */ #ifdef DEBUGprintf("兩地水平距離%lf\n", position->m_xdistance);printf("兩地垂直距離%lf\n", position->m_ydistance);printf("兩地高度相差%lf\n", position->m_zdistance);printf("兩地直線距離%lf\n", position->m_tdistance);printf("兩地的偏角%lf\n", position->m_angle);printf("%lf == %lf", position->m_tdistance, s);printf("***********************************\n"); #endif}return s; }int main( ) {// 經度相同,緯度每差1,相距111.319491GoToDate date = {2014, 5, 23, 10, 56, 00};GoToLocation left = {date,'1', 45.4225, 126.3445, 'N', 'W', 12.00, 20};GoToLocation right = {date,'1', 44.4211, 126.36455, 'N', 'W', 12.00, 20};GoToPosition position;printf("經度差, 水平%lf\n", 111.319491 *cos(Rad(45.4225)));printf("維度差, 垂直%lf\n", 111.319491 * 1);printf("%lf\n", GetDistance(&left, &right, &position));ShowPosition(&position); }

總結

以上是生活随笔為你收集整理的根据两点经纬度坐标计算距离的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。