简单计算两个经纬度距离(根据两个GPS点的经纬度计算实际距离的方法)
简单计算两个经纬度距离(根据两个GPS点的经纬度计算实际距离的方法)/// 从两个gps坐标点(经纬度)获得两点的直线距离,谷歌和高德地图的计算方式/// <summary>地球赤道半径 :6378.140千米航天使用的经过拟合的地球半径为:6378.137千米方法一:
特别注意:
网上有根据以下公式计算经纬度坐标的方法,实际上是错误的,这个d只能在111.12和-111.12之间
以下包含四种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; } |