Fix inversive search
This commit is contained in:
parent
b4f4ff8eaa
commit
9d3adfabc5
3 changed files with 93 additions and 49 deletions
|
@ -135,6 +135,8 @@ public class SearchCoreFactory {
|
||||||
if(!res.firstUnknownWordMatches) {
|
if(!res.firstUnknownWordMatches) {
|
||||||
ws.add(phrase.getUnknownSearchWord());
|
ws.add(phrase.getUnknownSearchWord());
|
||||||
}
|
}
|
||||||
|
// publish result to set parentSearchResult before search
|
||||||
|
resultMatcher.publish(res);
|
||||||
if (!ws.isEmpty() && api != null && api.isSearchAvailable(phrase)) {
|
if (!ws.isEmpty() && api != null && api.isSearchAvailable(phrase)) {
|
||||||
SearchPhrase nphrase = phrase.selectWord(res, ws,
|
SearchPhrase nphrase = phrase.selectWord(res, ws,
|
||||||
phrase.isLastUnknownSearchWordComplete());
|
phrase.isLastUnknownSearchWordComplete());
|
||||||
|
@ -143,9 +145,9 @@ public class SearchCoreFactory {
|
||||||
api.search(nphrase, resultMatcher);
|
api.search(nphrase, resultMatcher);
|
||||||
resultMatcher.setParentSearchResult(prev);
|
resultMatcher.setParentSearchResult(prev);
|
||||||
}
|
}
|
||||||
if (resultMatcher.getCount() == cnt) {
|
// if (resultMatcher.getCount() == cnt) {
|
||||||
resultMatcher.publish(res);
|
// resultMatcher.publish(res);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,40 +430,8 @@ public class SearchCoreFactory {
|
||||||
};
|
};
|
||||||
Iterator<BinaryMapIndexReader> offlineIterator = phrase.getRadiusOfflineIndexes(DEFAULT_ADDRESS_BBOX_RADIUS * 5,
|
Iterator<BinaryMapIndexReader> offlineIterator = phrase.getRadiusOfflineIndexes(DEFAULT_ADDRESS_BBOX_RADIUS * 5,
|
||||||
SearchPhraseDataType.ADDRESS);
|
SearchPhraseDataType.ADDRESS);
|
||||||
List<String> unknownSearchWords = phrase.getUnknownSearchWords();
|
|
||||||
|
|
||||||
String wordToSearch = "";
|
|
||||||
if (phrase.getUnknownSearchWordLength() > 1) {
|
|
||||||
List<String> searchWords = new ArrayList<>(unknownSearchWords);
|
|
||||||
searchWords.add(0, phrase.getUnknownSearchWord());
|
|
||||||
Collections.sort(searchWords, new Comparator<String>() {
|
|
||||||
|
|
||||||
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) {
|
while (offlineIterator.hasNext() && wordToSearch.length() > 0) {
|
||||||
BinaryMapIndexReader r = offlineIterator.next();
|
BinaryMapIndexReader r = offlineIterator.next();
|
||||||
currentFile[0] = r;
|
currentFile[0] = r;
|
||||||
|
@ -475,7 +445,9 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
r.searchAddressDataByName(req);
|
r.searchAddressDataByName(req);
|
||||||
for (SearchResult res : immediateResults) {
|
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) {
|
if (res.objectType == ObjectType.STREET) {
|
||||||
City ct = ((Street) res.object).getCity();
|
City ct = ((Street) res.object).getCity();
|
||||||
phrase.countUnknownWordsMatch(res,
|
phrase.countUnknownWordsMatch(res,
|
||||||
|
@ -879,10 +851,13 @@ public class SearchCoreFactory {
|
||||||
sw.getResult().file.preloadStreets(c, null);
|
sw.getResult().file.preloadStreets(c, null);
|
||||||
}
|
}
|
||||||
int limit = 0;
|
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()) {
|
for (Street object : c.getStreets()) {
|
||||||
|
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
|
|
||||||
res.localeName = object.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
res.localeName = object.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
||||||
res.otherNames = object.getAllNames(true);
|
res.otherNames = object.getAllNames(true);
|
||||||
if (object.getName().startsWith("<")) {
|
if (object.getName().startsWith("<")) {
|
||||||
|
@ -893,6 +868,9 @@ public class SearchCoreFactory {
|
||||||
&& !(nm.matches(res.localeName) || nm.matches(res.otherNames))) {
|
&& !(nm.matches(res.localeName) || nm.matches(res.otherNames))) {
|
||||||
continue;
|
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.localeRelatedObjectName = c.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
||||||
res.object = object;
|
res.object = object;
|
||||||
res.preferredZoom = 17;
|
res.preferredZoom = 17;
|
||||||
|
@ -969,8 +947,7 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
BinaryMapIndexReader file = phrase.getLastSelectedWord().getResult().file;
|
BinaryMapIndexReader file = phrase.getLastSelectedWord().getResult().file;
|
||||||
String lw = phrase.getUnknownSearchWord();
|
|
||||||
NameStringMatcher sm = phrase.getNameStringMatcher();
|
|
||||||
if (cacheBuilding != s) {
|
if (cacheBuilding != s) {
|
||||||
cacheBuilding = s;
|
cacheBuilding = s;
|
||||||
SearchRequest<Building> sr = BinaryMapIndexReader
|
SearchRequest<Building> 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()) {
|
for (Building b : s.getBuildings()) {
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
boolean interpolation = b.belongsToInterpolation(lw);
|
boolean interpolation = b.belongsToInterpolation(lw);
|
||||||
if ((!sm.matches(b.getName()) && !interpolation)
|
if ((!buildingMatch.matches(b.getName()) && !interpolation)
|
||||||
|| !phrase.isSearchTypeAllowed(ObjectType.HOUSE)) {
|
|| !phrase.isSearchTypeAllowed(ObjectType.HOUSE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1026,10 +1005,14 @@ public class SearchCoreFactory {
|
||||||
res.preferredZoom = 17;
|
res.preferredZoom = 17;
|
||||||
resultMatcher.publish(res);
|
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()) {
|
for (Street street : s.getIntersectedStreets()) {
|
||||||
SearchResult res = new SearchResult(phrase);
|
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)) {
|
|| !phrase.isSearchTypeAllowed(ObjectType.STREET_INTERSECTION)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1448,7 +1431,5 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int icompare(int x, int y) {
|
|
||||||
return (x < y) ? -1 : ((x == y) ? 0 : 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import net.osmand.CollatorStringMatcher;
|
||||||
import net.osmand.CollatorStringMatcher.StringMatcherMode;
|
import net.osmand.CollatorStringMatcher.StringMatcherMode;
|
||||||
import net.osmand.StringMatcher;
|
import net.osmand.StringMatcher;
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
import net.osmand.binary.CommonWords;
|
||||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
|
@ -421,11 +422,16 @@ public class SearchPhrase {
|
||||||
if(sm != null) {
|
if(sm != null) {
|
||||||
return sm;
|
return sm;
|
||||||
}
|
}
|
||||||
sm = new NameStringMatcher(unknownSearchWordTrim,
|
sm = getNameStringMatcher(unknownSearchWordTrim, lastUnknownSearchWordComplete);
|
||||||
(lastUnknownSearchWordComplete ?
|
return sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NameStringMatcher getNameStringMatcher(String word, boolean complete) {
|
||||||
|
return new NameStringMatcher(word,
|
||||||
|
(complete ?
|
||||||
StringMatcherMode.CHECK_EQUALS_FROM_SPACE :
|
StringMatcherMode.CHECK_EQUALS_FROM_SPACE :
|
||||||
StringMatcherMode.CHECK_STARTS_FROM_SPACE));
|
StringMatcherMode.CHECK_STARTS_FROM_SPACE));
|
||||||
return sm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasObjectType(ObjectType p) {
|
public boolean hasObjectType(ObjectType p) {
|
||||||
|
@ -613,5 +619,59 @@ public class SearchPhrase {
|
||||||
return (1 << (getRadiusLevel() - 1)) * meters;
|
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<String> 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<String> unknownSearchWords = getUnknownSearchWords();
|
||||||
|
|
||||||
|
String wordToSearch = "";
|
||||||
|
if (getUnknownSearchWordLength() > 1) {
|
||||||
|
List<String> searchWords = new ArrayList<>(unknownSearchWords);
|
||||||
|
searchWords.add(0, getUnknownSearchWord());
|
||||||
|
Collections.sort(searchWords, new Comparator<String>() {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,9 @@ public class SearchResult {
|
||||||
if(otherWordsMatch != null) {
|
if(otherWordsMatch != null) {
|
||||||
inc += otherWordsMatch.size();
|
inc += otherWordsMatch.size();
|
||||||
}
|
}
|
||||||
|
if(parentSearchResult != null) {
|
||||||
|
inc += parentSearchResult.getFoundWordCount();
|
||||||
|
}
|
||||||
return inc;
|
return inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue