示例#1
0
        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);
        }
示例#2
0
 public SearchResult(MPObject singleResult)
 {
     FilteredResult = singleResult;
     AllResults     = new List <MPObject> {
         singleResult
     };
 }
示例#3
0
        /// <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));
            }
        }
示例#4
0
        /// <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);
        }
示例#5
0
        /// <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));
            }
        }
示例#6
0
        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;
 }
示例#8
0
        /// <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()));
        }
示例#9
0
        /// <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);
        }
示例#10
0
        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);
        }
示例#11
0
        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));
        }
示例#12
0
        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());
        }