From 9564497f991f7f1b8c6ff6d49d20aee04adc571d Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Thu, 13 Apr 2017 10:32:00 +0200 Subject: [PATCH] Fix inversive search --- .../osmand/search/core/SearchCoreFactory.java | 73 +++++++------------ .../net/osmand/search/core/SearchPhrase.java | 66 ++++++++++++++++- .../net/osmand/search/core/SearchResult.java | 3 + 3 files changed, 93 insertions(+), 49 deletions(-) diff --git a/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java index 003cea47f5..6c44d40136 100644 --- a/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java +++ b/OsmAnd-java/src/net/osmand/search/core/SearchCoreFactory.java @@ -135,6 +135,8 @@ public class SearchCoreFactory { if(!res.firstUnknownWordMatches) { ws.add(phrase.getUnknownSearchWord()); } + // publish result to set parentSearchResult before search + resultMatcher.publish(res); if (!ws.isEmpty() && api != null && api.isSearchAvailable(phrase)) { SearchPhrase nphrase = phrase.selectWord(res, ws, phrase.isLastUnknownSearchWordComplete()); @@ -143,9 +145,9 @@ public class SearchCoreFactory { api.search(nphrase, resultMatcher); resultMatcher.setParentSearchResult(prev); } - if (resultMatcher.getCount() == cnt) { - resultMatcher.publish(res); - } +// if (resultMatcher.getCount() == cnt) { +// resultMatcher.publish(res); +// } } } @@ -428,40 +430,8 @@ public class SearchCoreFactory { }; Iterator offlineIterator = phrase.getRadiusOfflineIndexes(DEFAULT_ADDRESS_BBOX_RADIUS * 5, SearchPhraseDataType.ADDRESS); - List unknownSearchWords = phrase.getUnknownSearchWords(); - - String wordToSearch = ""; - if (phrase.getUnknownSearchWordLength() > 1) { - List searchWords = new ArrayList<>(unknownSearchWords); - searchWords.add(0, phrase.getUnknownSearchWord()); - Collections.sort(searchWords, new Comparator() { - - private int lengthWithoutNumbers(String s) { - int len = 0; - for(int k = 0; k < s.length(); k++) { - if(s.charAt(k) >= '0' && s.charAt(k) <= '9') { - - } else { - len++; - } - } - return len; - } - - @Override - public int compare(String o1, String o2) { - int i1 = CommonWords.getCommonSearch(o1); - int i2 = CommonWords.getCommonSearch(o2); - if (i1 != i2) { - return icompare(i1, i2); - } - // compare length without numbers to not include house numbers - return -icompare(lengthWithoutNumbers(o1), lengthWithoutNumbers(o2)); - } - }); - wordToSearch = searchWords.get(0); - } + String wordToSearch = phrase.getUnknownWordToSearch(); while (offlineIterator.hasNext() && wordToSearch.length() > 0) { BinaryMapIndexReader r = offlineIterator.next(); currentFile[0] = r; @@ -475,7 +445,9 @@ public class SearchCoreFactory { } r.searchAddressDataByName(req); for (SearchResult res : immediateResults) { - res.firstUnknownWordMatches = wordToSearch.equals(phrase.getUnknownSearchWord()); + res.firstUnknownWordMatches = wordToSearch.equals(phrase.getUnknownSearchWord()) || + phrase.getNameStringMatcher().matches(res.localeName) || + phrase.getNameStringMatcher().matches(res.otherNames); if (res.objectType == ObjectType.STREET) { City ct = ((Street) res.object).getCity(); phrase.countUnknownWordsMatch(res, @@ -879,10 +851,13 @@ public class SearchCoreFactory { sw.getResult().file.preloadStreets(c, null); } int limit = 0; - NameStringMatcher nm = phrase.getNameStringMatcher(); + String wordToSearch = phrase.getUnknownWordToSearch(); + boolean firstUnknownWordMatches = wordToSearch.equals(phrase.getUnknownSearchWord()); + NameStringMatcher nm = phrase.getNameStringMatcher(wordToSearch, phrase.isUnknownSearchWordComplete()); for (Street object : c.getStreets()) { SearchResult res = new SearchResult(phrase); + res.localeName = object.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate()); res.otherNames = object.getAllNames(true); if (object.getName().startsWith("<")) { @@ -893,6 +868,9 @@ public class SearchCoreFactory { && !(nm.matches(res.localeName) || nm.matches(res.otherNames))) { continue; } + res.firstUnknownWordMatches = firstUnknownWordMatches || + phrase.getNameStringMatcher().matches(res.localeName) || + phrase.getNameStringMatcher().matches(res.otherNames); res.localeRelatedObjectName = c.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate()); res.object = object; res.preferredZoom = 17; @@ -969,8 +947,7 @@ public class SearchCoreFactory { if (s != null) { BinaryMapIndexReader file = phrase.getLastSelectedWord().getResult().file; - String lw = phrase.getUnknownSearchWord(); - NameStringMatcher sm = phrase.getNameStringMatcher(); + if (cacheBuilding != s) { cacheBuilding = s; SearchRequest sr = BinaryMapIndexReader @@ -1001,10 +978,12 @@ public class SearchCoreFactory { } }); } + String lw = phrase.getUnknownWordToSearchBuilding(); + NameStringMatcher buildingMatch = phrase.getNameStringMatcher(lw, phrase.isLastUnknownSearchWordComplete()); for (Building b : s.getBuildings()) { SearchResult res = new SearchResult(phrase); boolean interpolation = b.belongsToInterpolation(lw); - if ((!sm.matches(b.getName()) && !interpolation) + if ((!buildingMatch.matches(b.getName()) && !interpolation) || !phrase.isSearchTypeAllowed(ObjectType.HOUSE)) { continue; } @@ -1026,10 +1005,14 @@ public class SearchCoreFactory { res.preferredZoom = 17; resultMatcher.publish(res); } - if (Algorithms.isEmpty(lw) || !Character.isDigit(lw.charAt(0))) { + String streetIntersection = phrase.getUnknownWordToSearch(); + NameStringMatcher streetMatch = phrase.getNameStringMatcher(streetIntersection, phrase.isLastUnknownSearchWordComplete()); + if (Algorithms.isEmpty(streetIntersection) || + (!Character.isDigit(streetIntersection.charAt(0)) && + CommonWords.getCommonSearch(streetIntersection) == -1) ) { for (Street street : s.getIntersectedStreets()) { SearchResult res = new SearchResult(phrase); - if ((!sm.matches(street.getName()) && !sm.matches(street.getAllNames(true))) + if ((!streetMatch.matches(street.getName()) && !streetMatch.matches(street.getAllNames(true))) || !phrase.isSearchTypeAllowed(ObjectType.STREET_INTERSECTION)) { continue; } @@ -1448,7 +1431,5 @@ public class SearchCoreFactory { } } - public static int icompare(int x, int y) { - return (x < y) ? -1 : ((x == y) ? 0 : 1); - } + } diff --git a/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java b/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java index 1d7995d7b6..31b66511a6 100644 --- a/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java +++ b/OsmAnd-java/src/net/osmand/search/core/SearchPhrase.java @@ -5,6 +5,7 @@ import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.StringMatcher; import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.binary.CommonWords; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.data.LatLon; import net.osmand.data.QuadRect; @@ -421,11 +422,16 @@ public class SearchPhrase { if(sm != null) { return sm; } - sm = new NameStringMatcher(unknownSearchWordTrim, - (lastUnknownSearchWordComplete ? + sm = getNameStringMatcher(unknownSearchWordTrim, lastUnknownSearchWordComplete); + return sm; + } + + + public NameStringMatcher getNameStringMatcher(String word, boolean complete) { + return new NameStringMatcher(word, + (complete ? StringMatcherMode.CHECK_EQUALS_FROM_SPACE : StringMatcherMode.CHECK_STARTS_FROM_SPACE)); - return sm; } public boolean hasObjectType(ObjectType p) { @@ -613,5 +619,59 @@ public class SearchPhrase { return (1 << (getRadiusLevel() - 1)) * meters; } + public static int icompare(int x, int y) { + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } + + public String getUnknownWordToSearchBuilding() { + List unknownSearchWords = getUnknownSearchWords(); + if(unknownSearchWords.size() > 0 && Algorithms.extractFirstIntegerNumber(getUnknownSearchWord()) == 0) { + for(String wrd : unknownSearchWords) { + if(Algorithms.extractFirstIntegerNumber(wrd) != 0) { + return wrd; + } + } + } + return getUnknownSearchWord(); + } + + public String getUnknownWordToSearch() { + List unknownSearchWords = getUnknownSearchWords(); + + String wordToSearch = ""; + if (getUnknownSearchWordLength() > 1) { + List searchWords = new ArrayList<>(unknownSearchWords); + searchWords.add(0, getUnknownSearchWord()); + Collections.sort(searchWords, new Comparator() { + + private int lengthWithoutNumbers(String s) { + int len = 0; + for(int k = 0; k < s.length(); k++) { + if(s.charAt(k) >= '0' && s.charAt(k) <= '9') { + + } else { + len++; + } + } + return len; + } + + @Override + public int compare(String o1, String o2) { + int i1 = CommonWords.getCommonSearch(o1); + int i2 = CommonWords.getCommonSearch(o2); + if (i1 != i2) { + return icompare(i1, i2); + } + // compare length without numbers to not include house numbers + return -icompare(lengthWithoutNumbers(o1), lengthWithoutNumbers(o2)); + } + }); + wordToSearch = searchWords.get(0); + } + + return wordToSearch; + } + } diff --git a/OsmAnd-java/src/net/osmand/search/core/SearchResult.java b/OsmAnd-java/src/net/osmand/search/core/SearchResult.java index 447dd2529b..3bf7cfa995 100644 --- a/OsmAnd-java/src/net/osmand/search/core/SearchResult.java +++ b/OsmAnd-java/src/net/osmand/search/core/SearchResult.java @@ -35,6 +35,9 @@ public class SearchResult { if(otherWordsMatch != null) { inc += otherWordsMatch.size(); } + if(parentSearchResult != null) { + inc += parentSearchResult.getFoundWordCount(); + } return inc; }