/// <summary>
        /// Coordinate build logic goes here.
        /// </summary>
        /// <param name="lat">Signed latitude</param>
        /// <param name="longi">Signed longitude</param>
        /// <param name="date">Date at location</param>
        /// <param name="eagerLoad">Eagerloading settings</param>
        private void Coordinate_Builder(double lat, double longi, DateTime date, EagerLoad eagerLoad)
        {
            //SET EagerLoading Setting
            EagerLoadSettings = eagerLoad;

            FormatOptions = new CoordinateFormatOptions();

            //Use default constructor if signed degree is 0 for performance.
            if (lat == 0)
            {
                latitude = new CoordinatePart(CoordinateType.Lat);
            }
            else
            {
                latitude = new CoordinatePart(lat, CoordinateType.Lat);
            }

            if (longi == 0)
            {
                longitude = new CoordinatePart(CoordinateType.Long);
            }
            else
            {
                longitude = new CoordinatePart(longi, CoordinateType.Long);
            }

            //Set CoordinatePart parents
            latitude.parent  = this;
            longitude.parent = this;

            //Set UTC date at location
            geoDate = date;


            //LOAD NEW COORDINATE SYSTEMS HERE

            //Load Celestial
            if (eagerLoad.Celestial)
            {
                celestialInfo = new Celestial(lat, longi, date, 0, eagerLoad);
            }
            //Load UTM MGRS
            if (eagerLoad.UTM_MGRS)
            {
                utm  = new UniversalTransverseMercator(lat, longi, this);
                mgrs = new MilitaryGridReferenceSystem(utm);
            }
            //Load CARTESIAN
            if (eagerLoad.Cartesian)
            {
                cartesian = new Cartesian(this);
            }
            //Load ECEF
            if (eagerLoad.ECEF)
            {
                ecef = new ECEF(this);
            }



            //Set Ellipsoid
            equatorial_radius  = 6378137.0;
            inverse_flattening = 298.257223563;
        }
