use of net.osmand.CollatorStringMatcher in project Osmand by osmandapp.
the class PoiUIFilter method getNameFilterInternal.
private AmenityNameFilter getNameFilterInternal(StringBuilder nmFilter, final boolean allTime, final boolean open, final List<PoiType> poiAdditionals) {
final CollatorStringMatcher sm = nmFilter.length() > 0 ? new CollatorStringMatcher(nmFilter.toString().trim(), StringMatcherMode.CHECK_CONTAINS) : null;
return new AmenityNameFilter() {
@Override
public boolean accept(Amenity a) {
if (sm != null) {
String lower = OsmAndFormatter.getPoiStringWithoutType(a, app.getSettings().MAP_PREFERRED_LOCALE.get(), app.getSettings().MAP_TRANSLITERATE_NAMES.get());
if (!sm.matches(lower)) {
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 (osmTag.length() < pt.getKeyName().length()) {
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())) {
return false;
}
}
if (open) {
OpeningHours rs = OpeningHoursParser.parseOpenedHours(a.getOpeningHours());
if (rs != null) {
Calendar inst = Calendar.getInstance();
inst.setTimeInMillis(System.currentTimeMillis());
boolean work = rs.isOpenedForTime(inst);
if (!work) {
return false;
}
} else {
return false;
}
}
return true;
}
};
}
use of net.osmand.CollatorStringMatcher in project Osmand by osmandapp.
the class BinaryMapAddressReaderAdapter method searchAddressDataByName.
public void searchAddressDataByName(AddressRegion reg, SearchRequest<MapObject> req, List<Integer> typeFilter) throws IOException {
TIntArrayList loffsets = new TIntArrayList();
CollatorStringMatcher stringMatcher = new CollatorStringMatcher(req.nameQuery, req.matcherMode);
String postcode = Postcode.normalize(req.nameQuery, map.getCountryName());
final CityMatcher postcodeMatcher = new DefaultCityMatcher(new CollatorStringMatcher(postcode, req.matcherMode));
final CityMatcher cityMatcher = new DefaultCityMatcher(stringMatcher);
final CityMatcher cityPostcodeMatcher = new CityMatcher() {
@Override
public boolean matches(City city) {
return city.isPostcode() ? postcodeMatcher.matches(city) : cityMatcher.matches(city);
}
};
long time = System.currentTimeMillis();
int indexOffset = 0;
while (true) {
if (req.isCancelled()) {
return;
}
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch(tag) {
case 0:
return;
case OsmAndAddressNameIndexData.TABLE_FIELD_NUMBER:
int length = readInt();
indexOffset = codedIS.getTotalBytesRead();
int oldLimit = codedIS.pushLimit(length);
// here offsets are sorted by distance
map.readIndexedStringTable(stringMatcher.getCollator(), req.nameQuery, "", loffsets, 0);
codedIS.popLimit(oldLimit);
break;
case OsmAndAddressNameIndexData.ATOM_FIELD_NUMBER:
// also offsets can be randomly skipped by limit
loffsets.sort();
TIntArrayList[] refs = new TIntArrayList[5];
TIntArrayList[] refsContainer = new TIntArrayList[5];
for (int i = 0; i < refs.length; i++) {
refs[i] = new TIntArrayList();
refsContainer[i] = new TIntArrayList();
}
LOG.info("Searched address structure in " + (System.currentTimeMillis() - time) + "ms. Found " + loffsets.size() + " subtress");
for (int j = 0; j < loffsets.size(); j++) {
int fp = indexOffset + loffsets.get(j);
codedIS.seek(fp);
int len = codedIS.readRawVarint32();
int oldLim = codedIS.pushLimit(len);
int stag = 0;
do {
int st = codedIS.readTag();
stag = WireFormat.getTagFieldNumber(st);
if (stag == AddressNameIndexData.ATOM_FIELD_NUMBER) {
int slen = codedIS.readRawVarint32();
int soldLim = codedIS.pushLimit(slen);
readAddressNameData(req, refs, refsContainer, fp);
codedIS.popLimit(soldLim);
} else if (stag != 0) {
skipUnknownField(st);
}
} while (stag != 0);
codedIS.popLimit(oldLim);
if (req.isCancelled()) {
return;
}
}
if (typeFilter == null) {
typeFilter = TYPES;
}
for (int i = 0; i < typeFilter.size() && !req.isCancelled(); i++) {
TIntArrayList list = refs[typeFilter.get(i)];
TIntArrayList listContainer = refsContainer[typeFilter.get(i)];
if (typeFilter.get(i) == STREET_TYPE) {
TIntLongHashMap mp = new TIntLongHashMap();
for (int j = 0; j < list.size(); j++) {
mp.put(list.get(j), listContainer.get(j));
}
list.sort();
for (int j = 0; j < list.size() && !req.isCancelled(); j++) {
int offset = list.get(j);
if (j > 0 && offset == list.get(j - 1)) {
continue;
}
City obj;
{
int contOffset = (int) mp.get(offset);
codedIS.seek(contOffset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
obj = readCityHeader(null, contOffset, reg.attributeTagsTable);
codedIS.popLimit(old);
}
if (obj != null) {
codedIS.seek(offset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
LatLon l = obj.getLocation();
Street s = new Street(obj);
s.setFileOffset(offset);
readStreet(s, null, false, MapUtils.get31TileNumberX(l.getLongitude()) >> 7, MapUtils.get31TileNumberY(l.getLatitude()) >> 7, obj.isPostcode() ? obj.getName() : null, reg.attributeTagsTable);
boolean matches = stringMatcher.matches(s.getName());
if (!matches) {
for (String n : s.getAllNames()) {
matches = stringMatcher.matches(n);
if (matches) {
break;
}
}
}
if (matches) {
req.publish(s);
}
codedIS.popLimit(old);
}
}
} else {
list.sort();
TIntSet published = new TIntHashSet();
for (int j = 0; j < list.size() && !req.isCancelled(); j++) {
int offset = list.get(j);
if (j > 0 && offset == list.get(j - 1)) {
continue;
}
codedIS.seek(offset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
City obj = readCityHeader(cityPostcodeMatcher, list.get(j), reg.attributeTagsTable);
if (obj != null && !published.contains(offset)) {
req.publish(obj);
published.add(offset);
}
codedIS.popLimit(old);
}
}
}
LOG.info("Whole address search by name is done in " + (System.currentTimeMillis() - time) + "ms. Found " + req.getSearchResults().size());
return;
default:
skipUnknownField(t);
break;
}
}
}
use of net.osmand.CollatorStringMatcher in project Osmand by osmandapp.
the class BinaryMapPoiReaderAdapter method searchPoiByName.
protected void searchPoiByName(PoiRegion region, SearchRequest<Amenity> req) throws IOException {
TIntLongHashMap offsets = new TIntLongHashMap();
String query = normalizeSearchPoiByNameQuery(req.nameQuery);
CollatorStringMatcher matcher = new CollatorStringMatcher(query, StringMatcherMode.CHECK_STARTS_FROM_SPACE);
long time = System.currentTimeMillis();
int indexOffset = codedIS.getTotalBytesRead();
while (true) {
if (req.isCancelled()) {
return;
}
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch(tag) {
case 0:
return;
case OsmandOdb.OsmAndPoiIndex.NAMEINDEX_FIELD_NUMBER:
int length = readInt();
int oldLimit = codedIS.pushLimit(length);
// here offsets are sorted by distance
offsets = readPoiNameIndex(matcher.getCollator(), query, req);
codedIS.popLimit(oldLimit);
break;
case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER:
// also offsets can be randomly skipped by limit
Integer[] offKeys = new Integer[offsets.size()];
if (offsets.size() > 0) {
int[] keys = offsets.keys();
for (int i = 0; i < keys.length; i++) {
offKeys[i] = keys[i];
}
final TIntLongHashMap foffsets = offsets;
Arrays.sort(offKeys, new Comparator<Integer>() {
@Override
public int compare(Integer object1, Integer object2) {
return Double.compare(foffsets.get(object1), foffsets.get(object2));
}
});
int p = BUCKET_SEARCH_BY_NAME * 3;
if (p < offKeys.length) {
for (int i = p + BUCKET_SEARCH_BY_NAME; ; i += BUCKET_SEARCH_BY_NAME) {
if (i > offKeys.length) {
Arrays.sort(offKeys, p, offKeys.length);
break;
} else {
Arrays.sort(offKeys, p, i);
}
p = i;
}
}
}
LOG.info("Searched poi structure in " + (System.currentTimeMillis() - time) + "ms. Found " + offKeys.length + " subtrees");
for (int j = 0; j < offKeys.length; j++) {
codedIS.seek(offKeys[j] + indexOffset);
int len = readInt();
int oldLim = codedIS.pushLimit(len);
readPoiData(matcher, req, region);
codedIS.popLimit(oldLim);
if (req.isCancelled() || req.limitExceeded()) {
return;
}
}
LOG.info("Whole poi by name search is done in " + (System.currentTimeMillis() - time) + "ms. Found " + req.getSearchResults().size());
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return;
default:
skipUnknownField(t);
break;
}
}
}
use of net.osmand.CollatorStringMatcher in project Osmand by osmandapp.
the class SearchPoiFilterFragment method getFilters.
public List<Object> getFilters(String s) {
List<Object> filters = new ArrayList<Object>();
OsmandApplication app = getApp();
if (app == null) {
return filters;
}
PoiFiltersHelper poiFilters = app.getPoiFilters();
if (Algorithms.isEmpty(s)) {
filters.addAll(poiFilters.getTopDefinedPoiFilters());
} else {
for (PoiUIFilter pf : poiFilters.getTopDefinedPoiFilters()) {
if (!pf.isStandardFilter() && pf.getName().toLowerCase().startsWith(s.toLowerCase())) {
filters.add(pf);
}
}
List<AbstractPoiType> res = app.getPoiTypes().getAllTypesTranslatedNames(new CollatorStringMatcher(s, StringMatcherMode.CHECK_STARTS_FROM_SPACE));
final Collator inst = Collator.getInstance();
Collections.sort(res, new Comparator<AbstractPoiType>() {
@Override
public int compare(AbstractPoiType lhs, AbstractPoiType rhs) {
return inst.compare(lhs.getTranslation(), rhs.getTranslation());
}
});
for (AbstractPoiType p : res) {
filters.add(p);
}
filters.add(poiFilters.getSearchByNamePOIFilter());
if (OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) != null) {
filters.add(poiFilters.getNominatimPOIFilter());
filters.add(poiFilters.getNominatimAddressFilter());
}
}
return filters;
}
Aggregations