Beispiel #1
0
        /// <summary>
        /// Searches for geographical locations synchronously.
        /// </summary>
        /// <param name="searchString">String to search</param>
        /// <returns>List of location items matching the specified search string</returns>
        private List <LocationSearchItem> Search(string searchString)
        {
            if (searchString.Length == 0)
            {
                return(new List <LocationSearchItem>());
            }

            return(_LocationsManager.Search(searchString, 10).Select(c => new LocationSearchItem()
            {
                Country = c.CountryCode,
                Location = c,
                Name = c.LocationName,
                Names = string.Join(", ", c.OtherNames)
            }).ToList());
        }
        /// <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));
        }