Initial commit address search refactoring
This commit is contained in:
parent
fd9f87ba1d
commit
f40657ebec
12 changed files with 514 additions and 503 deletions
|
@ -17,12 +17,20 @@ public class CollatorStringMatcher implements StringMatcher {
|
||||||
private final String part;
|
private final String part;
|
||||||
|
|
||||||
public static enum StringMatcherMode {
|
public static enum StringMatcherMode {
|
||||||
|
// tests only first word as base starts with part
|
||||||
CHECK_ONLY_STARTS_WITH,
|
CHECK_ONLY_STARTS_WITH,
|
||||||
|
// tests all words (split by space) and one of word should start with a given part
|
||||||
CHECK_STARTS_FROM_SPACE,
|
CHECK_STARTS_FROM_SPACE,
|
||||||
|
// tests all words except first (split by space) and one of word should start with a given part
|
||||||
CHECK_STARTS_FROM_SPACE_NOT_BEGINNING,
|
CHECK_STARTS_FROM_SPACE_NOT_BEGINNING,
|
||||||
|
// tests all words (split by space) and one of word should be equal to part
|
||||||
CHECK_EQUALS_FROM_SPACE,
|
CHECK_EQUALS_FROM_SPACE,
|
||||||
|
// TO DO: make a separate method
|
||||||
|
// trims part to make shorter then full text and tests only first word as base starts with part
|
||||||
|
TRIM_AND_CHECK_ONLY_STARTS_WITH,
|
||||||
|
// simple collator contains in any part of the base
|
||||||
CHECK_CONTAINS,
|
CHECK_CONTAINS,
|
||||||
CHECK_ONLY_STARTS_WITH_TRIM,
|
// simple collator equals
|
||||||
CHECK_EQUALS,
|
CHECK_EQUALS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,22 +50,25 @@ public class CollatorStringMatcher implements StringMatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean cmatches(Collator collator, String base, String part, StringMatcherMode mode){
|
public static boolean cmatches(Collator collator, String fullName, String part, StringMatcherMode mode){
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case CHECK_CONTAINS:
|
case CHECK_CONTAINS:
|
||||||
return ccontains(collator, base, part);
|
return ccontains(collator, fullName, part);
|
||||||
case CHECK_EQUALS_FROM_SPACE:
|
case CHECK_EQUALS_FROM_SPACE:
|
||||||
return cstartsWith(collator, base, part, true, true, true, false);
|
return cstartsWith(collator, fullName, part, true, true, true);
|
||||||
case CHECK_STARTS_FROM_SPACE:
|
case CHECK_STARTS_FROM_SPACE:
|
||||||
return cstartsWith(collator, base, part, true, true, false, false);
|
return cstartsWith(collator, fullName, part, true, true, false);
|
||||||
case CHECK_STARTS_FROM_SPACE_NOT_BEGINNING:
|
case CHECK_STARTS_FROM_SPACE_NOT_BEGINNING:
|
||||||
return cstartsWith(collator, base, part, false, true, false, false);
|
return cstartsWith(collator, fullName, part, false, true, false);
|
||||||
case CHECK_ONLY_STARTS_WITH:
|
case CHECK_ONLY_STARTS_WITH:
|
||||||
return cstartsWith(collator, base, part, true, false, false, false);
|
return cstartsWith(collator, fullName, part, true, false, false);
|
||||||
case CHECK_ONLY_STARTS_WITH_TRIM:
|
case TRIM_AND_CHECK_ONLY_STARTS_WITH:
|
||||||
return cstartsWith(collator, base, part, true, false, false, true);
|
if (part.length() > fullName.length()) {
|
||||||
|
part = part.substring(0, fullName.length());
|
||||||
|
}
|
||||||
|
return cstartsWith(collator, fullName, part, true, false, false);
|
||||||
case CHECK_EQUALS:
|
case CHECK_EQUALS:
|
||||||
return cstartsWith(collator, base, part, false, false, true, false);
|
return cstartsWith(collator, fullName, part, false, false, true);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -116,21 +127,14 @@ public class CollatorStringMatcher implements StringMatcher {
|
||||||
* Special check try to find as well in the middle of name
|
* Special check try to find as well in the middle of name
|
||||||
*
|
*
|
||||||
* @param collator
|
* @param collator
|
||||||
* @param searchInParam
|
* @param fullText
|
||||||
* @param theStart
|
* @param theStart
|
||||||
* @param trim - trim theStart to searchInParam length if searchInParam non empty
|
|
||||||
* @return true if searchIn starts with token
|
* @return true if searchIn starts with token
|
||||||
*/
|
*/
|
||||||
public static boolean cstartsWith(Collator collator, String searchInParam, String theStart,
|
public static boolean cstartsWith(Collator collator, String fullText, String theStart,
|
||||||
boolean checkBeginning, boolean checkSpaces, boolean equals, boolean trim) {
|
boolean checkBeginning, boolean checkSpaces, boolean equals) {
|
||||||
String searchIn = searchInParam.toLowerCase(Locale.getDefault());
|
String searchIn = fullText.toLowerCase(Locale.getDefault());
|
||||||
if (trim && searchIn.length() > 0) {
|
|
||||||
searchIn += " ";
|
|
||||||
}
|
|
||||||
int searchInLength = searchIn.length();
|
int searchInLength = searchIn.length();
|
||||||
if (trim && searchInLength > 0 && theStart.length() > searchInLength) {
|
|
||||||
theStart = theStart.substring(0, searchInLength);
|
|
||||||
}
|
|
||||||
int startLength = theStart.length();
|
int startLength = theStart.length();
|
||||||
if (startLength == 0) {
|
if (startLength == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -13,10 +13,6 @@ public class CommonWords {
|
||||||
frequentlyUsedWordsDictionary.put(string, frequentlyUsedWordsDictionary.size());
|
frequentlyUsedWordsDictionary.put(string, frequentlyUsedWordsDictionary.size());
|
||||||
}
|
}
|
||||||
public static int getCommon(String name) {
|
public static int getCommon(String name) {
|
||||||
// if(true) {
|
|
||||||
// // not ready for old versions yet
|
|
||||||
// return -1;
|
|
||||||
// }
|
|
||||||
Integer i = commonWordsDictionary.get(name);
|
Integer i = commonWordsDictionary.get(name);
|
||||||
return i == null ? -1 : i.intValue();
|
return i == null ? -1 : i.intValue();
|
||||||
}
|
}
|
||||||
|
@ -28,7 +24,15 @@ public class CommonWords {
|
||||||
|
|
||||||
public static int getCommonSearch(String name) {
|
public static int getCommonSearch(String name) {
|
||||||
Integer i = commonWordsDictionary.get(name);
|
Integer i = commonWordsDictionary.get(name);
|
||||||
return i == null ? getFrequentlyUsed(name) : i.intValue() + frequentlyUsedWordsDictionary.size();
|
// higher means better for search
|
||||||
|
if (i == null) {
|
||||||
|
int fq = getFrequentlyUsed(name);
|
||||||
|
if (fq != -1) {
|
||||||
|
return commonWordsDictionary.size() + fq;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return i.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCommonGeocoding(String name) {
|
public static int getCommonGeocoding(String name) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package net.osmand.search;
|
package net.osmand.search;
|
||||||
|
|
||||||
import net.osmand.Collator;
|
import net.osmand.Collator;
|
||||||
import net.osmand.OsmAndCollator;
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.ResultMatcher;
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
@ -72,7 +71,7 @@ public class SearchUICore {
|
||||||
taskQueue = new LinkedBlockingQueue<Runnable>();
|
taskQueue = new LinkedBlockingQueue<Runnable>();
|
||||||
searchSettings = new SearchSettings(new ArrayList<BinaryMapIndexReader>());
|
searchSettings = new SearchSettings(new ArrayList<BinaryMapIndexReader>());
|
||||||
searchSettings = searchSettings.setLang(locale, transliterate);
|
searchSettings = searchSettings.setLang(locale, transliterate);
|
||||||
phrase = new SearchPhrase(searchSettings, OsmAndCollator.primaryCollator());
|
phrase = SearchPhrase.emptyPhrase();
|
||||||
currentSearchResult = new SearchResultCollection(phrase);
|
currentSearchResult = new SearchResultCollection(phrase);
|
||||||
singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, taskQueue);
|
singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, taskQueue);
|
||||||
}
|
}
|
||||||
|
@ -351,10 +350,10 @@ public class SearchUICore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilterOrders(List<String> filterOrders) {
|
public void setActivePoiFiltersByOrder(List<String> filterOrders) {
|
||||||
for (SearchCoreAPI capi : apis) {
|
for (SearchCoreAPI capi : apis) {
|
||||||
if (capi instanceof SearchAmenityTypesAPI) {
|
if (capi instanceof SearchAmenityTypesAPI) {
|
||||||
((SearchAmenityTypesAPI) capi).setFilterOrders(filterOrders);
|
((SearchAmenityTypesAPI) capi).setActivePoiFiltersByOrder(filterOrders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,7 +403,7 @@ public class SearchUICore {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean filterOneResult(SearchResult object, SearchPhrase phrase) {
|
private boolean filterOneResult(SearchResult object, SearchPhrase phrase) {
|
||||||
NameStringMatcher nameStringMatcher = phrase.getNameStringMatcher();
|
NameStringMatcher nameStringMatcher = phrase.getFirstUnknownNameStringMatcher();
|
||||||
return nameStringMatcher.matches(object.localeName) || nameStringMatcher.matches(object.otherNames);
|
return nameStringMatcher.matches(object.localeName) || nameStringMatcher.matches(object.otherNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,16 +713,17 @@ public class SearchUICore {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(SearchResult object) {
|
public boolean publish(SearchResult object) {
|
||||||
if (phrase != null && object.otherNames != null && !phrase.getNameStringMatcher().matches(object.localeName)) {
|
// TODO first , other?
|
||||||
|
if (phrase != null && object.otherNames != null && !phrase.getFirstUnknownNameStringMatcher().matches(object.localeName)) {
|
||||||
for (String s : object.otherNames) {
|
for (String s : object.otherNames) {
|
||||||
if (phrase.getNameStringMatcher().matches(s)) {
|
if (phrase.getFirstUnknownNameStringMatcher().matches(s)) {
|
||||||
object.alternateName = s;
|
object.alternateName = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Algorithms.isEmpty(object.alternateName) && object.object instanceof Amenity) {
|
if (Algorithms.isEmpty(object.alternateName) && object.object instanceof Amenity) {
|
||||||
for (String value : ((Amenity) object.object).getAdditionalInfo().values()) {
|
for (String value : ((Amenity) object.object).getAdditionalInfo().values()) {
|
||||||
if (phrase.getNameStringMatcher().matches(value)) {
|
if (phrase.getFirstUnknownNameStringMatcher().matches(value)) {
|
||||||
object.alternateName = value;
|
object.alternateName = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -815,7 +815,7 @@ public class SearchUICore {
|
||||||
|
|
||||||
SearchExportSettings exportSettings = phrase.getSettings().getExportSettings();
|
SearchExportSettings exportSettings = phrase.getSettings().getExportSettings();
|
||||||
json.put("settings", phrase.getSettings().toJSON());
|
json.put("settings", phrase.getSettings().toJSON());
|
||||||
json.put("phrase", phrase.getRawUnknownSearchPhrase());
|
json.put("phrase", phrase.getFullSearchPhrase());
|
||||||
if (searchResult.searchResults != null && searchResult.searchResults.size() > 0) {
|
if (searchResult.searchResults != null && searchResult.searchResults.size() > 0) {
|
||||||
JSONArray resultsArr = new JSONArray();
|
JSONArray resultsArr = new JSONArray();
|
||||||
for (SearchResult r : searchResult.searchResults) {
|
for (SearchResult r : searchResult.searchResults) {
|
||||||
|
@ -963,14 +963,12 @@ public class SearchUICore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SearchResultComparator implements Comparator<SearchResult> {
|
public static class SearchResultComparator implements Comparator<SearchResult> {
|
||||||
private SearchPhrase sp;
|
|
||||||
private Collator collator;
|
private Collator collator;
|
||||||
private LatLon loc;
|
private LatLon loc;
|
||||||
private boolean sortByName;
|
private boolean sortByName;
|
||||||
|
|
||||||
|
|
||||||
public SearchResultComparator(SearchPhrase sp) {
|
public SearchResultComparator(SearchPhrase sp) {
|
||||||
this.sp = sp;
|
|
||||||
this.collator = sp.getCollator();
|
this.collator = sp.getCollator();
|
||||||
loc = sp.getLastTokenLocation();
|
loc = sp.getLastTokenLocation();
|
||||||
sortByName = sp.isSortByName();
|
sortByName = sp.isSortByName();
|
||||||
|
|
|
@ -140,20 +140,18 @@ public class SearchCoreFactory {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void subSearchApiOrPublish(SearchPhrase phrase,
|
protected void subSearchApiOrPublish(SearchPhrase phrase, SearchResultMatcher resultMatcher, SearchResult res, SearchBaseAPI api)
|
||||||
SearchResultMatcher resultMatcher, SearchResult res, SearchBaseAPI api)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
phrase.countUnknownWordsMatch(res);
|
phrase.countUnknownWordsMatchMainResult(res);
|
||||||
// int cnt = resultMatcher.getCount();
|
// TODO select word & delete found words
|
||||||
List<String> ws = phrase.getUnknownSearchWords(res.otherWordsMatch);
|
List<String> ws = phrase.getUnknownSearchWords(res.otherWordsMatch);
|
||||||
if (!res.firstUnknownWordMatches) {
|
if (!res.firstUnknownWordMatches) {
|
||||||
ws.add(phrase.getUnknownSearchWord());
|
ws.add(phrase.getFirstUnknownSearchWord());
|
||||||
}
|
}
|
||||||
// publish result to set parentSearchResult before search
|
// publish result to set parentSearchResult before search
|
||||||
resultMatcher.publish(res);
|
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());
|
|
||||||
resultMatcher.setParentSearchResult(res);
|
resultMatcher.setParentSearchResult(res);
|
||||||
api.search(nphrase, resultMatcher);
|
api.search(nphrase, resultMatcher);
|
||||||
resultMatcher.setParentSearchResult(res.parentSearchResult);
|
resultMatcher.setParentSearchResult(res.parentSearchResult);
|
||||||
|
@ -166,8 +164,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class SearchRegionByNameAPI extends SearchBaseAPI {
|
public static class SearchRegionByNameAPI extends SearchBaseAPI {
|
||||||
|
|
||||||
public SearchRegionByNameAPI() {
|
public SearchRegionByNameAPI() {
|
||||||
|
@ -186,9 +182,9 @@ public class SearchCoreFactory {
|
||||||
sr.objectType = ObjectType.REGION;
|
sr.objectType = ObjectType.REGION;
|
||||||
sr.location = bmir.getRegionCenter();
|
sr.location = bmir.getRegionCenter();
|
||||||
sr.preferredZoom = 6;
|
sr.preferredZoom = 6;
|
||||||
if (phrase.getUnknownSearchWordLength() <= 1 && phrase.isNoSelectedType()) {
|
if (phrase.getFirstUnknownSearchWord().length() <= 1 && phrase.isNoSelectedType()) {
|
||||||
resultMatcher.publish(sr);
|
resultMatcher.publish(sr);
|
||||||
} else if (phrase.getNameStringMatcher().matches(sr.localeName)) {
|
} else if (phrase.getFirstUnknownNameStringMatcher().matches(sr.localeName)) {
|
||||||
resultMatcher.publish(sr);
|
resultMatcher.publish(sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,19 +206,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String stripBraces(String localeName) {
|
|
||||||
int i = localeName.indexOf('(');
|
|
||||||
String retName = localeName;
|
|
||||||
if (i > -1) {
|
|
||||||
retName = localeName.substring(0, i);
|
|
||||||
int j = localeName.indexOf(')', i);
|
|
||||||
if (j > -1) {
|
|
||||||
retName = retName.trim() + ' ' + localeName.substring(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SearchAddressByNameAPI extends SearchBaseAPI {
|
public static class SearchAddressByNameAPI extends SearchBaseAPI {
|
||||||
|
|
||||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
||||||
|
@ -310,10 +293,7 @@ public class SearchCoreFactory {
|
||||||
if (phrase.isNoSelectedType() && bbox != null
|
if (phrase.isNoSelectedType() && bbox != null
|
||||||
&& (phrase.isUnknownSearchWordPresent() || phrase.isEmptyQueryAllowed())
|
&& (phrase.isUnknownSearchWordPresent() || phrase.isEmptyQueryAllowed())
|
||||||
&& phrase.isSearchTypeAllowed(ObjectType.CITY)) {
|
&& phrase.isSearchTypeAllowed(ObjectType.CITY)) {
|
||||||
String word = phrase.getUnknownWordToSearch();
|
NameStringMatcher nm = phrase.getMainUnknownNameStringMatcher();
|
||||||
NameStringMatcher nm = phrase.getNameStringMatcher(word, phrase.isUnknownSearchWordComplete());
|
|
||||||
NameStringMatcher wordEqualsMatcher = phrase.getNameStringMatcher(word, true);
|
|
||||||
boolean firstUnknownWordMatches = word.equals(phrase.getUnknownSearchWord());
|
|
||||||
resArray.clear();
|
resArray.clear();
|
||||||
resArray = townCitiesQR.queryInBox(bbox, resArray);
|
resArray = townCitiesQR.queryInBox(bbox, resArray);
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
|
@ -335,8 +315,6 @@ public class SearchCoreFactory {
|
||||||
if (phrase.isEmptyQueryAllowed() && phrase.isEmpty()) {
|
if (phrase.isEmptyQueryAllowed() && phrase.isEmpty()) {
|
||||||
resultMatcher.publish(res);
|
resultMatcher.publish(res);
|
||||||
} else if (nm.matches(res.localeName) || nm.matches(res.otherNames)) {
|
} else if (nm.matches(res.localeName) || nm.matches(res.otherNames)) {
|
||||||
res.firstUnknownWordMatches = firstUnknownWordMatches;
|
|
||||||
res.unknownPhraseMatches = wordEqualsMatcher.matches(res.localeName);
|
|
||||||
subSearchApiOrPublish(phrase, resultMatcher, res, cityApi);
|
subSearchApiOrPublish(phrase, resultMatcher, res, cityApi);
|
||||||
}
|
}
|
||||||
if (limit++ > LIMIT * phrase.getRadiusLevel()) {
|
if (limit++ > LIMIT * phrase.getRadiusLevel()) {
|
||||||
|
@ -348,7 +326,8 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
private void searchByName(final SearchPhrase phrase, final SearchResultMatcher resultMatcher)
|
private void searchByName(final SearchPhrase phrase, final SearchResultMatcher resultMatcher)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (phrase.getRadiusLevel() > 1 || phrase.getUnknownSearchWordLength() > 3 || phrase.getUnknownSearchWords().size() > 0 || phrase.isSearchTypeAllowed(ObjectType.POSTCODE, true)) {
|
if (phrase.getRadiusLevel() > 1 || phrase.getUnknownWordToSearch().length() > 3 ||
|
||||||
|
phrase.hasMoreThanOneUnknownSearchWord()|| phrase.isSearchTypeAllowed(ObjectType.POSTCODE, true)) {
|
||||||
final boolean locSpecified = phrase.getLastTokenLocation() != null;
|
final boolean locSpecified = phrase.getLastTokenLocation() != null;
|
||||||
LatLon loc = phrase.getLastTokenLocation();
|
LatLon loc = phrase.getLastTokenLocation();
|
||||||
final List<SearchResult> immediateResults = new ArrayList<>();
|
final List<SearchResult> immediateResults = new ArrayList<>();
|
||||||
|
@ -391,7 +370,7 @@ public class SearchCoreFactory {
|
||||||
if (object.getName().startsWith("<")) {
|
if (object.getName().startsWith("<")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!phrase.getNameStringMatcher().matches(stripBraces(sr.localeName))) {
|
if (!phrase.getFirstUnknownNameStringMatcher().matches(stripBraces(sr.localeName))) {
|
||||||
sr.priorityDistance = 5;
|
sr.priorityDistance = 5;
|
||||||
}
|
}
|
||||||
sr.objectType = ObjectType.STREET;
|
sr.objectType = ObjectType.STREET;
|
||||||
|
@ -460,16 +439,13 @@ 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);
|
||||||
|
|
||||||
String wordToSearch = phrase.getUnknownWordToSearch();
|
String wordToSearch = phrase.getUnknownWordToSearch();
|
||||||
NameStringMatcher wordEqualsMatcher = phrase.getNameStringMatcher(wordToSearch, true);
|
|
||||||
boolean firstUnknownWordMatches = wordToSearch.equals(phrase.getUnknownSearchWord());
|
|
||||||
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;
|
||||||
immediateResults.clear();
|
immediateResults.clear();
|
||||||
SearchRequest<MapObject> req = BinaryMapIndexReader.buildAddressByNameRequest(rm, wordToSearch.toLowerCase(),
|
SearchRequest<MapObject> req = BinaryMapIndexReader.buildAddressByNameRequest(rm, wordToSearch.toLowerCase(),
|
||||||
phrase.isUnknownSearchWordComplete() ? StringMatcherMode.CHECK_EQUALS_FROM_SPACE
|
phrase.isMainUnknownSearchWordComplete() ? StringMatcherMode.CHECK_EQUALS_FROM_SPACE
|
||||||
: StringMatcherMode.CHECK_STARTS_FROM_SPACE);
|
: StringMatcherMode.CHECK_STARTS_FROM_SPACE);
|
||||||
if (locSpecified) {
|
if (locSpecified) {
|
||||||
req.setBBoxRadius(loc.getLatitude(), loc.getLongitude(),
|
req.setBBoxRadius(loc.getLatitude(), loc.getLongitude(),
|
||||||
|
@ -477,8 +453,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
r.searchAddressDataByName(req);
|
r.searchAddressDataByName(req);
|
||||||
for (SearchResult res : immediateResults) {
|
for (SearchResult res : immediateResults) {
|
||||||
res.firstUnknownWordMatches = firstUnknownWordMatches;
|
|
||||||
res.unknownPhraseMatches = wordEqualsMatcher.matches(res.localeName);
|
|
||||||
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,
|
||||||
|
@ -510,29 +484,28 @@ public class SearchCoreFactory {
|
||||||
if (!phrase.isUnknownSearchWordPresent()) {
|
if (!phrase.isUnknownSearchWordPresent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean hasUnselectedType = phrase.isNoSelectedType() && phrase.isUnknownSearchWordPresent()
|
// TODO
|
||||||
&& phrase.isUnknownSearchWordComplete() && phrase.hasUnknownSearchWordPoiTypes();
|
// consider 'bar' - 'Hospital 512'
|
||||||
|
if (!phrase.isNoSelectedType()) {
|
||||||
|
// don't search by name when type is selected or poi type is part of name
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// boolean hasUnselectedType = phrase.isNoSelectedType() && phrase.isUnknownSearchWordPresent()
|
||||||
|
// && phrase.isMainUnknownSearchWordComplete() && phrase.hasUnknownSearchWordPoiTypes();
|
||||||
|
// Check feedback before it was searching exact match of whole phrase.getUnknownSearchPhrase()
|
||||||
|
|
||||||
final BinaryMapIndexReader[] currentFile = new BinaryMapIndexReader[1];
|
final BinaryMapIndexReader[] currentFile = new BinaryMapIndexReader[1];
|
||||||
Iterator<BinaryMapIndexReader> offlineIterator = phrase.getRadiusOfflineIndexes(BBOX_RADIUS,
|
Iterator<BinaryMapIndexReader> offlineIterator = phrase.getRadiusOfflineIndexes(BBOX_RADIUS,
|
||||||
SearchPhraseDataType.POI);
|
SearchPhraseDataType.POI);
|
||||||
String unknownSearchPhrase = phrase.getUnknownSearchPhrase().trim();
|
String searchWord = phrase.getUnknownWordToSearch();
|
||||||
String searchWord = hasUnselectedType ? unknownSearchPhrase : phrase.getUnknownWordToSearch();
|
final NameStringMatcher nm = phrase.getMainUnknownNameStringMatcher();
|
||||||
final NameStringMatcher nm = phrase.getNameStringMatcher(searchWord, phrase.isUnknownSearchWordComplete());
|
|
||||||
final NameStringMatcher phraseMatcher;
|
|
||||||
if (!Algorithms.isEmpty(unknownSearchPhrase)) {
|
|
||||||
phraseMatcher = new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_EQUALS);
|
|
||||||
} else {
|
|
||||||
phraseMatcher = null;
|
|
||||||
}
|
|
||||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS_INSIDE);
|
QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS_INSIDE);
|
||||||
final Set<String> ids = new HashSet<String>();
|
final Set<String> ids = new HashSet<String>();
|
||||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(
|
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest((int) bbox.centerX(),
|
||||||
(int)bbox.centerX(), (int)bbox.centerY(),
|
(int) bbox.centerY(), searchWord, (int) bbox.left, (int) bbox.right, (int) bbox.top,
|
||||||
searchWord,
|
(int) bbox.bottom, new ResultMatcher<Amenity>() {
|
||||||
(int)bbox.left, (int)bbox.right,
|
|
||||||
(int)bbox.top, (int)bbox.bottom,
|
|
||||||
new ResultMatcher<Amenity>() {
|
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean publish(Amenity object) {
|
public boolean publish(Amenity object) {
|
||||||
if (phrase.getSettings().isExportObjects()) {
|
if (phrase.getSettings().isExportObjects()) {
|
||||||
|
@ -547,19 +520,17 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
SearchResult sr = new SearchResult(phrase);
|
SearchResult sr = new SearchResult(phrase);
|
||||||
sr.otherNames = object.getAllNames(true);
|
sr.otherNames = object.getAllNames(true);
|
||||||
sr.localeName = object.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
sr.localeName = object.getName(phrase.getSettings().getLang(),
|
||||||
if (phrase.isUnknownSearchWordComplete()) {
|
phrase.getSettings().isTransliterate());
|
||||||
if(!nm.matches(sr.localeName) && !nm.matches(sr.otherNames) &&
|
if (!nm.matches(sr.localeName) && !nm.matches(sr.otherNames)
|
||||||
!nm.matches(object.getAdditionalInfo().values())) {
|
&& !nm.matches(object.getAdditionalInfo().values())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
sr.object = object;
|
sr.object = object;
|
||||||
sr.preferredZoom = 17;
|
sr.preferredZoom = 17;
|
||||||
sr.file = currentFile[0];
|
sr.file = currentFile[0];
|
||||||
sr.location = object.getLocation();
|
sr.location = object.getLocation();
|
||||||
if (object.getSubType().equals("city") ||
|
if (object.getSubType().equals("city") || object.getSubType().equals("country")) {
|
||||||
object.getSubType().equals("country")) {
|
|
||||||
sr.priorityDistance = SEARCH_AMENITY_BY_NAME_CITY_PRIORITY_DISTANCE;
|
sr.priorityDistance = SEARCH_AMENITY_BY_NAME_CITY_PRIORITY_DISTANCE;
|
||||||
sr.preferredZoom = object.getSubType().equals("country") ? 7 : 13;
|
sr.preferredZoom = object.getSubType().equals("country") ? 7 : 13;
|
||||||
} else if (object.getSubType().equals("town")) {
|
} else if (object.getSubType().equals("town")) {
|
||||||
|
@ -568,10 +539,7 @@ public class SearchCoreFactory {
|
||||||
sr.priorityDistance = 1;
|
sr.priorityDistance = 1;
|
||||||
}
|
}
|
||||||
sr.priority = SEARCH_AMENITY_BY_NAME_PRIORITY;
|
sr.priority = SEARCH_AMENITY_BY_NAME_PRIORITY;
|
||||||
if (phraseMatcher != null) {
|
phrase.countUnknownWordsMatchMainResult(sr);
|
||||||
sr.unknownPhraseMatches = phraseMatcher.matches(sr.localeName);
|
|
||||||
}
|
|
||||||
phrase.countUnknownWordsMatch(sr);
|
|
||||||
sr.objectType = ObjectType.POI;
|
sr.objectType = ObjectType.POI;
|
||||||
resultMatcher.publish(sr);
|
resultMatcher.publish(sr);
|
||||||
ids.add(poiID);
|
ids.add(poiID);
|
||||||
|
@ -633,9 +601,8 @@ public class SearchCoreFactory {
|
||||||
private List<AbstractPoiType> topVisibleFilters;
|
private List<AbstractPoiType> topVisibleFilters;
|
||||||
private List<PoiCategory> categories;
|
private List<PoiCategory> categories;
|
||||||
private List<CustomSearchPoiFilter> customPoiFilters = new ArrayList<>();
|
private List<CustomSearchPoiFilter> customPoiFilters = new ArrayList<>();
|
||||||
private TIntArrayList customPoiFiltersPriorites = new TIntArrayList();
|
private Map<String, Integer> activePoiFilters = new HashMap<>();
|
||||||
private MapPoiTypes types;
|
private MapPoiTypes types;
|
||||||
private List<String> filterOrders = new ArrayList<>();
|
|
||||||
|
|
||||||
public SearchAmenityTypesAPI(MapPoiTypes types) {
|
public SearchAmenityTypesAPI(MapPoiTypes types) {
|
||||||
super(ObjectType.POI_TYPE);
|
super(ObjectType.POI_TYPE);
|
||||||
|
@ -644,52 +611,33 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
public void clearCustomFilters() {
|
public void clearCustomFilters() {
|
||||||
this.customPoiFilters.clear();
|
this.customPoiFilters.clear();
|
||||||
this.customPoiFiltersPriorites.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCustomFilter(CustomSearchPoiFilter poiFilter, int priority) {
|
public void addCustomFilter(CustomSearchPoiFilter poiFilter, int priority) {
|
||||||
this.customPoiFilters.add(poiFilter);
|
this.customPoiFilters.add(poiFilter);
|
||||||
this.customPoiFiltersPriorites.add(priority);
|
if (priority > 0) {
|
||||||
|
this.activePoiFilters.put(poiFilter.getFilterId(), priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFilterOrders(List<String> filterOrders) {
|
public void setActivePoiFiltersByOrder(List<String> filterOrder) {
|
||||||
this.filterOrders = filterOrders;
|
for (int i = 0; i < filterOrder.size(); i++) {
|
||||||
|
this.activePoiFilters.put(filterOrder.get(i), i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public List<AbstractPoiType> getPoiTypeResults(NameStringMatcher nm, boolean includeAdditionals) {
|
||||||
public boolean search(SearchPhrase phrase, SearchResultMatcher resultMatcher) throws IOException {
|
|
||||||
if (translatedNames.isEmpty()) {
|
|
||||||
translatedNames = types.getAllTranslatedNames(false);
|
|
||||||
topVisibleFilters = types.getTopVisibleFilters();
|
|
||||||
categories = types.getCategories(false);
|
|
||||||
}
|
|
||||||
List<AbstractPoiType> results = new ArrayList<AbstractPoiType>();
|
List<AbstractPoiType> results = new ArrayList<AbstractPoiType>();
|
||||||
List<AbstractPoiType> searchWordTypes = new ArrayList<AbstractPoiType>();
|
|
||||||
NameStringMatcher nm;
|
|
||||||
String unknownSearchPhrase = phrase.getUnknownSearchPhrase();
|
|
||||||
boolean showTopFiltersOnly = !phrase.isUnknownSearchWordPresent();
|
|
||||||
if (phrase.getUnknownSearchWord().length() < unknownSearchPhrase.length()) {
|
|
||||||
nm = new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_ONLY_STARTS_WITH_TRIM);
|
|
||||||
} else {
|
|
||||||
nm = new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_STARTS_FROM_SPACE);
|
|
||||||
}
|
|
||||||
for (AbstractPoiType pf : topVisibleFilters) {
|
for (AbstractPoiType pf : topVisibleFilters) {
|
||||||
if (showTopFiltersOnly
|
if (nm.matches(pf.getTranslation()) || nm.matches(pf.getEnTranslation())
|
||||||
|| nm.matches(pf.getTranslation())
|
|
||||||
|| nm.matches(pf.getEnTranslation())
|
|
||||||
|| nm.matches(pf.getSynonyms())) {
|
|| nm.matches(pf.getSynonyms())) {
|
||||||
results.add(pf);
|
results.add(pf);
|
||||||
searchWordTypes.add(pf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!showTopFiltersOnly) {
|
|
||||||
for (PoiCategory c : categories) {
|
for (PoiCategory c : categories) {
|
||||||
if (!results.contains(c)
|
if (!results.contains(c) && (nm.matches(c.getTranslation()) || nm.matches(c.getEnTranslation())
|
||||||
&& (nm.matches(c.getTranslation())
|
|
||||||
|| nm.matches(c.getEnTranslation())
|
|
||||||
|| nm.matches(c.getSynonyms()))) {
|
|| nm.matches(c.getSynonyms()))) {
|
||||||
results.add(c);
|
results.add(c);
|
||||||
searchWordTypes.add(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Iterator<Entry<String, PoiType>> it = translatedNames.entrySet().iterator();
|
Iterator<Entry<String, PoiType>> it = translatedNames.entrySet().iterator();
|
||||||
|
@ -697,20 +645,18 @@ public class SearchCoreFactory {
|
||||||
Entry<String, PoiType> e = it.next();
|
Entry<String, PoiType> e = it.next();
|
||||||
PoiType pt = e.getValue();
|
PoiType pt = e.getValue();
|
||||||
if (pt.getCategory() != types.getOtherMapCategory()) {
|
if (pt.getCategory() != types.getOtherMapCategory()) {
|
||||||
if (!results.contains(pt)
|
if (!results.contains(pt) && (nm.matches(pt.getEnTranslation()) || nm.matches(pt.getTranslation())
|
||||||
&& (nm.matches(pt.getEnTranslation())
|
|
||||||
|| nm.matches(pt.getTranslation())
|
|
||||||
|| nm.matches(pt.getSynonyms()))) {
|
|| nm.matches(pt.getSynonyms()))) {
|
||||||
results.add(pt);
|
results.add(pt);
|
||||||
searchWordTypes.add(pt);
|
|
||||||
}
|
}
|
||||||
List<PoiType> additionals = pt.getPoiAdditionals();
|
List<PoiType> additionals = pt.getPoiAdditionals();
|
||||||
if (additionals != null) {
|
if (additionals != null && includeAdditionals) {
|
||||||
for (PoiType a : additionals) {
|
for (PoiType a : additionals) {
|
||||||
if (!results.contains(a)) {
|
if (!results.contains(a)) {
|
||||||
String enTranslation = a.getEnTranslation().toLowerCase();
|
String enTranslation = a.getEnTranslation().toLowerCase();
|
||||||
if (!"yes".equals(enTranslation) && !"no".equals(enTranslation)
|
if (!"yes".equals(enTranslation) && !"no".equals(enTranslation)
|
||||||
&& (nm.matches(enTranslation) || nm.matches(a.getTranslation()) || nm.matches(a.getSynonyms()))) {
|
&& (nm.matches(enTranslation) || nm.matches(a.getTranslation())
|
||||||
|
|| nm.matches(a.getSynonyms()))) {
|
||||||
results.add(a);
|
results.add(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -718,52 +664,70 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
phrase.setUnknownSearchWordPoiTypes(searchWordTypes);
|
|
||||||
|
|
||||||
if (resultMatcher != null) {
|
private void initPoiTypes() {
|
||||||
String word = phrase.getUnknownSearchWord();
|
if (translatedNames.isEmpty()) {
|
||||||
NameStringMatcher startMatch = new NameStringMatcher(word, StringMatcherMode.CHECK_ONLY_STARTS_WITH);
|
translatedNames = types.getAllTranslatedNames(false);
|
||||||
for (AbstractPoiType pt : results) {
|
topVisibleFilters = types.getTopVisibleFilters();
|
||||||
|
categories = types.getCategories(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean search(SearchPhrase phrase, SearchResultMatcher resultMatcher) throws IOException {
|
||||||
|
boolean showTopFiltersOnly = !phrase.isUnknownSearchWordPresent();
|
||||||
|
NameStringMatcher nm = phrase.getFullUnknownNameMatcher();
|
||||||
|
initPoiTypes();
|
||||||
|
List<AbstractPoiType> poiTypes = topVisibleFilters;
|
||||||
|
if (!showTopFiltersOnly) {
|
||||||
|
poiTypes = getPoiTypeResults(nm, true);
|
||||||
|
}
|
||||||
|
for (AbstractPoiType pt : poiTypes) {
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
res.localeName = pt.getTranslation();
|
res.localeName = pt.getTranslation();
|
||||||
res.object = pt;
|
res.object = pt;
|
||||||
res.priorityDistance = 0;
|
addPoiTypeResult(phrase, resultMatcher, showTopFiltersOnly, getStandardFilterId(pt), res);
|
||||||
res.objectType = ObjectType.POI_TYPE;
|
|
||||||
res.firstUnknownWordMatches = startMatch.matches(res.localeName);
|
|
||||||
if (showTopFiltersOnly) {
|
|
||||||
String stdFilterId = getStandardFilterId(pt);
|
|
||||||
if (filterOrders.contains(stdFilterId)) {
|
|
||||||
res.priority = SEARCH_AMENITY_TYPE_PRIORITY + filterOrders.indexOf(stdFilterId);
|
|
||||||
resultMatcher.publish(res);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.priority = SEARCH_AMENITY_TYPE_PRIORITY;
|
|
||||||
resultMatcher.publish(res);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < customPoiFilters.size(); i++) {
|
for (int i = 0; i < customPoiFilters.size(); i++) {
|
||||||
CustomSearchPoiFilter csf = customPoiFilters.get(i);
|
CustomSearchPoiFilter csf = customPoiFilters.get(i);
|
||||||
if (!phrase.isUnknownSearchWordPresent() || nm.matches(csf.getName())) {
|
if (showTopFiltersOnly || nm.matches(csf.getName())) {
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
res.localeName = csf.getName();
|
res.localeName = csf.getName();
|
||||||
res.object = csf;
|
res.object = csf;
|
||||||
res.objectType = ObjectType.POI_TYPE;
|
addPoiTypeResult(phrase, resultMatcher, showTopFiltersOnly, csf.getFilterId(), res);
|
||||||
if (showTopFiltersOnly) {
|
|
||||||
if (filterOrders.contains(csf.getFilterId())) {
|
|
||||||
res.priority = SEARCH_AMENITY_TYPE_PRIORITY + filterOrders.indexOf(csf.getFilterId());
|
|
||||||
resultMatcher.publish(res);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.priority = SEARCH_AMENITY_TYPE_PRIORITY + customPoiFiltersPriorites.get(i);
|
|
||||||
resultMatcher.publish(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addPoiTypeResult(SearchPhrase phrase, SearchResultMatcher resultMatcher, boolean showTopFiltersOnly,
|
||||||
|
String stdFilterId , SearchResult res) {
|
||||||
|
res.priorityDistance = 0;
|
||||||
|
res.objectType = ObjectType.POI_TYPE;
|
||||||
|
if (showTopFiltersOnly) {
|
||||||
|
if (activePoiFilters.containsKey(stdFilterId)) {
|
||||||
|
res.priority = getPoiTypePriority(stdFilterId);
|
||||||
|
resultMatcher.publish(res);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
phrase.countUnknownWordsMatchMainResult(res);
|
||||||
|
res.priority = SEARCH_AMENITY_TYPE_PRIORITY;
|
||||||
|
resultMatcher.publish(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPoiTypePriority(String stdFilterId) {
|
||||||
|
Integer i = activePoiFilters.get(stdFilterId);
|
||||||
|
if ( i == null) {
|
||||||
|
return SEARCH_AMENITY_TYPE_PRIORITY;
|
||||||
|
}
|
||||||
|
return SEARCH_AMENITY_TYPE_PRIORITY + i.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getStandardFilterId(AbstractPoiType poi) {
|
public String getStandardFilterId(AbstractPoiType poi) {
|
||||||
return STD_POI_FILTER_PREFIX + poi.getKeyName();
|
return STD_POI_FILTER_PREFIX + poi.getKeyName();
|
||||||
}
|
}
|
||||||
|
@ -842,68 +806,67 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean search(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
public boolean search(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
||||||
|
SearchPoiTypeFilter poiTypeFilter = null;
|
||||||
|
String nameFilter = null;
|
||||||
if (phrase.isLastWord(ObjectType.POI_TYPE)) {
|
if (phrase.isLastWord(ObjectType.POI_TYPE)) {
|
||||||
Object obj = phrase.getLastSelectedWord().getResult().object;
|
Object obj = phrase.getLastSelectedWord().getResult().object;
|
||||||
SearchPoiTypeFilter ptf;
|
|
||||||
if (obj instanceof AbstractPoiType) {
|
if (obj instanceof AbstractPoiType) {
|
||||||
ptf = getPoiTypeFilter((AbstractPoiType) obj);
|
poiTypeFilter = getPoiTypeFilter((AbstractPoiType) obj);
|
||||||
} else if (obj instanceof SearchPoiTypeFilter) {
|
} else if (obj instanceof SearchPoiTypeFilter) {
|
||||||
ptf = (SearchPoiTypeFilter) obj;
|
poiTypeFilter = (SearchPoiTypeFilter) obj;
|
||||||
} else {
|
} else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
searchPoi(phrase, resultMatcher, obj, null, ptf);
|
|
||||||
} else if (searchAmenityTypesAPI != null) {
|
} else if (searchAmenityTypesAPI != null) {
|
||||||
if (phrase.getUnknownSearchWordPoiTypes() == null) {
|
NameStringMatcher nm = phrase.getFullUnknownNameMatcher();
|
||||||
searchAmenityTypesAPI.search(phrase, null);
|
searchAmenityTypesAPI.initPoiTypes();
|
||||||
}
|
List<AbstractPoiType> presentPoiTypes = searchAmenityTypesAPI.getPoiTypeResults(nm, false);
|
||||||
|
// TODO get first ?
|
||||||
AbstractPoiType poiType = phrase.getUnknownSearchWordPoiType();
|
AbstractPoiType poiType = phrase.getUnknownSearchWordPoiType();
|
||||||
if (poiType != null) {
|
if (poiType != null) {
|
||||||
SearchPoiTypeFilter ptf = getPoiTypeFilter(poiType);
|
poiTypeFilter = getPoiTypeFilter(poiType);
|
||||||
String customName = phrase.getPoiNameFilter(poiType);
|
nameFilter = phrase.getPoiNameFilter(poiType);
|
||||||
if (customName != null) {
|
if (nameFilter != null) {
|
||||||
phrase.setUnknownSearchWordPoiType(poiType);
|
phrase.setUnknownSearchWordPoiType(poiType);
|
||||||
searchPoi(phrase, resultMatcher, null, customName.length() == 0 ? null : customName, ptf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (poiTypeFilter != null) {
|
||||||
|
QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS);
|
||||||
|
List<BinaryMapIndexReader> offlineIndexes = phrase.getOfflineIndexes();
|
||||||
|
Set<String> searchedPois = new TreeSet<>();
|
||||||
|
for (BinaryMapIndexReader r : offlineIndexes) {
|
||||||
|
ResultMatcher<Amenity> rm = getResultMatcher(phrase, resultMatcher, nameFilter, r, searchedPois);
|
||||||
|
if (poiTypeFilter instanceof CustomSearchPoiFilter) {
|
||||||
|
rm = ((CustomSearchPoiFilter) poiTypeFilter).wrapResultMatcher(rm);
|
||||||
|
}
|
||||||
|
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest((int) bbox.left,
|
||||||
|
(int) bbox.right, (int) bbox.top, (int) bbox.bottom, -1, poiTypeFilter, rm);
|
||||||
|
r.searchPoi(req);
|
||||||
|
resultMatcher.apiSearchRegionFinished(this, r, phrase);
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchPoi(SearchPhrase phrase, SearchResultMatcher resultMatcher, Object obj, String customName, SearchPoiTypeFilter ptf) throws IOException {
|
|
||||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS);
|
|
||||||
List<BinaryMapIndexReader> oo = phrase.getOfflineIndexes();
|
|
||||||
Set<String> searchedPois = new TreeSet<>();
|
|
||||||
for (BinaryMapIndexReader o : oo) {
|
|
||||||
ResultMatcher<Amenity> rm = getResultMatcher(phrase, resultMatcher, customName, o, searchedPois);
|
|
||||||
if (obj instanceof CustomSearchPoiFilter) {
|
|
||||||
rm = ((CustomSearchPoiFilter) obj).wrapResultMatcher(rm);
|
|
||||||
}
|
|
||||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(
|
|
||||||
(int) bbox.left, (int) bbox.right,
|
|
||||||
(int) bbox.top, (int) bbox.bottom, -1, ptf,
|
|
||||||
rm);
|
|
||||||
o.searchPoi(req);
|
|
||||||
resultMatcher.apiSearchRegionFinished(this, o, phrase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResultMatcher<Amenity> getResultMatcher(final SearchPhrase phrase, final SearchResultMatcher resultMatcher,
|
private ResultMatcher<Amenity> getResultMatcher(final SearchPhrase phrase, final SearchResultMatcher resultMatcher,
|
||||||
final String customName, final BinaryMapIndexReader selected,
|
final String nameFilter, final BinaryMapIndexReader selected,
|
||||||
final Set<String> searchedPois) {
|
final Set<String> searchedPois) {
|
||||||
String unknownSearchPhrase = phrase.getUnknownSearchPhrase().trim();
|
// TODO
|
||||||
final NameStringMatcher phraseMatcher;
|
// String unknownSearchPhrase = phrase.getUnknownSearchPhrase().trim();
|
||||||
if (!Algorithms.isEmpty(unknownSearchPhrase)) {
|
// final NameStringMatcher phraseMatcher;
|
||||||
phraseMatcher = new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_EQUALS);
|
// if (!Algorithms.isEmpty(unknownSearchPhrase)) {
|
||||||
} else {
|
// phraseMatcher = new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_EQUALS);
|
||||||
phraseMatcher = null;
|
// } else {
|
||||||
}
|
// phraseMatcher = null;
|
||||||
|
// }
|
||||||
final NameStringMatcher ns;
|
final NameStringMatcher ns;
|
||||||
final boolean hasCustomName = !Algorithms.isEmpty(customName);
|
final boolean hasCustomName = !Algorithms.isEmpty(nameFilter);
|
||||||
if (hasCustomName) {
|
if (hasCustomName) {
|
||||||
ns = phrase.getNameStringMatcher(customName, phrase.isLastUnknownSearchWordComplete());
|
ns = phrase.getNameStringMatcher(nameFilter, phrase.isLastUnknownSearchWordComplete());
|
||||||
} else {
|
} else {
|
||||||
ns = phrase.getNameStringMatcher();
|
ns = phrase.getFirstUnknownNameStringMatcher();
|
||||||
}
|
}
|
||||||
return new ResultMatcher<Amenity>() {
|
return new ResultMatcher<Amenity>() {
|
||||||
|
|
||||||
|
@ -930,15 +893,19 @@ public class SearchCoreFactory {
|
||||||
res.localeName = object.getSubType();
|
res.localeName = object.getSubType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (phrase.isUnknownSearchWordPresent()
|
if (phrase.isUnknownSearchWordPresent()) {
|
||||||
&& !(ns.matches(res.localeName) || ns.matches(res.otherNames))) {
|
if (ns.matches(res.localeName) || ns.matches(res.otherNames)) {
|
||||||
|
phrase.countUnknownWordsMatchMainResult(res);
|
||||||
|
} else {
|
||||||
String ref = object.getTagContent(Amenity.REF, null);
|
String ref = object.getTagContent(Amenity.REF, null);
|
||||||
if (ref == null || !ns.matches(ref)) {
|
if (ref == null || !ns.matches(ref)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
phrase.countUnknownWordsMatch(res, ref, null);
|
||||||
res.localeName += " " + ref;
|
res.localeName += " " + ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
res.object = object;
|
res.object = object;
|
||||||
res.preferredZoom = 17;
|
res.preferredZoom = 17;
|
||||||
|
@ -946,6 +913,7 @@ public class SearchCoreFactory {
|
||||||
res.location = object.getLocation();
|
res.location = object.getLocation();
|
||||||
res.priority = SEARCH_AMENITY_BY_TYPE_PRIORITY;
|
res.priority = SEARCH_AMENITY_BY_TYPE_PRIORITY;
|
||||||
res.priorityDistance = 1;
|
res.priorityDistance = 1;
|
||||||
|
|
||||||
if (phraseMatcher != null) {
|
if (phraseMatcher != null) {
|
||||||
boolean unknownPhraseMatches = phraseMatcher.matches(res.localeName);
|
boolean unknownPhraseMatches = phraseMatcher.matches(res.localeName);
|
||||||
AbstractPoiType unknownSearchWordPoiType = phrase.getUnknownSearchWordPoiType();
|
AbstractPoiType unknownSearchWordPoiType = phrase.getUnknownSearchWordPoiType();
|
||||||
|
@ -969,7 +937,6 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchPoiTypeFilter getPoiTypeFilter(AbstractPoiType pt) {
|
private SearchPoiTypeFilter getPoiTypeFilter(AbstractPoiType pt) {
|
||||||
|
|
||||||
acceptedTypes.clear();
|
acceptedTypes.clear();
|
||||||
poiAdditionals.clear();
|
poiAdditionals.clear();
|
||||||
updateTypesToAccept(pt);
|
updateTypesToAccept(pt);
|
||||||
|
@ -1045,16 +1012,8 @@ public class SearchCoreFactory {
|
||||||
sw.getResult().file.preloadStreets(c, null);
|
sw.getResult().file.preloadStreets(c, null);
|
||||||
}
|
}
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
String wordToSearch = phrase.getUnknownWordToSearch();
|
NameStringMatcher nm = phrase.getMainUnknownNameStringMatcher();
|
||||||
boolean firstUnknownWordMatches = wordToSearch.equals(phrase.getUnknownSearchWord());
|
|
||||||
NameStringMatcher nm = phrase.getNameStringMatcher(wordToSearch, phrase.isUnknownSearchWordComplete());
|
|
||||||
String unknownSearchPhrase = phrase.getUnknownSearchPhrase().trim();
|
|
||||||
NameStringMatcher phraseMatcher = null;
|
|
||||||
if (!Algorithms.isEmpty(unknownSearchPhrase)) {
|
|
||||||
phraseMatcher = new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_EQUALS);
|
|
||||||
}
|
|
||||||
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());
|
||||||
|
@ -1067,12 +1026,6 @@ 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);
|
|
||||||
if (phraseMatcher != null) {
|
|
||||||
res.unknownPhraseMatches = phraseMatcher.matches(res.localeName);
|
|
||||||
}
|
|
||||||
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;
|
||||||
|
@ -1102,11 +1055,6 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLastWordCityGroup(SearchPhrase p ) {
|
|
||||||
return p.isLastWord(ObjectType.CITY) || p.isLastWord(ObjectType.POSTCODE) ||
|
|
||||||
p.isLastWord(ObjectType.VILLAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SearchBuildingAndIntersectionsByStreetAPI extends SearchBaseAPI {
|
public static class SearchBuildingAndIntersectionsByStreetAPI extends SearchBaseAPI {
|
||||||
Street cacheBuilding;
|
Street cacheBuilding;
|
||||||
|
|
||||||
|
@ -1179,7 +1127,7 @@ public class SearchCoreFactory {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
String lw = phrase.getUnknownWordToSearchBuilding();
|
String lw = phrase.getUnknownWordToSearchBuilding();
|
||||||
NameStringMatcher buildingMatch = phrase.getNameStringMatcher(lw, phrase.isLastUnknownSearchWordComplete());
|
NameStringMatcher buildingMatch = phrase.getUnknownWordToSearchBuildingNameMatcher();
|
||||||
NameStringMatcher startMatch = new NameStringMatcher(lw, StringMatcherMode.CHECK_ONLY_STARTS_WITH);
|
NameStringMatcher startMatch = new NameStringMatcher(lw, StringMatcherMode.CHECK_ONLY_STARTS_WITH);
|
||||||
for (Building b : s.getBuildings()) {
|
for (Building b : s.getBuildings()) {
|
||||||
SearchResult res = new SearchResult(phrase);
|
SearchResult res = new SearchResult(phrase);
|
||||||
|
@ -1194,6 +1142,7 @@ public class SearchCoreFactory {
|
||||||
res.file = file;
|
res.file = file;
|
||||||
res.priority = priority;
|
res.priority = priority;
|
||||||
res.priorityDistance = 0;
|
res.priorityDistance = 0;
|
||||||
|
// TOOO phrase.countUnknownWordsMatchMainResult(res);
|
||||||
res.firstUnknownWordMatches = startMatch.matches(res.localeName);
|
res.firstUnknownWordMatches = startMatch.matches(res.localeName);
|
||||||
res.relatedObject = s;
|
res.relatedObject = s;
|
||||||
res.localeRelatedObjectName = s.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
res.localeRelatedObjectName = s.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
||||||
|
@ -1208,7 +1157,7 @@ public class SearchCoreFactory {
|
||||||
resultMatcher.publish(res);
|
resultMatcher.publish(res);
|
||||||
}
|
}
|
||||||
String streetIntersection = phrase.getUnknownWordToSearch();
|
String streetIntersection = phrase.getUnknownWordToSearch();
|
||||||
NameStringMatcher streetMatch = phrase.getNameStringMatcher(streetIntersection, phrase.isLastUnknownSearchWordComplete());
|
NameStringMatcher streetMatch = phrase.getMainUnknownNameStringMatcher();
|
||||||
if (Algorithms.isEmpty(streetIntersection) ||
|
if (Algorithms.isEmpty(streetIntersection) ||
|
||||||
(!Character.isDigit(streetIntersection.charAt(0)) &&
|
(!Character.isDigit(streetIntersection.charAt(0)) &&
|
||||||
CommonWords.getCommonSearch(streetIntersection) == -1) ) {
|
CommonWords.getCommonSearch(streetIntersection) == -1) ) {
|
||||||
|
@ -1218,6 +1167,7 @@ public class SearchCoreFactory {
|
||||||
|| !phrase.isSearchTypeAllowed(ObjectType.STREET_INTERSECTION)) {
|
|| !phrase.isSearchTypeAllowed(ObjectType.STREET_INTERSECTION)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// TOOO phrase.countUnknownWordsMatchMainResult(res);
|
||||||
res.otherNames = street.getAllNames(true);
|
res.otherNames = street.getAllNames(true);
|
||||||
res.localeName = street.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
res.localeName = street.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
||||||
res.object = street;
|
res.object = street;
|
||||||
|
@ -1404,4 +1354,22 @@ public class SearchCoreFactory {
|
||||||
return cachedParsedCode == null ? SEARCH_LOCATION_PRIORITY : SEARCH_MAX_PRIORITY;
|
return cachedParsedCode == null ? SEARCH_LOCATION_PRIORITY : SEARCH_MAX_PRIORITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String stripBraces(String localeName) {
|
||||||
|
int i = localeName.indexOf('(');
|
||||||
|
String retName = localeName;
|
||||||
|
if (i > -1) {
|
||||||
|
retName = localeName.substring(0, i);
|
||||||
|
int j = localeName.indexOf(')', i);
|
||||||
|
if (j > -1) {
|
||||||
|
retName = retName.trim() + ' ' + localeName.substring(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLastWordCityGroup(SearchPhrase p ) {
|
||||||
|
return p.isLastWord(ObjectType.CITY) || p.isLastWord(ObjectType.POSTCODE) ||
|
||||||
|
p.isLastWord(ObjectType.VILLAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package net.osmand.search.core;
|
package net.osmand.search.core;
|
||||||
|
|
||||||
import net.osmand.Collator;
|
import net.osmand.Collator;
|
||||||
import net.osmand.CollatorStringMatcher;
|
import net.osmand.CollatorStringMatcher;import net.osmand.OsmAndCollator;
|
||||||
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;
|
||||||
|
@ -10,6 +10,7 @@ import net.osmand.binary.CommonWords;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.osm.AbstractPoiType;
|
import net.osmand.osm.AbstractPoiType;
|
||||||
|
import net.osmand.search.core.SearchPhrase.NameStringMatcher;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.LocationParser;
|
import net.osmand.util.LocationParser;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
@ -27,31 +28,39 @@ import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
//immutable object
|
// Immutable object !
|
||||||
public class SearchPhrase {
|
public class SearchPhrase {
|
||||||
|
|
||||||
private List<SearchWord> words = new ArrayList<>();
|
|
||||||
private List<String> unknownWords = new ArrayList<>();
|
|
||||||
private List<NameStringMatcher> unknownWordsMatcher = new ArrayList<>();
|
|
||||||
private String unknownSearchWordTrim;
|
|
||||||
private String rawUnknownSearchPhrase = "";
|
|
||||||
private String unknownSearchPhrase = "";
|
|
||||||
private AbstractPoiType unknownSearchWordPoiType;
|
|
||||||
private List<AbstractPoiType> unknownSearchWordPoiTypes = null;
|
|
||||||
|
|
||||||
private NameStringMatcher sm;
|
|
||||||
private SearchSettings settings;
|
|
||||||
private List<BinaryMapIndexReader> indexes;
|
|
||||||
|
|
||||||
private QuadRect cache1kmRect;
|
|
||||||
private boolean lastUnknownSearchWordComplete;
|
|
||||||
private static final String DELIMITER = " ";
|
private static final String DELIMITER = " ";
|
||||||
private static final String ALLDELIMITERS = "\\s|,";
|
private static final String ALLDELIMITERS = "\\s|,";
|
||||||
private static final Pattern reg = Pattern.compile(ALLDELIMITERS);
|
private static final Pattern reg = Pattern.compile(ALLDELIMITERS);
|
||||||
private Collator clt;
|
|
||||||
private static Comparator<String> commonWordsComparator;
|
private static Comparator<String> commonWordsComparator;
|
||||||
|
|
||||||
private static Set<String> conjunctions = new TreeSet<>();
|
private static Set<String> conjunctions = new TreeSet<>();
|
||||||
|
|
||||||
|
private final Collator clt;
|
||||||
|
private final SearchSettings settings;
|
||||||
|
private List<BinaryMapIndexReader> indexes;
|
||||||
|
|
||||||
|
// Object consists of 2 part [known + unknown]
|
||||||
|
private String fullTextSearchPhrase = "";
|
||||||
|
private String unknownSearchPhrase = "";
|
||||||
|
|
||||||
|
// Words of 2 parts
|
||||||
|
private List<SearchWord> words = new ArrayList<>();
|
||||||
|
private String firstUnknownSearchWord = "";
|
||||||
|
private List<String> otherUnknownWords = new ArrayList<>();
|
||||||
|
private boolean lastUnknownSearchWordComplete;
|
||||||
|
|
||||||
|
// Main unknown word used for search
|
||||||
|
private String mainUnknownWordToSearch = null;
|
||||||
|
private boolean mainUnknownSearchWordComplete;
|
||||||
|
|
||||||
|
// Name Searchers
|
||||||
|
private NameStringMatcher firstUnknownNameStringMatcher;
|
||||||
|
private NameStringMatcher mainUnknownNameStringMatcher;
|
||||||
|
private List<NameStringMatcher> unknownWordsMatcher = new ArrayList<>();
|
||||||
|
|
||||||
|
private QuadRect cache1kmRect;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// the
|
// the
|
||||||
conjunctions.add("the");
|
conjunctions.add("the");
|
||||||
|
@ -140,7 +149,7 @@ public class SearchPhrase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SearchPhrase(SearchSettings settings, Collator clt) {
|
private SearchPhrase(SearchSettings settings, Collator clt) {
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.clt = clt;
|
this.clt = clt;
|
||||||
}
|
}
|
||||||
|
@ -149,83 +158,160 @@ public class SearchPhrase {
|
||||||
return clt;
|
return clt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public SearchPhrase generateNewPhrase(String text, SearchSettings settings) {
|
public SearchPhrase generateNewPhrase(String text, SearchSettings settings) {
|
||||||
SearchPhrase sp = new SearchPhrase(settings, this.clt);
|
String textToSearch = text;
|
||||||
String restText = text;
|
|
||||||
List<SearchWord> leftWords = this.words;
|
List<SearchWord> leftWords = this.words;
|
||||||
String thisTxt = getText(true);
|
String thisTxt = getText(true);
|
||||||
|
List<SearchWord> foundWords = new ArrayList<>();
|
||||||
if (text.startsWith(thisTxt)) {
|
if (text.startsWith(thisTxt)) {
|
||||||
// string is longer
|
// string is longer
|
||||||
restText = text.substring(getText(false).length());
|
textToSearch = text.substring(getText(false).length());
|
||||||
sp.words = new ArrayList<>(this.words);
|
foundWords.addAll(this.words);
|
||||||
leftWords = leftWords.subList(leftWords.size(), leftWords.size());
|
leftWords = leftWords.subList(leftWords.size(), leftWords.size());
|
||||||
}
|
}
|
||||||
for (SearchWord w : leftWords) {
|
for (SearchWord w : leftWords) {
|
||||||
if(restText.startsWith(w.getWord() + DELIMITER)) {
|
if (textToSearch.startsWith(w.getWord() + DELIMITER)) {
|
||||||
sp.words.add(w);
|
foundWords.add(w);
|
||||||
restText = restText.substring(w.getWord().length() + DELIMITER.length());
|
textToSearch = textToSearch.substring(w.getWord().length() + DELIMITER.length());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sp.rawUnknownSearchPhrase = text;
|
SearchPhrase sp = createNewSearchPhrase(settings, text, foundWords, textToSearch);
|
||||||
sp.unknownSearchPhrase = restText;
|
return sp;
|
||||||
sp.unknownWords.clear();
|
}
|
||||||
sp.unknownWordsMatcher.clear();
|
|
||||||
|
|
||||||
if (!reg.matcher(restText).find()) {
|
|
||||||
sp.unknownSearchWordTrim = sp.unknownSearchPhrase.trim();
|
public static SearchPhrase emptyPhrase() {
|
||||||
|
return emptyPhrase(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SearchPhrase emptyPhrase(SearchSettings settings) {
|
||||||
|
return emptyPhrase(settings, OsmAndCollator.primaryCollator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SearchPhrase emptyPhrase(SearchSettings settings, Collator clt) {
|
||||||
|
return new SearchPhrase(settings, clt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// init search phrase
|
||||||
|
private SearchPhrase createNewSearchPhrase(SearchSettings settings, String fullText, List<SearchWord> foundWords,
|
||||||
|
String textToSearch) {
|
||||||
|
SearchPhrase sp = new SearchPhrase(settings, this.clt);
|
||||||
|
sp.words = foundWords;
|
||||||
|
sp.fullTextSearchPhrase = fullText;
|
||||||
|
sp.unknownSearchPhrase = textToSearch;
|
||||||
|
|
||||||
|
if (!reg.matcher(textToSearch).find()) {
|
||||||
|
sp.firstUnknownSearchWord = sp.unknownSearchPhrase.trim();
|
||||||
} else {
|
} else {
|
||||||
sp.unknownSearchWordTrim = "";
|
sp.firstUnknownSearchWord = "";
|
||||||
String[] ws = restText.split(ALLDELIMITERS);
|
String[] ws = textToSearch.split(ALLDELIMITERS);
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (int i = 0; i < ws.length ; i++) {
|
for (int i = 0; i < ws.length ; i++) {
|
||||||
String wd = ws[i].trim();
|
String wd = ws[i].trim();
|
||||||
if (wd.length() > 0 && !conjunctions.contains(wd.toLowerCase())) {
|
if (wd.length() > 0 && !conjunctions.contains(wd.toLowerCase())) {
|
||||||
if (first) {
|
if (first) {
|
||||||
sp.unknownSearchWordTrim = wd;
|
sp.firstUnknownSearchWord = wd;
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
sp.unknownWords.add(wd);
|
sp.otherUnknownWords.add(wd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sp.lastUnknownSearchWordComplete = false;
|
sp.lastUnknownSearchWordComplete = isTextComplete(fullText) ;
|
||||||
if (text.length() > 0 ) {
|
|
||||||
char ch = text.charAt(text.length() - 1);
|
|
||||||
sp.lastUnknownSearchWordComplete = ch == ' ' || ch == ',' || ch == '\r' || ch == '\n'
|
|
||||||
|| ch == ';';
|
|
||||||
}
|
|
||||||
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SearchPhrase selectWord(SearchResult res, List<String> unknownWords, boolean lastComplete) {
|
||||||
|
SearchPhrase sp = new SearchPhrase(this.settings, this.clt);
|
||||||
|
addResult(res, sp);
|
||||||
|
SearchResult prnt = res.parentSearchResult;
|
||||||
|
while (prnt != null) {
|
||||||
|
addResult(prnt, sp);
|
||||||
|
prnt = prnt.parentSearchResult;
|
||||||
|
}
|
||||||
|
sp.words.addAll(0, this.words);
|
||||||
|
if (unknownWords != null) {
|
||||||
|
sp.lastUnknownSearchWordComplete = lastComplete;
|
||||||
|
StringBuilder genUnknownSearchPhrase = new StringBuilder();
|
||||||
|
for (int i = 0; i < unknownWords.size(); i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
sp.firstUnknownSearchWord = unknownWords.get(0);
|
||||||
|
} else {
|
||||||
|
sp.otherUnknownWords.add(unknownWords.get(i));
|
||||||
|
}
|
||||||
|
genUnknownSearchPhrase.append(unknownWords.get(i)).append(" ");
|
||||||
|
}
|
||||||
|
sp.fullTextSearchPhrase = fullTextSearchPhrase;
|
||||||
|
sp.unknownSearchPhrase = genUnknownSearchPhrase.toString().trim();
|
||||||
|
}
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void calcMainUnknownWordToSearch() {
|
||||||
|
if (mainUnknownWordToSearch != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> unknownSearchWords = otherUnknownWords;
|
||||||
|
mainUnknownWordToSearch = firstUnknownSearchWord;
|
||||||
|
mainUnknownSearchWordComplete = lastUnknownSearchWordComplete;
|
||||||
|
if (unknownSearchWords.size() > 0) {
|
||||||
|
mainUnknownSearchWordComplete = true;
|
||||||
|
List<String> searchWords = new ArrayList<>(unknownSearchWords);
|
||||||
|
searchWords.add(0, getFirstUnknownSearchWord());
|
||||||
|
Collections.sort(searchWords, commonWordsComparator);
|
||||||
|
for (String s : searchWords) {
|
||||||
|
if (s.length() > 0 && !Character.isDigit(s.charAt(0)) && !LocationParser.isValidOLC(s)) {
|
||||||
|
mainUnknownWordToSearch = s.trim();
|
||||||
|
int unknownInd = unknownSearchWords.indexOf(s);
|
||||||
|
if (!lastUnknownSearchWordComplete && unknownSearchWords.size() - 1 == unknownInd) {
|
||||||
|
mainUnknownSearchWordComplete = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<SearchWord> getWords() {
|
public List<SearchWord> getWords() {
|
||||||
return words;
|
return words;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isUnknownSearchWordComplete() {
|
public boolean isMainUnknownSearchWordComplete() {
|
||||||
return lastUnknownSearchWordComplete || unknownWords.size() > 0 || unknownSearchWordPoiType != null;
|
// return lastUnknownSearchWordComplete || otherUnknownWords.size() > 0 || unknownSearchWordPoiType != null;
|
||||||
|
// TODO unknownSearchWordPoiType != null;!!!
|
||||||
|
return mainUnknownSearchWordComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isLastUnknownSearchWordComplete() {
|
public boolean isLastUnknownSearchWordComplete() {
|
||||||
return lastUnknownSearchWordComplete;
|
return lastUnknownSearchWordComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NameStringMatcher getFullUnknownNameMatcher() {
|
||||||
|
// TODO investigate diesel 95
|
||||||
|
if (isLastUnknownSearchWordComplete() || hasMoreThanOneUnknownSearchWord()) {
|
||||||
|
return new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.TRIM_AND_CHECK_ONLY_STARTS_WITH);
|
||||||
|
} else {
|
||||||
|
return new NameStringMatcher(unknownSearchPhrase, StringMatcherMode.CHECK_STARTS_FROM_SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getUnknownSearchWords() {
|
public boolean hasMoreThanOneUnknownSearchWord() {
|
||||||
return unknownWords;
|
return otherUnknownWords.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getUnknownSearchWords(Collection<String> exclude) {
|
public List<String> getUnknownSearchWords(Collection<String> exclude) {
|
||||||
if(exclude == null || unknownWords.size() == 0 || exclude.size() == 0) {
|
if(exclude == null || otherUnknownWords.size() == 0 || exclude.size() == 0) {
|
||||||
return unknownWords;
|
return otherUnknownWords;
|
||||||
}
|
}
|
||||||
List<String> l = new ArrayList<>();
|
List<String> l = new ArrayList<>();
|
||||||
for(String uw : unknownWords) {
|
for(String uw : otherUnknownWords) {
|
||||||
if(exclude == null || !exclude.contains(uw)) {
|
if(exclude == null || !exclude.contains(uw)) {
|
||||||
l.add(uw);
|
l.add(uw);
|
||||||
}
|
}
|
||||||
|
@ -234,12 +320,12 @@ public class SearchPhrase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getUnknownSearchWord() {
|
public String getFirstUnknownSearchWord() {
|
||||||
return unknownSearchWordTrim;
|
return firstUnknownSearchWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRawUnknownSearchPhrase() {
|
public String getFullSearchPhrase() {
|
||||||
return rawUnknownSearchPhrase;
|
return fullTextSearchPhrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnknownSearchPhrase() {
|
public String getUnknownSearchPhrase() {
|
||||||
|
@ -247,64 +333,7 @@ public class SearchPhrase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnknownSearchWordPresent() {
|
public boolean isUnknownSearchWordPresent() {
|
||||||
return unknownSearchWordTrim.length() > 0;
|
return firstUnknownSearchWord.length() > 0;
|
||||||
}
|
|
||||||
|
|
||||||
public int getUnknownSearchWordLength() {
|
|
||||||
return unknownSearchWordTrim.length() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractPoiType getUnknownSearchWordPoiType() {
|
|
||||||
return unknownSearchWordPoiType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnknownSearchWordPoiType(AbstractPoiType unknownSearchWordPoiType) {
|
|
||||||
this.unknownSearchWordPoiType = unknownSearchWordPoiType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasUnknownSearchWordPoiType() {
|
|
||||||
return unknownSearchWordPoiType != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPoiNameFilter() {
|
|
||||||
return getPoiNameFilter(unknownSearchWordPoiType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasUnknownSearchWordPoiTypes() {
|
|
||||||
return unknownSearchWordPoiTypes != null && unknownSearchWordPoiTypes.size() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<AbstractPoiType> getUnknownSearchWordPoiTypes() {
|
|
||||||
return unknownSearchWordPoiTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnknownSearchWordPoiTypes(List<AbstractPoiType> unknownSearchWordPoiTypes) {
|
|
||||||
this.unknownSearchWordPoiTypes = unknownSearchWordPoiTypes;
|
|
||||||
for (AbstractPoiType pt : unknownSearchWordPoiTypes) {
|
|
||||||
if (getPoiNameFilter(pt) != null) {
|
|
||||||
setUnknownSearchWordPoiType(pt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPoiNameFilter(AbstractPoiType pt) {
|
|
||||||
String nameFilter = null;
|
|
||||||
if (pt != null) {
|
|
||||||
NameStringMatcher nm = getNameStringMatcher(getUnknownSearchWord(), true);
|
|
||||||
String unknownSearchPhrase = getUnknownSearchPhrase();
|
|
||||||
String enTranslation = pt.getEnTranslation();
|
|
||||||
String translation = pt.getTranslation();
|
|
||||||
String synonyms = pt.getSynonyms();
|
|
||||||
if (unknownSearchPhrase.length() >= enTranslation.length() && nm.matches(enTranslation)) {
|
|
||||||
nameFilter = unknownSearchPhrase.substring(enTranslation.length()).trim();
|
|
||||||
} else if (unknownSearchPhrase.length() >= translation.length() && nm.matches(translation)) {
|
|
||||||
nameFilter = unknownSearchPhrase.substring(translation.length()).trim();
|
|
||||||
} else if (unknownSearchPhrase.length() >= synonyms.length() && nm.matches(synonyms)) {
|
|
||||||
nameFilter = unknownSearchPhrase.substring(synonyms.length()).trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nameFilter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuadRect getRadiusBBoxToSearch(int radius) {
|
public QuadRect getRadiusBBoxToSearch(int radius) {
|
||||||
|
@ -459,31 +488,6 @@ public class SearchPhrase {
|
||||||
return selectWord(res, null, false);
|
return selectWord(res, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchPhrase selectWord(SearchResult res, List<String> unknownWords, boolean lastComplete) {
|
|
||||||
SearchPhrase sp = new SearchPhrase(this.settings, this.clt);
|
|
||||||
addResult(res, sp);
|
|
||||||
SearchResult prnt = res.parentSearchResult;
|
|
||||||
while (prnt != null) {
|
|
||||||
addResult(prnt, sp);
|
|
||||||
prnt = prnt.parentSearchResult;
|
|
||||||
}
|
|
||||||
sp.words.addAll(0, this.words);
|
|
||||||
if (unknownWords != null) {
|
|
||||||
sp.lastUnknownSearchWordComplete = lastComplete;
|
|
||||||
StringBuilder genUnknownSearchPhrase = new StringBuilder();
|
|
||||||
for (int i = 0; i < unknownWords.size(); i++) {
|
|
||||||
if (i == 0) {
|
|
||||||
sp.unknownSearchWordTrim = unknownWords.get(0);
|
|
||||||
} else {
|
|
||||||
sp.unknownWords.add(unknownWords.get(i));
|
|
||||||
}
|
|
||||||
genUnknownSearchPhrase.append(unknownWords.get(i)).append(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
sp.rawUnknownSearchPhrase = sp.unknownSearchPhrase = genUnknownSearchPhrase.toString().trim();
|
|
||||||
}
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addResult(SearchResult res, SearchPhrase sp) {
|
private void addResult(SearchResult res, SearchPhrase sp) {
|
||||||
SearchWord sw = new SearchWord(res.wordsSpan != null ? res.wordsSpan : res.localeName.trim(), res);
|
SearchWord sw = new SearchWord(res.wordsSpan != null ? res.wordsSpan : res.localeName.trim(), res);
|
||||||
|
@ -513,16 +517,32 @@ public class SearchPhrase {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NameStringMatcher getNameStringMatcher() {
|
public NameStringMatcher getMainUnknownNameStringMatcher() {
|
||||||
if(sm != null) {
|
calcMainUnknownWordToSearch();
|
||||||
return sm;
|
if (mainUnknownNameStringMatcher == null) {
|
||||||
|
mainUnknownNameStringMatcher = getNameStringMatcher(mainUnknownWordToSearch, mainUnknownSearchWordComplete);
|
||||||
}
|
}
|
||||||
sm = getNameStringMatcher(unknownSearchWordTrim, lastUnknownSearchWordComplete);
|
return mainUnknownNameStringMatcher;
|
||||||
return sm;
|
}
|
||||||
|
|
||||||
|
public NameStringMatcher getFirstUnknownNameStringMatcher() {
|
||||||
|
if (firstUnknownNameStringMatcher == null) {
|
||||||
|
firstUnknownNameStringMatcher = getNameStringMatcher(firstUnknownSearchWord, lastUnknownSearchWordComplete);
|
||||||
|
}
|
||||||
|
return firstUnknownNameStringMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameStringMatcher getUnknownNameStringMatcher(int i) {
|
||||||
|
while (unknownWordsMatcher.size() <= i) {
|
||||||
|
int ind = unknownWordsMatcher.size() - 1;
|
||||||
|
boolean completeMatch = ind < otherUnknownWords.size() - 1 || isLastUnknownSearchWordComplete();
|
||||||
|
unknownWordsMatcher.add(getNameStringMatcher(otherUnknownWords.get(ind), completeMatch));
|
||||||
|
}
|
||||||
|
return unknownWordsMatcher.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NameStringMatcher getNameStringMatcher(String word, boolean complete) {
|
private NameStringMatcher getNameStringMatcher(String word, boolean complete) {
|
||||||
return new NameStringMatcher(word,
|
return new NameStringMatcher(word,
|
||||||
(complete ?
|
(complete ?
|
||||||
StringMatcherMode.CHECK_EQUALS_FROM_SPACE :
|
StringMatcherMode.CHECK_EQUALS_FROM_SPACE :
|
||||||
|
@ -544,12 +564,12 @@ public class SearchPhrase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText(boolean includeLastWord) {
|
public String getText(boolean includeUnknownPart) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for(SearchWord s : words) {
|
for(SearchWord s : words) {
|
||||||
sb.append(s.getWord()).append(DELIMITER.trim() + " ");
|
sb.append(s.getWord()).append(DELIMITER);
|
||||||
}
|
}
|
||||||
if(includeLastWord) {
|
if(includeUnknownPart) {
|
||||||
sb.append(unknownSearchPhrase);
|
sb.append(unknownSearchPhrase);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -558,11 +578,11 @@ public class SearchPhrase {
|
||||||
public String getTextWithoutLastWord() {
|
public String getTextWithoutLastWord() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
List<SearchWord> words = new ArrayList<>(this.words);
|
List<SearchWord> words = new ArrayList<>(this.words);
|
||||||
if(Algorithms.isEmpty(unknownSearchWordTrim) && words.size() > 0) {
|
if (Algorithms.isEmpty(unknownSearchPhrase.trim()) && words.size() > 0) {
|
||||||
words.remove(words.size() - 1);
|
words.remove(words.size() - 1);
|
||||||
}
|
}
|
||||||
for(SearchWord s : words) {
|
for(SearchWord s : words) {
|
||||||
sb.append(s.getWord()).append(DELIMITER.trim() + " ");
|
sb.append(s.getWord()).append(DELIMITER);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -705,8 +725,8 @@ public class SearchPhrase {
|
||||||
|
|
||||||
private CollatorStringMatcher sm;
|
private CollatorStringMatcher sm;
|
||||||
|
|
||||||
public NameStringMatcher(String lastWordTrim, StringMatcherMode mode) {
|
public NameStringMatcher(String namePart, StringMatcherMode mode) {
|
||||||
sm = new CollatorStringMatcher(lastWordTrim, mode);
|
sm = new CollatorStringMatcher(namePart, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matches(Collection<String> map) {
|
public boolean matches(Collection<String> map) {
|
||||||
|
@ -728,35 +748,32 @@ public class SearchPhrase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void countUnknownWordsMatch(SearchResult sr) {
|
public void countUnknownWordsMatchMainResult(SearchResult sr) {
|
||||||
countUnknownWordsMatch(sr, sr.localeName, sr.otherNames);
|
countUnknownWordsMatch(sr, sr.localeName, sr.otherNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void countUnknownWordsMatch(SearchResult sr, String localeName, Collection<String> otherNames) {
|
public void countUnknownWordsMatch(SearchResult sr, String localeName, Collection<String> otherNames) {
|
||||||
if (unknownWords.size() > 0) {
|
if (otherUnknownWords.size() > 0) {
|
||||||
for (int i = 0; i < unknownWords.size(); i++) {
|
for (int i = 0; i < otherUnknownWords.size(); i++) {
|
||||||
if (unknownWordsMatcher.size() == i) {
|
NameStringMatcher ms = getUnknownNameStringMatcher(i);
|
||||||
unknownWordsMatcher.add(new NameStringMatcher(unknownWords.get(i),
|
|
||||||
i < unknownWords.size() - 1 || isLastUnknownSearchWordComplete()
|
|
||||||
? StringMatcherMode.CHECK_EQUALS_FROM_SPACE
|
|
||||||
: StringMatcherMode.CHECK_STARTS_FROM_SPACE));
|
|
||||||
}
|
|
||||||
NameStringMatcher ms = unknownWordsMatcher.get(i);
|
|
||||||
if (ms.matches(localeName) || ms.matches(otherNames)) {
|
if (ms.matches(localeName) || ms.matches(otherNames)) {
|
||||||
if (sr.otherWordsMatch == null) {
|
if (sr.otherWordsMatch == null) {
|
||||||
sr.otherWordsMatch = new TreeSet<>();
|
sr.otherWordsMatch = new TreeSet<>();
|
||||||
}
|
}
|
||||||
sr.otherWordsMatch.add(unknownWords.get(i));
|
sr.otherWordsMatch.add(otherUnknownWords.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!sr.firstUnknownWordMatches) {
|
if(!sr.firstUnknownWordMatches) {
|
||||||
sr.firstUnknownWordMatches = localeName.equals(getUnknownSearchWord()) ||
|
sr.firstUnknownWordMatches = localeName.equals(getFirstUnknownSearchWord()) ||
|
||||||
getNameStringMatcher().matches(localeName) ||
|
getFirstUnknownNameStringMatcher().matches(localeName) ||
|
||||||
getNameStringMatcher().matches(otherNames);
|
getFirstUnknownNameStringMatcher().matches(otherNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getRadiusSearch(int meters, int radiusLevel) {
|
public int getRadiusSearch(int meters, int radiusLevel) {
|
||||||
int res = meters;
|
int res = meters;
|
||||||
for(int k = 0; k < radiusLevel; k++) {
|
for(int k = 0; k < radiusLevel; k++) {
|
||||||
|
@ -777,18 +794,39 @@ public class SearchPhrase {
|
||||||
return (x < y) ? -1 : ((x == y) ? 0 : 1);
|
return (x < y) ? -1 : ((x == y) ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnknownWordToSearchBuilding() {
|
private int getUnknownWordToSearchBuildingInd() {
|
||||||
List<String> unknownSearchWords = getUnknownSearchWords();
|
if (otherUnknownWords.size() > 0 && Algorithms.extractFirstIntegerNumber(getFirstUnknownSearchWord()) == 0) {
|
||||||
if(unknownSearchWords.size() > 0 && Algorithms.extractFirstIntegerNumber(getUnknownSearchWord()) == 0) {
|
int ind = 0;
|
||||||
for(String wrd : unknownSearchWords) {
|
for (String wrd : otherUnknownWords) {
|
||||||
|
ind++;
|
||||||
if (Algorithms.extractFirstIntegerNumber(wrd) != 0) {
|
if (Algorithms.extractFirstIntegerNumber(wrd) != 0) {
|
||||||
return wrd;
|
return ind;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getUnknownSearchWord();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NameStringMatcher getUnknownWordToSearchBuildingNameMatcher() {
|
||||||
|
int ind = getUnknownWordToSearchBuildingInd();
|
||||||
|
if(ind > 0) {
|
||||||
|
return getUnknownNameStringMatcher(ind - 1);
|
||||||
|
} else {
|
||||||
|
return getFirstUnknownNameStringMatcher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnknownWordToSearchBuilding() {
|
||||||
|
int ind = getUnknownWordToSearchBuildingInd();
|
||||||
|
if(ind > 0) {
|
||||||
|
return otherUnknownWords.get(ind - 1);
|
||||||
|
} else {
|
||||||
|
return firstUnknownSearchWord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static int lengthWithoutNumbers(String s) {
|
private static int lengthWithoutNumbers(String s) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
for(int k = 0; k < s.length(); k++) {
|
for(int k = 0; k < s.length(); k++) {
|
||||||
|
@ -802,19 +840,18 @@ public class SearchPhrase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnknownWordToSearch() {
|
public String getUnknownWordToSearch() {
|
||||||
List<String> unknownSearchWords = getUnknownSearchWords();
|
calcMainUnknownWordToSearch();
|
||||||
String wordToSearch = getUnknownSearchWord();
|
return mainUnknownWordToSearch;
|
||||||
if (unknownSearchWords.size() > 0) {
|
|
||||||
List<String> searchWords = new ArrayList<>(unknownSearchWords);
|
|
||||||
searchWords.add(0, getUnknownSearchWord());
|
|
||||||
Collections.sort(searchWords, commonWordsComparator);
|
|
||||||
for (String s : searchWords) {
|
|
||||||
if (s.length() > 0 && !Character.isDigit(s.charAt(0)) && !LocationParser.isValidOLC(s)) {
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isTextComplete(String fullText) {
|
||||||
|
boolean lastUnknownSearchWordComplete = false;
|
||||||
|
if (fullText.length() > 0 ) {
|
||||||
|
char ch = fullText.charAt(fullText.length() - 1);
|
||||||
|
lastUnknownSearchWordComplete = ch == ' ' || ch == ',' || ch == '\r' || ch == '\n'
|
||||||
|
|| ch == ';';
|
||||||
}
|
}
|
||||||
}
|
return lastUnknownSearchWordComplete;
|
||||||
return wordToSearch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,32 @@ public class SearchResult {
|
||||||
// search phrase that makes search result valid
|
// search phrase that makes search result valid
|
||||||
public SearchPhrase requiredSearchPhrase;
|
public SearchPhrase requiredSearchPhrase;
|
||||||
|
|
||||||
|
// internal package fields (used for sorting)
|
||||||
|
public SearchResult parentSearchResult;
|
||||||
|
String wordsSpan ;
|
||||||
|
// TODO
|
||||||
|
boolean firstUnknownWordMatches = true;
|
||||||
|
Collection<String> otherWordsMatch = null;
|
||||||
|
boolean unknownPhraseMatches = false;
|
||||||
|
|
||||||
|
|
||||||
public Object object;
|
public Object object;
|
||||||
public ObjectType objectType;
|
public ObjectType objectType;
|
||||||
public BinaryMapIndexReader file;
|
public BinaryMapIndexReader file;
|
||||||
|
|
||||||
public double priority;
|
public double priority;
|
||||||
public double priorityDistance;
|
public double priorityDistance;
|
||||||
public String wordsSpan ;
|
|
||||||
public SearchResult parentSearchResult;
|
public LatLon location;
|
||||||
public Collection<String> otherWordsMatch = null;
|
public int preferredZoom = 15;
|
||||||
public boolean firstUnknownWordMatches = true;
|
|
||||||
public boolean unknownPhraseMatches = false;
|
public String localeName;
|
||||||
|
public String alternateName;
|
||||||
|
public Collection<String> otherNames;
|
||||||
|
|
||||||
|
public String localeRelatedObjectName;
|
||||||
|
public Object relatedObject;
|
||||||
|
public double distRelatedObjectName;
|
||||||
|
|
||||||
public SearchResult(SearchPhrase sp) {
|
public SearchResult(SearchPhrase sp) {
|
||||||
this.requiredSearchPhrase = sp;
|
this.requiredSearchPhrase = sp;
|
||||||
|
@ -40,7 +55,12 @@ public class SearchResult {
|
||||||
res = ObjectType.getTypeWeight(objectType);
|
res = ObjectType.getTypeWeight(objectType);
|
||||||
}
|
}
|
||||||
if (parentSearchResult != null) {
|
if (parentSearchResult != null) {
|
||||||
|
// TODO
|
||||||
// 10 > maximum type
|
// 10 > maximum type
|
||||||
|
// double x = parentSearchResult.getUnknownPhraseMatchWeight();
|
||||||
|
// if (x == 0) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
// res = Math.max(res, parentSearchResult.getUnknownPhraseMatchWeight());
|
// res = Math.max(res, parentSearchResult.getUnknownPhraseMatchWeight());
|
||||||
res += parentSearchResult.getUnknownPhraseMatchWeight() / 10;
|
res += parentSearchResult.getUnknownPhraseMatchWeight() / 10;
|
||||||
}
|
}
|
||||||
|
@ -77,16 +97,6 @@ public class SearchResult {
|
||||||
return priority - 1 / (1 + pd * distance);
|
return priority - 1 / (1 + pd * distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LatLon location;
|
|
||||||
public int preferredZoom = 15;
|
|
||||||
public String localeName;
|
|
||||||
public String alternateName;
|
|
||||||
|
|
||||||
public Collection<String> otherNames;
|
|
||||||
|
|
||||||
public String localeRelatedObjectName;
|
|
||||||
public Object relatedObject;
|
|
||||||
public double distRelatedObjectName;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class LocationSearchTest {
|
||||||
private void search(String string, LatLon latLon) throws IOException {
|
private void search(String string, LatLon latLon) throws IOException {
|
||||||
SearchResultMatcher srm = new SearchUICore.SearchResultMatcher(null, null, 0, null, 100);
|
SearchResultMatcher srm = new SearchUICore.SearchResultMatcher(null, null, 0, null, 100);
|
||||||
new SearchCoreFactory.SearchLocationAndUrlAPI().
|
new SearchCoreFactory.SearchLocationAndUrlAPI().
|
||||||
search(new SearchPhrase(null, OsmAndCollator.primaryCollator()).generateNewPhrase(string, null), srm);
|
search(SearchPhrase.emptyPhrase().generateNewPhrase(string, null), srm);
|
||||||
Assert.assertEquals(1, srm.getRequestResults().size());
|
Assert.assertEquals(1, srm.getRequestResults().size());
|
||||||
Assert.assertEquals(latLon, srm.getRequestResults().get(0).location);
|
Assert.assertEquals(latLon, srm.getRequestResults().get(0).location);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import net.osmand.OsmAndCollator;
|
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||||
import net.osmand.search.core.SearchPhrase;
|
import net.osmand.search.core.SearchPhrase;
|
||||||
|
@ -29,7 +28,7 @@ public class SearchUICoreGenericTest {
|
||||||
public void testDuplicates() throws IOException {
|
public void testDuplicates() throws IOException {
|
||||||
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
||||||
ss = ss.setOriginalLocation(new LatLon(0, 0));
|
ss = ss.setOriginalLocation(new LatLon(0, 0));
|
||||||
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
|
SearchPhrase phrase = SearchPhrase.emptyPhrase(ss);
|
||||||
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
|
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
|
||||||
List<SearchResult> rs = new ArrayList<>();
|
List<SearchResult> rs = new ArrayList<>();
|
||||||
SearchResult a1 = searchResult(rs, phrase, "a", 100);
|
SearchResult a1 = searchResult(rs, phrase, "a", 100);
|
||||||
|
@ -47,7 +46,7 @@ public class SearchUICoreGenericTest {
|
||||||
public void testNoResort() throws IOException {
|
public void testNoResort() throws IOException {
|
||||||
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
||||||
ss = ss.setOriginalLocation(new LatLon(0, 0));
|
ss = ss.setOriginalLocation(new LatLon(0, 0));
|
||||||
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
|
SearchPhrase phrase = SearchPhrase.emptyPhrase(ss);
|
||||||
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
|
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
|
||||||
List<SearchResult> rs = new ArrayList<>();
|
List<SearchResult> rs = new ArrayList<>();
|
||||||
SearchResult a1 = searchResult(rs, phrase, "a", 100);
|
SearchResult a1 = searchResult(rs, phrase, "a", 100);
|
||||||
|
@ -80,7 +79,7 @@ public class SearchUICoreGenericTest {
|
||||||
public void testNoResortDuplicate() throws IOException {
|
public void testNoResortDuplicate() throws IOException {
|
||||||
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
SearchSettings ss = new SearchSettings((SearchSettings)null);
|
||||||
ss = ss.setOriginalLocation(new LatLon(0, 0));
|
ss = ss.setOriginalLocation(new LatLon(0, 0));
|
||||||
SearchPhrase phrase = new SearchPhrase(ss, OsmAndCollator.primaryCollator());
|
SearchPhrase phrase = SearchPhrase.emptyPhrase(ss);
|
||||||
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
|
SearchResultCollection cll = new SearchUICore.SearchResultCollection(phrase);
|
||||||
List<SearchResult> rs = new ArrayList<>();
|
List<SearchResult> rs = new ArrayList<>();
|
||||||
SearchResult a1 = searchResult(rs, phrase, "a", 100);
|
SearchResult a1 = searchResult(rs, phrase, "a", 100);
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class SearchUICoreTest {
|
||||||
SearchSettings s = SearchSettings.parseJSON(settingsJson);
|
SearchSettings s = SearchSettings.parseJSON(settingsJson);
|
||||||
s.setOfflineIndexes(Collections.singletonList(reader));
|
s.setOfflineIndexes(Collections.singletonList(reader));
|
||||||
|
|
||||||
SearchPhrase phrase = new SearchPhrase(s, OsmAndCollator.primaryCollator());
|
SearchPhrase phrase = SearchPhrase.emptyPhrase(s);
|
||||||
phrase = phrase.generateNewPhrase(phraseText, s);
|
phrase = phrase.generateNewPhrase(phraseText, s);
|
||||||
|
|
||||||
final SearchUICore core = new SearchUICore(MapPoiTypes.getDefault(), "en", false);
|
final SearchUICore core = new SearchUICore(MapPoiTypes.getDefault(), "en", false);
|
||||||
|
|
|
@ -351,11 +351,11 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
cancelSearch();
|
cancelSearch();
|
||||||
SearchPhrase searchPhrase = searchUICore.getPhrase();
|
SearchPhrase searchPhrase = searchUICore.getPhrase();
|
||||||
if (foundPartialLocation) {
|
if (foundPartialLocation) {
|
||||||
QuickSearchCoordinatesFragment.showDialog(QuickSearchDialogFragment.this, searchPhrase.getUnknownSearchWord());
|
QuickSearchCoordinatesFragment.showDialog(QuickSearchDialogFragment.this, searchPhrase.getFirstUnknownSearchWord());
|
||||||
} else if (searchPhrase.isNoSelectedType() || searchPhrase.isLastWord(POI_TYPE)) {
|
} else if (searchPhrase.isNoSelectedType() || searchPhrase.isLastWord(POI_TYPE)) {
|
||||||
PoiUIFilter filter;
|
PoiUIFilter filter;
|
||||||
if (searchPhrase.isNoSelectedType()) {
|
if (searchPhrase.isNoSelectedType()) {
|
||||||
if (isOnlineSearch() && !Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) {
|
if (isOnlineSearch() && !Algorithms.isEmpty(searchPhrase.getFirstUnknownSearchWord())) {
|
||||||
app.getPoiFilters().resetNominatimFilters();
|
app.getPoiFilters().resetNominatimFilters();
|
||||||
filter = app.getPoiFilters().getNominatimPOIFilter();
|
filter = app.getPoiFilters().getNominatimPOIFilter();
|
||||||
filter.setFilterByName(searchPhrase.getUnknownSearchPhrase());
|
filter.setFilterByName(searchPhrase.getUnknownSearchPhrase());
|
||||||
|
@ -369,8 +369,8 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filter = app.getPoiFilters().getSearchByNamePOIFilter();
|
filter = app.getPoiFilters().getSearchByNamePOIFilter();
|
||||||
if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) {
|
if (!Algorithms.isEmpty(searchPhrase.getFirstUnknownSearchWord())) {
|
||||||
filter.setFilterByName(searchPhrase.getUnknownSearchWord());
|
filter.setFilterByName(searchPhrase.getFirstUnknownSearchWord());
|
||||||
filter.clearCurrentResults();
|
filter.clearCurrentResults();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,8 +382,8 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
.getResult().object;
|
.getResult().object;
|
||||||
filter = new PoiUIFilter(abstractPoiType, app, "");
|
filter = new PoiUIFilter(abstractPoiType, app, "");
|
||||||
}
|
}
|
||||||
if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) {
|
if (!Algorithms.isEmpty(searchPhrase.getFirstUnknownSearchWord())) {
|
||||||
filter.setFilterByName(searchPhrase.getUnknownSearchWord());
|
filter.setFilterByName(searchPhrase.getFirstUnknownSearchWord());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filter = (PoiUIFilter) searchPhrase.getLastSelectedWord().getResult().object;
|
filter = (PoiUIFilter) searchPhrase.getLastSelectedWord().getResult().object;
|
||||||
|
@ -628,9 +628,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (searchEditText.getText().length() > 0) {
|
if (searchEditText.getText().length() > 0) {
|
||||||
String newText = searchUICore.getPhrase().getTextWithoutLastWord();
|
clearLastWord();
|
||||||
searchEditText.setText(newText);
|
|
||||||
searchEditText.setSelection(newText.length());
|
|
||||||
} else if (useMapCenter && location != null) {
|
} else if (useMapCenter && location != null) {
|
||||||
useMapCenter = false;
|
useMapCenter = false;
|
||||||
centerLatLon = null;
|
centerLatLon = null;
|
||||||
|
|
|
@ -123,7 +123,7 @@ public class QuickSearchHelper implements ResourceListener {
|
||||||
|
|
||||||
public void refreshFilterOrders() {
|
public void refreshFilterOrders() {
|
||||||
PoiFiltersHelper filtersHelper = app.getPoiFilters();
|
PoiFiltersHelper filtersHelper = app.getPoiFilters();
|
||||||
core.setFilterOrders(filtersHelper.getPoiFilterOrders(true));
|
core.setActivePoiFiltersByOrder(filtersHelper.getPoiFilterOrders(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRepositoriesForSearchUICore(final OsmandApplication app) {
|
public void setRepositoriesForSearchUICore(final OsmandApplication app) {
|
||||||
|
@ -353,7 +353,7 @@ public class QuickSearchHelper implements ResourceListener {
|
||||||
public boolean search(SearchPhrase phrase, SearchResultMatcher matcher) throws IOException {
|
public boolean search(SearchPhrase phrase, SearchResultMatcher matcher) throws IOException {
|
||||||
double lat = phrase.getSettings().getOriginalLocation().getLatitude();
|
double lat = phrase.getSettings().getOriginalLocation().getLatitude();
|
||||||
double lon = phrase.getSettings().getOriginalLocation().getLongitude();
|
double lon = phrase.getSettings().getOriginalLocation().getLongitude();
|
||||||
String text = phrase.getRawUnknownSearchPhrase();
|
String text = phrase.getFullSearchPhrase();
|
||||||
filter.setFilterByName(text);
|
filter.setFilterByName(text);
|
||||||
publishAmenities(phrase, matcher, filter.initializeNewSearch(lat, lon,
|
publishAmenities(phrase, matcher, filter.initializeNewSearch(lat, lon,
|
||||||
-1, null, phrase.getRadiusLevel() + 3));
|
-1, null, phrase.getRadiusLevel() + 3));
|
||||||
|
|
|
@ -785,13 +785,6 @@ public class QuickSearchDialogFragment extends DialogFragment implements SampleC
|
||||||
runCoreSearch(txt, false, false);
|
runCoreSearch(txt, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearLastWord() {
|
|
||||||
if (searchEditText.getText().length() > 0) {
|
|
||||||
String newText = searchUICore.getPhrase().getTextWithoutLastWord();
|
|
||||||
searchEditText.setText(newText);
|
|
||||||
searchEditText.setSelection(newText.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMoreButton() {
|
private void addMoreButton() {
|
||||||
QuickSearchMoreListItem moreListItem =
|
QuickSearchMoreListItem moreListItem =
|
||||||
|
|
Loading…
Reference in a new issue