Exemplo n.º 1
0
 /// <inheritdoc/>
 public ICollection <SolarEclipseLocalCircumstances> FindLocalCircumstancesForCities(PolynomialBesselianElements be, ICollection <CrdsGeographical> cities, CancellationToken?cancelToken = null, IProgress <double> progress = null)
 {
     return(cities
            .Distinct()
            .Select(c => SolarEclipses.LocalCircumstances(be, c))
            .ToArray());
 }
Exemplo n.º 2
0
        private ICollection <AstroEvent> FindSolarEclipses(AstroEventsContext context)
        {
            List <AstroEvent> events = new List <AstroEvent>();

            int ln = LunarEphem.Lunation(context.From, LunationSystem.Meeus);

            do
            {
                SolarEclipse eclipse = GetNearestSolarEclipse(ln, next: true, saros: false);
                double       jd      = eclipse.JulianDayMaximum;
                if (jd <= context.To)
                {
                    var pbe       = GetBesselianElements(jd);
                    var localCirc = SolarEclipses.LocalCircumstances(pbe, context.GeoLocation);

                    string type            = Text.Get($"SolarEclipse.Type.{eclipse.EclipseType}");
                    string subtype         = eclipse.IsNonCentral ? $" {Text.Get("SolarEclipse.Type.NoCentral")}" : "";
                    string phase           = eclipse.EclipseType == SolarEclipseType.Partial ? $" ({Text.Get("SolarEclipse.MaxPhase")} {Formatters.Phase.Format(eclipse.Magnitude)})" : "";
                    double jdMax           = localCirc.MaxMagnitude > 0 ? localCirc.Maximum.JulianDay : jd;
                    string localVisibility = GetLocalVisibilityString(eclipse, localCirc);

                    events.Add(new AstroEvent(jdMax, Text.Get("SolarEclipse.Event", ("type", type), ("subtype", subtype), ("phase", phase), ("localVisibility", localVisibility)), sun, moon));
                    ln = eclipse.MeeusLunationNumber + 1;
                }
                else
                {
                    break;
                }
            }while (true);
            return(events);
        }
Exemplo n.º 3
0
        /// <inheritdoc/>
        public ICollection <SolarEclipseLocalCircumstances> FindCitiesOnCentralLine(PolynomialBesselianElements be, ICollection <CrdsGeographical> centralLine, CancellationToken?cancelToken = null, IProgress <double> progress = null)
        {
            var cities = new List <CrdsGeographical>();

            for (int i = 0; i < centralLine.Count - 1; i++)
            {
                // Report progess
                progress?.Report((double)(i + 1) / centralLine.Count * 100);

                // Exit loop if cancel requested
                if (cancelToken?.IsCancellationRequested == true)
                {
                    return(new SolarEclipseLocalCircumstances[0]);
                }

                // 2 successive points create a central line segment
                var g0 = centralLine.ElementAt(i);
                var g1 = centralLine.ElementAt(i + 1);

                // Segment length, distance between 2 points on central line, in kilometers
                var length = g0.DistanceTo(g1);

                // Local circumstances at point "g0"
                var local = SolarEclipses.LocalCircumstances(be, g0);

                // Lunar umbra radius, in kilometers
                float r  = (float)(local.PathWidth / 2);
                float r0 = r;
                if (r < 10)
                {
                    r = 10;
                }

                if (r > 0)
                {
                    // Count of parts the segment should be splitted
                    int parts = (int)Math.Round(length / r);

                    // If the segment should be splitted
                    if (parts > 1)
                    {
                        // Find intermediate points and add closest cities
                        for (int j = 0; j < parts; j++)
                        {
                            // Exit loop if cancel requested
                            if (cancelToken?.IsCancellationRequested == true)
                            {
                                return(new SolarEclipseLocalCircumstances[0]);
                            }

                            var g         = Angle.Intermediate(g0, g1, (float)j / parts);
                            var locations = locationsManager.Search(g, r);
                            cities.AddRange(locations.Where(loc => loc.DistanceTo(g) <= r0));
                        }
                    }
                    // The segment should not be splitted, add closest cities to the first point
                    else
                    {
                        var locations = locationsManager.Search(g0, r);
                        cities.AddRange(locations.Where(loc => loc.DistanceTo(g0) <= r0));
                    }
                }
            }

            return(FindLocalCircumstancesForCities(be, cities, cancelToken, progress));
        }