コード例 #1
0
        /// <summary>
        /// Creates a Celestial object based on a location and specified date.
        /// </summary>
        /// <param name="lat">Latitude</param>
        /// <param name="longi">Longitude</param>
        /// <param name="geoDate">DateTime (UTC)</param>
        /// <param name="offset">UTC offset in hours</param>
        /// <param name="el">EagerLoad</param>
        /// <remarks>
        /// Celestial information is normally populated within the Coordinate classes CelestialInfo property.
        /// However, you may choose to work directly within the Celestial class.
        /// </remarks>
        /// <example>
        /// The following example demonstrates how to get the sunset time at Seattle on 19-Mar-2019
        /// directly from a Celestial object in local time populated only with solar cycle information.
        /// <code>
        /// //Create EagerLoading object to load only solar cycle data for maximum efficiency.
        /// EagerLoad el = new EagerLoad(EagerLoadType.Celestial);
        /// el.Extensions = new EagerLoad_Extensions(EagerLoad_ExtensionsType.Solar_Cycle);
        ///
        /// //Create a Celestial object the calculates from Seattle's signed lat/long on
        /// //19-Mar-2019 (UTC) Date. Seattle is -7 UTC on this date.
        /// Celestial cel = new Celestial(47.60357, -122.32945, new DateTime(2019, 3, 19), -7, el);
        ///
        /// //Check if a sunset will occur on the specified day.
        /// if(cel.SunSet.HasValue)
        /// {
        ///     Console.WriteLine(cel.SunSet.Value); //3/19/2019 7:20:56 PM
        /// }
        /// </code>
        /// </example>
        public Celestial(double lat, double longi, DateTime geoDate, double offset, EagerLoad el)
        {
            DateTime d = new DateTime(geoDate.Year, geoDate.Month, geoDate.Day, geoDate.Hour, geoDate.Minute, geoDate.Second, DateTimeKind.Utc);

            Create_Properties();
            CalculateCelestialTime(lat, longi, d, el, offset);
        }
コード例 #2
0
        /// <summary>
        /// Creates a Celestial object based on a location and specified date.
        /// </summary>
        /// <param name="lat">Latitude</param>
        /// <param name="longi">Longitude</param>
        /// <param name="geoDate">DateTime (UTC)</param>
        /// <param name="offset">UTC offset in hours</param>
        /// <param name="el">EagerLoad</param>
        /// <remarks>
        /// Celestial information is normally populated within the Coordinate classes CelestialInfo property.
        /// However, you may choose to work directly within the Celestial class.
        /// </remarks>
        /// <example>
        /// The following example demonstrates how to get the sunset time at Seattle on 19-Mar-2019
        /// directly from a Celestial object in local time populated only with solar cycle information.
        /// <code>
        /// //Create EagerLoading object to load only solar cycle data for maximum efficiency.
        /// EagerLoad el = new EagerLoad(EagerLoadType.Celestial);
        /// el.Extensions = new EagerLoad_Extensions(EagerLoad_ExtensionsType.Solar_Cycle);
        ///
        /// //Create a Celestial object the calculates from Seattle's signed lat/long on
        /// //19-Mar-2019 (UTC) Date. Seattle is -7 UTC on this date.
        /// Celestial cel = new Celestial(47.60357, -122.32945, new DateTime(2019, 3, 19), -7, el);
        ///
        /// //Check if a sunset will occur on the specified day.
        /// if(cel.SunSet.HasValue)
        /// {
        ///     Console.WriteLine(cel.SunSet.Value); //3/19/2019 7:20:56 PM
        /// }
        /// </code>
        /// </example>
        public Celestial(double lat, double longi, DateTime geoDate, double offset, EagerLoad el)
        {
            DateTime d = new DateTime(geoDate.Year, geoDate.Month, geoDate.Day, geoDate.Hour, geoDate.Minute, geoDate.Second, DateTimeKind.Utc);

            astrologicalSigns = new AstrologicalSigns();
            lunarEclipse      = new LunarEclipse();
            solarEclipse      = new SolarEclipse();
            CalculateCelestialTime(lat, longi, d, el, offset);
        }
コード例 #3
0
        /// <summary>
        /// Parses a string into a Coordinate with a specified Cartesian system type and eager loading settings.
        /// </summary>
        /// <param name="value">Coordinate string</param>
        /// <param name="cartesianType">Cartesian Type</param>
        /// <param name="eagerLoad">Eager loading options</param>
        /// <returns>Coordinate</returns>
        /// <example>
        /// The following example parses an ECEF formatted coordinate string.
        /// Because this is an ECEF Cartesian type coordinate, we will specify the Cartesian system type.
        /// Eager loading options have been specified for efficiency.
        /// <code>
        /// EagerLoad el = new EagerLoad(EagerLoadType.Cartesian);
        /// Coordinate c = Coordinate.Parse("5242.097 km, 2444.43 km, 2679.074 km", CartesianType.Cartesian, el);
        /// </code>
        /// </example>
        public static Coordinate Parse(string value, CartesianType cartesianType, EagerLoad eagerLoad)
        {
            Coordinate coordinate = null;

            if (TryParse(value, cartesianType, eagerLoad, out coordinate))
            {
                return(coordinate);
            }

            throw new FormatException(string.Format("Input Coordinate \"{0}\" was not in a correct format.", value));
        }
コード例 #4
0
        /// <summary>
        /// Attempts to parse a string into a Coordinate with a specified date and eager loading settings.
        /// </summary>
        /// <param name="value">Coordinate string</param>
        /// <param name="geoDate">GeoDate</param>
        /// <param name="eagerLoad">Eager loading options</param>
        /// <param name="coordinate">Coordinate</param>
        /// <returns>boolean</returns>
        /// <example>
        /// The following example parses a decimal degree formatted geodetic coordinate string, with a provided GeoDate.
        /// Eager loading is set to load celestial calculations only.
        /// <code>
        /// Coordinate c;
        /// EagerLoad el = new EagerLoad(EagerLoadType.Celestial);
        /// if(Coordinate.TryParse("N 32.891º W 64.872º", new DateTime(2018,7,7), el, out c))
        /// {
        ///     Console.WriteLine(c); //N 32º 53' 28.212" W 64º 52' 20.914"
        /// }
        /// </code>
        /// </example>
        public static bool TryParse(string value, DateTime geoDate, EagerLoad eagerLoad, out Coordinate coordinate)
        {
            coordinate = null;
            if (FormatFinder.TryParse(value, CartesianType.Cartesian, out coordinate))
            {
                Parse_Format_Type pft = coordinate.Parse_Format;
                coordinate = new Coordinate(coordinate.Latitude.ToDouble(), coordinate.Longitude.ToDouble(), geoDate, eagerLoad); //Reset with specified eager load options.
                coordinate.parse_Format = pft;

                return(true);
            }
            return(false);
        }
