diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java index bde007c84d..e328c83965 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchCoreFactory.java @@ -626,6 +626,7 @@ public class SearchCoreFactory { private TIntArrayList customPoiFiltersPriorites = new TIntArrayList(); private MapPoiTypes types; private List foundPoiTypes = new ArrayList<>(); + private SearchPhrase lastSearchedPhrase; public SearchAmenityTypesAPI(MapPoiTypes types) { super(ObjectType.POI_TYPE); @@ -640,6 +641,14 @@ public class SearchCoreFactory { return foundPoiTypes.size() > 0; } + public SearchPhrase getLastSearchedPhrase() { + return lastSearchedPhrase; + } + + public void setLastSearchedPhrase(SearchPhrase lastSearchedPhrase) { + this.lastSearchedPhrase = lastSearchedPhrase; + } + public void clearCustomFilters() { this.customPoiFilters.clear(); this.customPoiFiltersPriorites.clear(); @@ -702,29 +711,31 @@ public class SearchCoreFactory { } } foundPoiTypes = new ArrayList<>(results); + lastSearchedPhrase = phrase; - for (AbstractPoiType pt : results) { - SearchResult res = new SearchResult(phrase); - res.localeName = pt.getTranslation(); - res.object = pt; - res.priority = SEARCH_AMENITY_TYPE_PRIORITY; - res.priorityDistance = 0; - res.objectType = ObjectType.POI_TYPE; - resultMatcher.publish(res); - } - for (int i = 0; i < customPoiFilters.size(); i++) { - CustomSearchPoiFilter csf = customPoiFilters.get(i); - int p = customPoiFiltersPriorites.get(i); - if (!phrase.isUnknownSearchWordPresent() || nm.matches(csf.getName())) { + if (resultMatcher != null) { + for (AbstractPoiType pt : results) { SearchResult res = new SearchResult(phrase); - res.localeName = csf.getName(); - res.object = csf; - res.priority = SEARCH_AMENITY_TYPE_PRIORITY + p; + res.localeName = pt.getTranslation(); + res.object = pt; + res.priority = SEARCH_AMENITY_TYPE_PRIORITY; + res.priorityDistance = 0; res.objectType = ObjectType.POI_TYPE; resultMatcher.publish(res); } + for (int i = 0; i < customPoiFilters.size(); i++) { + CustomSearchPoiFilter csf = customPoiFilters.get(i); + int p = customPoiFiltersPriorites.get(i); + if (!phrase.isUnknownSearchWordPresent() || nm.matches(csf.getName())) { + SearchResult res = new SearchResult(phrase); + res.localeName = csf.getName(); + res.object = csf; + res.priority = SEARCH_AMENITY_TYPE_PRIORITY + p; + res.objectType = ObjectType.POI_TYPE; + resultMatcher.publish(res); + } + } } - return true; } @@ -810,54 +821,42 @@ public class SearchCoreFactory { } else { throw new UnsupportedOperationException(); } - QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS); - List oo = phrase.getOfflineIndexes(); - Set searchedPois = new TreeSet<>(); - for (BinaryMapIndexReader o : oo) { - ResultMatcher rm = getResultMatcher(phrase, resultMatcher, null, o, searchedPois); - if (obj instanceof CustomSearchPoiFilter) { - rm = ((CustomSearchPoiFilter) obj).wrapResultMatcher(rm); - } - searchPoi(phrase, resultMatcher, ptf, bbox, o, rm); + searchPoi(phrase, resultMatcher, obj, null, ptf); + } else if (searchAmenityTypesAPI != null) { + if (searchAmenityTypesAPI.lastSearchedPhrase == null + || !searchAmenityTypesAPI.lastSearchedPhrase.getUnknownSearchPhrase().equals(phrase.getUnknownSearchPhrase())) { + searchAmenityTypesAPI.search(phrase, null); } - } else { List poiTypes = searchAmenityTypesAPI.getFoundPoiTypes(); for (AbstractPoiType pt : poiTypes) { SearchPoiTypeFilter ptf = getPoiTypeFilter(pt); - QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS); - String customName = null; - NameStringMatcher nm = phrase.getNameStringMatcher(phrase.getUnknownSearchWord(), true); - String unknownSearchPhrase = phrase.getUnknownSearchPhrase(); - String enTranslation = pt.getEnTranslation(); - String translation = pt.getTranslation(); - String synonyms = pt.getSynonyms(); - if (unknownSearchPhrase.length() > enTranslation.length() && nm.matches(enTranslation)) { - customName = unknownSearchPhrase.substring(enTranslation.length()).trim(); - } else if (unknownSearchPhrase.length() > translation.length() && nm.matches(translation)) { - customName = unknownSearchPhrase.substring(translation.length()).trim(); - } else if (unknownSearchPhrase.length() > synonyms.length() && nm.matches(synonyms)) { - customName = unknownSearchPhrase.substring(synonyms.length()).trim(); - } - if (!Algorithms.isEmpty(customName)) { - List oo = phrase.getOfflineIndexes(); - Set searchedPois = new TreeSet<>(); - for (BinaryMapIndexReader o : oo) { - ResultMatcher rm = getResultMatcher(phrase, resultMatcher, customName, o, searchedPois); - searchPoi(phrase, resultMatcher, ptf, bbox, o, rm); - } + String customName = phrase.getPoiNameFilter(pt); + if (customName != null) { + phrase.setUnknownSearchWordPoiType(pt); + searchPoi(phrase, resultMatcher, null, customName, ptf); + break; } } } return true; } - private void searchPoi(SearchPhrase phrase, SearchResultMatcher resultMatcher, SearchPoiTypeFilter ptf, QuadRect bbox, BinaryMapIndexReader o, ResultMatcher rm) throws IOException { - SearchRequest 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 void searchPoi(SearchPhrase phrase, SearchResultMatcher resultMatcher, Object obj, String customName, SearchPoiTypeFilter ptf) throws IOException { + QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS); + List oo = phrase.getOfflineIndexes(); + Set searchedPois = new TreeSet<>(); + for (BinaryMapIndexReader o : oo) { + ResultMatcher rm = getResultMatcher(phrase, resultMatcher, customName, o, searchedPois); + if (obj instanceof CustomSearchPoiFilter) { + rm = ((CustomSearchPoiFilter) obj).wrapResultMatcher(rm); + } + SearchRequest 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 getResultMatcher(final SearchPhrase phrase, final SearchResultMatcher resultMatcher, diff --git a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java index 8a38ea536b..0ce72dcd27 100644 --- a/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java +++ b/OsmAnd-java/src/main/java/net/osmand/search/core/SearchPhrase.java @@ -5,10 +5,11 @@ import net.osmand.CollatorStringMatcher; import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.StringMatcher; import net.osmand.binary.BinaryMapIndexReader; -import net.osmand.binary.CommonWords; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; +import net.osmand.binary.CommonWords; import net.osmand.data.LatLon; import net.osmand.data.QuadRect; +import net.osmand.osm.AbstractPoiType; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; @@ -33,7 +34,8 @@ public class SearchPhrase { private List unknownWordsMatcher = new ArrayList<>(); private String unknownSearchWordTrim; private String unknownSearchPhrase = ""; - + private AbstractPoiType unknownSearchWordPoiType; + private NameStringMatcher sm; private SearchSettings settings; private List indexes; @@ -223,8 +225,42 @@ public class SearchPhrase { 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 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) { int radiusInMeters = getRadiusSearch(radius); QuadRect cache1kmRect = get1km31Rect(); diff --git a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java index ecf63063cc..2acd39103c 100644 --- a/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/search/QuickSearchDialogFragment.java @@ -342,6 +342,13 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC filter = app.getPoiFilters().getNominatimPOIFilter(); filter.setFilterByName(searchPhrase.getUnknownSearchPhrase()); filter.clearCurrentResults(); + } else if (searchPhrase.hasUnknownSearchWordPoiType()) { + AbstractPoiType pt = searchPhrase.getUnknownSearchWordPoiType(); + filter = new PoiUIFilter(pt, app, ""); + String customName = searchPhrase.getPoiNameFilter(); + if (!Algorithms.isEmpty(customName)) { + filter.setFilterByName(customName); + } } else { filter = app.getPoiFilters().getSearchByNamePOIFilter(); if (!Algorithms.isEmpty(searchPhrase.getUnknownSearchWord())) {