我目前正在處理GPS數據並結合精確高度測量。 我想計算兩個連接點之間的距離。關於使用WGS84橢球等計算兩點之間的距離有很多信息。計算測地距離時考慮海拔高度
但是,我沒有找到任何信息,這需要海拔高度更改爲計算此 距離。
有沒有人知道一些網站,論文,書籍等描述這種方法? 謝謝
編輯:當計算距離時,Sql Server 2008地理擴展也忽略了海拔高度信息。
我目前正在處理GPS數據並結合精確高度測量。 我想計算兩個連接點之間的距離。關於使用WGS84橢球等計算兩點之間的距離有很多信息。計算測地距離時考慮海拔高度
但是,我沒有找到任何信息,這需要海拔高度更改爲計算此 距離。
有沒有人知道一些網站,論文,書籍等描述這種方法? 謝謝
編輯:當計算距離時,Sql Server 2008地理擴展也忽略了海拔高度信息。
我會建議在使用WGS84的任何距離上都會給你更高的準確度,以至於海拔差異無關緊要。在任何高度差異很重要的距離上,你應該使用直線近似。
爲了做到這一點,你必須解決的第一個問題是如何定義高度變化。法線方程式因爲它們位於二維曲面上而起作用,但是添加第三維意味着最短距離的簡單定義不再適用,例如現在第三維是「起作用」的,您的最短距離可能會穿過原始曲線橢球。 這有點快速和骯髒,但你最好的解決方案可能是假設在橢球體上原始2D路徑上的變化率是恆定的。然後,您可以將二維距離計算爲長度,求出高度變化率,然後簡單地使用畢達哥拉斯計算長度的增加量,三角形的一邊爲二維距離,高度爲第二長度。
我使用開始和結束高度的平均值作爲恆定高度,實現了WGS84距離函數。如果你確定沿着你的路徑會有相對較小的高度變化,這個工作可以接受的很好(誤差與你的兩個LLA點的高度差有關)。
這裏是我的代碼(C#):
/// <summary>
/// Gets the geodesic distance between two pathpoints in the current mode's coordinate system
/// </summary>
/// <param name="point1">First point</param>
/// <param name="point2">Second point</param>
/// <param name="mode">Coordinate mode that both points are in</param>
/// <returns>Distance between the two points in the current coordinate mode</returns>
public static double GetGeodesicDistance(PathPoint point1, PathPoint point2, CoordMode mode) {
// calculate proper geodesics for LLA paths
if (mode == CoordMode.LLA) {
// meeus approximation
double f = (point1.Y + point2.Y)/2 * LatLonAltTransformer.DEGTORAD;
double g = (point1.Y - point2.Y)/2 * LatLonAltTransformer.DEGTORAD;
double l = (point1.X - point2.X)/2 * LatLonAltTransformer.DEGTORAD;
double sinG = Math.Sin(g);
double sinL = Math.Sin(l);
double sinF = Math.Sin(f);
double s, c, w, r, d, h1, h2;
// not perfect but use the average altitude
double a = (LatLonAltTransformer.A + point1.Z + LatLonAltTransformer.A + point2.Z)/2.0;
sinG *= sinG;
sinL *= sinL;
sinF *= sinF;
s = sinG * (1 - sinL) + (1 - sinF) * sinL;
c = (1 - sinG) * (1 - sinL) + sinF * sinL;
w = Math.Atan(Math.Sqrt(s/c));
r = Math.Sqrt(s * c)/w;
d = 2 * w * a;
h1 = (3 * r - 1)/2/c;
h2 = (3 * r + 1)/2/s;
return d * (1 + (1/LatLonAltTransformer.RF) * (h1 * sinF * (1 - sinG) - h2 * (1 - sinF) * sinG));
}
PathPoint diff = new PathPoint(point2.X - point1.X, point2.Y - point1.Y, point2.Z - point1.Z, 0);
return Math.Sqrt(diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z);
}
在實踐中我們發現,高度差幾乎使一個大的差異,我們的路徑通常與100米量級的高度變化的1-2km長我們發現平均約5米的變化與使用未修改的WGS84橢球相比。
編輯:
要添加到這一點,如果你希望大高度變化,您可以將您的WGS84座標ECEF(地心地固定)和在底部所示評估直線路徑我功能。轉換一個點到ECEF很簡單的事:
/// <summary>
/// Converts a point in the format (Lon, Lat, Alt) to ECEF
/// </summary>
/// <param name="point">Point as (Lon, Lat, Alt)</param>
/// <returns>Point in ECEF</returns>
public static PathPoint WGS84ToECEF(PathPoint point) {
PathPoint outPoint = new PathPoint(0);
double lat = point.Y * DEGTORAD;
double lon = point.X * DEGTORAD;
double e2 = 1.0/RF * (2.0 - 1.0/RF);
double sinLat = Math.Sin(lat), cosLat = Math.Cos(lat);
double chi = A/Math.Sqrt(1 - e2 * sinLat * sinLat);
outPoint.X = (chi + point.Z) * cosLat * Math.Cos(lon);
outPoint.Y = (chi + point.Z) * cosLat * Math.Sin(lon);
outPoint.Z = (chi * (1 - e2) + point.Z) * sinLat;
return outPoint;
}
編輯2:
有人問我的一些在我的代碼中的其他變量:
// RF is the eccentricity of the WGS84 ellipsoid
public const double RF = 298.257223563;
// A is the radius of the earth in meters
public const double A = 6378137.0;
LatLonAltTransformer
是我使用的類將LatLonAlt座標轉換爲ECEF座標並定義上述常量。
對於初學者,您需要一個模型,告訴您兩個點之間的高度如何變化。沒有這樣的模型,你沒有任何兩點之間距離的一致定義。
如果你有一個線性模型(行駛50%的點之間的距離也意味着你上升了50%的高度),那麼你可以假設整個事情是一個直角三角形;即您確定世界是平坦的,以確定高度變化如何影響距離。沿地面的距離是基礎,高度變化是三角形的高度,斜邊是您估計的從點到點的真實行駛距離。
如果您想進一步細化,那麼您可以注意到上面的模型對於無窮小距離來說是非常好的,這意味着您可以遍歷距離的單個增量,微積分式,每次使用當前高度計算地面距離,然後使用相同的三角比來計算行駛距離的高度變化貢獻。我可能會在包含10到100段的for()循環中執行此操作,並且可能通過反覆試驗找出需要達到真實值的epsilon所需的塊數。計算這個模型下兩點之間的實際距離也可以計算出線積分。
您可能並不關心大型2D距離分離的高度。所以如果你得到的距離超過20(或50公里),那麼誰在乎高度差(取決於你的需求情況)。在說20公里以下,飼餵簡單的畢達哥拉斯加除了高度差。順利進料。
我沒有看過的WGS84方程,所以我不寫這作爲一個答案。也就是說,在我看來,你應該能夠調整一個或兩個半徑以使您的測量點成爲「新」表面。如果你的高度測量是基於GPS的話,這可能效果最好;如果基於機械手段(例如氣壓),那麼「海平面」可能與模型大地水準面幾乎沒有關係。 – kdgregory 2009-07-10 12:11:53
你有沒有想出一個好的解決方案呢? – lnafziger 2012-08-19 18:06:37