public static MPObject GetItemWithMatchingUrl(string url, List <MPObject> listToSearch) { foreach (MPObject item in listToSearch) { if (item.URL == url) { return(item); } else { if (item is Area) { MPObject matchingRoute = (item as Area).Routes.Find(p => p.URL == url); if (matchingRoute != null) { return(matchingRoute); } else { MPObject matchingSubArea = GetItemWithMatchingUrl(url, (item as Area).SubAreas.Cast <MPObject>().ToList()); if (matchingSubArea != null) { return(matchingSubArea); } } } } } return(null); }
public SearchResult(MPObject singleResult) { FilteredResult = singleResult; AllResults = new List <MPObject> { singleResult }; }
/// <summary> /// Gets the parent for the child (ie Area that contains the object) /// </summary> /// <param name="child">The object of which to get the parent</param> /// <param name="parentLevel">The parent level. "0" is the highest parent, "1" is the next parent down, etc. "-1" will return the immediate parent</param> /// <returns>The parent object to the child. Will return null if the child has no parents or if the parentLevel is invalid</returns> public static MPObject GetParent(MPObject child, int parentLevel) { string url; if (parentLevel < 0 && Math.Abs(parentLevel) <= child.ParentUrls.Count) //"Negative indicies" { url = child.ParentUrls[child.ParentUrls.Count + parentLevel]; } else if (parentLevel <= child.ParentUrls.Count - 1) //Positive indicies (check for "within range") { url = child.ParentUrls[parentLevel]; } else //Out of range { return(null); } if (child.Parents.Count == 0) { return(GetItemWithMatchingUrl(url)); } else { return(child.Parents.Find(p => p.URL == url)); } }
/// <summary> /// Gets the outer parent (state for US, country for international) for a child /// </summary> /// <param name="child">The area or route of the parent to return</param> /// <returns></returns> public static MPObject GetOuterParent(MPObject child) { MPObject parent = GetParent(child, 0); //Get state that route/area is in if (parent?.URL == Utilities.GetSimpleURL(Utilities.INTERNATIONALURL)) //If this is international, get the country instead of the state (eg "China") { if (child.ParentIDs.Count > 3) { if (child.ParentIDs.Contains(Utilities.GetID(Utilities.AUSTRALIAURL))) //Australia is both a continent and a country so it is an exception { parent = GetParent(child, 1); } else { parent = GetParent(child, 2); } } else { parent = null; //Return null if "child" is an area like "China" (so we don't return a string like "China is located in Asia") } } return(parent); }
/// <summary> /// Gets the parent for the child (ie Area that contains the object) /// </summary> /// <param name="child">The object of which to get the parent</param> /// <param name="parentLevel">The parent level. "0" is the highest parent, "1" is the next parent down, etc. "-1" will return the immediate parent</param> /// <returns>The parent object to the child. Will return null if the child has no parents or if the parentLevel is invalid</returns> public static MPObject GetParent(MPObject child, int parentLevel) { string id; if (parentLevel < 0 && Math.Abs(parentLevel) <= child.ParentIDs.Count) //"Negative indicies" { id = child.ParentIDs[child.ParentIDs.Count + parentLevel]; } else if (parentLevel >= 0 && parentLevel <= child.ParentIDs.Count - 1) //Positive indicies (check for "within range") { id = child.ParentIDs[parentLevel]; } else //Out of range { return(null); } if (child.Parents.Count == 0) { return(GetItemWithMatchingID(id)); } else { return(child.Parents.Find(p => p.ID == id)); } }
public static MPObject GetItemWithMatchingID(string id, List <MPObject> listToSearch) { foreach (MPObject item in listToSearch) { if (item.ID == id) { return(item); } else { if (item is Area) { MPObject matchingRoute = (item as Area).Routes.Find(p => p.ID == id); if (matchingRoute != null) { return(matchingRoute); } else { MPObject matchingSubArea = GetItemWithMatchingID(id, (item as Area).SubAreas); if (matchingSubArea != null) { return(matchingSubArea); } } } } } return(null); }
public SearchResult(MPObject singleResult, Area relatedLocation = null) { FilteredResult = singleResult; AllResults = new List <MPObject> { singleResult }; RelatedLocation = relatedLocation; }
/// <summary> /// Gets the parent for the child (ie Area that contains the object) /// </summary> /// <param name="child">The object of which to get the parent</param> /// <param name="parentLevel">The parent level. "0" is the highest parent, "1" is the next parent down, etc. "-1" will return the immediate parent</param> /// <returns>The parent object to the child. Will return null if the child has no parents or if the parentLevel is invalid</returns> public static MPObject GetParent(MPObject child, int parentLevel) { string url; if (parentLevel < 0 && Math.Abs(parentLevel) <= child.ParentUrls.Count) //"Negative indicies" { url = child.ParentUrls[child.ParentUrls.Count + parentLevel]; } else if (parentLevel <= child.ParentUrls.Count - 1) //Positive indicies (check for "within range") { url = child.ParentUrls[parentLevel]; } else //Out of range { return(null); } return(GetItemWithMatchingUrl(url, DestAreas.Cast <MPObject>().ToList())); }
/// <summary> /// Gets the inner parent for a child /// </summary> /// <param name="child">The area or route of the parent to return</param> /// <returns></returns> public static MPObject GetInnerParent(MPObject child) { MPObject parent = null; if (child is Route) { parent = GetParent(child, -2); //Get the "second to last" parent https://github.com/derekantrican/MountainProject/issues/12 if (parent.URL == GetParent(child, 0).URL) { parent = GetParent(child, -1); } } else if (child is Area) { parent = GetParent(child, -1); //Get immediate parent } if (parent != null && parent.URL == Utilities.GetSimpleURL(Utilities.INTERNATIONALURL)) //If "child" is an area like "Europe" { parent = null; } return(parent); }
public static SearchResult Search(string queryText, SearchParameters searchParameters = null) { Console.WriteLine($" Getting info from MountainProject for \"{queryText}\""); Stopwatch searchStopwatch = Stopwatch.StartNew(); SearchResult searchResult; List <SearchResult> possibleResults = new List <SearchResult>(); List <Tuple <string, string> > possibleQueryAndLocationGroups = GetPossibleQueryAndLocationGroups(queryText, searchParameters); foreach (Tuple <string, string> group in possibleQueryAndLocationGroups) { string query = Utilities.FilterStringForMatch(group.Item1); string location = Utilities.FilterStringForMatch(group.Item2); List <MPObject> possibleMatches = DeepSearch(query, DestAreas); possibleMatches = FilterBySearchParameters(possibleMatches, searchParameters); MPObject filteredResult = null; SearchResult possibleResult = new SearchResult(); if (!string.IsNullOrEmpty(location)) { Dictionary <MPObject, Area> resultsWithLocations = GetMatchingResultLocationPairs(possibleMatches, location); filteredResult = DetermineBestMatch(resultsWithLocations.Keys.ToList(), group.Item1, searchParameters); if (filteredResult == null) { continue; } possibleResult = new SearchResult() { AllResults = resultsWithLocations.Keys.ToList(), FilteredResult = filteredResult, RelatedLocation = resultsWithLocations[filteredResult] }; } else { filteredResult = DetermineBestMatch(possibleMatches, group.Item1, searchParameters); if (filteredResult == null) { continue; } possibleResult = new SearchResult() { AllResults = possibleMatches, FilteredResult = filteredResult }; } if (!possibleResult.IsEmpty()) { possibleResults.Add(possibleResult); } } if (possibleResults.Count > 0) { searchResult = DetermineBestMatch(possibleResults, queryText, searchParameters); } else if (searchParameters != null && !string.IsNullOrEmpty(searchParameters.SpecificLocation)) { //If we used searchParameters to find a specific location, but couldn't find a match at that location, //we should return an empty result searchResult = new SearchResult(); } else { string filteredQuery = Utilities.FilterStringForMatch(queryText); List <MPObject> results = FilterBySearchParameters(DeepSearch(filteredQuery, DestAreas), searchParameters); MPObject filteredResult = DetermineBestMatch(results, queryText, searchParameters); searchResult = new SearchResult() { AllResults = results, FilteredResult = filteredResult }; } Console.WriteLine($" Found {searchResult.AllResults.Count} matching results from MountainProject in {searchStopwatch.ElapsedMilliseconds} ms"); searchResult.TimeTaken = searchStopwatch.Elapsed; return(searchResult); }
private static SearchResult DetermineBestMatch(List <SearchResult> searchResults, string searchQuery, SearchParameters searchParameters = null) { MPObject bestMatch = DetermineBestMatch(searchResults.Select(p => p.FilteredResult).ToList(), searchQuery, searchParameters); return(searchResults.Find(p => p.FilteredResult == bestMatch)); }
private static List <Area> ParentsInString(MPObject child, string inputString, bool allowStateAbbr = false, bool allowPartialParents = false, bool caseSensitive = false) { List <MPObject> matchedParents = new List <MPObject>(); List <string> possibleNames = GetPossibleRouteNames(inputString); foreach (Area parent in child.Parents) { List <string> parentWords = Utilities.GetWords(parent.Name); foreach (string possibleName in possibleNames) { List <string> possibleNameWords = Utilities.GetWords(possibleName); bool allMatchingWordsValid = possibleNameWords.All(possibleNameWord => { string containingParentWord = parentWords.Find(parentWord => Utilities.StringsEqualWithFilters(possibleNameWord, parentWord, !caseSensitive) /*|| Utilities.StringStartsWithFiltered(n, p)*/); return(containingParentWord != null); }); if (Utilities.StringContainsWithFilters(parent.Name, possibleName, !caseSensitive) && allMatchingWordsValid) { matchedParents.Add(parent); } else if (Utilities.AreaNicknames.ContainsKey(parent.ID) && possibleNameWords.Any(p => Regex.IsMatch(p, Utilities.AreaNicknames[parent.ID]))) { matchedParents.Add(parent); } } } if (allowStateAbbr) { foreach (MPObject parent in child.Parents) { if (Utilities.StatesWithAbbr.ContainsKey(parent.Name) && inputString.Contains(Utilities.StatesWithAbbr[parent.Name])) { matchedParents.Add(parent); } } } if (allowPartialParents) { foreach (MPObject parent in child.Parents) { if (caseSensitive) { List <string> parentWords = Utilities.GetWordGroups(Utilities.FilterStringForMatch(parent.Name, false), false); if (parentWords.Any(p => Utilities.FilterStringForMatch(inputString, false).Contains(p))) { matchedParents.Add(parent); } } else { List <string> parentWords = Utilities.GetWordGroups(Utilities.FilterStringForMatch(parent.Name.ToLower(), false), false); if (parentWords.Any(p => Utilities.FilterStringForMatch(inputString, false).ToLower().Contains(p))) { matchedParents.Add(parent); } } } } matchedParents = matchedParents.Distinct().ToList(); matchedParents = matchedParents.OrderByDescending(p => child.ParentIDs.IndexOf(p.ID)).ToList(); //Sort by closest to child return(matchedParents.Cast <Area>().ToList()); }