예제 #2
0
 /// <summary>
 /// Load UTM and MGRS information (required if eager loading is turned off).
 /// </summary>
 /// <example>
 /// The following example shows how to Load UTM and MGRS information when eager loading is turned off.
 /// <code>
 /// EagerLoad eagerLoad = new EagerLoad();
 /// eagerLoad.UTM_MGRS = false;
 /// Coordinate c = new Coordinate(40.0352, -74.5844, DateTime.Now, eagerLoad);
 ///
 /// //To load UTM_MGRS information when ready
 /// c.LoadUTM_MGRSInfo;
 /// </code>
 /// </example>
 public void LoadUTM_MGRS_Info()
 {
     utm  = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this);
     mgrs = new MilitaryGridReferenceSystem(utm);
 }
        /// <summary>
        /// Notify property changed
        /// </summary>
        /// <param name="propName">Property Name</param>
        public void NotifyPropertyChanged(string propName)
        {
            switch (propName)
            {
            case "CelestialInfo":
                if (!EagerLoadSettings.Celestial)
                {
                    return;
                }                                                 //Prevent calls while eagerloading is off
                if (EagerLoadSettings.Celestial && celestialInfo == null)
                {
                    celestialInfo = new Celestial(false);
                }                                                                                                      //Create object if EagerLoading is on and object is null (EagerLoading turned on later).
                celestialInfo.CalculateCelestialTime(latitude.DecimalDegree, longitude.DecimalDegree, geoDate, EagerLoadSettings, offset);
                break;

            case "UTM":
                if (!EagerLoadSettings.UTM_MGRS)
                {
                    return;
                }
                else if (EagerLoadSettings.UTM_MGRS && utm == null)
                {
                    utm = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this, equatorial_radius, inverse_flattening);
                }
                else
                {
                    utm.ToUTM(latitude.ToDouble(), longitude.ToDouble(), utm);
                }
                break;

            case "utm":
                //Adjust case and notify of change.
                //Use to notify without calling ToUTM()
                propName = "UTM";
                break;

            case "MGRS":
                if (!EagerLoadSettings.UTM_MGRS || !EagerLoadSettings.Extensions.MGRS || utm == null)
                {
                    return;
                }
                else if (EagerLoadSettings.UTM_MGRS && EagerLoadSettings.Extensions.MGRS && mgrs == null)
                {
                    mgrs = new MilitaryGridReferenceSystem(utm);
                }
                else
                {
                    MGRS.ToMGRS(utm);
                }
                break;

            case "Cartesian":
                if (!EagerLoadSettings.Cartesian)
                {
                    return;
                }
                else if (EagerLoadSettings.Cartesian && cartesian == null)
                {
                    cartesian = new Cartesian(this);
                }
                else
                {
                    Cartesian.ToCartesian(this);
                }
                break;

            case "ECEF":
                if (!EagerLoadSettings.ECEF)
                {
                    return;
                }
                else if (EagerLoadSettings.ECEF && ecef == null)
                {
                    ecef = new ECEF(this);
                }
                else
                {
                    ECEF.ToECEF(this);
                }
                break;

            default:
                break;
            }
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        }
예제 #4
0
        //Add main to Coordinate and tunnel to Format class. Add private methods to format.
        //WHEN PARSING NO EXCPETIONS FOR OUT OF RANGE ARGS WILL BE THROWN
        public static bool TryParse(string coordString, out Coordinate c)
        {
            //Turn of eagerload for efficiency
            EagerLoad eg = new EagerLoad();

            eg.Cartesian = false;
            eg.Celestial = false;
            eg.UTM_MGRS  = false;

            c = new Coordinate(eg);
            string s = coordString;

            s = s.Trim(); //Trim all spaces before and after string
            double[] d;
            //Try Signed Degree
            if (TrySignedDegree(s, out d))
            {
                try
                {
                    c = new Coordinate(d[0], d[1], eg);
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }
            //Try Decimal Degree
            if (TryDecimalDegree(s, out d))
            {
                try
                {
                    c = new Coordinate(d[0], d[1], eg);
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }
            //Try DDM
            if (TryDegreeDecimalMinute(s, out d))
            {
                try
                {
                    //0 Lat Degree
                    //1 Lat Minute
                    //2 Lat Direction (0 = N, 1 = S)
                    //3 Long Degree
                    //4 Long Minute
                    //5 Long Direction (0 = E, 1 = W)
                    CoordinatesPosition latP = CoordinatesPosition.N;
                    CoordinatesPosition lngP = CoordinatesPosition.E;
                    if (d[2] != 0)
                    {
                        latP = CoordinatesPosition.S;
                    }
                    if (d[5] != 0)
                    {
                        lngP = CoordinatesPosition.W;
                    }
                    CoordinatePart lat = new CoordinatePart((int)d[0], d[1], latP, c);
                    CoordinatePart lng = new CoordinatePart((int)d[3], d[4], lngP, c);
                    c           = new Coordinate(eg);
                    c.Latitude  = lat;
                    c.Longitude = lng;
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }
            //Try DMS
            if (TryDegreeMinuteSecond(s, out d))
            {
                try
                {
                    //0 Lat Degree
                    //1 Lat Minute
                    //2 Lat Second
                    //3 Lat Direction (0 = N, 1 = S)
                    //4 Long Degree
                    //5 Long Minute
                    //6 Long Second
                    //7 Long Direction (0 = E, 1 = W)
                    CoordinatesPosition latP = CoordinatesPosition.N;
                    CoordinatesPosition lngP = CoordinatesPosition.E;
                    if (d[3] != 0)
                    {
                        latP = CoordinatesPosition.S;
                    }
                    if (d[7] != 0)
                    {
                        lngP = CoordinatesPosition.W;
                    }

                    CoordinatePart lat = new CoordinatePart((int)d[0], (int)d[1], d[2], latP, c);
                    CoordinatePart lng = new CoordinatePart((int)d[4], (int)d[5], d[6], lngP, c);
                    c           = new Coordinate(eg);
                    c.Latitude  = lat;
                    c.Longitude = lng;
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }

            string[] um;
            //Try MGRS
            if (TryMGRS(s, out um))
            {
                try
                {
                    double zone     = Convert.ToDouble(um[0]);
                    double easting  = Convert.ToDouble(um[3]);
                    double northing = Convert.ToDouble(um[4]);
                    MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem(um[1], (int)zone, um[2], easting, northing);
                    c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs);
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }
            //Try UTM
            if (TryUTM(s, out um))
            {
                try
                {
                    double zone     = Convert.ToDouble(um[0]);
                    double easting  = Convert.ToDouble(um[2]);
                    double northing = Convert.ToDouble(um[3]);
                    UniversalTransverseMercator utm = new UniversalTransverseMercator(um[1], (int)zone, easting, northing);
                    c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }
            if (TryCartesian(s, out d))
            {
                try
                {
                    Cartesian cart = new Cartesian(d[0], d[1], d[2]);
                    c = Cartesian.CartesianToLatLong(cart);
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }
            //Try Cartesian
            return(false);
        }
예제 #5
0
        /// <summary>
        /// Assigns UTM values based of Lat/Long
        /// </summary>
        /// <param name="lat">DD Latitude</param>
        /// <param name="longi">DD longitude</param>
        /// <param name="utm">UTM Object to modify</param>
        internal void ToUTM(double lat, double longi, UniversalTransverseMercator utm)
        {
            string letter   = "";
            double easting  = 0;
            double northing = 0;
            int    zone     = (int)Math.Floor(longi / 6 + 31);

            if (lat < -72)
            {
                letter = "C";
            }
            else if (lat < -64)
            {
                letter = "D";
            }
            else if (lat < -56)
            {
                letter = "E";
            }
            else if (lat < -48)
            {
                letter = "F";
            }
            else if (lat < -40)
            {
                letter = "G";
            }
            else if (lat < -32)
            {
                letter = "H";
            }
            else if (lat < -24)
            {
                letter = "J";
            }
            else if (lat < -16)
            {
                letter = "K";
            }
            else if (lat < -8)
            {
                letter = "L";
            }
            else if (lat < 0)
            {
                letter = "M";
            }
            else if (lat < 8)
            {
                letter = "N";
            }
            else if (lat < 16)
            {
                letter = "P";
            }
            else if (lat < 24)
            {
                letter = "Q";
            }
            else if (lat < 32)
            {
                letter = "R";
            }
            else if (lat < 40)
            {
                letter = "S";
            }
            else if (lat < 48)
            {
                letter = "T";
            }
            else if (lat < 56)
            {
                letter = "U";
            }
            else if (lat < 64)
            {
                letter = "V";
            }
            else if (lat < 72)
            {
                letter = "W";
            }
            else
            {
                letter = "X";
            }

            double a = utm.equatorial_radius;
            double f = 1.0 / utm.inverse_flattening;
            double b = a * (1 - f);   // polar radius

            double e  = Math.Sqrt(1 - Math.Pow(b, 2) / Math.Pow(a, 2));
            double e0 = e / Math.Sqrt(1 - Math.Pow(e, 1));

            double drad = Math.PI / 180;
            double k0   = 0.9996;

            double phi  = lat * drad;                             // convert latitude to radians
            double lng  = longi * drad;                           // convert longitude to radians
            double utmz = 1 + Math.Floor((longi + 180) / 6.0);    // longitude to utm zone
            double zcm  = 3 + 6.0 * (utmz - 1) - 180;             // central meridian of a zone
            // this gives us zone A-B for below 80S
            double esq  = (1 - (b / a) * (b / a));
            double e0sq = e * e / (1 - Math.Pow(e, 2));
            double M    = 0;

            double N = a / Math.Sqrt(1 - Math.Pow(e * Math.Sin(phi), 2));
            double T = Math.Pow(Math.Tan(phi), 2);
            double C = e0sq * Math.Pow(Math.Cos(phi), 2);
            double A = (longi - zcm) * drad * Math.Cos(phi);

            // calculate M (USGS style)
            M = phi * (1 - esq * (1.0 / 4.0 + esq * (3.0 / 64.0 + 5.0 * esq / 256.0)));
            M = M - Math.Sin(2.0 * phi) * (esq * (3.0 / 8.0 + esq * (3.0 / 32.0 + 45.0 * esq / 1024.0)));
            M = M + Math.Sin(4.0 * phi) * (esq * esq * (15.0 / 256.0 + esq * 45.0 / 1024.0));
            M = M - Math.Sin(6.0 * phi) * (esq * esq * esq * (35.0 / 3072.0));
            M = M * a;     //Arc length along standard meridian

            double M0 = 0; // if another point of origin is used than the equator

            // Calculate the UTM values...
            // first the easting
            var x = k0 * N * A * (1 + A * A * ((1 - T + C) / 6 + A * A * (5 - 18 * T + T * T + 72.0 * C - 58 * e0sq) / 120.0)); //Easting relative to CM

            x = x + 500000;                                                                                                     // standard easting

            // Northing

            double y  = k0 * (M - M0 + N * Math.Tan(phi) * (A * A * (1 / 2.0 + A * A * ((5 - T + 9 * C + 4 * C * C) / 24.0 + A * A * (61 - 58 * T + T * T + 600 * C - 330 * e0sq) / 720.0)))); // first from the equator
            double yg = y + 10000000;                                                                                                                                                          //yg = y global, from S. Pole

            if (y < 0)
            {
                y = 10000000 + y;   // add in false northing if south of the equator
            }


            easting  = x;
            northing = y;

            utm.latZone  = letter;
            utm.longZone = zone;
            utm.easting  = easting;
            utm.northing = northing;

            if (lat <= -80 || lat >= 84)
            {
                withinCoordinateSystemBounds = false;
            }
            else
            {
                withinCoordinateSystemBounds = true;
            }
        }
예제 #6
0
 internal MilitaryGridReferenceSystem(UniversalTransverseMercator utm)
 {
     ToMGRS(utm);
 }
예제 #7
0
        /// <summary>
        /// Creates a Coordinate object from an MGRS/NATO UTM Coordinate
        /// </summary>
        /// <param name="mgrs">MilitaryGridReferenceSystem</param>
        /// <returns>Coordinate object</returns>
        public static Coordinate MGRStoLatLong(MilitaryGridReferenceSystem mgrs)
        {
            string latz    = mgrs.LatZone;
            string digraph = mgrs.Digraph;

            char eltr = digraph[0];
            char nltr = digraph[1];

            string digraphLettersE   = "ABCDEFGHJKLMNPQRSTUVWXYZ";
            string digraphLettersN   = "ABCDEFGHJKLMNPQRSTUV";
            string digraphLettersAll = "";

            for (int lt = 1; lt < 25; lt++)
            {
                digraphLettersAll += "ABCDEFGHJKLMNPQRSTUV";
            }

            var eidx = digraphLettersE.IndexOf(eltr);
            var nidx = digraphLettersN.IndexOf(nltr);

            if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0))
            {
                nidx -= 5;  // correction for even numbered zones
            }

            var ebase = 100000 * (1 + eidx - 8 * Math.Floor(Convert.ToDouble(eidx) / 8));

            var latBand     = digraphLettersE.IndexOf(latz);
            var latBandLow  = 8 * latBand - 96;
            var latBandHigh = 8 * latBand - 88;

            if (latBand < 2)
            {
                latBandLow  = -90;
                latBandHigh = -80;
            }
            else if (latBand == 21)
            {
                latBandLow  = 72;
                latBandHigh = 84;
            }
            else if (latBand > 21)
            {
                latBandLow  = 84;
                latBandHigh = 90;
            }

            var    lowLetter      = Math.Floor(100 + 1.11 * latBandLow);
            var    highLetter     = Math.Round(100 + 1.11 * latBandHigh);
            string latBandLetters = null;
            int    l = Convert.ToInt32(lowLetter);
            int    h = Convert.ToInt32(highLetter);

            if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0))
            {
                latBandLetters = digraphLettersAll.Substring(l + 5, h + 5).ToString();
            }
            else
            {
                latBandLetters = digraphLettersAll.Substring(l, h).ToString();
            }
            var nbase = 100000 * (lowLetter + latBandLetters.IndexOf(nltr));

            var x = ebase + mgrs.Easting;
            var y = nbase + mgrs.Northing;

            if (y > 10000000)
            {
                y = y - 10000000;
            }
            if (nbase >= 10000000)
            {
                y = nbase + mgrs.northing - 10000000;
            }

            var southern = nbase < 10000000;

            UniversalTransverseMercator utm = new UniversalTransverseMercator(mgrs.LatZone, mgrs.LongZone, x, y);

            utm.equatorial_radius  = mgrs.equatorialRadius;
            utm.inverse_flattening = mgrs.inverseFlattening;
            Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);

            c.Set_Datum(mgrs.equatorialRadius, mgrs.inverseFlattening);
            // Coordinate nc = new Coordinate(c.Latitude.ToDouble(), c.Longitude.ToDouble());

            return(c);
        }
예제 #8
0
        private static Coordinate MGRS_Polar_ToLatLong(MilitaryGridReferenceSystem mgrs, EagerLoad el)
        {
            //WORKING
            bool isNorth = true;

            if (mgrs.latZone.ToUpper() == "A" || mgrs.latZone.ToUpper() == "B")
            {
                isNorth = false;
            }

            string latz    = mgrs.LatZone;
            string digraph = mgrs.Digraph;

            char eltr = digraph[0];
            char nltr = digraph[1];


            string digraphLettersE;

            if (!isNorth)
            {
                digraphLettersE = "KLPQRSTUXYZABCFGH";
            }
            else
            {
                digraphLettersE = "RSTUXYZABCFGHJ";
            }

            string digraphLettersN;

            if (!isNorth)
            {
                digraphLettersN = "VWXYBCDEFGHJKLMNPQRSTUVWXYZ";
            }
            else
            {
                digraphLettersN = "ABCDEFGHJKLMNP";
            }


            string digraphLettersAll = "";

            for (int lt = 1; lt < 31; lt++)
            {
                digraphLettersAll += digraphLettersN;
            }

            var eidx = digraphLettersE.IndexOf(eltr);

            //Offsets are set due to less Easting Identifiers.
            //North has 4 less than S
            double offset = 9;

            if (isNorth)
            {
                offset = 13;
            }

            if (mgrs.latZone == "B" && eidx < offset && mgrs.easting != 0)
            {
                eidx += 18;
            }


            double subbase = eidx + offset;

            var ebase       = 100000 * subbase;
            var latBand     = digraphLettersE.IndexOf(latz);
            var latBandLow  = 8 * latBand - 96;
            var latBandHigh = 8 * latBand - 88;

            if (!isNorth)
            {
                latBandLow  = -90;
                latBandHigh = -80;
            }
            else
            {
                latBandLow  = 84;
                latBandHigh = 90;
            }

            var lowLetter  = Math.Floor(100 + 1.11 * latBandLow);
            var highLetter = Math.Round(100 + 1.11 * latBandHigh);

            string latBandLetters = null;
            int    l = Convert.ToInt32(lowLetter);
            int    h = Convert.ToInt32(highLetter + 7);

            if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0))
            {
                latBandLetters = digraphLettersAll.Substring(l + 5, h + 5).ToString();
            }
            else
            {
                latBandLetters = digraphLettersAll.Substring(l, h).ToString();
            }

            //North offset + 4 due to lower band count.
            double nOffset = 13;

            if (!isNorth)
            {
                nOffset = 10;
            }
            else
            {
                latBandLetters = digraphLettersN;
            }
            int index = latBandLetters.IndexOf(nltr);

            if (index == -1 && nltr == 'A')
            {
                index -= 1;
            }                                            //ALPHA PATCH

            //int subset = 0;
            //if ((latz == "Y" || latz == "Z") && (nOffset+index)>25 && (ebase> 2100000 || ebase<2000000) && ebase!= 2000000) { subset = -14; }
            var nbase = 100000 * (index + nOffset);

            var x = ebase + mgrs.Easting;
            var y = nbase + mgrs.Northing;

            if (mgrs.systemType != MGRS_Type.MGRS_Polar)
            {
                if (y > 10000000)
                {
                    y = y - 10000000;
                }
                if (nbase >= 10000000)
                {
                    y = nbase + mgrs.northing - 10000000;
                }
            }

            // Debug.WriteLine("MGRS {0} {1}", x, y);
            UniversalTransverseMercator utm = new UniversalTransverseMercator(mgrs.LatZone, mgrs.LongZone, x, y, true);

            utm.equatorial_radius  = mgrs.equatorialRadius;
            utm.inverse_flattening = mgrs.inverseFlattening;
            Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm, el);

            c.Set_Datum(mgrs.equatorialRadius, mgrs.inverseFlattening);

            return(c);
        }
