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;
}
}
}
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;
}
}
}
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;
}
}
}
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;
}
}
}
Aggregations