轉:經緯度相關計算

近期做一個與GRPS相關的應用,涉及到經緯度的計算,找資料時頗費了一番功夫,特此將其相關資料整理了一下,發佈出來,希望對用到的同學有所幫助。

閒話少說,經緯度計算主要有兩種:

1. 知道兩點的經緯度值,計算兩點間的距離

2. 知道一點的經緯度,知道另一點相對於此點的角度,距離。計算另一點的經緯度信息

 

對於第一種計算,網上搜索到大概有三種:

1. 把地球當球體,根據球面公式計算

2. 根據公式d111.12cos{1/[sinΦAsinΦBcosΦAcosΦBcos(λB—λA)]}

其中A點經度,緯度分別爲λA和ΦAB點的經度、緯度分別爲λB和ΦBd爲距離。

這個公司搜索結果挺多,在百度搜索“經緯度 計算距離”,一二位都是這個公式。

3. Google地圖中反推出的算法(詳見參考文檔1)。公式如下圖

第一種沒做驗證,第二種測試了一下,偏差較大(以圓明園、動物園之間的距離進行測定)目前採用的是第三種算法。

 

對於第二種計算,找到的資料很少,倒是找到不少遇到相同問題的朋友。不過最終還是找到了(詳見參考文檔2)。並使用第一種計算進行反驗證,偏差很小。

 

整理後的代碼如下:

經緯度類

 

代碼

 

 

計算類:

 

 

代碼
1 using System;
2 using System.Data;
3 using System.Configuration;
4 using System.Linq;
5 using System.Web;
6 using System.Web.Security;
7 using System.Web.UI;
8 using System.Web.UI.HtmlControls;
9 using System.Web.UI.WebControls;
10 using System.Web.UI.WebControls.WebParts;
11 using System.Xml.Linq;
12
13 namespace GeoSite
14 {
15 /// <summary>
16 /// Geo輔助類
17 /// </summary>
18 public static class GeoHelper
19 {
20 /// <summary>
21 /// 根據兩點的經緯度計算兩點距離
22 /// 可參考:通過經緯度計算距離的公式 http://www.storyday.com/html/y2009/2212_according-to-latitude-and-longitude-distance-calculation-formula.html
23 /// </summary>
24 /// <param name="src">A點維度</param>
25 /// <param name="dest">B點經度</param>
26 /// <returns></returns>
27 public static double GetDistance(LatLon src, LatLon dest)
28 {
29 if (Math.Abs(src.Lat) > 90 || Math.Abs(dest.Lat) > 90 || Math.Abs(src.Lon) > 180 || Math.Abs(dest.Lon) > 180)
30 throw new ArgumentException("經緯度信息不正確!");
31
32 double latDis = src.RadLat - dest.RadLat;
33 double lonDis = src.RadLon - dest.RadLon;
34
35 double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(latDis / 2), 2) + Math.Cos(src.Lat) * Math.Cos(dest.Lat) * Math.Pow(Math.Sin(lonDis / 2), 2)));
36 s = s * LatLon.EARTH_RADIUS / 1000;
37 s = Math.Round(s * 10000) / 10000;
38
39 return s;
40 }
41
42 /// <summary>
43 /// 根據兩點的經緯度計算兩點距離
44 /// 可參考:通過經緯度計算距離的公式 http://www.storyday.com/html/y2009/2212_according-to-latitude-and-longitude-distance-calculation-formula.html
45 /// </summary>
46 /// <param name="lat1">A點維度</param>
47 /// <param name="lon1">A點經度</param>
48 /// <param name="lat2">B點維度</param>
49 /// <param name="lon2">B點經度</param>
50 /// <returns></returns>
51 public static double GetDistance(double lat1, double lon1, double lat2, double lon2)
52 {
53 LatLon src = new LatLon(lat1, lon1);
54 LatLon dest = new LatLon(lat2, lon2);
55 return GetDistance(src, dest);
56 }
57
58
59 /// <summary>
60 /// 已知點A經緯度,根據B點據A點的距離,和方位,求B點的經緯度
61 /// </summary>
62 /// <param name="a">已知點A</param>
63 /// <param name="distance">B點到A點的距離 </param>
64 /// <param name="angle">B點相對於A點的方位,12點鐘方向爲零度,角度順時針增加</param>
65 /// <returns>B點的經緯度座標</returns>
66 public static LatLon GetLatLon(LatLon a, double distance, double angle)
67 {
68 double dx = distance * 1000 * Math.Sin(angle * Math.PI / 180);
69 double dy = distance * 1000 * Math.Cos(angle * Math.PI / 180);
70
71 double lon = (dx / a.Ed + a.RadLon) * 180 / Math.PI;
72 double lat = (dy / a.Ec + a.RadLat) * 180 / Math.PI;
73
74 LatLon b = new LatLon(lat, lon);
75 return b;
76 }
77
78 /// <summary>
79 /// 已知點A經緯度,根據B點據A點的距離,和方位,求B點的經緯度
80 /// </summary>
81 /// <param name="longitude">已知點A經度</param>
82 /// <param name="latitude">已知點A緯度</param>
83 /// <param name="distance">B點到A點的距離</param>
84 /// <param name="angle">B點相對於A點的方位,12點鐘方向爲零度,角度順時針增加</param>
85 /// <returns>B點的經緯度座標</returns>
86 public static LatLon GetLatLon(double longitude, double latitude, double distance, double angle)
87 {
88 LatLon a = new LatLon(latitude, longitude);
89 return GetLatLon(a, distance, angle);
90 }
91 }
92 }
93
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章