コード例 #5
0
        /// <summary>
        /// Creates a Coordinate object with default values and a custom datum.
        /// </summary>
        /// <remarks>
        /// Default Coordinate objects will initialize with a latitude and longitude of 0 degrees,
        /// a GeoDate of 1900-1-1 00:00:00. All properties will be set to EagerLoaded.
        /// </remarks>
        internal Coordinate(double equatorialRadius, double inverseFlattening, bool t)
        {
            FormatOptions    = new CoordinateFormatOptions();
            geoDate          = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            latitude         = new CoordinatePart(CoordinateType.Lat);
            longitude        = new CoordinatePart(CoordinateType.Long);
            latitude.parent  = this;
            longitude.parent = this;
            celestialInfo    = new Celestial();
            utm       = new UniversalTransverseMercator(latitude.ToDouble(), longitude.ToDouble(), this, equatorialRadius, inverseFlattening);
            mgrs      = new MilitaryGridReferenceSystem(utm);
            cartesian = new Cartesian(this);
            ecef      = new ECEF(this);

            EagerLoadSettings = new EagerLoad();
            Set_Datum(equatorialRadius, inverseFlattening);
        }
コード例 #6
0
        /// <summary>
        /// Attempts to parse a string into a Coordinate with a specified Cartesian system type and eager loading settings.
        /// </summary>
        /// <param name="value">Coordinate string</param>
        /// <param name="cartesianType">Cartesian Type</param>
        /// <param name="eagerLoad">Eager loading options</param>
        /// <param name="coordinate">Coordinate</param>
        /// <returns>boolean</returns>
        /// <example>
        /// The following example parses an ECEF formatted coordinate string.
        /// Because this is an ECEF Cartesian type coordinate, we will specify the Cartesian system type.
        /// Eager loading options have been specified for efficiency.
        /// <code>
        /// Coordinate c;
        /// EagerLoad el = new EagerLoad(EagerLoadType.Cartesian);
        /// if(Coordinate.TryParse("5242.097 km, 2444.43 km, 2679.074 km", CartesianType.Cartesian, el, out c))
        /// {
        ///     Console.WriteLine(c); //N 24º 59' 59.987" E 25º 0' 0.001"
        /// }
        /// </code>
        /// </example>
        public static bool TryParse(string value, CartesianType cartesianType, EagerLoad eagerLoad, out Coordinate coordinate)
        {
            coordinate = null;
            if (FormatFinder.TryParse(value, cartesianType, out coordinate))
            {
                Parse_Format_Type pft = coordinate.Parse_Format;
                if (cartesianType == CartesianType.ECEF)
                {
                    Distance h = coordinate.ecef.GeoDetic_Height;
                    coordinate = new Coordinate(coordinate.Latitude.ToDouble(), coordinate.Longitude.ToDouble(), eagerLoad); //Reset with eager load options specified.
                    coordinate.ecef.Set_GeoDetic_Height(coordinate, h);
                }
                else
                {
                    coordinate = new Coordinate(coordinate.Latitude.ToDouble(), coordinate.Longitude.ToDouble(), eagerLoad); //Reset with eager load options specified.
                }
                coordinate.parse_Format = pft;

                return(true);
            }
            return(false);
        }
コード例 #7
0
        /// <summary>
        /// Converts UTM coordinate to Lat/Long
        /// </summary>
        /// <param name="utm">utm</param>
        /// <param name="eagerLoad">EagerLoad</param>
        /// <returns>Coordinate</returns>
        /// <example>
        /// The following example creates (converts to) a geodetic Coordinate object based on a UTM object.
        /// Performance is maximized by turning off EagerLoading.
        /// <code>
        /// EagerLoad el = new EagerLoad(false);
        /// UniversalTransverseMercator utm = new UniversalTransverseMercator("T", 32, 233434, 234234);
        /// Coordinate c = UniversalTransverseMercator.ConvertUTMtoLatLong(utm, el);
        /// Console.WriteLine(c); //N 2º 7' 2.332" E 6º 36' 12.653"
        /// </code>
        /// </example>
        public static Coordinate ConvertUTMtoLatLong(UniversalTransverseMercator utm, EagerLoad eagerLoad)
        {
            bool  southhemi = false;
            Regex upsCheck  = new Regex("[AaBbYyZz]");

            if (upsCheck.IsMatch(utm.latZone))
            {
                return(UPS.UPS_To_Geodetic(utm, eagerLoad));
            }

            Regex regex = new Regex("[CcDdEeFfGgHhJjKkLlMm]");

            if (regex.IsMatch(utm.latZone))
            {
                southhemi = true;
            }

            double cmeridian;

            double x = utm.Easting - 500000.0;
            double UTMScaleFactor = 0.9996;

            x /= UTMScaleFactor;

            /* If in southern hemisphere, adjust y accordingly. */
            double y = utm.Northing;

            if (southhemi)
            {
                y -= 10000000.0;
            }

            y /= UTMScaleFactor;

            cmeridian = UTMCentralMeridian(utm.LongZone);

            Coordinate c = UTMtoLatLong(x, y, cmeridian, utm.equatorial_radius, utm.inverse_flattening, eagerLoad);

            return(c);
        }
