namespace DynamicBibleUtility.Geolocation; /// /// An index of Bible location data by Strong's numbers. /// Strong's numbers tend to be more useful for lookups in the Dynamic Bible app /// due to how they're integrated into the rest of the app and can help more clearly /// define a particular location. /// This class maintains a simple lookup of Strong's numbers to location names /// in addition to a lookup that includes the full location data. /// public class BibleLocationIndexByStrongsNumbers { /// /// A mapping of Strong's numbers to normalized location names. /// A Strong's number may refer to multiple locations. /// public readonly IDictionary> StrongsNumberToLocationNameLookup = new Dictionary>(); /// /// A mapping of Strong's numbers to full location data (in JSON format). /// A Strong's number may refer to multiple locations. /// public readonly IDictionary> StrongsNumberToLocationLookup = new Dictionary>(); /// /// Creates the index from the provided locations. /// /// The locations to put in the index. /// Thrown if the locations are null. public BibleLocationIndexByStrongsNumbers(IEnumerable locations) { // INDEX THE LOCATIONS BY STRONG'S NUMBERS. foreach (var location in locations) { // DON'T INDEX THE LOCATION IF IT HAS GEOGRAPHIC COORDINATES. // The information currently isn't useful without these coordinates. if (!location.HasGeographicCoordinates) { continue; } // DON'T INDEX THE LOCATION IF IT DOESN'T HAVE ANY STRONG'S NUMBERS. var location_has_strongs_numbers = location.StrongsNumbers.Any(); if (!location_has_strongs_numbers) { continue; } // INDEX THE LOCATION BY STRONG'S NUMBERS. foreach (var strongs_number in location.StrongsNumbers) { // MAKE SURE EXISTING COLLECTIONS EXIST FOR THE STRONG'S NUMBER. var strongs_number_exists_in_index = StrongsNumberToLocationLookup.ContainsKey(strongs_number); if (!strongs_number_exists_in_index) { StrongsNumberToLocationNameLookup[strongs_number] = []; StrongsNumberToLocationLookup[strongs_number] = []; } // CONVERT THE LOCATION TO JSON FORMAT. // Since the location data needs to be converted to JSON in different // scenarios with different properties serialized, there's not an easy // way to simply mark which fields should/shouldn't be serialized in // all situations. While a custom JSON converter could be used, // creating a dynamic object here seemed simpler. In this scenario, // the Strong's number doesn't need to be included in the member data // since it already serves as the key in the lookup. dynamic converted_location = new { name = location.Name, lat = location.Latitude, lon = location.Longitude, vss = location.VerseReferenceStrings, }; // INDEX THE LOCATION BY STRONG'S NUMBER. // Indices with just the location name and full location data are maintained. StrongsNumberToLocationNameLookup[strongs_number].Add(location.Name); StrongsNumberToLocationLookup[strongs_number].Add(converted_location); } } } }