Search in sources :

Example 1 with CollatorStringMatcher

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;
        }
    };
}
Also used : Amenity(net.osmand.data.Amenity) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Calendar(java.util.Calendar) AbstractPoiType(net.osmand.osm.AbstractPoiType) PoiType(net.osmand.osm.PoiType) OpeningHours(net.osmand.util.OpeningHoursParser.OpeningHours) CollatorStringMatcher(net.osmand.CollatorStringMatcher) ArrayList(java.util.ArrayList) List(java.util.List)

Example 2 with CollatorStringMatcher

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;
        }
    }
}
Also used : TIntLongHashMap(gnu.trove.map.hash.TIntLongHashMap) TIntSet(gnu.trove.set.TIntSet) City(net.osmand.data.City) TIntArrayList(gnu.trove.list.array.TIntArrayList) TIntHashSet(gnu.trove.set.hash.TIntHashSet) LatLon(net.osmand.data.LatLon) CollatorStringMatcher(net.osmand.CollatorStringMatcher) Street(net.osmand.data.Street)

Example 3 with CollatorStringMatcher

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;
        }
    }
}
Also used : TIntLongHashMap(gnu.trove.map.hash.TIntLongHashMap) CollatorStringMatcher(net.osmand.CollatorStringMatcher) AmenityRoutePoint(net.osmand.data.Amenity.AmenityRoutePoint)

Example 4 with CollatorStringMatcher

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;
}
Also used : OsmandApplication(net.osmand.plus.OsmandApplication) ArrayList(java.util.ArrayList) PoiFiltersHelper(net.osmand.plus.poi.PoiFiltersHelper) AbstractPoiType(net.osmand.osm.AbstractPoiType) PoiUIFilter(net.osmand.plus.poi.PoiUIFilter) Collator(java.text.Collator) CollatorStringMatcher(net.osmand.CollatorStringMatcher) OsmandRasterMapsPlugin(net.osmand.plus.rastermaps.OsmandRasterMapsPlugin)

Aggregations

CollatorStringMatcher (net.osmand.CollatorStringMatcher)4 TIntLongHashMap (gnu.trove.map.hash.TIntLongHashMap)2 ArrayList (java.util.ArrayList)2 AbstractPoiType (net.osmand.osm.AbstractPoiType)2 TIntArrayList (gnu.trove.list.array.TIntArrayList)1 TIntSet (gnu.trove.set.TIntSet)1 TIntHashSet (gnu.trove.set.hash.TIntHashSet)1 Collator (java.text.Collator)1 Calendar (java.util.Calendar)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Amenity (net.osmand.data.Amenity)1 AmenityRoutePoint (net.osmand.data.Amenity.AmenityRoutePoint)1 City (net.osmand.data.City)1 LatLon (net.osmand.data.LatLon)1 Street (net.osmand.data.Street)1 PoiType (net.osmand.osm.PoiType)1 OsmandApplication (net.osmand.plus.OsmandApplication)1 PoiFiltersHelper (net.osmand.plus.poi.PoiFiltersHelper)1