コード例 #8
0
        private static Coordinate UTMtoLatLong(double x, double y, double zone, double equatorialRadius, double flattening, EagerLoad el)
        {
            //x easting
            //y northing

            //http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html
            double phif, Nf, Nfpow, nuf2, ep2, tf, tf2, tf4, cf;
            double x1frac, x2frac, x3frac, x4frac, x5frac, x6frac, x7frac, x8frac;
            double x2poly, x3poly, x4poly, x5poly, x6poly, x7poly, x8poly;

            double sm_a = equatorialRadius;
            double sm_b = equatorialRadius * (1 - (1.0 / flattening)); //Polar Radius

            /* Get the value of phif, the footpoint latitude. */
            phif = FootpointLatitude(y, equatorialRadius, flattening);

            /* Precalculate ep2 */
            ep2 = (Math.Pow(sm_a, 2.0) - Math.Pow(sm_b, 2.0))
                  / Math.Pow(sm_b, 2.0);

            /* Precalculate cos (phif) */
            cf = Math.Cos(phif);

            /* Precalculate nuf2 */
            nuf2 = ep2 * Math.Pow(cf, 2.0);

            /* Precalculate Nf and initialize Nfpow */
            Nf    = Math.Pow(sm_a, 2.0) / (sm_b * Math.Sqrt(1 + nuf2));
            Nfpow = Nf;

            /* Precalculate tf */
            tf  = Math.Tan(phif);
            tf2 = tf * tf;
            tf4 = tf2 * tf2;

            /* Precalculate fractional coefficients for x**n in the equations
             * below to simplify the expressions for latitude and longitude. */
            x1frac = 1.0 / (Nfpow * cf);

            Nfpow *= Nf;   /* now equals Nf**2) */
            x2frac = tf / (2.0 * Nfpow);

            Nfpow *= Nf;   /* now equals Nf**3) */
            x3frac = 1.0 / (6.0 * Nfpow * cf);

            Nfpow *= Nf;   /* now equals Nf**4) */
            x4frac = tf / (24.0 * Nfpow);

            Nfpow *= Nf;   /* now equals Nf**5) */
            x5frac = 1.0 / (120.0 * Nfpow * cf);

            Nfpow *= Nf;   /* now equals Nf**6) */
            x6frac = tf / (720.0 * Nfpow);

            Nfpow *= Nf;   /* now equals Nf**7) */
            x7frac = 1.0 / (5040.0 * Nfpow * cf);

            Nfpow *= Nf;   /* now equals Nf**8) */
            x8frac = tf / (40320.0 * Nfpow);

            /* Precalculate polynomial coefficients for x**n.
             * -- x**1 does not have a polynomial coefficient. */
            x2poly = -1.0 - nuf2;

            x3poly = -1.0 - 2 * tf2 - nuf2;

            x4poly = 5.0 + 3.0 * tf2 + 6.0 * nuf2 - 6.0 * tf2 * nuf2
                     - 3.0 * (nuf2 * nuf2) - 9.0 * tf2 * (nuf2 * nuf2);

            x5poly = 5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * nuf2 + 8.0 * tf2 * nuf2;

            x6poly = -61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * nuf2
                     + 162.0 * tf2 * nuf2;

            x7poly = -61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2);

            x8poly = 1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2);

            /* Calculate latitude */
            double nLat = phif + x2frac * x2poly * (x * x)
                          + x4frac * x4poly * Math.Pow(x, 4.0)
                          + x6frac * x6poly * Math.Pow(x, 6.0)
                          + x8frac * x8poly * Math.Pow(x, 8.0);

            /* Calculate longitude */
            double nLong = zone + x1frac * x
                           + x3frac * x3poly * Math.Pow(x, 3.0)
                           + x5frac * x5poly * Math.Pow(x, 5.0)
                           + x7frac * x7poly * Math.Pow(x, 7.0);

            double dLat  = RadToDeg(nLat);
            double dLong = RadToDeg(nLong);

            if (dLat > 90)
            {
                dLat = 90;
            }
            if (dLat < -90)
            {
                dLat = -90;
            }
            if (dLong > 180)
            {
                dLong = 180;
            }
            if (dLong < -180)
            {
                dLong = -180;
            }

            Coordinate c = new Coordinate(dLat, dLong, el, equatorialRadius, flattening);

            return(c);
        }
コード例 #9
0
 /// <summary>
 /// Returns a populated MGRS_GridBox details based on the MGRS coordinate.
 /// This can be useful for grid zone junction adjacent partial boxes or when needing
 /// Lat/Long coordinates at the corners of the MGRS square.
 /// </summary>
 /// <param name="el">EagerLoad</param>
 /// <returns>MGRS_GridBox</returns>
 /// <example>
 /// The following example will create an MGRS_GridBox that will allow us to determine
 /// The MGRS Point at the bottom left of the current 100km grid square and convert it to Lat/Long.
 /// <code>
 /// MilitaryGridReferenceSystem mgrs = new MilitaryGridReferenceSystem("N", 21, "SA", 66037, 61982);
 /// EagerLoad el = new EagerLoad(EagerLoadType.UTM_MGRS); //Only eager load UTM MGRS data for efficiency
 /// var box = mgrs.Get_Box_Boundaries();
 ///
 /// //Check if created MGRS coordinate is valid
 /// if(!box.IsBoxValid){return;} //MGRS Coordinate GZD and Identifier are not standard. Box cannot be determined.
 ///
 /// Console.WriteLine("BL: " + gb.Bottom_Left_MGRS_Point); //21N SA 66022 00000
 /// Console.WriteLine("BL: " + gb.Bottom_Left_Coordinate_Point); //N 0º 0' 0" W 59º 59' 59.982"
 /// </code>
 /// </example>
 public MGRS_GridBox Get_Box_Boundaries(EagerLoad el)
 {
     return(new MGRS_GridBox(this, el));
 }
コード例 #10
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);
        }
