Ejemplo n.º 1
0
        /// <summary>
        /// 旋转方位角
        /// </summary>
        /// <param name="val"></param>
        /// <param name="unit"></param>
        /// <returns></returns>
        public PlanePolar RotateAzimuth(double val, AngleUnit unit = AngleUnit.Degree)
        {
            if (this.Unit != unit)
            {
                val = AngularConvert.Convert(val, unit, this.Unit);
            }
            double azimuth = Azimuth + val;

            return(new PlanePolar(Range, azimuth));
        }
Ejemplo n.º 2
0
        /// <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));
        }
Ejemplo n.º 3
0
        /// <summary>
        ///  空间直角坐标系到,站心坐标系的转换。默认B L 单位 度,可以为球坐标和大地坐标
        ///  地心空间直角坐标系(XYZ)转换为地方左手笛卡尔直角坐标系(NEU,XYZ)
        /// </summary>
        /// <param name="vector1">测站到卫星的向径</param>
        /// <param name="lat">站点所在纬度</param>
        /// <param name="lon">站点所在经度</param>
        /// <param name="angleUnit">站点所在经度的单位</param>
        /// <returns></returns>
        public static NEU XyzToNeu(XYZ vector1, double lat, double lon, AngleUnit angleUnit = AngleUnit.Degree)
        {
            if (angleUnit != AngleUnit.Radian) //当前经度为 0 的时候,U 的转换会出现符号错误???!!!2017.10.12.
            {
                lat = AngularConvert.ToRad(lat, angleUnit);
                lon = AngularConvert.ToRad(lon, angleUnit);
            }

            XYZ v = vector1;

            double n = -v.X * Sin(lat) * Cos(lon) - v.Y * Sin(lat) * Sin(lon) + v.Z * Cos(lat);
            double e = -v.X * Sin(lon) + v.Y * Cos(lon);
            double u = v.X * Cos(lat) * Cos(lon) + v.Y * Cos(lat) * Sin(lon) + v.Z * Sin(lat);

            return(new NEU(n, e, u));// { N = n, E = e, U = u };
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 椭球坐标转为空间直角坐标。默认单位为度。
        /// </summary>
        /// <param name="lon">经度(度)</param>
        /// <param name="lat">纬度(度)</param>
        /// <param name="height">大地高</param>
        /// <param name="a">椭球半径</param>
        /// <param name="flatOrInverse">扁率或其倒数</param>
        /// <param name="unit">单位</param>
        /// <returns></returns>
        public static XYZ GeoCoordToXyz(double lon, double lat, double height, double a, double flatOrInverse, AngleUnit unit = AngleUnit.Degree)
        {
            lon = AngularConvert.ToRad(lon, unit);
            lat = AngularConvert.ToRad(lat, unit);

            //扁率判断
            double e = flatOrInverse;

            if (flatOrInverse > 1)
            {
                e = 1.0 / e;
            }

            double n = a / Math.Sqrt(1 - Math.Pow(e * Sin(lat), 2));

            double x = (n + height) * Cos(lat) * Cos(lon);
            double y = (n + height) * Cos(lat) * Sin(lon);
            double z = (n * (1 - e * e) + height) * Sin(lat);

            return(new XYZ(x, y, z));
        }
Ejemplo n.º 5
0
        /// <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
            });
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dval"></param>
        /// <param name="degreeFormat"></param>
        public DMS(double dval, AngleUnit degreeFormat)
        {
            switch (degreeFormat)
            {
            case AngleUnit.Radian:
                InitDegree(AngularConvert.RadToDeg(dval));
                break;

            case AngleUnit.Degree:
                InitDegree(dval);
                break;

            case AngleUnit.DMS_S:
            {
                this.IsPlus = dval > 0;
                double d         = Math.Abs(dval);
                var    str       = d.ToString("0.00000000000");
                var    indexOfPt = str.IndexOf(".");

                if (indexOfPt > 4)
                {
                    var degr = str.Substring(0, indexOfPt - 4);
                    this.Degree = int.Parse(degr);
                }
                if (indexOfPt > 2)
                {
                    var minStr = str.Substring(indexOfPt - 4, 2);
                    this.Minute = int.Parse(minStr);
                }
                var secStr = str.Substring(indexOfPt - 2);
                this.Second = Double.Parse(secStr);
            }
            break;

            case AngleUnit.D_MS:    //120.30300
            {
                this.IsPlus = dval > 0;
                double d         = Math.Abs(dval);
                var    str       = d.ToString("0.00000000000");
                var    indexOfPt = str.IndexOf(".");
                var    degr      = str.Substring(0, indexOfPt);
                this.Degree = int.Parse(degr);
                this.Minute = int.Parse(str.Substring(indexOfPt + 1, 2));
                var secStr = str.Substring(indexOfPt + 3, 2) + "." + str.Substring(indexOfPt + 5);
                this.Second = Double.Parse(secStr);
            }
            break;

            case AngleUnit.HMS_S:
            {
                this.IsPlus = dval > 0;
                double d         = Math.Abs(dval);
                var    str       = d.ToString("0.00000000000");
                var    indexOfPt = str.IndexOf(".");

                if (indexOfPt > 4)
                {
                    var degr = str.Substring(0, indexOfPt - 4);
                    this.Degree = int.Parse(degr) * 15;
                }
                if (indexOfPt > 2)
                {
                    var minStr = str.Substring(indexOfPt - 4, 2);
                    this.Minute = int.Parse(minStr);
                }
                var secStr = str.Substring(indexOfPt - 2);
                this.Second = Double.Parse(secStr);
            }
                //this.IsPlus = dval > 0;
                //double deg0 = Math.Abs(dval);
                //var hour = (int)(deg0 / 10000);
                //var minute = (int)((deg0) / 100.0) - Degree * 100;
                //var second = deg0 % 100;
                //var hours = hour + minute / 60.0 + second / 3600.0;

                //var degs = hours * 15.0;
                //InitDegree(degs);
                break;

            default:
                throw new ArgumentException("暂不支持这种类型 " + degreeFormat);
            }
        }