Search in sources :

Example 1 with TIntLongHashMap

use of gnu.trove.map.hash.TIntLongHashMap in project Osmand by osmandapp.

the class BinaryMapPoiReaderAdapter method readPoiNameIndex.

private TIntLongHashMap readPoiNameIndex(Collator instance, String query, SearchRequest<Amenity> req) throws IOException {
    TIntLongHashMap offsets = new TIntLongHashMap();
    TIntArrayList dataOffsets = null;
    int offset = 0;
    while (true) {
        int t = codedIS.readTag();
        int tag = WireFormat.getTagFieldNumber(t);
        switch(tag) {
            case 0:
                return offsets;
            case OsmandOdb.OsmAndPoiNameIndex.TABLE_FIELD_NUMBER:
                {
                    int length = readInt();
                    int oldLimit = codedIS.pushLimit(length);
                    dataOffsets = new TIntArrayList();
                    offset = codedIS.getTotalBytesRead();
                    map.readIndexedStringTable(instance, query, "", dataOffsets, 0);
                    codedIS.popLimit(oldLimit);
                    break;
                }
            case OsmandOdb.OsmAndPoiNameIndex.DATA_FIELD_NUMBER:
                {
                    if (dataOffsets != null) {
                        // 1104125
                        dataOffsets.sort();
                        for (int i = 0; i < dataOffsets.size(); i++) {
                            codedIS.seek(dataOffsets.get(i) + offset);
                            int len = codedIS.readRawVarint32();
                            int oldLim = codedIS.pushLimit(len);
                            readPoiNameIndexData(offsets, req);
                            codedIS.popLimit(oldLim);
                            if (req.isCancelled()) {
                                codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
                                return offsets;
                            }
                        }
                    }
                    codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
                    return offsets;
                }
            default:
                skipUnknownField(t);
                break;
        }
    }
}
Also used : TIntLongHashMap(gnu.trove.map.hash.TIntLongHashMap) TIntArrayList(gnu.trove.list.array.TIntArrayList) AmenityRoutePoint(net.osmand.data.Amenity.AmenityRoutePoint)

Example 2 with TIntLongHashMap

use of gnu.trove.map.hash.TIntLongHashMap in project Osmand by osmandapp.

the class BinaryMapPoiReaderAdapter method searchPoiIndex.

protected void searchPoiIndex(int left31, int right31, int top31, int bottom31, SearchRequest<Amenity> req, PoiRegion region) throws IOException {
    int indexOffset = codedIS.getTotalBytesRead();
    long time = System.currentTimeMillis();
    TLongHashSet skipTiles = null;
    if (req.zoom >= 0 && req.zoom < 16) {
        skipTiles = new TLongHashSet();
    }
    int length;
    int oldLimit;
    TIntLongHashMap offsetsMap = new TIntLongHashMap();
    while (true) {
        if (req.isCancelled()) {
            return;
        }
        int t = codedIS.readTag();
        int tag = WireFormat.getTagFieldNumber(t);
        switch(tag) {
            case 0:
                return;
            case OsmandOdb.OsmAndPoiIndex.BOXES_FIELD_NUMBER:
                length = readInt();
                oldLimit = codedIS.pushLimit(length);
                readBoxField(left31, right31, top31, bottom31, 0, 0, 0, offsetsMap, skipTiles, req, region);
                codedIS.popLimit(oldLimit);
                break;
            case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER:
                int[] offsets = offsetsMap.keys();
                // also offsets can be randomly skipped by limit
                Arrays.sort(offsets);
                if (skipTiles != null) {
                    skipTiles.clear();
                }
                LOG.info("Searched poi structure in " + (System.currentTimeMillis() - time) + " ms. Found " + offsets.length + " subtrees");
                for (int j = 0; j < offsets.length; j++) {
                    long skipVal = offsetsMap.get(offsets[j]);
                    if (skipTiles != null && skipVal != -1) {
                        int dzoom = ZOOM_TO_SKIP_FILTER_READ - ZOOM_TO_SKIP_FILTER;
                        long dx = (skipVal >> ZOOM_TO_SKIP_FILTER_READ);
                        long dy = skipVal - (dx << ZOOM_TO_SKIP_FILTER_READ);
                        skipVal = ((dx >> dzoom) << ZOOM_TO_SKIP_FILTER) | (dy >> dzoom);
                        if (skipVal != -1 && skipTiles.contains(skipVal)) {
                            continue;
                        }
                    }
                    codedIS.seek(offsets[j] + indexOffset);
                    int len = readInt();
                    int oldLim = codedIS.pushLimit(len);
                    boolean read = readPoiData(left31, right31, top31, bottom31, req, region, skipTiles, req.zoom == -1 ? 31 : req.zoom + ZOOM_TO_SKIP_FILTER);
                    if (read && skipVal != -1 && skipTiles != null) {
                        skipTiles.add(skipVal);
                    }
                    codedIS.popLimit(oldLim);
                    if (req.isCancelled()) {
                        return;
                    }
                }
                codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
                return;
            default:
                skipUnknownField(t);
                break;
        }
    }
}
Also used : TIntLongHashMap(gnu.trove.map.hash.TIntLongHashMap) TLongHashSet(gnu.trove.set.hash.TLongHashSet) AmenityRoutePoint(net.osmand.data.Amenity.AmenityRoutePoint)

Example 3 with TIntLongHashMap

use of gnu.trove.map.hash.TIntLongHashMap 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 4 with TIntLongHashMap

use of gnu.trove.map.hash.TIntLongHashMap 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)

Aggregations

TIntLongHashMap (gnu.trove.map.hash.TIntLongHashMap)4 AmenityRoutePoint (net.osmand.data.Amenity.AmenityRoutePoint)3 TIntArrayList (gnu.trove.list.array.TIntArrayList)2 CollatorStringMatcher (net.osmand.CollatorStringMatcher)2 TIntSet (gnu.trove.set.TIntSet)1 TIntHashSet (gnu.trove.set.hash.TIntHashSet)1 TLongHashSet (gnu.trove.set.hash.TLongHashSet)1 City (net.osmand.data.City)1 LatLon (net.osmand.data.LatLon)1 Street (net.osmand.data.Street)1