コード例 #11
0
        public static void CalculateSunTime(double lat, double longi, DateTime date, Celestial c, EagerLoad el, double offset = 0)
        {
            if (date.Year == 0001)
            {
                return;
            }                                  //Return if date value hasn't been established.
            if (el.Extensions.Solar_Cycle)
            {
                DateTime actualDate = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc);

                ////Sun Time Calculations

                //Get Julian
                double lw  = rad * -longi;
                double phi = rad * lat;

                //Rise Set
                DateTime?[] evDate = Get_Event_Time(lw, phi, -.8333, actualDate);
                c.sunRise = evDate[0];
                c.sunSet  = evDate[1];

                c.sunCondition = CelestialStatus.RiseAndSet;
                //Azimuth and Altitude
                CalculateSunAngle(date, longi, lat, c);
                // neither sunrise nor sunset
                if ((!c.SunRise.HasValue) && (!c.SunSet.HasValue))
                {
                    if (c.SunAltitude < 0)
                    {
                        c.sunCondition = CelestialStatus.DownAllDay;
                    }
                    else
                    {
                        c.sunCondition = CelestialStatus.UpAllDay;
                    }
                }
                // sunrise or sunset
                else
                {
                    if (!c.SunRise.HasValue)
                    {
                        // No sunrise this date
                        c.sunCondition = CelestialStatus.NoRise;
                    }
                    else if (!c.SunSet.HasValue)
                    {
                        // No sunset this date
                        c.sunCondition = CelestialStatus.NoSet;
                    }
                }
                //Additional Times
                c.additionalSolarTimes = new AdditionalSolarTimes();
                //Dusk and Dawn
                //Civil
                evDate = Get_Event_Time(lw, phi, -6, actualDate);
                c.AdditionalSolarTimes.civilDawn = evDate[0];
                c.AdditionalSolarTimes.civilDusk = evDate[1];


                //Nautical
                evDate = Get_Event_Time(lw, phi, -12, actualDate);
                c.AdditionalSolarTimes.nauticalDawn = evDate[0];
                c.AdditionalSolarTimes.nauticalDusk = evDate[1];

                //Astronomical
                evDate = Get_Event_Time(lw, phi, -18, actualDate);

                c.AdditionalSolarTimes.astronomicalDawn = evDate[0];
                c.AdditionalSolarTimes.astronomicalDusk = evDate[1];

                //BottomDisc
                evDate = Get_Event_Time(lw, phi, -.2998, actualDate);
                c.AdditionalSolarTimes.sunriseBottomDisc = evDate[0];
                c.AdditionalSolarTimes.sunsetBottomDisc  = evDate[1];
            }
            if (el.Extensions.Solar_Eclipse)
            {
                CalculateSolarEclipse(date, lat, longi, c);
            }
        }
コード例 #12
0
        /*PARSER METHODS*/


        /// <summary>
        /// Attempts to parse a string into a Coordinate.
        /// </summary>
        /// <param name="value">Coordinate string</param>
        /// <param name="coordinate">Coordinate</param>
        /// <returns>boolean</returns>
        /// <example>
        /// The following example parses a decimal degree formatted geodetic coordinate string.
        /// <code>
        /// Coordinate c;
        /// if(Coordinate.TryParse("N 32.891º W 64.872º", e, out c))
        /// {
        ///     Console.WriteLine(c); //N 32º 53' 28.212" W 64º 52' 20.914"
        /// }
        /// </code>
        /// </example>
        public static bool TryParse(string value, out Coordinate coordinate)
        {
            var eagerLoad = new EagerLoad();

            return(TryParse(value, eagerLoad, out coordinate));
        }
コード例 #13
0
 /// <summary>
 /// Calculates all celestial data. Coordinates will notify as changes occur
 /// </summary>
 /// <param name="lat">Decimal format latitude</param>
 /// <param name="longi">Decimal format longitude</param>
 /// <param name="date">Geographic DateTime</param>
 /// <param name="el">EagerLoading Info for Auto-Calculations</param>
 internal void CalculateCelestialTime(double lat, double longi, DateTime date, EagerLoad el)
 {
     CalculateCelestialTime(lat, longi, date, el, 0);
 }
コード例 #14
0
 /// <summary>
 /// Creates a populated Coordinate object with specified eager load options, assigned GeoDate and Earth Shape. Should only be called when Coordinate
 /// is create from another system.
 /// </summary>
 /// <param name="lat">signed latitude</param>
 /// <param name="longi">signed longitude</param>
 /// <param name="eagerLoad">Eager loading options</param>
 /// <param name="equatorialRadius">Semi Major Axis or Equatorial Radius of the Earth</param>
 /// <param name="inverseFlattening">Inverse of Flattening of the Earth</param>
 internal Coordinate(double lat, double longi, EagerLoad eagerLoad, double equatorialRadius, double inverseFlattening)
 {
     Coordinate_Builder(lat, longi, new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc), eagerLoad);
     equatorial_radius  = equatorialRadius;
     inverse_flattening = inverseFlattening;
 }
コード例 #15
0
        /// <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)
        {
            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);
            }
            //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 EagerLoading Setting
            EagerLoadSettings = eagerLoad;

            //Set Ellipsoid
            equatorial_radius  = 6378137.0;
            inverse_flattening = 298.257223563;
        }
コード例 #16
0
 /// <summary>
 /// Creates a populated Coordinate object with specified eager load options and an assigned GeoDate.
 /// </summary>
 /// <param name="lat">signed latitude</param>
 /// <param name="longi">signed longitude</param>
 /// <param name="date">DateTime you wish to use for celestial calculation</param>
 /// <param name="eagerLoad">Eager loading options</param>
 /// <example>
 /// The following example demonstrates how to create a defined Coordinate object with defined
 /// eager loading options and a GeoDate.
 /// <code>
 /// //Create a new EagerLoading object set to only
 /// //eager load celestial calculations.
 /// EagerLoading el = new EagerLoading(EagerLoadType.Celestial);
 /// DateTime geoDate = new DateTime(2018, 2, 5, 10, 38, 22);
 ///
 /// Coordinate c = new Coordinate(25, 25, geoDate, el);
 /// </code>
 /// </example>
 public Coordinate(double lat, double longi, DateTime date, EagerLoad eagerLoad)
 {
     Coordinate_Builder(lat, longi, date, eagerLoad);
 }
コード例 #17
0
 /// <summary>
 /// Creates a populated Coordinate object with specified eager loading options.
 /// </summary>
 /// <remarks>
 /// Geodate will default to 1900-01-01.
 /// </remarks>
 /// <param name="lat">signed latitude</param>
 /// <param name="longi">signed longitude</param>
 /// <param name="eagerLoad">Eager loading options</param>
 /// <example>
 /// The following example demonstrates how to create a defined Coordinate object with defined
 /// eager loading options.
 /// <code>
 /// //Create a new EagerLoading object set to only
 /// //eager load celestial calculations.
 /// EagerLoading el = new EagerLoading(EagerLoadType.Celestial);
 ///
 /// Coordinate c = new Coordinate(25, 25, el);
 /// </code>
 /// </example>
 public Coordinate(double lat, double longi, EagerLoad eagerLoad)
 {
     Coordinate_Builder(lat, longi, new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc), eagerLoad);
 }