예제 #9
0
        /// <summary>
        /// Assigns UTM values based of Lat/Long
        /// </summary>
        /// <param name="lat">DD Latitude</param>
        /// <param name="longi">DD longitude</param>
        /// <param name="utm">UTM Object to modify</param>
        internal void ToUTM(double lat, double longi, UniversalTransverseMercator utm)
        {
            string letter   = "";
            double easting  = 0;
            double northing = 0;
            int    zone     = (int)Math.Floor(longi / 6 + 31);

            if (lat < -72)
            {
                letter = "C";
            }
            else if (lat < -64)
            {
                letter = "D";
            }
            else if (lat < -56)
            {
                letter = "E";
            }
            else if (lat < -48)
            {
                letter = "F";
            }
            else if (lat < -40)
            {
                letter = "G";
            }
            else if (lat < -32)
            {
                letter = "H";
            }
            else if (lat < -24)
            {
                letter = "J";
            }
            else if (lat < -16)
            {
                letter = "K";
            }
            else if (lat < -8)
            {
                letter = "L";
            }
            else if (lat < 0)
            {
                letter = "M";
            }
            else if (lat < 8)
            {
                letter = "N";
            }
            else if (lat < 16)
            {
                letter = "P";
            }
            else if (lat < 24)
            {
                letter = "Q";
            }
            else if (lat < 32)
            {
                letter = "R";
            }
            else if (lat < 40)
            {
                letter = "S";
            }
            else if (lat < 48)
            {
                letter = "T";
            }
            else if (lat < 56)
            {
                letter = "U";
            }
            else if (lat < 64)
            {
                letter = "V";
            }
            else if (lat < 72)
            {
                letter = "W";
            }
            else
            {
                letter = "X";
            }
            easting = 0.5 * Math.Log((1 + Math.Cos(lat * Math.PI / 180) * Math.Sin(longi * Math.PI / 180 - (6 * zone - 183) * Math.PI / 180)) / (1 - Math.Cos(lat *
                                                                                                                                                              Math.PI / 180) * Math.Sin(longi * Math.PI / 180 - (6 * zone - 183) * Math.PI / 180))) * 0.9996 * 6399593.62 / Math.Pow((1 + Math.Pow(0.0820944379,
                                                                                                                                                                                                                                                                                                   2) * Math.Pow(Math.Cos(lat * Math.PI / 180), 2)), 0.5) * (1 + Math.Pow(0.0820944379, 2) / 2 * Math.Pow((0.5 * Math.Log((1 + Math.Cos(lat * Math.PI /
                                                                                                                                                                                                                                                                                                                                                                                                                                        180) * Math.Sin(longi * Math.PI / 180 - (6 * zone - 183) * Math.PI / 180)) / (1 - Math.Cos(lat * Math.PI / 180) * Math.Sin(longi * Math.PI / 180 -
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   (6 * zone - 183) * Math.PI / 180)))), 2) * Math.Pow(Math.Cos(lat * Math.PI / 180), 2) / 3) + 500000;
            easting  = Math.Round(easting * 100) * 0.01;
            northing = (Math.Atan(Math.Tan(lat * Math.PI / 180) / Math.Cos((longi * Math.PI / 180 - (6 * zone - 183) * Math.PI / 180))) - lat * Math.PI / 180) *
                       0.9996 * 6399593.625 / Math.Sqrt(1 + 0.006739496742 * Math.Pow(Math.Cos(lat * Math.PI / 180), 2)) * (1 + 0.006739496742 / 2 * Math.Pow(0.5 *
                                                                                                                                                              Math.Log((1 + Math.Cos(lat * Math.PI / 180) * Math.Sin((longi * Math.PI / 180 - (6 * zone - 183) * Math.PI / 180))) / (1 - Math.Cos(lat * Math.PI /
                                                                                                                                                                                                                                                                                                  180) * Math.Sin((longi * Math.PI / 180 - (6 * zone - 183) * Math.PI / 180)))), 2) * Math.Pow(Math.Cos(lat * Math.PI / 180), 2)) + 0.9996 *
                       6399593.625 * (lat * Math.PI / 180 - 0.005054622556 * (lat * Math.PI / 180 + Math.Sin(2 * lat * Math.PI / 180) / 2) + 4.258201531e-05 * (3 * (lat *
                                                                                                                                                                     Math.PI / 180 + Math.Sin(2 * lat * Math.PI / 180) / 2) + Math.Sin(2 * lat * Math.PI / 180) * Math.Pow(Math.Cos(lat * Math.PI / 180), 2)) / 4 -
                                      1.674057895e-07 * (5 * (3 * (lat * Math.PI / 180 + Math.Sin(2 * lat * Math.PI / 180) / 2) + Math.Sin(2 * lat * Math.PI / 180) *
                                                              Math.Pow(Math.Cos(lat * Math.PI / 180), 2)) / 4 + Math.Sin(2 * lat * Math.PI / 180) * Math.Pow(Math.Cos(lat * Math.PI / 180), 2) *
                                                         Math.Pow(Math.Cos(lat * Math.PI / 180), 2)) / 3);
            if ((new[] { "C", "D", "E", "F", "G", "H", "J", "K", "L", "M" }).Contains(letter))
            {
                northing = northing + 10000000;
            }

            northing     = Math.Round(northing * 100) * 0.01;
            utm.latZone  = letter;
            utm.longZone = zone;
            utm.easting  = easting;
            utm.northing = northing;
        }
