Merge pull request #10550 from osmandapp/fix_search_by_fuel_type

Fix #10454 Search by fuel type
This commit is contained in:
vshcherb 2021-01-11 10:12:34 +01:00 committed by GitHub
commit 233fe7aefe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -352,11 +352,11 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
} }
}; };
} }
StringBuilder nmFilter = new StringBuilder();
String[] items = filter.split(" "); String[] items = filter.split(" ");
boolean allTime = false; boolean allTime = false;
boolean open = false; boolean open = false;
List<PoiType> poiAdditionalsFilter = null; List<PoiType> poiAdditionalsFilter = null;
List<String> unknownFilters = null;
for (String s : items) { for (String s : items) {
s = s.trim(); s = s.trim();
if (!Algorithms.isEmpty(s)) { if (!Algorithms.isEmpty(s)) {
@ -373,110 +373,179 @@ public class PoiUIFilter implements SearchPoiTypeFilter, Comparable<PoiUIFilter>
poiAdditionalsFilter.add(pt); poiAdditionalsFilter.add(pt);
} }
} else { } else {
nmFilter.append(s).append(" "); if (unknownFilters == null) {
unknownFilters = new ArrayList<>();
}
unknownFilters.add(s);
} }
} }
} }
return getNameFilterInternal(nmFilter, allTime, open, poiAdditionalsFilter); return getNameFilterInternal(unknownFilters, allTime, open, poiAdditionalsFilter);
} }
private AmenityNameFilter getNameFilterInternal(StringBuilder nmFilter, private AmenityNameFilter getNameFilterInternal(
final boolean allTime, final boolean open, final List<PoiType> poiAdditionals) { final List<String> unknownFilters, final boolean shouldBeAllTime,
final CollatorStringMatcher sm = nmFilter.length() > 0 ? final boolean shouldBeOpened, final List<PoiType> selectedFilters
new CollatorStringMatcher(nmFilter.toString().trim(), StringMatcherMode.CHECK_CONTAINS) : null; ) {
return new AmenityNameFilter() { return new AmenityNameFilter() {
@Override @Override
public boolean accept(Amenity a) { public boolean accept(Amenity amenity) {
if (sm != null) { if (shouldBeAllTime) {
List<String> names = OsmAndFormatter.getPoiStringsWithoutType(a, if (!"24/7".equalsIgnoreCase(amenity.getOpeningHours()) &&
app.getSettings().MAP_PREFERRED_LOCALE.get(), app.getSettings().MAP_TRANSLITERATE_NAMES.get()); !"Mo-Su 00:00-24:00".equalsIgnoreCase(amenity.getOpeningHours())) {
boolean match = false;
for (String name : names) {
if (sm.matches(name)) {
match = true;
break;
}
}
if (!match) {
return false; return false;
} }
} }
if (poiAdditionals != null) {
Map<PoiType, PoiType> textPoiAdditionalsMap = new HashMap<>();
Map<String, List<PoiType>> poiAdditionalCategoriesMap = new HashMap<>();
for (PoiType pt : poiAdditionals) {
String category = pt.getPoiAdditionalCategory();
List<PoiType> types = poiAdditionalCategoriesMap.get(category);
if (types == null) {
types = new ArrayList<>();
poiAdditionalCategoriesMap.put(category, types);
}
types.add(pt);
String osmTag = pt.getOsmTag(); if (shouldBeOpened && !isOpened(amenity)) {
if (osmTag.length() < pt.getKeyName().length()) { return false;
PoiType textPoiType = poiTypes.getTextPoiAdditionalByKey(osmTag);
if (textPoiType != null) {
textPoiAdditionalsMap.put(pt, textPoiType);
}
}
}
for (List<PoiType> types : poiAdditionalCategoriesMap.values()) {
boolean acceptedAnyInCategory = false;
for (PoiType p : types) {
String inf = a.getAdditionalInfo(p.getKeyName());
if (inf != null) {
acceptedAnyInCategory = true;
break;
} else {
PoiType textPoiType = textPoiAdditionalsMap.get(p);
if (textPoiType != null) {
inf = a.getAdditionalInfo(textPoiType.getKeyName());
if (!Algorithms.isEmpty(inf)) {
String[] items = inf.split(";");
String val = p.getOsmValue().trim().toLowerCase();
for (String item : items) {
if (item.trim().toLowerCase().equals(val)) {
acceptedAnyInCategory = true;
break;
}
}
if (acceptedAnyInCategory) {
break;
}
}
}
}
}
if (!acceptedAnyInCategory) {
return false;
}
}
} }
if (allTime) {
if (!"24/7".equalsIgnoreCase(a.getOpeningHours()) && !"Mo-Su 00:00-24:00".equalsIgnoreCase(a.getOpeningHours())) { String nameFilter = extractNameFilter(amenity, unknownFilters);
return false; if (!matchesAnyAmenityName(amenity, nameFilter)) {
} return false;
} }
if (open) {
OpeningHours rs = OpeningHoursParser.parseOpenedHours(a.getOpeningHours()); if (!acceptedAnyFilterOfEachCategory(amenity, selectedFilters)) {
if (rs != null) { return false;
Calendar inst = Calendar.getInstance();
inst.setTimeInMillis(System.currentTimeMillis());
boolean work = rs.isOpenedForTime(inst);
if (!work) {
return false;
}
} else {
return false;
}
} }
return true; return true;
} }
}; };
} }
private boolean isOpened(Amenity amenity) {
OpeningHours openedHours = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
if (openedHours == null) {
return false;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
return openedHours.isOpenedForTime(calendar);
}
private String extractNameFilter(Amenity amenity, List<String> unknownFilters) {
if (unknownFilters == null) {
return "";
}
StringBuilder nameFilter = new StringBuilder();
for (String filter : unknownFilters) {
String formattedFilter = filter.replace(':', '_').toLowerCase();
if (amenity.getAdditionalInfo(formattedFilter) == null) {
nameFilter.append(filter).append(" ");
}
}
return nameFilter.toString();
}
private boolean matchesAnyAmenityName(Amenity amenity, String nameFilter) {
if (nameFilter.length() == 0) {
return true;
}
final CollatorStringMatcher sm =
new CollatorStringMatcher(nameFilter.trim(), StringMatcherMode.CHECK_CONTAINS);
List<String> names = OsmAndFormatter.getPoiStringsWithoutType(
amenity, app.getSettings().MAP_PREFERRED_LOCALE.get(),
app.getSettings().MAP_TRANSLITERATE_NAMES.get());
for (String name : names) {
if (sm.matches(name)) {
return true;
}
}
return false;
}
private boolean acceptedAnyFilterOfEachCategory(Amenity amenity, List<PoiType> selectedFilters) {
if (selectedFilters == null) {
return true;
}
Map<String, List<PoiType>> filterCategories = new HashMap<>();
Map<PoiType, PoiType> textFilters = new HashMap<>();
fillFilterCategories(selectedFilters, filterCategories, textFilters);
for (List<PoiType> category : filterCategories.values()) {
if (!acceptedAnyFilterOfCategory(amenity, category, textFilters)) {
return false;
}
}
return true;
}
private void fillFilterCategories(
List<PoiType> selectedFilters,
Map<String, List<PoiType>> filterCategories, Map<PoiType, PoiType> textFilters
) {
for (PoiType filter : selectedFilters) {
String category = filter.getPoiAdditionalCategory();
List<PoiType> filtersOfCategory = filterCategories.get(category);
if (filtersOfCategory == null) {
filtersOfCategory = new ArrayList<>();
filterCategories.put(category, filtersOfCategory);
}
filtersOfCategory.add(filter);
String osmTag = filter.getOsmTag();
if (osmTag.length() < filter.getKeyName().length()) {
PoiType textFilter = poiTypes.getTextPoiAdditionalByKey(osmTag);
if (textFilter != null) {
textFilters.put(filter, textFilter);
}
}
}
}
private boolean acceptedAnyFilterOfCategory(
Amenity amenity, List<PoiType> category, Map<PoiType, PoiType> textFilters) {
for (PoiType filter : category) {
if (acceptedFilter(amenity, filter, textFilters)) {
return true;
}
}
return false;
}
private boolean acceptedFilter(
Amenity amenity, PoiType filter, Map<PoiType, PoiType> textFilterCategories
) {
String filterValue = amenity.getAdditionalInfo(filter.getKeyName());
if (filterValue != null) {
return true;
}
PoiType textPoiType = textFilterCategories.get(filter);
if (textPoiType == null) {
return false;
}
filterValue = amenity.getAdditionalInfo(textPoiType.getKeyName());
if (Algorithms.isEmpty(filterValue)) {
return false;
}
String[] items = filterValue.split(";");
String val = filter.getOsmValue().trim().toLowerCase();
for (String item : items) {
if (item.trim().toLowerCase().equals(val)) {
return true;
}
}
return false;
}
public String getNameToken24H() { public String getNameToken24H() {
return app.getString(R.string.shared_string_is_open_24_7).replace(' ', '_').toLowerCase(); return app.getString(R.string.shared_string_is_open_24_7).replace(' ', '_').toLowerCase();
} }