コード例 #18
0
 /// <summary>
 /// Creates an empty Coordinates object with specified eager loading options.
 /// </summary>
 /// <remarks>
 /// Coordinate will initialize with a latitude and longitude of 0 degrees and
 /// a GeoDate of 1900-1-1.
 /// </remarks>
 /// <param name="eagerLoad">Eager loading options</param>
 /// <example>
 /// The following example demonstrates how to create a default Coordinate object with defined
 /// eager loading options
 /// <code>
 /// //Create a new EagerLoading object set to only
 /// //eager load celestial calculations.
 /// EagerLoading el = new EagerLoading(EagerLoadType.Celestial);
 ///
 /// Coordinate c = new Coordinate(el);
 /// </code>
 /// </example>
 public Coordinate(EagerLoad eagerLoad)
 {
     Coordinate_Builder(0, 0, new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc), eagerLoad);
 }
コード例 #19
0
        /// <summary>
        /// Calculate celestial data based on latitude, longitude and UTC date with hours offset at the location.
        /// </summary>
        /// <param name="lat">Decimal format latitude</param>
        /// <param name="longi">Decimal format longitude</param>
        /// <param name="date">Geographic DateTime</param>
        /// <param name="el">EagerLoad</param>
        /// <param name="offset">Offset hours</param>
        /// <returns>Celestial</returns>
        /// <example>
        /// The following example demonstrates how to create a fully populated Celestial object in local time
        /// using static functions using solar cycle only eager loading.
        /// <code>
        /// // Set EagerLoading parameters to only load solar cycle data for maximum efficiency
        /// EagerLoad el = new EagerLoad(EagerLoadType.Celestial);
        /// el.Extensions = new EagerLoad_Extensions(EagerLoad_ExtensionsType.Solar_Cycle);
        ///
        /// //Get Celestial data at N 39, W 72 on 19-Mar-2019 10:10:12 Local using Pacific Standard Time offset in hours (-7)
        /// Celestial cel = Celestial.CalculateCelestialTimes(39, -72, new DateTime(2019, 3, 19, 10, 10, 12), el, -7);
        /// Console.WriteLine(cel.SunRise); //03:54:50 AM
        ///
        /// </code>
        /// </example>
        public static Celestial CalculateCelestialTimes(double lat, double longi, DateTime date, EagerLoad el, double offset)
        {
            Celestial c = new Celestial(lat, longi, date, offset, el);

            return(c);
        }
コード例 #20
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 CoordinatePart cp)
        {
            //Turn of eagerload for efficiency
            EagerLoad eg   = new EagerLoad();
            int       type = 0; //0 = unspecifed, 1 = lat, 2 = long;

            eg.Cartesian = false;
            eg.Celestial = false;
            eg.UTM_MGRS  = false;
            cp           = null;
            Coordinate c = new Coordinate(eg);
            string     s = coordString;

            s = s.Trim(); //Trim all spaces before and after string
            double[] d;

            if (s[0] == ',')
            {
                type = 2;
                s    = s.Replace(",", "");
                s    = s.Trim();
            }
            if (s[0] == '*')
            {
                type = 1;
                s    = s.Replace("*", "");
                s    = s.Trim();
            }

            if (TrySignedDegree(s, type, out d))
            {
                try
                {
                    switch (type)
                    {
                    case 0:
                        //Attempt Lat first (default for signed)
                        try
                        {
                            cp             = new CoordinatePart(d[0], CoordinateType.Lat);
                            c.Parse_Format = Parse_Format_Type.Signed_Degree;
                            return(true);
                        }
                        catch
                        {
                            cp             = new CoordinatePart(d[0], CoordinateType.Long);
                            c.Parse_Format = Parse_Format_Type.Signed_Degree;
                            return(true);
                        }

                    case 1:
                        //Attempt Lat
                        cp             = new CoordinatePart(d[0], CoordinateType.Lat);
                        c.Parse_Format = Parse_Format_Type.Signed_Degree;
                        return(true);

                    case 2:
                        //Attempt long
                        cp             = new CoordinatePart(d[0], CoordinateType.Long);
                        c.Parse_Format = Parse_Format_Type.Signed_Degree;
                        return(true);
                    }
                }
                catch
                {
                    //silent fail
                }
            }
            //SIGNED DEGREE FAILED, REMOVE DASHES FOR OTHER FORMATS
            s = s.Replace("-", " ");

            //All other formats should contain 1 letter.
            if (Regex.Matches(s, @"[a-zA-Z]").Count != 1)
            {
                return(false);
            }                                                               //Should only contain 1 letter.
            //Get Coord Direction
            int direction = Find_Position(s);

            if (direction == -1)
            {
                return(false); //No direction found
            }
            //If Coordinate type int specified, look for mismatch
            if (type == 1 && (direction == 1 || direction == 3))
            {
                return(false); //mismatch
            }
            if (type == 2 && (direction == 0 || direction == 2))
            {
                return(false); //mismatch
            }
            CoordinateType t;

            if (direction == 0 || direction == 2)
            {
                t = CoordinateType.Lat;
            }
            else
            {
                t = CoordinateType.Long;
            }

            s = Regex.Replace(s, "[^0-9. ]", ""); //Remove directional character
            s = s.Trim();                         //Trim all spaces before and after string

            //Try Decimal Degree with Direction
            if (TryDecimalDegree(s, direction, out d))
            {
                try
                {
                    cp             = new CoordinatePart(d[0], t);
                    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  Degree
                    //1  Minute
                    //2  Direction (0 = N, 1 = E, 2 = S, 3 = W)
                    cp             = new CoordinatePart((int)d[0], d[1], (CoordinatesPosition)direction);
                    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 Degree
                    //1 Minute
                    //2 Second
                    //3 Direction (0 = N, 1 = E, 2 = S, 3 = W)
                    cp             = new CoordinatePart((int)d[0], (int)d[1], d[2], (CoordinatesPosition)direction);
                    c.Parse_Format = Parse_Format_Type.Degree_Minute_Second;
                    return(true);
                }
                catch
                {//Parser failed try next method
                }
            }

            return(false);
        }
コード例 #21
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);
        }