예제 #10
0
 /// <summary>
 /// Converts UTM coordinate to Lat/Long
 /// </summary>
 /// <param name="utm">utm</param>
 /// <returns>Coordinate</returns>
 /// <example>
 /// The following example creates (converts to) a geodetic Coordinate object based on a UTM object.
 /// <code>
 /// UniversalTransverseMercator utm = new UniversalTransverseMercator("T", 32, 233434, 234234);
 /// Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
 /// Console.WriteLine(c); //N 2º 7' 2.332" E 6º 36' 12.653"
 /// </code>
 /// </example>
 public static Coordinate ConvertUTMtoLatLong(UniversalTransverseMercator utm)
 {
     return(ConvertUTMtoLatLong(utm, GlobalSettings.Default_EagerLoad));
 }
예제 #11
0
        /// <summary>
        /// Creates a Coordinate object from an MGRS/NATO UTM Coordinate
        /// </summary>
        /// <param name="mgrs">MilitaryGridReferenceSystem</param>
        /// <param name="eagerLoad">EagerLoad</param>
        /// <returns>Coordinate object</returns>
        /// <example>
        /// The following example creates (converts to) a geodetic Coordinate object based on a MGRS object.
        /// <code>
        /// MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem("N", 21, "SA", 66037, 61982);
        /// Coordinate c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs, new EagerLoad(false));
        /// Console.WriteLine(c); //N 0º 33' 35.988" W 60º 0' 0.01"
        /// </code>
        /// </example>
        public static Coordinate MGRStoLatLong(MilitaryGridReferenceSystem mgrs, EagerLoad eagerLoad)
        {
            if (mgrs.systemType == MGRS_Type.MGRS_Polar)
            {
                return(MGRS_Polar_ToLatLong(mgrs, eagerLoad));
            }

            string latz    = mgrs.LatZone;
            string digraph = mgrs.Digraph;

            char eltr = digraph[0];
            char nltr = digraph[1];

            string digraphLettersE = "ABCDEFGHJKLMNPQRSTUVWXYZ";
            string digraphLettersN = "ABCDEFGHJKLMNPQRSTUV";

            string digraphLettersAll = "";

            for (int lt = 1; lt < 25; lt++)
            {
                digraphLettersAll += digraphLettersN;
            }

            var eidx = digraphLettersE.IndexOf(eltr);

            var pbase = 100000;

            double fl = Math.Floor(Convert.ToDouble(eidx) / 8);

            double subbase = 1 + eidx - 8 * fl;

            var ebase       = pbase * subbase;
            var latBand     = digraphLettersE.IndexOf(latz);
            var latBandLow  = 8 * latBand - 96;
            var latBandHigh = 8 * latBand - 88;

            if (latBand < 2)
            {
                latBandLow  = -90;
                latBandHigh = -80;
            }
            else if (latBand == 21)
            {
                latBandLow  = 72;
                latBandHigh = 84;
            }
            else if (latBand > 21)
            {
                latBandLow  = 84;
                latBandHigh = 90;
            }


            var lowLetter  = Math.Floor(100 + 1.11 * latBandLow);
            var highLetter = Math.Round(100 + 1.11 * latBandHigh);

            string latBandLetters = null;
            int    l = Convert.ToInt32(lowLetter);
            int    h = Convert.ToInt32(highLetter);

            if (mgrs.LongZone / 2.0 == Math.Floor(mgrs.LongZone / 2.0))
            {
                latBandLetters = digraphLettersAll.Substring(l + 5, h + 5).ToString();
            }
            else
            {
                latBandLetters = digraphLettersAll.Substring(l, h).ToString();
            }



            var nbase = 100000 * (lowLetter + latBandLetters.IndexOf(nltr));

            //latBandLetters.IndexOf(nltr) value causing incorrect Northing below -80
            var x = ebase + mgrs.Easting;
            var y = nbase + mgrs.Northing;

            if (mgrs.systemType != MGRS_Type.MGRS_Polar)
            {
                if (y > 10000000)
                {
                    y = y - 10000000;
                }
                if (nbase >= 10000000)
                {
                    y = nbase + mgrs.northing - 10000000;
                }
            }

            UniversalTransverseMercator utm = new UniversalTransverseMercator(mgrs.LatZone, mgrs.LongZone, x, y, true);

            utm.equatorial_radius  = mgrs.equatorialRadius;
            utm.inverse_flattening = mgrs.inverseFlattening;
            Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm, eagerLoad);

            c.Set_Datum(mgrs.equatorialRadius, mgrs.inverseFlattening);

            return(c);
        }
