simplification binary map index reader (functionally no changes)

git-svn-id: https://osmand.googlecode.com/svn/trunk@839 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
vics001 2010-12-19 13:32:57 +00:00
parent 55dc0e2a76
commit 1d9d4cf8b6
4 changed files with 1216 additions and 1108 deletions

View file

@ -13,10 +13,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import net.osmand.binary.BinaryMapIndexReader.AddressRegion;
import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion;
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
import net.osmand.binary.BinaryMapIndexReader.MapRoot;
import net.osmand.binary.BinaryMapIndexReader.TransportIndex;
import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex;
import net.osmand.osm.MapUtils;
import com.google.protobuf.CodedOutputStream;

View file

@ -0,0 +1,504 @@
package net.osmand.binary;
import java.io.IOException;
import java.util.List;
import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
import net.osmand.data.City.CityType;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import net.sf.junidecode.Junidecode;
import com.google.protobuf.CodedInputStreamRAF;
import com.google.protobuf.WireFormat;
public class BinaryMapAddressReaderAdapter {
public static class AddressRegion extends BinaryIndexPart {
String enName;
int postcodesOffset = -1;
int villagesOffset = -1;
int citiesOffset = -1;
}
private CodedInputStreamRAF codedIS;
private final BinaryMapIndexReader map;
protected BinaryMapAddressReaderAdapter(BinaryMapIndexReader map){
this.codedIS = map.codedIS;
this.map = map;
}
private void skipUnknownField(int t) throws IOException {
map.skipUnknownField(t);
}
private int readInt() throws IOException {
return map.readInt();
}
protected void readAddressIndex(AddressRegion region) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndAddressIndex.NAME_FIELD_NUMBER :
region.name = codedIS.readString();
if(region.enName == null){
region.enName = Junidecode.unidecode(region.name);
}
break;
case OsmandOdb.OsmAndAddressIndex.NAME_EN_FIELD_NUMBER :
region.enName = codedIS.readString();
break;
case OsmandOdb.OsmAndAddressIndex.CITIES_FIELD_NUMBER :
region.citiesOffset = codedIS.getTotalBytesRead();
int length = readInt();
codedIS.seek(region.citiesOffset + length + 4);
break;
case OsmandOdb.OsmAndAddressIndex.VILLAGES_FIELD_NUMBER :
region.villagesOffset = codedIS.getTotalBytesRead();
length = readInt();
codedIS.seek(region.villagesOffset + length + 4);
break;
case OsmandOdb.OsmAndAddressIndex.POSTCODES_FIELD_NUMBER :
region.postcodesOffset = codedIS.getTotalBytesRead();
length = readInt();
codedIS.seek(region.postcodesOffset + length + 4);
break;
default:
skipUnknownField(t);
break;
}
}
}
protected void readCities(List<City> cities, String nameContains, boolean useEn) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.CitiesIndex.CITIES_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
if(nameContains != null){
String name = null;
int read = 0;
int toRead = useEn ? 3 : 2;
int seek = codedIS.getTotalBytesRead();
while(read++ < toRead){
int ts = codedIS.readTag();
int tags = WireFormat.getTagFieldNumber(ts);
switch (tags) {
case OsmandOdb.CityIndex.NAME_EN_FIELD_NUMBER :
name = codedIS.readString();
break;
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
name = codedIS.readString();
if(useEn){
name = Junidecode.unidecode(name);
}
break;
case OsmandOdb.CityIndex.CITY_TYPE_FIELD_NUMBER :
codedIS.readUInt32();
break;
}
}
if(name == null || !name.toLowerCase().contains(nameContains)){
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
codedIS.popLimit(oldLimit);
break;
}
codedIS.seek(seek);
}
City c = readCity(null, offset, false);
if(c != null){
cities.add(c);
}
codedIS.popLimit(oldLimit);
break;
default:
skipUnknownField(t);
break;
}
}
}
protected PostCode readPostcode(PostCode p, int fileOffset, boolean loadStreets, String postcodeFilter) throws IOException{
int x = 0;
int y = 0;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
p.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
p.setFileOffset(fileOffset);
return p;
case OsmandOdb.PostcodeIndex.POSTCODE_FIELD_NUMBER :
String name = codedIS.readString();
if(postcodeFilter != null && !postcodeFilter.equalsIgnoreCase(name)){
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return null;
}
if(p == null){
p = new PostCode(name);
}
p.setName(name);
break;
case OsmandOdb.PostcodeIndex.X_FIELD_NUMBER :
x = codedIS.readFixed32();
break;
case OsmandOdb.PostcodeIndex.Y_FIELD_NUMBER :
y = codedIS.readFixed32();
break;
case OsmandOdb.PostcodeIndex.STREETS_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
if(loadStreets){
Street s = new Street(null);
int oldLimit = codedIS.pushLimit(length);
s.setFileOffset(offset);
readStreet(s, true, x >> 7, y >> 7, p.getName());
p.registerStreet(s, false);
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
}
break;
default:
skipUnknownField(t);
break;
}
}
}
protected City readCity(City c, int fileOffset, boolean loadStreets) throws IOException{
int x = 0;
int y = 0;
int streetInd = 0;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
c.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
return c;
case OsmandOdb.CityIndex.CITY_TYPE_FIELD_NUMBER :
int type = codedIS.readUInt32();
if(c == null){
c = new City(CityType.values()[type]);
c.setFileOffset(fileOffset);
}
break;
case OsmandOdb.CityIndex.ID_FIELD_NUMBER :
c.setId(codedIS.readUInt64());
break;
case OsmandOdb.CityIndex.NAME_EN_FIELD_NUMBER :
c.setEnName(codedIS.readString());
break;
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
c.setName(codedIS.readString());
if(c.getEnName().length() == 0){
c.setEnName(Junidecode.unidecode(c.getName()));
}
break;
case OsmandOdb.CityIndex.X_FIELD_NUMBER :
x = codedIS.readFixed32();
break;
case OsmandOdb.CityIndex.Y_FIELD_NUMBER :
y = codedIS.readFixed32();
break;
case OsmandOdb.CityIndex.INTERSECTIONS_FIELD_NUMBER :
codedIS.skipRawBytes(codedIS.readRawVarint32());
break;
case OsmandOdb.CityIndex.STREETS_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
if(loadStreets){
Street s = new Street(c);
int oldLimit = codedIS.pushLimit(length);
s.setFileOffset(offset);
s.setIndexInCity(streetInd++);
readStreet(s, false, x >> 7, y >> 7, null);
c.registerStreet(s);
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
}
break;
default:
skipUnknownField(t);
break;
}
}
}
protected Street readStreet(Street s, boolean loadBuildings, int city24X, int city24Y, String postcodeFilter) throws IOException{
int x = 0;
int y = 0;
boolean loadLocation = city24X != 0 || city24Y != 0;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
if(loadLocation){
s.setLocation(MapUtils.getLatitudeFromTile(24, y), MapUtils.getLongitudeFromTile(24, x));
}
return s;
case OsmandOdb.StreetIndex.ID_FIELD_NUMBER :
s.setId(codedIS.readUInt64());
break;
case OsmandOdb.StreetIndex.NAME_EN_FIELD_NUMBER :
s.setEnName(codedIS.readString());
break;
case OsmandOdb.StreetIndex.NAME_FIELD_NUMBER :
s.setName(codedIS.readString());
if(s.getEnName().length() == 0){
s.setEnName(Junidecode.unidecode(s.getName()));
}
break;
case OsmandOdb.StreetIndex.X_FIELD_NUMBER :
int sx = codedIS.readSInt32();
if(loadLocation){
x = sx + city24X;
} else {
x = (int) MapUtils.getTileNumberX(24, s.getLocation().getLongitude());
}
break;
case OsmandOdb.StreetIndex.Y_FIELD_NUMBER :
int sy = codedIS.readSInt32();
if(loadLocation){
y = sy + city24Y;
} else {
y = (int) MapUtils.getTileNumberY(24, s.getLocation().getLatitude());
}
break;
case OsmandOdb.StreetIndex.BUILDINGS_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
if(loadBuildings){
int oldLimit = codedIS.pushLimit(length);
Building b = readBuilding(offset, x, y);
if (postcodeFilter == null || postcodeFilter.equalsIgnoreCase(b.getPostcode())) {
s.registerBuilding(b);
}
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
}
break;
default:
skipUnknownField(t);
break;
}
}
}
protected Building readBuilding(int fileOffset, int street24X, int street24Y) throws IOException{
int x = 0;
int y = 0;
Building b = new Building();
b.setFileOffset(fileOffset);
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
b.setLocation(MapUtils.getLatitudeFromTile(24, y), MapUtils.getLongitudeFromTile(24, x));
return b;
case OsmandOdb.BuildingIndex.ID_FIELD_NUMBER :
b.setId(codedIS.readUInt64());
break;
case OsmandOdb.BuildingIndex.NAME_EN_FIELD_NUMBER :
b.setEnName(codedIS.readString());
break;
case OsmandOdb.BuildingIndex.NAME_FIELD_NUMBER :
b.setName(codedIS.readString());
if(b.getEnName().length() == 0){
b.setEnName(Junidecode.unidecode(b.getName()));
}
break;
case OsmandOdb.BuildingIndex.X_FIELD_NUMBER :
x = codedIS.readSInt32() + street24X;
break;
case OsmandOdb.BuildingIndex.Y_FIELD_NUMBER :
y = codedIS.readSInt32() + street24Y;
break;
case OsmandOdb.BuildingIndex.POSTCODE_FIELD_NUMBER :
b.setPostcode(codedIS.readString());
break;
default:
skipUnknownField(t);
break;
}
}
}
// 2 different quires : s2 == null -> fill possible streets, s2 != null return LatLon intersection
private LatLon readIntersectedStreets(Street[] cityStreets, Street s, Street s2, LatLon parent, List<Street> streets) throws IOException {
int size = codedIS.readRawVarint32();
int old = codedIS.pushLimit(size);
boolean e = false;
while(!e){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
e = true;
break;
case OsmandOdb.InteresectedStreets.INTERSECTIONS_FIELD_NUMBER:
int nsize = codedIS.readRawVarint32();
int nold = codedIS.pushLimit(nsize);
int st1 = -1;
int st2 = -1;
int cx = 0;
int cy = 0;
boolean end = false;
while (!end) {
int nt = codedIS.readTag();
int ntag = WireFormat.getTagFieldNumber(nt);
switch (ntag) {
case 0:
end = true;
break;
case OsmandOdb.StreetIntersection.INTERSECTEDSTREET1_FIELD_NUMBER:
st1 = codedIS.readUInt32();
break;
case OsmandOdb.StreetIntersection.INTERSECTEDSTREET2_FIELD_NUMBER:
st2 = codedIS.readUInt32();
break;
case OsmandOdb.StreetIntersection.INTERSECTEDX_FIELD_NUMBER:
cx = codedIS.readSInt32();
break;
case OsmandOdb.StreetIntersection.INTERSECTEDY_FIELD_NUMBER:
cy = codedIS.readSInt32();
break;
default:
skipUnknownField(nt);
}
}
codedIS.popLimit(nold);
if (s2 == null) {
// find all intersections
if (st1 == s.getIndexInCity() && st2 != -1 && st2 < cityStreets.length && cityStreets[st2] != null) {
streets.add(cityStreets[st2]);
} else if (st2 == s.getIndexInCity() && st1 != -1 && st1 < cityStreets.length && cityStreets[st1] != null) {
streets.add(cityStreets[st1]);
}
} else {
if((st1 == s.getIndexInCity() && st2 == s2.getIndexInCity() ) ||
(st2 == s.getIndexInCity() && st1 == s2.getIndexInCity())) {
int x = (int) (MapUtils.getTileNumberX(24, parent.getLongitude()) + cx);
int y = (int) (MapUtils.getTileNumberY(24, parent.getLatitude()) + cy);
codedIS.popLimit(old);
return new LatLon(MapUtils.getLatitudeFromTile(24, y), MapUtils.getLongitudeFromTile(24, x));
}
}
break;
default:
skipUnknownField(t);
}
}
codedIS.popLimit(old);
return null;
}
// do not preload streets in city
protected LatLon findIntersectedStreets(City c, Street s, Street s2, List<Street> streets) throws IOException {
if(s.getIndexInCity() == -1){
return null;
}
codedIS.seek(c.getFileOffset());
int size = codedIS.readRawVarint32();
int old = codedIS.pushLimit(size);
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
codedIS.popLimit(old);
return null;
case OsmandOdb.CityIndex.INTERSECTIONS_FIELD_NUMBER :
Street[] cityStreets = new Street[c.getStreets().size()];
for(Street st : c.getStreets()){
if(st.getIndexInCity() >= 0 && st.getIndexInCity() < cityStreets.length){
cityStreets[st.getIndexInCity()] = st;
}
}
LatLon ret = readIntersectedStreets(cityStreets, s, s2, c.getLocation(), streets);
codedIS.popLimit(old);
return ret;
default:
skipUnknownField(t);
}
}
}
void readPostcodes(List<PostCode> postcodes) throws IOException{
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.PostcodesIndex.POSTCODES_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
postcodes.add(readPostcode(null, offset, false, null));
codedIS.popLimit(oldLimit);
break;
default:
skipUnknownField(t);
break;
}
}
}
PostCode findPostcode(String name) throws IOException{
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return null;
case OsmandOdb.PostcodesIndex.POSTCODES_FIELD_NUMBER :
int offset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
PostCode p = readPostcode(null, offset, true, name);
codedIS.popLimit(oldLimit);
if(p != null){
return p;
}
break;
default:
skipUnknownField(t);
break;
}
}
}
}