コード例 #22
0
ファイル: SunCalculations.cs プロジェクト: Punchcards/Sphere
        public static void CalculateSunTime(double lat, double longi, DateTime date, Celestial c, EagerLoad el, double offset)
        {
            if (date.Year == 0001)
            {
                return;
            }                                  //Return if date value hasn't been established.
            if (el.Extensions.Solar_Cycle)
            {
                DateTime actualDate = new DateTime(date.Year, date.Month, date.Day, 0, 0, 0, DateTimeKind.Utc);

                ////Sun Time Calculations
                //Get solar coordinate info and feed
                //Get Julian
                double lw  = rad * -longi;
                double phi = rad * lat;

                //Rise Set
                DateTime?[] evDate = Get_Event_Time(lw, phi, -.8333, actualDate, offset, true); //ADDED OFFSET TO ALL Get_Event_Time calls.

                c.sunRise   = evDate[0];
                c.sunSet    = evDate[1];
                c.solarNoon = evDate[2];

                c.sunCondition = CelestialStatus.RiseAndSet;

                //Get Solar Coordinate
                var celC = Get_Solar_Coordinates(date, -offset);
                c.solarCoordinates = celC;
                //Azimuth and Altitude
                CalculateSunAngle(date.AddHours(-offset), longi, lat, c, celC); //SUBTRACT OFFSET TO CALC IN Z TIME AND ADJUST SUN ANGLE DURING LOCAL CALCULATIONS.
                // neither sunrise nor sunset
                if ((!c.SunRise.HasValue) && (!c.SunSet.HasValue))
                {
                    if (c.SunAltitude < 0)
                    {
                        c.sunCondition = CelestialStatus.DownAllDay;
                    }
                    else
                    {
                        c.sunCondition = CelestialStatus.UpAllDay;
                    }
                }
                // sunrise or sunset
                else
                {
                    if (!c.SunRise.HasValue)
                    {
                        // No sunrise this date
                        c.sunCondition = CelestialStatus.NoRise;
                    }
                    else if (!c.SunSet.HasValue)
                    {
                        // No sunset this date
                        c.sunCondition = CelestialStatus.NoSet;
                    }
                }
                //Additional Times
                c.additionalSolarTimes = new AdditionalSolarTimes();
                //Dusk and Dawn
                //Civil
                evDate = Get_Event_Time(lw, phi, -6, actualDate, offset, false);
                c.AdditionalSolarTimes.civilDawn = evDate[0];
                c.AdditionalSolarTimes.civilDusk = evDate[1];


                //Nautical
                evDate = Get_Event_Time(lw, phi, -12, actualDate, offset, false);
                c.AdditionalSolarTimes.nauticalDawn = evDate[0];
                c.AdditionalSolarTimes.nauticalDusk = evDate[1];

                //Astronomical
                evDate = Get_Event_Time(lw, phi, -18, actualDate, offset, false);

                c.AdditionalSolarTimes.astronomicalDawn = evDate[0];
                c.AdditionalSolarTimes.astronomicalDusk = evDate[1];

                //BottomDisc
                evDate = Get_Event_Time(lw, phi, -.2998, actualDate, offset, false);
                c.AdditionalSolarTimes.sunriseBottomDisc = evDate[0];
                c.AdditionalSolarTimes.sunsetBottomDisc  = evDate[1];
            }
            if (el.Extensions.Solstice_Equinox)
            {
                Calculate_Soltices_Equinoxes(date, c, offset);
            }
            if (el.Extensions.Solar_Eclipse)
            {
                CalculateSolarEclipse(date, lat, longi, c);
            }
        }
コード例 #23
0
        /// <summary>
        /// Calculates all celestial data. Coordinates will notify as changes occur
        /// </summary>
        /// <param name="lat">Decimal format latitude</param>
        /// <param name="longi">Decimal format longitude</param>
        /// <param name="date">Geographic DateTime</param>
        /// <param name="el">EagerLoading Info for Auto-Calculations</param>
        /// <param name="offset">UTC offset in hours</param>
        internal void CalculateCelestialTime(double lat, double longi, DateTime date, EagerLoad el, double offset)
        {
            if (offset < -12 || offset > 12)
            {
                throw new ArgumentOutOfRangeException("Time offsets cannot be greater than 12 or less than -12.");
            }

            date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);

            if (el.Extensions.Solar_Cycle || el.Extensions.Solar_Eclipse)
            {
                SunCalc.CalculateSunTime(lat, longi, date, this, el, offset);
            }
            if (el.Extensions.Lunar_Cycle)
            {
                MoonCalc.GetMoonTimes(date, lat, longi, this, offset);
                MoonCalc.GetMoonDistance(date, this, offset);


                perigee = MoonCalc.GetPerigeeEvents(date);
                apogee  = MoonCalc.GetApogeeEvents(date);

                //Shift perigee / apogee is working outside UTC
                if (offset != 0)
                {
                    perigee.ConvertTo_Local_Time(offset);
                    apogee.ConvertTo_Local_Time(offset);
                }
            }

            if (el.Extensions.Lunar_Cycle || el.Extensions.Zodiac || el.Extensions.Lunar_Eclipse)
            {
                MoonCalc.GetMoonIllumination(date, this, lat, longi, el, offset);
            }

            if (el.Extensions.Zodiac)
            {
                SunCalc.CalculateZodiacSign(date, this);
                MoonCalc.GetMoonSign(date, this);
            }

            if (el.Extensions.Lunar_Cycle || el.Extensions.Solar_Cycle)
            {
                Calculate_Celestial_IsUp_Booleans(date, this);
            }

            //Shift eclipses if eagerloaded and offset is not 0
            if (el.Extensions.Lunar_Eclipse && offset != 0)
            {
                lunarEclipse.ConvertTo_LocalTime(offset);
            }
            if (el.Extensions.Solar_Eclipse && offset != 0)
            {
                solarEclipse.ConvertTo_LocalTime(offset);
            }
        }
コード例 #24
0
        /// <summary>
        /// Attempts to parse a string into a Coordinate with specified DateTime
        /// </summary>
        /// <param name="value">Coordinate string</param>
        /// <param name="geoDate">GeoDate</param>
        /// <param name="coordinate">Coordinate</param>
        /// <param name="cartesianType">Cartesian Type</param>
        /// <returns>boolean</returns>
        /// <example>
        /// The following example parses an ECEF formatted coordinate string, with an included GeoDate.
        /// Because this is an ECEF Cartesian type coordinate, we will specify the Cartesian system type.
        /// <code>
        /// Coordinate c;
        /// if(Coordinate.TryParse("5242.097 km, 2444.43 km, 2679.074 km", new DateTime(2018,7,7), CartesianType.ECEF, out c))
        /// {
        ///     Console.WriteLine(c); //N 24º 59' 59.987" E 25º 0' 0.001"
        /// }
        /// </code>
        /// </example>
        public static bool TryParse(string value, DateTime geoDate, CartesianType cartesianType, out Coordinate coordinate)
        {
            var eagerLoad = new EagerLoad();

            return(TryParse(value, geoDate, cartesianType, eagerLoad, out coordinate));
        }
コード例 #25
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, 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
                    }
                }

                string[] um;
                //Try MGRS
                if (TryMGRS(s, out um) || TryMGRS_Polar(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);
                        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]);
                        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);
                        c.Parse_Format = Parse_Format_Type.UTM;
                        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
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //Parser exception has occurred
                Debug.WriteLine("PARSER EXCEPTION HANDLED: " + ex.ToString());
            }
            c = null;
            return(false);
        }
コード例 #26
0
        public static void GetMoonIllumination(DateTime date, Celestial c, double lat, double lng, EagerLoad el, double offset)
        {
            //Moon Illum must be done for both the Moon Name and Phase so either will trigger it to load
            if (el.Extensions.Lunar_Cycle || el.Extensions.Zodiac)
            {
                date    = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);
                offset *= -1;
                double julianOffset = offset * .04166667;

                SolarCoordinates s     = SunCalc.Get_Solar_Coordinates(date, offset);
                double           JDE   = JulianConversions.GetJulian(date) + julianOffset; //Get julian
                double           T     = (JDE - 2451545) / 36525;                          //Get dynamic time.
                double[]         LDMNF = Get_Moon_LDMNF(T);

                LunarCoordinates m = GetMoonCoords(LDMNF, T, JDE);

                double sdist = 149598000,
                       phi   = Math.Acos(Math.Sin(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) + Math.Cos(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians())),
                       inc   = Math.Atan2(sdist * Math.Sin(phi), 0 - sdist * Math.Cos(phi)),
                       angle = Math.Atan2(Math.Cos(s.declination.ToRadians()) * Math.Sin(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()), Math.Sin(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) -
                                          Math.Cos(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));


                MoonIllum mi = new MoonIllum();

                mi.Fraction = (1 + Math.Cos(inc)) / 2;
                mi.Phase    = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;
                mi.Angle    = angle;


                c.moonIllum = mi;

                string moonName = "";
                int    moonDate = 0;
                //GET PHASE NAME

                //CHECK MOON AT BEGINNING AT END OF DAY TO GET DAY PHASE
                DateTime dMon = new DateTime(date.Year, date.Month, 1);
                for (int x = 1; x <= date.Day; x++)
                {
                    DateTime nDate = new DateTime(dMon.Year, dMon.Month, x, 0, 0, 0, DateTimeKind.Utc);

                    s     = SunCalc.Get_Solar_Coordinates(date, offset);
                    JDE   = JulianConversions.GetJulian(nDate) + julianOffset; //Get julian
                    T     = (JDE - 2451545) / 36525;                           //Get dynamic time.
                    LDMNF = Get_Moon_LDMNF(T);
                    m     = GetMoonCoords(LDMNF, T, JDE);

                    phi   = Math.Acos(Math.Sin(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) + Math.Cos(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));
                    inc   = Math.Atan2(sdist * Math.Sin(phi), 0 - sdist * Math.Cos(phi));
                    angle = Math.Atan2(Math.Cos(s.declination.ToRadians()) * Math.Sin(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()), Math.Sin(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) -
                                       Math.Cos(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));

                    double startPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;

                    nDate = new DateTime(dMon.Year, dMon.Month, x, 23, 59, 59, DateTimeKind.Utc);

                    s     = SunCalc.Get_Solar_Coordinates(date, offset);
                    JDE   = JulianConversions.GetJulian(nDate) + julianOffset; //Get julian
                    T     = (JDE - 2451545) / 36525;                           //Get dynamic time.
                    LDMNF = Get_Moon_LDMNF(T);
                    m     = GetMoonCoords(LDMNF, T, JDE);

                    phi   = Math.Acos(Math.Sin(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) + Math.Cos(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));
                    inc   = Math.Atan2(sdist * Math.Sin(phi), 0 - sdist * Math.Cos(phi));
                    angle = Math.Atan2(Math.Cos(s.declination.ToRadians()) * Math.Sin(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()), Math.Sin(s.declination.ToRadians()) * Math.Cos(m.declination.ToRadians()) -
                                       Math.Cos(s.declination.ToRadians()) * Math.Sin(m.declination.ToRadians()) * Math.Cos(s.rightAscension.ToRadians() - m.rightAscension.ToRadians()));

                    double endPhase = 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI;
                    //Determine Moon Name.
                    if (startPhase <= .5 && endPhase >= .5)
                    {
                        moonDate = x;
                        moonName = GetMoonName(dMon.Month, moonName);
                    }
                    //Get Moon Name (month, string);
                    //Get Moon Phase Name
                    if (date.Day == x)
                    {
                        if (startPhase > endPhase)
                        {
                            mi.PhaseName = "New Moon";
                            break;
                        }
                        if (startPhase <= .25 && endPhase >= .25)
                        {
                            mi.PhaseName = "First Quarter";
                            break;
                        }
                        if (startPhase <= .5 && endPhase >= .5)
                        {
                            mi.PhaseName = "Full Moon";
                            break;
                        }
                        if (startPhase <= .75 && endPhase >= .75)
                        {
                            mi.PhaseName = "Last Quarter";
                            break;
                        }

                        if (startPhase > 0 && startPhase < .25 && endPhase > 0 && endPhase < .25)
                        {
                            mi.PhaseName = "Waxing Crescent";
                            break;
                        }
                        if (startPhase > .25 && startPhase < .5 && endPhase > .25 && endPhase < .5)
                        {
                            mi.PhaseName = "Waxing Gibbous";
                            break;
                        }
                        if (startPhase > .5 && startPhase < .75 && endPhase > .5 && endPhase < .75)
                        {
                            mi.PhaseName = "Waning Gibbous";
                            break;
                        }
                        if (startPhase > .75 && startPhase < 1 && endPhase > .75 && endPhase < 1)
                        {
                            mi.PhaseName = "Waning Crescent";
                            break;
                        }
                    }
                }
                if (date.Day == moonDate)
                {
                    if (el.Extensions.Zodiac)
                    {
                        c.AstrologicalSigns.moonName = moonName;
                    }
                }
                else
                {
                    if (el.Extensions.Zodiac)
                    {
                        c.AstrologicalSigns.moonName = "";
                    }
                }
            }
            if (el.Extensions.Lunar_Eclipse)
            {
                CalculateLunarEclipse(date, lat, lng, c);
            }
        }
