/// <summary> /// 由空间直角坐标转换为椭球坐标。默认角度单位为度。 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> /// <param name="a"></param> /// <param name="e"></param> /// <returns></returns> public static GeoCoord XyzToGeoCoord(double x, double y, double z, double a, double e, AngleUnit angeUnit = AngleUnit.Degree) { double ee = e * e; double lon = Math.Atan2(y, x); double lat; double height; //iteration double deltaZ = 0; double sqrtXy = Math.Sqrt(x * x + y * y); double tempLat = Math.Atan2(z, sqrtXy);//初始取值 lat = tempLat; //if (Math.Abs(lat) > 80.0 * CoordConverter.DegToRadMultiplier)//lat=+-90,或height特大时,采用此算法更稳定(实际有待实验,保留both代码) //{ int count = 0;//避免死循环 do { var sinLat = Sin(lat); deltaZ = a * ee * sinLat / Math.Sqrt(1 - Math.Pow(e * sinLat, 2)); tempLat = lat; lat = Math.Atan2(z + deltaZ, sqrtXy); count++; } while (Math.Abs(lat - tempLat) > 1E-12 || count < 20); //} //else//经典算法 //{ // do // { // double tanB = Math.Tan(lat); // tempLat = lat; // lat = Math.Atan2(z + a * ee * tanB / Math.Sqrt(1 + tanB * tanB * (1 - ee)), sqrtXy); // } while (Math.Abs(lat - tempLat) > 1E-12); //} double n = a / Math.Sqrt(1 - Math.Pow(e * Sin(tempLat), 2)); //double height = Math.Sqrt(x * x + y * y + Math.Pow((z + deltaZ), 2)) - n; height = sqrtXy / Cos(lat) - n; //地心纬度 //double dixinLat = (1 - ee * n / (n + height)) * Math.Tan(lat); //double dixinLatDeg = dixinLat * CoordConverter.RadToDegdMultiplier; lon = AngularConvert.RadTo(lon, angeUnit); lat = AngularConvert.RadTo(lat, angeUnit); return(new GeoCoord(lon, lat, height)); }
/// <summary> /// 站心坐标系到站心极坐标系。 /// </summary> /// <param name="neu"></param> /// <param name="unit">默认单位为度</param> /// <returns></returns> public static Polar NeuToPolar(NEU neu, AngleUnit unit = AngleUnit.Degree) { double r = neu.Length; double a = Math.Atan2(neu.E, neu.N); if (a < 0)//以北向为基准,顺时针,无负号 { a += 2.0 * CoordConsts.PI; } double o = Math.Asin(neu.U / r); if (unit != AngleUnit.Radian) { a = AngularConvert.RadTo(a, unit); o = AngularConvert.RadTo(o, unit); } return(new Polar(r, a, o) { Unit = unit }); }