예제 #12
0
        /// <summary>
        /// Assigns UTM values based of Lat/Long
        /// </summary>
        /// <param name="lat">DD Latitude</param>
        /// <param name="longi">DD longitude</param>
        /// <param name="utm">UTM Object to modify</param>
        /// <param name="szone">specified zone (for under/over projection</param>
        internal void ToUTM(double lat, double longi, UniversalTransverseMercator utm, int?szone = null)
        {
            //Switch to UPS
            if (lat < -80 || lat > 84)
            {
                UPS ups = new UPS();
                ups.Geodetic_To_UPS(lat, longi, utm);
                systemType = UTM_Type.UPS;
                return;
            }
            else
            {
                systemType = UTM_Type.UTM;
            }

            //Within UTM BOUNDS
            string letter;

            int zone;

            if (szone == null)
            {
                zone = (int)Math.Floor(longi / 6 + 31);
            }
            else
            {
                zone = szone.Value;
            }
            if (lat < -72)
            {
                letter = "C";
            }
            else if (lat < -64)
            {
                letter = "D";
            }
            else if (lat < -56)
            {
                letter = "E";
            }
            else if (lat < -48)
            {
                letter = "F";
            }
            else if (lat < -40)
            {
                letter = "G";
            }
            else if (lat < -32)
            {
                letter = "H";
            }
            else if (lat < -24)
            {
                letter = "J";
            }
            else if (lat < -16)
            {
                letter = "K";
            }
            else if (lat < -8)
            {
                letter = "L";
            }
            else if (lat < 0)
            {
                letter = "M";
            }
            else if (lat < 8)
            {
                letter = "N";
            }
            else if (lat < 16)
            {
                letter = "P";
            }
            else if (lat < 24)
            {
                letter = "Q";
            }
            else if (lat < 32)
            {
                letter = "R";
            }
            else if (lat < 40)
            {
                letter = "S";
            }
            else if (lat < 48)
            {
                letter = "T";
            }
            else if (lat < 56)
            {
                letter = "U";
            }
            else if (lat < 64)
            {
                letter = "V";
            }
            else if (lat < 72)
            {
                letter = "W";
            }
            else
            {
                letter = "X";
            }

            double a = utm.equatorial_radius;
            double f = 1.0 / utm.inverse_flattening;
            double b = a * (1 - f);   // polar radius

            double e = Math.Sqrt(1 - Math.Pow(b, 2) / Math.Pow(a, 2));
            // double e0 = e / Math.Sqrt(1 - Math.Pow(e, 1));

            double drad = Math.PI / 180;
            double k0   = 0.9996;

            double phi = lat * drad;                              // convert latitude to radians

            double utmz;

            if (szone == null)
            {
                utmz = 1 + Math.Floor((longi + 180) / 6.0);
            }
            else
            {
                utmz = szone.Value;
            }
            // longitude to utm zone
            double zcm = 3 + 6.0 * (utmz - 1) - 180;                     // central meridian of a zone
            // this gives us zone A-B for below 80S
            double esq  = (1 - (b / a) * (b / a));
            double e0sq = e * e / (1 - Math.Pow(e, 2));


            double N = a / Math.Sqrt(1 - Math.Pow(e * Math.Sin(phi), 2));
            double T = Math.Pow(Math.Tan(phi), 2);
            double C = e0sq * Math.Pow(Math.Cos(phi), 2);
            double A = (longi - zcm) * drad * Math.Cos(phi);

            // calculate M (USGS style)
            double M = phi * (1 - esq * (1.0 / 4.0 + esq * (3.0 / 64.0 + 5.0 * esq / 256.0)));

            M -= Math.Sin(2.0 * phi) * (esq * (3.0 / 8.0 + esq * (3.0 / 32.0 + 45.0 * esq / 1024.0)));
            M += Math.Sin(4.0 * phi) * (esq * esq * (15.0 / 256.0 + esq * 45.0 / 1024.0));
            M -= Math.Sin(6.0 * phi) * (esq * esq * esq * (35.0 / 3072.0));
            M *= a;        //Arc length along standard meridian

            double M0 = 0; // if another point of origin is used than the equator

            // Calculate the UTM values...
            // first the easting
            var x = k0 * N * A * (1 + A * A * ((1 - T + C) / 6 + A * A * (5 - 18 * T + T * T + 72.0 * C - 58 * e0sq) / 120.0)); //Easting relative to CM

            x += 500000;                                                                                                        // standard easting

            // Northing

            double y = k0 * (M - M0 + N * Math.Tan(phi) * (A * A * (1 / 2.0 + A * A * ((5 - T + 9 * C + 4 * C * C) / 24.0 + A * A * (61 - 58 * T + T * T + 600 * C - 330 * e0sq) / 720.0))));    // first from the equator

            if (y < 0)
            {
                y = 10000000 + y;   // add in false northing if south of the equator
            }

            //Last zone is 60, but will hit 61 at 180 degrees exactly. Reset to 1.
            if (zone == 61)
            {
                zone = 1;
            }

            double easting  = x;
            double northing = y;

            utm.latZone    = letter;
            utm.longZone   = zone;
            utm.easting    = easting;
            utm.northing   = northing;
            utm.systemType = systemType;
        }
