特别注意:
网上有根据以下公式计算经纬度坐标的方法,实际上是错误的,这个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) { constdoubleEARTH_RADIUS = 6378.137; doubleradLat1 = rad(dLati1); doubleradLat2 = rad(dLati2); doublea = radLat1 – radLat2; doubleb = rad(dLong1) – rad(dLong2); doubles = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000000) / 10000; returns; } publicdoublerad(doubled) { constdoublePI = Math.PI; returnd * PI / 180.0; } |
方法二:
/// <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; } |
本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至89291810@qq.com举报,一经查实,本站将立刻删除。