/// <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)); }