tft每日頭條

 > 生活

 > 怎麼根據gps兩個點坐标算長度

怎麼根據gps兩個點坐标算長度

生活 更新时间:2024-12-27 17:48:15

特别注意:

網上有根據以下公式計算經緯度坐标的方法,實際上是錯誤的,這個d隻能在111.12和-111.12之間

怎麼根據gps兩個點坐标算長度(根據兩個GPS點的經緯度計算實際距離的方法)1

以下包含四種C#實現方法,地球半徑不統一,從精确度上推薦使用【方法一】,注意參數的經緯度順序

地球平均半徑 :6371.004千米

地球赤道半徑 :6378.140千米

航天使用的經過拟合的地球半徑為:6378.137千米

方法一:

/// <summary>

/// 從兩個gps坐标點(經緯度)獲得兩點的直線距離,谷歌和高德地圖的計算方式

/// </summary>

/// <param name="dLati1">第一個點的緯度</param>

/// <param name="dLong1">第一個點的經度</param>

/// <param name="dLati2">第二個點的緯度</param>

/// <param name="dLong2">第二個點的經度</param>

/// <returns>單位是米</returns>

publicdoublegetDistanceGD(doubledLati1, doubledLong1, doubledLati2, doubledLong2)

{

/// <summary>

/// 從兩個gps坐标點(經緯度)獲得兩點的直線距離,百度地圖的計算方式(JS代碼修改而來,可能不精準),參數依次為A點的經度、A點的緯度、B點的經度、B點的緯度

/// </summary>

/// <param name="a"></param>

/// <param name="b"></param>

/// <param name="c"></param>

/// <param name="d"></param>

/// <returns></returns>

publicdoublegetDistanceBD(doublea, doubleb, doublec, doubled)

{

if(a < 0 || b < 0 || c < 0 || d < 0)

return0;

a = fD(a, -180, 180);

b = jD(b, -74, 74);

c = fD(c, -180, 180);

d = jD(d, -74, 74);

returnCe(yk(a), yk(c), yk(b), yk(d));

}

privatedoublefD(doublea, doubleb, doublec)

{

for(; a > c;)

a -= c - b;

for(; a < b;)

a = c - b;

returna;

}

privatedoublejD(doublea, doubleb, doublec)

{

//JS代碼

//b != null && (a = Math.Max(a, b));

//c != null && (a = Math.Min(a, c));

//C#代碼

if(b > 0)

{

a = Math.Max(a, b);

}

if(c > 0)

{

a = Math.Min(a, c);

}

returna;

}

privatedoubleyk(doublea)

{

returnMath.PI * a / 180;

}

privatedoubleCe(doublea, doubleb, doublec, doubled)

{

doubledO = 6370996.81;

//double dO = 6378137.0;

returndO * Math.Acos(Math.Sin(c) * Math.Sin(d) Math.Cos(c) * Math.Cos(d) * Math.Cos(b - a));

}

//對應的JS代碼

functionfD(a, b, c) {

for(; a > c;)

a -= c - b;

for(; a < b;)

a = c - b;

returna;

};

functionjD(a, b, c) {

b != null&& (a = Math.max(a, b));

c != null&& (a = Math.min(a, c));

returna;

};

functionyk(a) {

returnMath.PI * a / 180

};

functionCe(a, b, c, d) {

vardO = 6370996.81;

returndO * Math.acos(Math.sin(c) * Math.sin(d) Math.cos(c) * Math.cos(d) * Math.cos(b - a));

};

functiongetDistance(a, b) {

if(!a || !b)

return0;

a.lng = fD(a.lng, -180, 180);

a.lat = jD(a.lat, -74, 74);

b.lng = fD(b.lng, -180, 180);

b.lat = jD(b.lat, -74, 74);

returnCe(yk(a.lng), yk(b.lng), yk(a.lat), yk(b.lat));

};

alert(getDistance({lng : 106.486654, lat: 29.490295},{lng : 106.581515,lat :29.615467}));

方法三:

/// <summary>

///計算兩點GPS坐标的距離,複雜度較低

/// </summary>

/// <param name="n1">第一點的緯度坐标</param>

/// <param name="e1">第一點的經度坐标</param>

/// <param name="n2">第二點的緯度坐标</param>

/// <param name="e2">第二點的經度坐标</param>

/// <returns></returns>

publicdoubleDistance(doublen1, doublee1, doublen2, doublee2)

{

doublejl_jd = 102834.74258026089786013677476285;

doublejl_wd = 111712.69150641055729984301412873;

doubleb = Math.Abs((e1 - e2) * jl_jd);

doublea = Math.Abs((n1 - n2) * jl_wd);

returnMath.Sqrt((a * a b * b));

}

方法四:

staticdoubleDEF_PI = 3.14159265359; // PI

staticdoubleDEF_2PI = 6.28318530712; // 2*PI

staticdoubleDEF_PI180 = 0.01745329252; // PI/180.0

staticdoubleDEF_R = 6370693.5; // radius of earth

/// <summary>

/// 從兩個gps坐标點(經緯度)獲得兩點的直線距離,适用于計算短程距離

/// </summary>

/// <param name="lon1">第一個點的經度</param>

/// <param name="lat1">第一個點的緯度</param>

/// <param name="lon2">第二個點的經度</param>

/// <param name="lat2">第二個點的緯度</param>

/// <returns>單位是米</returns>

publicdoubleGetShortDistance(doublelon1, doublelat1, doublelon2, doublelat2)

{

doubleew1, ns1, ew2, ns2;

doubledx, dy, dew;

doubledistance;

// 角度轉換為弧度

ew1 = lon1 * DEF_PI180;

ns1 = lat1 * DEF_PI180;

ew2 = lon2 * DEF_PI180;

ns2 = lat2 * DEF_PI180;

// 經度差

dew = ew1 - ew2;

// 若跨東經和西經180 度,進行調整

if(dew > DEF_PI)

dew = DEF_2PI - dew;

elseif(dew < -DEF_PI)

dew = DEF_2PI dew;

dx = DEF_R * Math.Cos(ns1) * dew; // 東西方向長度(在緯度圈上的投影長度)

dy = DEF_R * (ns1 - ns2); // 南北方向長度(在經度圈上的投影長度)

// 勾股定理求斜邊長

distance = Math.Sqrt(dx * dx dy * dy);

returndistance;

}

/// <summary>

/// 從兩個gps坐标點(經緯度)獲得兩點的直線距離,适用于計算長程距離

/// </summary>

/// <param name="lon1">第一個點的經度</param>

/// <param name="lat1">第一個點的緯度</param>

/// <param name="lon2">第二個點的經度</param>

/// <param name="lat2">第二個點的緯度</param>

/// <returns>單位是米</returns>

publicdoubleGetLongDistance(doublelon1, doublelat1, doublelon2, doublelat2)

{

doubleew1, ns1, ew2, ns2;

doubledistance;

// 角度轉換為弧度

ew1 = lon1 * DEF_PI180;

ns1 = lat1 * DEF_PI180;

ew2 = lon2 * DEF_PI180;

ns2 = lat2 * DEF_PI180;

// 求大圓劣弧與球心所夾的角(弧度)

distance = Math.Sin(ns1) * Math.Sin(ns2) Math.Cos(ns1) * Math.Cos(ns2) * Math.Cos(ew1 - ew2);

// 調整到[-1..1]範圍内,避免溢出

if(distance > 1.0)

distance = 1.0;

elseif(distance < -1.0)

distance = -1.0;

// 求大圓劣弧長度

distance = DEF_R * Math.Acos(distance);

returndistance;

}

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved