예제 #1
0
        public SunAndMoonData GetData(DateTime dt, double lat, double lng, double TimeZoneDifferenceFromUTC)
        {
            SunAndMoonData data = new SunAndMoonData();

            FindSunAndTwilightDataForDate(data, dt, TimeZoneDifferenceFromUTC, lng, lat);
            FindMoonRiseAndSet(data, dt, TimeZoneDifferenceFromUTC, lng, lat);

            TimeSpan ts = data.SunSet - data.SunRise;

            data.SolarNoon = data.SunRise.AddMilliseconds(ts.TotalMilliseconds / 2);

            return(data);
        }
예제 #2
0
        private string FindMoonRiseAndSet(SunAndMoonData data, DateTime dt, double tz, double glong, double glat)
        {
            //
            //	Im using a separate function for moonrise/set to allow for different tabulations
            //  of moonrise and sun events ie weekly for sun and daily for moon. The logic of
            //  the function is identical to find_sun_and_twi_events_for_date()
            //
            //alert(mjd);
            //alert(tz);
            //alert(glong);
            //alert(glat);

            double mjd = GetJulianDate(dt, 0);

            double sglong, sglat, sinho, cglat, date, ym, yz, utrise, utset, j;
            double yp, nz, hour, z1, z2, xe, ye, iobj, rads = 0.0174532925;

            bool rise, sett, above;

            double[] quadout = new double[4];
            //var sinho;
            string always_up   = " ****";
            string always_down = " ....";
            string outstring   = "";

            sinho  = Math.Sin(rads * 8 / 60);       //moonrise taken as centre of moon at +8 arcmin
            sglat  = Math.Sin(rads * glat);
            cglat  = Math.Cos(rads * glat);
            date   = mjd - tz / 24;
            rise   = false;
            sett   = false;
            above  = false;
            hour   = 1.0;
            utrise = 0;
            utset  = 0;
            ym     = sin_alt(1, date, hour - 1.0, glong, cglat, sglat) - sinho;
            if (ym > 0.0)
            {
                above = true;
            }
            while (hour < 25 && (sett == false || rise == false))
            {
                yz      = sin_alt(1, date, hour, glong, cglat, sglat) - sinho;
                yp      = sin_alt(1, date, hour + 1.0, glong, cglat, sglat) - sinho;
                quadout = quad(ym, yz, yp);
                nz      = quadout[0];
                z1      = quadout[1];
                z2      = quadout[2];
                xe      = quadout[3];
                ye      = quadout[4];

                // case when one event is found in the interval
                if (nz == 1)
                {
                    if (ym < 0.0)
                    {
                        utrise = hour + z1;
                        rise   = true;
                    }
                    else
                    {
                        utset = hour + z1;
                        sett  = true;
                    }
                } // end of nz = 1 case

                // case where two events are found in this interval
                // (rare but whole reason we are not using simple iteration)
                if (nz == 2)
                {
                    if (ye < 0.0)
                    {
                        utrise = hour + z2;
                        utset  = hour + z1;
                    }
                    else
                    {
                        utrise = hour + z1;
                        utset  = hour + z2;
                    }
                }

                // set up the next search interval
                ym    = yp;
                hour += 2.0;
            } // end of while loop

            data.MoonRise = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
            data.MoonSet  = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);

            if (rise == true || sett == true)
            {
                if (rise == true)
                {
                    outstring += " " + hrsmin(utrise);
                }
                else
                {
                    outstring += " No Rise";
                }
                if (sett == true)
                {
                    outstring += " " + hrsmin(utset);
                }
                else
                {
                    outstring += " No Set";
                }
            }
            else
            {
                if (above == true)
                {
                    outstring += "above";
                }
                else
                {
                    outstring += "below";
                }
            }
            return(outstring);
        }
예제 #3
0
        private string FindSunAndTwilightDataForDate(SunAndMoonData data, DateTime dt, double tz, double glong, double glat)
        {
            //
            //	this is my attempt to encapsulate most of the program in a function
            //	then this function can be generalised to find all the Sun events.
            //
            //
            double mjd = GetJulianDate(dt, 0);
            double sglong, sglat, cglat, date, ym, yz, utrise = 0, utset = 0;
            double yp, nz, hour, xe, ye, z1, z2, iobj, rads = 0.0174532925;

            bool rise, sett, above;

            double[] quadout     = new double[4];
            double[] sinho       = new double[4];
            string   always_up   = " ****";
            string   always_down = " ....";
            string   outstring   = "";

            //
            //	Set up the array with the 4 values of sinho needed for the 4
            //      kinds of sun event
            //
            sinho[0] = Math.Sin(rads * -0.833);     //sunset upper limb simple refraction
            sinho[1] = Math.Sin(rads * -6.0);       //civil twi
            sinho[2] = Math.Sin(rads * -12.0);      //nautical twi
            sinho[3] = Math.Sin(rads * -18.0);      //astro twi
            sglat    = Math.Sin(rads * glat);
            cglat    = Math.Cos(rads * glat);
            date     = mjd - tz / 24;
            //
            //	main loop takes each value of sinho in turn and finds the rise/set
            //      events associated with that altitude of the Sun
            //
            for (int j = 0; j < 4; j++)
            {
                rise  = false;
                sett  = false;
                above = false;
                hour  = 1.0;
                ym    = sin_alt(2, date, hour - 1.0, glong, cglat, sglat) - sinho[j];
                if (ym > 0.0)
                {
                    above = true;
                }
                //
                // the while loop finds the sin(alt) for sets of three consecutive
                // hours, and then tests for a single zero crossing in the interval
                // or for two zero crossings in an interval or for a grazing event
                // The flags rise and sett are set accordingly
                //
                nz = 0; z1 = 0; z2 = 0; xe = 0; ye = 0;
                while (hour < 25 && (sett == false || rise == false))
                {
                    yz      = sin_alt(2, date, hour, glong, cglat, sglat) - sinho[j];
                    yp      = sin_alt(2, date, hour + 1.0, glong, cglat, sglat) - sinho[j];
                    quadout = quad(ym, yz, yp);
                    nz      = quadout[0];
                    z1      = quadout[1];
                    z2      = quadout[2];
                    xe      = quadout[3];
                    ye      = quadout[4];

                    // case when one event is found in the interval
                    if (nz == 1)
                    {
                        if (ym < 0.0)
                        {
                            utrise = hour + z1;
                            rise   = true;
                        }
                        else
                        {
                            utset = hour + z1;
                            sett  = true;
                        }
                    } // end of nz = 1 case

                    // case where two events are found in this interval
                    // (rare but whole reason we are not using simple iteration)
                    if (nz == 2)
                    {
                        if (ye < 0.0)
                        {
                            utrise = hour + z2;
                            utset  = hour + z1;
                        }
                        else
                        {
                            utrise = hour + z1;
                            utset  = hour + z2;
                        }
                    } // end of nz = 2 case

                    // set up the next search interval
                    ym    = yp;
                    hour += 2.0;
                } // end of while loop
                  //
                  // now search has completed, we compile the string to pass back
                  // to the main loop. The string depends on several combinations
                  // of the above flag (always above or always below) and the rise
                  // and sett flags
                  //

                switch (j)
                {
                case 0:     // SunRise/SunSet
                            //data.XXX = z2.ToString();
                    data.SunRise = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    data.SunSet  = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    break;

                case 1:     // Civial Twilight
                    data.CivalTwilightStart = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    data.CivalTwilightEnd   = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    break;

                case 2:     // nautical Twilight
                    data.NauticalTwilightStart = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    data.NauticalTwilightEnd   = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    break;

                case 3:     // Astronomical Twilight
                    data.AstronomicalTwilightStart = ((rise == true || sett == true)) ? (rise == true) ? ConvertToDateTime(dt, utrise) : DateTime.MinValue : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    data.AstronomicalTwilightEnd   = ((rise == true || sett == true)) ? (sett == true) ? ConvertToDateTime(dt, utset) : DateTime.MinValue.AddDays(1) : (above == true) ? DateTime.MaxValue : DateTime.MaxValue.AddDays(-1);
                    break;
                }

                if (rise == true || sett == true)
                {
                    if (rise == true)
                    {
                        outstring += " " + hrsmin(utrise);
                    }
                    else
                    {
                        outstring += " No Rise";
                    }
                    if (sett == true)
                    {
                        outstring += " " + hrsmin(utset);
                    }
                    else
                    {
                        outstring += " No Set";
                    }
                }
                else
                {
                    if (above == true)
                    {
                        outstring += "above";
                    }
                    else
                    {
                        outstring += "below";
                    }
                }
            } // end of for loop - next condition

            return(outstring);
        }