コード例 #27
0
        /// <summary>
        /// Calculates all celestial data. Coordinates will notify as changes occur
        /// </summary>
        /// <param name="lat">Decimal format latitude</param>
        /// <param name="longi">Decimal format longitude</param>
        /// <param name="date">Geographic DateTime</param>
        /// <param name="el">EagerLoading Info for Auto-Calculations</param>
        internal void CalculateCelestialTime(double lat, double longi, DateTime date, EagerLoad el)
        {
            date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);


            SunCalc.CalculateSunTime(lat, longi, date, this, el);


            if (el.Extensions.Lunar_Cycle)
            {
                MoonCalc.GetMoonTimes(date, lat, longi, this);
                MoonCalc.GetMoonDistance(date, this);


                perigee = MoonCalc.GetPerigeeEvents(date);
                apogee  = MoonCalc.GetApogeeEvents(date);
            }
            MoonCalc.GetMoonIllumination(date, this, lat, longi, el);

            if (el.Extensions.Zodiac)
            {
                SunCalc.CalculateZodiacSign(date, this);
                MoonCalc.GetMoonSign(date, this);
            }

            Calculate_Celestial_IsUp_Booleans(date, this);
        }
コード例 #28
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);
        }
コード例 #29
0
ファイル: UPS.cs プロジェクト: Punchcards/Sphere
        public static Coordinate UPS_To_Geodetic(UniversalTransverseMercator utm, EagerLoad el)
        {
            //INTERNATIONAL ELLIPSOID
            double f = 1 / utm.Inverse_Flattening; //Flattening (convert from Inverse that CoordinateSharp works in)
            double a = utm.Equatorial_Radius;      //Semi-Major Axis
            double b = a * (1 - f);                //Semi Minor Axis a(1-f)


            double E2 = (2 * f) - Math.Pow(f, 2); //Eccentricity Squared
            double E  = Math.Sqrt(E2);            //Eccentricity

            //CONVERT BACK
            double x = utm.Easting;
            double y = utm.Northing;

            //STEP 1
            double Xps = (x - 2000000) / .994;

            double Yps = (y - 2000000) / .994; // 001116144;

            double tPS = Yps;                  //Used for true longi calcs.

            if (Yps == 0)
            {
                Yps = 1;
            }

            //STEP 2
            //ATAN = ARCTAN

            bool southernHemi = true;

            if (utm.LatZone.ToUpper() == "Z" || utm.LatZone.ToUpper() == "Y")
            {
                southernHemi = false;
            }

            double longRad;
            double longRadForCalcs; //USED FOR LAT CALCS. LongRad is will LongRad. This is needed to due exact 90 issues.

            if (southernHemi)
            {
                longRad         = Math.PI + Math.Atan(Xps / tPS);
                longRadForCalcs = Math.PI + Math.Atan(Xps / Yps);
            }
            else
            {
                longRad         = Math.PI - Math.Atan(Xps / tPS);
                longRadForCalcs = Math.PI - Math.Atan(Xps / Yps);
            }

            //STEP 3
            double K = (2 * Math.Pow(a, 2) / b) * Math.Pow(((1 - E) / (1 + E)), (E / 2));


            //STEP 4
            double absYps = Math.Abs(Yps);
            double kCos   = K * Math.Abs(Math.Cos(longRadForCalcs));
            double q      = Math.Log(absYps / kCos) / Math.Log(Math.E) * -1;

            //STEP 5
            double estLat = 2 * Math.Atan(Math.Pow(Math.E, q)) - (Math.PI / 2);


            double lat = 0;

            while (Math.Abs(estLat - lat) > .0000001)
            {
                if (double.IsInfinity(estLat))
                {
                    break;
                }
                lat = estLat;
                //STEP 6
                double bracket = (1 + Math.Sin(estLat)) / (1 - Math.Sin(estLat)) * Math.Pow((1 - E * Math.Sin(estLat)) / (1 + E * Math.Sin(estLat)), E);
                double fLat    = -q + 1 / 2.0 * Math.Log(bracket);
                double fLat2   = (1 - Math.Pow(E, 2)) / ((1 - Math.Pow(E, 2) * Math.Pow(Math.Sin(estLat), 2)) * Math.Cos(estLat));

                //STEP 7
                estLat = estLat - fLat / fLat2;
            }
            if (!double.IsInfinity(estLat))
            {
                lat = estLat;
            }

            //NaN signals poles
            double latDeg;

            if (double.IsNaN(lat))
            {
                latDeg = 90;
            }
            else
            {
                latDeg = lat * (180 / Math.PI); //Radians to Degrees
            }
            if (southernHemi)
            {
                latDeg *= -1;
            }


            double longDeg;

            if (double.IsNaN(longRad))
            {
                longDeg = 0;
            }
            else
            {
                longDeg = (longRad) * (180 / Math.PI);
            }
            if (utm.Easting < 2000000)
            {
                longDeg  = 180 - longDeg % 180; //Normalize to 180 degrees
                longDeg *= -1;                  //Set Western Hemi
            }

            else if (longDeg > 180)
            {
                longDeg -= 180;
            }
            else if (longDeg < -180)
            {
                longDeg += 180;
            }

            if (utm.Northing >= 2000000 && Xps == 0 && southernHemi)
            {
                longDeg = 0;
            }                                                                         // SET TO 0 or it will equate to 180
            if (utm.Northing < 2000000 && Xps == 0 && !southernHemi)
            {
                longDeg = 0;
            }                                                                        // SET TO 0 or it will equate to 180
            return(new Coordinate(latDeg, longDeg, el));
        }
コード例 #30
0
        private Coordinate ClosestPointOnSegment(Point a, Point b, Coordinate p, DateTime dt, EagerLoad eg)
        {
            var d = new Point
            {
                Longitude = b.Longitude - a.Longitude,
                Latitude  = b.Latitude - a.Latitude,
            };

            double number = (p.Longitude.ToDouble() - a.Longitude) * d.Longitude + (p.Latitude.ToDouble() - a.Latitude) * d.Latitude;

            if (number <= 0.0)
            {
                return(new Coordinate(a.Latitude, a.Longitude, dt, eg));
            }

            double denom = d.Longitude * d.Longitude + d.Latitude * d.Latitude;

            if (number >= denom)
            {
                return(new Coordinate(b.Latitude, b.Longitude, dt, eg));
            }

            return(new Coordinate(a.Latitude + (number / denom) * d.Latitude, a.Longitude + (number / denom) * d.Longitude, dt, eg));
        }