예제 #13
0
 /// <summary>
 /// Converts UTM coordinate to Lat/Long
 /// </summary>
 /// <param name="utm">utm</param>
 /// <returns>Coordinate</returns>
 /// <example>
 /// The following example creates (converts to) a geodetic Coordinate object based on a UTM object.
 /// <code>
 /// UniversalTransverseMercator utm = new UniversalTransverseMercator("T", 32, 233434, 234234);
 /// Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
 /// Console.WriteLine(c); //N 2º 7' 2.332" E 6º 36' 12.653"
 /// </code>
 /// </example>
 public static Coordinate ConvertUTMtoLatLong(UniversalTransverseMercator utm)
 {
     return(ConvertUTMtoLatLong(utm, new EagerLoad()));
 }
        //Add main to Coordinate and tunnel to Format class. Add private methods to format.
        //WHEN PARSING NO EXCPETIONS FOR OUT OF RANGE ARGS WILL BE THROWN
        public static bool TryParse(string coordString, CartesianType ct, out Coordinate c)
        {
            try
            {
                //Turn of eagerload for efficiency
                EagerLoad eg = new EagerLoad();
                eg.Cartesian = false;
                eg.Celestial = false;
                eg.UTM_MGRS  = false;

                c = new Coordinate(eg);
                if (string.IsNullOrEmpty(coordString))
                {
                    return(false);
                }

                string s = coordString;
                s = s.Trim(); //Trim all spaces before and after string
                double[] d;
                //Try Signed Degree
                if (TrySignedDegree(s, out d))
                {
                    try
                    {
                        c = new Coordinate(d[0], d[1], eg);
                        c.Parse_Format = Parse_Format_Type.Signed_Degree;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }

                //Try Decimal Degree
                if (TryDecimalDegree(s, out d))
                {
                    try
                    {
                        c = new Coordinate(d[0], d[1], eg);
                        c.Parse_Format = Parse_Format_Type.Decimal_Degree;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
                //Try DDM
                if (TryDegreeDecimalMinute(s, out d))
                {
                    try
                    {
                        //0 Lat Degree
                        //1 Lat Minute
                        //2 Lat Direction (0 = N, 1 = S)
                        //3 Long Degree
                        //4 Long Minute
                        //5 Long Direction (0 = E, 1 = W)
                        CoordinatesPosition latP = CoordinatesPosition.N;
                        CoordinatesPosition lngP = CoordinatesPosition.E;
                        if (d[2] != 0)
                        {
                            latP = CoordinatesPosition.S;
                        }
                        if (d[5] != 0)
                        {
                            lngP = CoordinatesPosition.W;
                        }
                        CoordinatePart lat = new CoordinatePart((int)d[0], d[1], latP);
                        CoordinatePart lng = new CoordinatePart((int)d[3], d[4], lngP);
                        c              = new Coordinate(eg);
                        c.Latitude     = lat;
                        c.Longitude    = lng;
                        c.Parse_Format = Parse_Format_Type.Degree_Decimal_Minute;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
                //Try DMS
                if (TryDegreeMinuteSecond(s, out d))
                {
                    try
                    {
                        //0 Lat Degree
                        //1 Lat Minute
                        //2 Lat Second
                        //3 Lat Direction (0 = N, 1 = S)
                        //4 Long Degree
                        //5 Long Minute
                        //6 Long Second
                        //7 Long Direction (0 = E, 1 = W)
                        CoordinatesPosition latP = CoordinatesPosition.N;
                        CoordinatesPosition lngP = CoordinatesPosition.E;
                        if (d[3] != 0)
                        {
                            latP = CoordinatesPosition.S;
                        }
                        if (d[7] != 0)
                        {
                            lngP = CoordinatesPosition.W;
                        }

                        CoordinatePart lat = new CoordinatePart((int)d[0], (int)d[1], d[2], latP);
                        CoordinatePart lng = new CoordinatePart((int)d[4], (int)d[5], d[6], lngP);
                        c              = new Coordinate(eg);
                        c.Latitude     = lat;
                        c.Longitude    = lng;
                        c.Parse_Format = Parse_Format_Type.Degree_Minute_Second;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
                //Try Cartesian
                if (TryCartesian(s.ToUpper().Replace("KM", "").Replace("X", "").Replace("Y", "").Replace("Z", ""), out d))
                {
                    if (ct == CartesianType.Cartesian)
                    {
                        try
                        {
                            Cartesian cart = new Cartesian(d[0], d[1], d[2]);
                            c = Cartesian.CartesianToLatLong(cart);
                            c.Parse_Format = Parse_Format_Type.Cartesian_Spherical;
                            return(true);
                        }
                        catch
                        {//Parser failed try next method
                        }
                    }
                    if (ct == CartesianType.ECEF)
                    {
                        try
                        {
                            ECEF ecef = new ECEF(d[0], d[1], d[2]);
                            c = ECEF.ECEFToLatLong(ecef);
                            c.Parse_Format = Parse_Format_Type.Cartesian_ECEF;
                            return(true);
                        }
                        catch
                        {//Parser failed try next method
                        }
                    }
                }
                string[] um;
                //Try MGRS
                if (TryMGRS(s, out um) || TryMGRS_Polar(s, out um))
                {
                    try
                    {
                        double zone     = Convert.ToDouble(um[0], CultureInfo.InvariantCulture);
                        double easting  = Convert.ToDouble(um[3], CultureInfo.InvariantCulture);
                        double northing = Convert.ToDouble(um[4], CultureInfo.InvariantCulture);
                        MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem(um[1], (int)zone, um[2], easting, northing);
                        c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs);
                        c.Parse_Format = Parse_Format_Type.MGRS;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
                //Try UTM
                if (TryUTM(s, out um) || TryUPS(s, out um))
                {
                    try
                    {
                        double zone     = Convert.ToDouble(um[0], CultureInfo.InvariantCulture);
                        double easting  = Convert.ToDouble(um[2], CultureInfo.InvariantCulture);
                        double northing = Convert.ToDouble(um[3], CultureInfo.InvariantCulture);
                        UniversalTransverseMercator utm = new UniversalTransverseMercator(um[1], (int)zone, easting, northing);
                        c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
                        c.Parse_Format = Parse_Format_Type.UTM;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
            }
            catch (Exception ex)
            {
                //Parser exception has occurred
                Debug.WriteLine("PARSER EXCEPTION HANDLED: " + ex.ToString());
            }
            c = null;
            return(false);
        }
        //Add main to Coordinate and tunnel to Format class. Add private methods to format.
        //WHEN PARSING NO EXCPETIONS FOR OUT OF RANGE ARGS WILL BE THROWN
        public static bool TryParse(string coordString, CartesianType ct, out Coordinate c)
        {
            try
            {
                //Turn of eagerload for efficiency
                EagerLoad eg = new EagerLoad();
                eg.Cartesian = false;
                eg.Celestial = false;
                eg.UTM_MGRS  = false;

                c = new Coordinate(eg);
                if (string.IsNullOrEmpty(coordString))
                {
                    return(false);
                }

                string s = coordString;
                s = s.Trim(); //Trim all spaces before and after string
                double[] d;
                //Try Signed Degree
                if (TrySignedDegree(s, out d))
                {
                    try
                    {
                        c = new Coordinate(d[0], d[1], eg);
                        c.Parse_Format = Parse_Format_Type.Signed_Degree;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }

                //Try Decimal Degree
                if (TryDecimalDegree(s, out d))
                {
                    try
                    {
                        c = new Coordinate(d[0], d[1], eg);
                        c.Parse_Format = Parse_Format_Type.Decimal_Degree;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
                //Try DDM
                if (TryDegreeDecimalMinute(s, out d))
                {
                    try
                    {
                        //0 Lat Degree
                        //1 Lat Minute
                        //2 Lat Direction (0 = N, 1 = S)
                        //3 Long Degree
                        //4 Long Minute
                        //5 Long Direction (0 = E, 1 = W)
                        CoordinatesPosition latP = CoordinatesPosition.N;
                        CoordinatesPosition lngP = CoordinatesPosition.E;
                        if (d[2] != 0)
                        {
                            latP = CoordinatesPosition.S;
                        }
                        if (d[5] != 0)
                        {
                            lngP = CoordinatesPosition.W;
                        }
                        CoordinatePart lat = new CoordinatePart((int)d[0], d[1], latP);
                        CoordinatePart lng = new CoordinatePart((int)d[3], d[4], lngP);
                        c              = new Coordinate(eg);
                        c.Latitude     = lat;
                        c.Longitude    = lng;
                        c.Parse_Format = Parse_Format_Type.Degree_Decimal_Minute;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
                //Try DMS
                if (TryDegreeMinuteSecond(s, out d))
                {
                    try
                    {
                        //0 Lat Degree
                        //1 Lat Minute
                        //2 Lat Second
                        //3 Lat Direction (0 = N, 1 = S)
                        //4 Long Degree
                        //5 Long Minute
                        //6 Long Second
                        //7 Long Direction (0 = E, 1 = W)
                        CoordinatesPosition latP = CoordinatesPosition.N;
                        CoordinatesPosition lngP = CoordinatesPosition.E;
                        if (d[3] != 0)
                        {
                            latP = CoordinatesPosition.S;
                        }
                        if (d[7] != 0)
                        {
                            lngP = CoordinatesPosition.W;
                        }

                        CoordinatePart lat = new CoordinatePart((int)d[0], (int)d[1], d[2], latP);
                        CoordinatePart lng = new CoordinatePart((int)d[4], (int)d[5], d[6], lngP);
                        c              = new Coordinate(eg);
                        c.Latitude     = lat;
                        c.Longitude    = lng;
                        c.Parse_Format = Parse_Format_Type.Degree_Minute_Second;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }

                Cartesian cart;
                if (ct == CartesianType.Cartesian && Cartesian.TryParse(s, out cart))
                {
                    try
                    {
                        c = Cartesian.CartesianToLatLong(cart);
                        c.Parse_Format = Parse_Format_Type.Cartesian_Spherical;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }

                ECEF ecef;
                if (ct == CartesianType.ECEF && ECEF.TryParse(s, out ecef))
                {
                    try
                    {
                        c = ECEF.ECEFToLatLong(ecef);
                        c.Parse_Format = Parse_Format_Type.Cartesian_ECEF;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }


                //Try MGRS
                MilitaryGridReferenceSystem mgrs;
                if (MilitaryGridReferenceSystem.TryParse(s, out mgrs))
                {
                    try
                    {
                        c = MilitaryGridReferenceSystem.MGRStoLatLong(mgrs);
                        c.Parse_Format = Parse_Format_Type.MGRS;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }

                //Try UTM
                UniversalTransverseMercator utm;
                if (UniversalTransverseMercator.TryParse(s, out utm))
                {
                    try
                    {
                        c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm);
                        c.Parse_Format = Parse_Format_Type.UTM;
                        return(true);
                    }
                    catch
                    {//Parser failed try next method
                    }
                }
            }
            catch (Exception ex)
            {
                //Parser exception has occurred
                Debug.WriteLine("PARSER EXCEPTION HANDLED: " + ex.ToString());
            }
            c = null;
            return(false);
        }
예제 #16
0
        /// <summary>
        /// Attempts to parse a string into an UTM coordinate.
        /// </summary>
        /// <param name="value">string</param>
        /// <param name="spec">Earth_Ellipsoid_Spec</param>
        /// <param name="utm">UniversalTransverseMercator</param>
        /// <returns>UniversalTransverseMercator</returns>
        /// <example>
        /// The following example attempts to parse a UTM coordinate set with a GRS80 system ellipsoid.
        /// <code>
        /// UniversalTransverseMercator utm;
        /// if(!UniversalTransverseMercator.TryParse("16U 500872mE 5505009mN", Earth_Ellipsoid_Spec.GRS80_1979, out utm))
        /// {
        ///     Console.WriteLine(utm);//16U 500872mE 5505009mN
        /// }
        /// </code>
        /// </example>
        public static bool TryParse(string value, Earth_Ellipsoid_Spec spec, out UniversalTransverseMercator utm)
        {
            Earth_Ellipsoid ee = Earth_Ellipsoid.Get_Ellipsoid(spec);

            return(TryParse(value, ee.Equatorial_Radius, ee.Inverse_Flattening, out utm));
        }