View file

@ -0,0 +1,536 @@
package net.osmand.binary;
import gnu.trove.list.array.TIntArrayList;
import static net.osmand.binary.BinaryMapIndexReader.TRANSPORT_STOP_ZOOM;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.data.TransportStop;
import net.osmand.osm.MapUtils;
import net.sf.junidecode.Junidecode;
import com.google.protobuf.CodedInputStreamRAF;
import com.google.protobuf.WireFormat;
public class BinaryMapTransportReaderAdapter {
private CodedInputStreamRAF codedIS;
private final BinaryMapIndexReader map;
protected BinaryMapTransportReaderAdapter(BinaryMapIndexReader map){
this.codedIS = map.codedIS;
this.map = map;
}
private void skipUnknownField(int t) throws IOException {
map.skipUnknownField(t);
}
private int readInt() throws IOException {
return map.readInt();
}
public static class TransportIndex extends BinaryIndexPart {
int left = 0;
int right = 0;
int top = 0;
int bottom = 0;
int stopsFileOffset = 0;
int stopsFileLength = 0;
public int getLeft() {
return left;
}
public int getRight() {
return right;
}
public int getTop() {
return top;
}
public int getBottom() {
return bottom;
}
IndexStringTable stringTable = null;
}
private static class IndexStringTable {
private static final int SIZE_OFFSET_ARRAY = 100;
private static final int WINDOW_SIZE = 25;
int fileOffset = 0;
int length = 0;
// offset from start for each SIZE_OFFSET_ARRAY elements
// (SIZE_OFFSET_ARRAY + 1) offset = offsets[0] + skipOneString()
TIntArrayList offsets = new TIntArrayList();
Map<Integer, String> cacheOfStrings = new LinkedHashMap<Integer, String>();
int windowOffset = 0;
List<String> window = new ArrayList<String>();
}
protected void readTransportIndex(TransportIndex ind) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndTransportIndex.ROUTES_FIELD_NUMBER :
skipUnknownField(t);
break;
case OsmandOdb.OsmAndTransportIndex.NAME_FIELD_NUMBER :
ind.setName(codedIS.readString());
break;
case OsmandOdb.OsmAndTransportIndex.STOPS_FIELD_NUMBER :
ind.stopsFileLength = readInt();
ind.stopsFileOffset = codedIS.getTotalBytesRead();
int old = codedIS.pushLimit(ind.stopsFileLength);
readTransportBounds(ind);
codedIS.popLimit(old);
break;
case OsmandOdb.OsmAndTransportIndex.STRINGTABLE_FIELD_NUMBER :
IndexStringTable st = new IndexStringTable();
st.length = codedIS.readRawVarint32();
st.fileOffset = codedIS.getTotalBytesRead();
readStringTable(st, 0, 20, true);
ind.stringTable = st;
codedIS.seek(st.length + st.fileOffset);
break;
default:
skipUnknownField(t);
break;
}
}
}
private void readTransportBounds(TransportIndex ind) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.TransportStopsTree.LEFT_FIELD_NUMBER :
ind.left = codedIS.readSInt32();
break;
case OsmandOdb.TransportStopsTree.RIGHT_FIELD_NUMBER :
ind.right = codedIS.readSInt32();
break;
case OsmandOdb.TransportStopsTree.TOP_FIELD_NUMBER :
ind.top = codedIS.readSInt32();
break;
case OsmandOdb.TransportStopsTree.BOTTOM_FIELD_NUMBER :
ind.bottom = codedIS.readSInt32();
break;
default:
skipUnknownField(t);
break;
}
}
}
// if cache false put into window
private int readStringTable(IndexStringTable st, int startOffset, int length, boolean cache) throws IOException {
int toSkip = seekUsingOffsets(st, startOffset);
if(!cache){
st.window.clear();
st.windowOffset = startOffset;
}
int old = codedIS.pushLimit(st.fileOffset + st.length - codedIS.getTotalBytesRead());
while (length > 0) {
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
length = 0;
break;
case OsmandOdb.StringTable.S_FIELD_NUMBER:
if (toSkip > 0) {
toSkip--;
skipUnknownField(t);
} else {
String string = codedIS.readString();
if(cache){
st.cacheOfStrings.put(startOffset, string);
} else {
st.window.add(string);
}
startOffset++;
length--;
}
break;
default:
skipUnknownField(t);
break;
}
}
codedIS.popLimit(old);
return startOffset;
}
protected String getStringFromStringTable(IndexStringTable st, int ind) throws IOException {
int lastRead = Integer.MAX_VALUE;
while (lastRead >= ind) {
if (st.cacheOfStrings.containsKey(ind)) {
return st.cacheOfStrings.get(ind);
}
if (ind >= st.windowOffset && (ind - st.windowOffset) < st.window.size()) {
return st.window.get(ind - st.windowOffset);
}
lastRead = readStringTable(st, ind - IndexStringTable.WINDOW_SIZE / 4, IndexStringTable.WINDOW_SIZE, false);
}
return null;
}
private int seekUsingOffsets(IndexStringTable st, int index) throws IOException {
initStringOffsets(st, index);
int shift = 0;
int a = index / IndexStringTable.SIZE_OFFSET_ARRAY;
if (a > st.offsets.size()) {
a = st.offsets.size();
}
if (a > 0) {
shift = st.offsets.get(a - 1);
}
codedIS.seek(st.fileOffset + shift);
return index - a * IndexStringTable.SIZE_OFFSET_ARRAY;
}
private void initStringOffsets(IndexStringTable st, int index) throws IOException {
if (index > IndexStringTable.SIZE_OFFSET_ARRAY * (st.offsets.size() + 1)) {
int shift = 0;
if (!st.offsets.isEmpty()) {
shift = st.offsets.get(st.offsets.size() - 1);
}
codedIS.seek(st.fileOffset + shift);
int old = codedIS.pushLimit(st.length - shift);
while (index > IndexStringTable.SIZE_OFFSET_ARRAY * (st.offsets.size() + 1)) {
int ind = 0;
while (ind < IndexStringTable.SIZE_OFFSET_ARRAY && ind != -1) {
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
ind = -1;
break;
case OsmandOdb.StringTable.S_FIELD_NUMBER:
skipUnknownField(t);
ind++;
break;
default:
skipUnknownField(t);
break;
}
}
if(ind == IndexStringTable.SIZE_OFFSET_ARRAY){
st.offsets.add(codedIS.getTotalBytesRead() - st.fileOffset);
} else {
// invalid index
break;
}
}
codedIS.popLimit(old);
}
}
protected void searchTransportTreeBounds(int pleft, int pright, int ptop, int pbottom,
SearchRequest<TransportStop> req) throws IOException {
int init = 0;
int lastIndexResult = -1;
int cright = 0;
int cleft = 0;
int ctop = 0;
int cbottom = 0;
req.numberOfReadSubtrees++;
while(true){
if(req.isInterrupted()){
return;
}
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
if(init == 0xf){
// coordinates are init
init = 0;
if(cright < req.left || cleft > req.right || ctop > req.bottom || cbottom < req.top){
return;
} else {
req.numberOfAcceptedSubtrees++;
}
}
switch (tag) {
case 0:
return;
case OsmandOdb.TransportStopsTree.BOTTOM_FIELD_NUMBER :
cbottom = codedIS.readSInt32() + pbottom;
init |= 1;
break;
case OsmandOdb.TransportStopsTree.LEFT_FIELD_NUMBER :
cleft = codedIS.readSInt32() + pleft;
init |= 2;
break;
case OsmandOdb.TransportStopsTree.RIGHT_FIELD_NUMBER :
cright = codedIS.readSInt32() + pright;
init |= 4;
break;
case OsmandOdb.TransportStopsTree.TOP_FIELD_NUMBER :
ctop = codedIS.readSInt32() + ptop;
init |= 8;
break;
case OsmandOdb.TransportStopsTree.LEAFS_FIELD_NUMBER :
int stopOffset = codedIS.getTotalBytesRead();
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
if(lastIndexResult == -1){
lastIndexResult = req.searchResults.size();
}
req.numberOfVisitedObjects++;
TransportStop transportStop = readTransportStop(stopOffset, cleft, cright, ctop, cbottom, req);
if(transportStop != null){
req.searchResults.add(transportStop);
}
codedIS.popLimit(oldLimit);
break;
case OsmandOdb.TransportStopsTree.SUBTREES_FIELD_NUMBER :
// left, ... already initialized
length = readInt();
int filePointer = codedIS.getTotalBytesRead();
if (req.limit == -1 || req.limit >= req.searchResults.size()) {
oldLimit = codedIS.pushLimit(length);
searchTransportTreeBounds(cleft, cright, ctop, cbottom, req);
codedIS.popLimit(oldLimit);
}
codedIS.seek(filePointer + length);
if(lastIndexResult >= 0){
throw new IllegalStateException();
}
break;
case OsmandOdb.TransportStopsTree.BASEID_FIELD_NUMBER :
long baseId = codedIS.readUInt64();
if (lastIndexResult != -1) {
for (int i = lastIndexResult; i < req.searchResults.size(); i++) {
TransportStop rs = req.searchResults.get(i);
rs.setId(rs.getId() + baseId);
}
}
break;
default:
skipUnknownField(t);
break;
}
}
}
public net.osmand.data.TransportRoute getTransportRoute(int filePointer, TransportIndex ind) throws IOException {
codedIS.seek(filePointer);
int routeLength = codedIS.readRawVarint32();
int old = codedIS.pushLimit(routeLength);
net.osmand.data.TransportRoute dataObject = new net.osmand.data.TransportRoute();
boolean end = false;
int name = -1;
int nameEn = -1;
int operator = -1;
int type = -1;
long rid = 0;
int rx = 0;
int ry = 0;
long did = 0;
int dx = 0;
int dy = 0;
while(!end){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
end = true;
break;
case OsmandOdb.TransportRoute.DISTANCE_FIELD_NUMBER :
dataObject.setDistance(codedIS.readUInt32());
break;
case OsmandOdb.TransportRoute.ID_FIELD_NUMBER :
dataObject.setId(codedIS.readUInt64());
break;
case OsmandOdb.TransportRoute.REF_FIELD_NUMBER :
dataObject.setRef(codedIS.readString());
break;
case OsmandOdb.TransportRoute.TYPE_FIELD_NUMBER :
type = codedIS.readUInt32();
break;
case OsmandOdb.TransportRoute.NAME_EN_FIELD_NUMBER :
nameEn = codedIS.readUInt32();
break;
case OsmandOdb.TransportRoute.NAME_FIELD_NUMBER :
name = codedIS.readUInt32();
break;
case OsmandOdb.TransportRoute.OPERATOR_FIELD_NUMBER:
operator = codedIS.readUInt32();
break;
case OsmandOdb.TransportRoute.REVERSESTOPS_FIELD_NUMBER:
int length = codedIS.readRawVarint32();
int olds = codedIS.pushLimit(length);
TransportStop stop = readTransportRouteStop(dx, dy, did);
dataObject.getBackwardStops().add(stop);
did = stop.getId();
dx = (int) MapUtils.getTileNumberX(TRANSPORT_STOP_ZOOM, stop.getLocation().getLongitude());
dy = (int) MapUtils.getTileNumberY(TRANSPORT_STOP_ZOOM, stop.getLocation().getLatitude());
codedIS.popLimit(olds);
break;
case OsmandOdb.TransportRoute.DIRECTSTOPS_FIELD_NUMBER:
length = codedIS.readRawVarint32();
olds = codedIS.pushLimit(length);
stop = readTransportRouteStop(rx, ry, rid);
dataObject.getForwardStops().add(stop);
rid = stop.getId();
rx = (int) MapUtils.getTileNumberX(TRANSPORT_STOP_ZOOM, stop.getLocation().getLongitude());
ry = (int) MapUtils.getTileNumberY(TRANSPORT_STOP_ZOOM, stop.getLocation().getLatitude());
codedIS.popLimit(olds);
break;
default:
skipUnknownField(t);
break;
}
}
codedIS.popLimit(old);
if(name != -1){
dataObject.setName(getStringFromStringTable(ind.stringTable, name));
}
if(nameEn != -1){
dataObject.setEnName(getStringFromStringTable(ind.stringTable, nameEn));
} else {
dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
}
if(operator != -1){
dataObject.setOperator(getStringFromStringTable(ind.stringTable, operator));
}
if(type != -1){
dataObject.setType(getStringFromStringTable(ind.stringTable, type));
}
for (int i = 0; i < 2; i++) {
List<TransportStop> stops = i == 0 ? dataObject.getForwardStops() : dataObject.getBackwardStops();
for (TransportStop s : stops) {
if (s.getName().length() > 0) {
s.setName(getStringFromStringTable(ind.stringTable, s.getName().charAt(0)));
}
if (s.getEnName().length() > 0) {
s.setEnName(getStringFromStringTable(ind.stringTable, s.getEnName().charAt(0)));
} else {
s.setEnName(Junidecode.unidecode(s.getName()));
}
}
}
return dataObject;
}
private TransportStop readTransportRouteStop(int dx, int dy, long did) throws IOException {
TransportStop dataObject = new TransportStop();
boolean end = false;
while(!end){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
if(dataObject.getEnName().length() == 0){
dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
}
end = true;
break;
case OsmandOdb.TransportRouteStop.NAME_EN_FIELD_NUMBER :
dataObject.setEnName(""+((char) codedIS.readUInt32())); //$NON-NLS-1$
break;
case OsmandOdb.TransportRouteStop.NAME_FIELD_NUMBER :
dataObject.setName(""+((char) codedIS.readUInt32())); //$NON-NLS-1$
break;
case OsmandOdb.TransportRouteStop.ID_FIELD_NUMBER :
did += codedIS.readSInt64();
break;
case OsmandOdb.TransportRouteStop.DX_FIELD_NUMBER :
dx += codedIS.readSInt32();
break;
case OsmandOdb.TransportRouteStop.DY_FIELD_NUMBER :
dy += codedIS.readSInt32();
break;
default:
skipUnknownField(t);
break;
}
}
dataObject.setId(did);
dataObject.setLocation(MapUtils.getLatitudeFromTile(TRANSPORT_STOP_ZOOM, dy), MapUtils.getLongitudeFromTile(TRANSPORT_STOP_ZOOM, dx));
return dataObject;
}
private TransportStop readTransportStop(int shift, int cleft, int cright, int ctop, int cbottom, SearchRequest<TransportStop> req) throws IOException {
int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
if(OsmandOdb.TransportStop.DX_FIELD_NUMBER != tag) {
throw new IllegalArgumentException();
}
int x = codedIS.readSInt32() + cleft;
tag = WireFormat.getTagFieldNumber(codedIS.readTag());
if(OsmandOdb.TransportStop.DY_FIELD_NUMBER != tag) {
throw new IllegalArgumentException();
}
int y = codedIS.readSInt32() + ctop;
if(req.right < x || req.left > x || req.top > y || req.bottom < y){
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return null;
}
req.numberOfAcceptedObjects++;
req.cacheTypes.clear();
TransportStop dataObject = new TransportStop();
dataObject.setLocation(MapUtils.getLatitudeFromTile(TRANSPORT_STOP_ZOOM, y), MapUtils.getLongitudeFromTile(TRANSPORT_STOP_ZOOM, x));
dataObject.setFileOffset(shift);
while(true){
int t = codedIS.readTag();
tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
dataObject.setReferencesToRoutes(req.cacheTypes.toArray());
if(dataObject.getEnName().length() == 0){
dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
}
return dataObject;
case OsmandOdb.TransportStop.ROUTES_FIELD_NUMBER :
req.cacheTypes.add(shift - codedIS.readUInt32());
break;
case OsmandOdb.TransportStop.NAME_EN_FIELD_NUMBER :
dataObject.setEnName(""+((char) codedIS.readUInt32())); //$NON-NLS-1$
break;
case OsmandOdb.TransportStop.NAME_FIELD_NUMBER :
int i = codedIS.readUInt32();
dataObject.setName(""+((char) i)); //$NON-NLS-1$
break;
case OsmandOdb.TransportStop.ID_FIELD_NUMBER :
dataObject.setId(codedIS.readSInt64());
break;
default:
skipUnknownField(t);
break;
}
}
}
}