implement binary transport reader

git-svn-id: https://osmand.googlecode.com/svn/trunk@636 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-11-06 12:42:46 +00:00
parent 082c6ea018
commit 4dd4efe6ba
11 changed files with 1266 additions and 499 deletions

View file

@ -541,6 +541,23 @@ public final class CodedInputStreamRAF {
return oldLimit;
}
public int pushAbsoluteLimit(int byteLimit) throws InvalidProtocolBufferException {
if (byteLimit < 0) {
throw InvalidProtocolBufferException.negativeSize();
}
// that's absolute limit as parameter
// byteLimit += totalBytesRetired + bufferPos;
final int oldLimit = currentLimit;
if (byteLimit > oldLimit) {
throw InvalidProtocolBufferException.truncatedMessage();
}
currentLimit = byteLimit;
recomputeBufferSizeAfterLimit();
return oldLimit;
}
private void recomputeBufferSizeAfterLimit() {
bufferSize += bufferSizeAfterLimit;
final int bufferEnd = totalBytesRetired + bufferSize;

View file

@ -7,7 +7,9 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.osmand.Algoritms;
import net.osmand.LogUtil;
@ -15,6 +17,7 @@ import net.osmand.data.Building;
import net.osmand.data.City;
import net.osmand.data.PostCode;
import net.osmand.data.Street;
import net.osmand.data.TransportStop;
import net.osmand.data.City.CityType;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
@ -27,10 +30,13 @@ import com.google.protobuf.WireFormat;
public class BinaryMapIndexReader {
private final static int TRANSPORT_STOP_ZOOM = 24;
private final RandomAccessFile raf;
private int version;
private List<MapRoot> mapIndexes = new ArrayList<MapRoot>();
private List<AddressRegion> addressIndexes = new ArrayList<AddressRegion>();
private List<TransportIndex> transportIndexes = new ArrayList<TransportIndex>();
private CodedInputStreamRAF codedIS;
private final static Log log = LogUtil.getLog(BinaryMapIndexReader.class);
@ -75,6 +81,16 @@ public class BinaryMapIndexReader {
codedIS.popLimit(oldLimit);
codedIS.seek(region.fileOffset + region.length);
break;
case OsmandOdb.OsmAndStructure.TRANSPORTINDEX_FIELD_NUMBER:
TransportIndex ind = new TransportIndex();
ind.length = readInt();
ind.fileOffset = codedIS.getTotalBytesRead();
oldLimit = codedIS.pushLimit(ind.length);
readTransportIndex(ind);
codedIS.popLimit(oldLimit);
codedIS.seek(ind.fileOffset + ind.length);
transportIndexes.add(ind);
break;
case OsmandOdb.OsmAndStructure.VERSIONCONFIRM_FIELD_NUMBER :
int cversion = codedIS.readUInt32();
initCorrectly = cversion == version;
@ -86,6 +102,7 @@ public class BinaryMapIndexReader {
}
}
private void skipUnknownField(int tag) throws IOException{
int wireType = WireFormat.getTagWireType(tag);
if(wireType == WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED){
@ -96,6 +113,305 @@ public class BinaryMapIndexReader {
}
}
private 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.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, 30, true);
ind.stringTable = st;
codedIS.seek(st.length + st.fileOffset);
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 old = codedIS.pushAbsoluteLimit(st.fileOffset + st.length);
int toSkip = seekUsingOffsets(st, startOffset);
if(!cache){
st.window.clear();
st.windowOffset = startOffset;
}
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;
}
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);
}
}
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;
}
}
}
private 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 length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
if(lastIndexResult == -1){
lastIndexResult = req.searchResults.size();
}
TransportStop transportStop = readTransportStop(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();
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;
}
}
}
private TransportStop readTransportStop(int cleft, int cright, int ctop, int cbottom, SearchRequest<TransportStop> req) throws IOException {
int shift = codedIS.getTotalBytesRead();
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(cright < x || cleft > x || ctop > y || cbottom < 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));
while(true){
int t = codedIS.readTag();
tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
dataObject.setReferencesToRoutes(req.cacheTypes.toArray());
return dataObject;
case OsmandOdb.TransportStop.ROUTES_FIELD_NUMBER :
req.cacheTypes.add(shift - codedIS.readUInt32());
break;
case OsmandOdb.TransportStop.NAME_EN_FIELD_NUMBER :
dataObject.setName(""+((char) codedIS.readUInt32())); //$NON-NLS-1$
break;
case OsmandOdb.TransportStop.NAME_FIELD_NUMBER :
dataObject.setName(""+((char) codedIS.readUInt32())); //$NON-NLS-1$
break;
case OsmandOdb.TransportStop.ID_FIELD_NUMBER :
dataObject.setId(codedIS.readSInt64());
break;
default:
skipUnknownField(t);
break;
}
}
}
private void readAddressIndex(AddressRegion region) throws IOException {
while(true){
int t = codedIS.readTag();
@ -242,7 +558,7 @@ public class BinaryMapIndexReader {
public List<BinaryMapDataObject> searchMapIndex(SearchRequest req) throws IOException {
public List<BinaryMapDataObject> searchMapIndex(SearchRequest<BinaryMapDataObject> req) throws IOException {
for (MapRoot index : mapIndexes) {
if (index.minZoom <= req.zoom && index.maxZoom >= req.zoom) {
if(index.right < req.left || index.left > req.right || index.top > req.bottom || index.bottom < req.top){
@ -808,7 +1124,7 @@ public class BinaryMapIndexReader {
}
private void searchMapTreeBounds(int pleft, int pright, int ptop, int pbottom,
SearchRequest req) throws IOException {
SearchRequest<BinaryMapDataObject> req) throws IOException {
int init = 0;
int lastIndexResult = -1;
int cright = 0;
@ -913,7 +1229,7 @@ public class BinaryMapIndexReader {
}
private int MASK_TO_READ = ~((1 << BinaryMapIndexWriter.SHIFT_COORDINATES) - 1);
private BinaryMapDataObject readMapDataObject(int left, int right, int top, int bottom, SearchRequest req) throws IOException {
private BinaryMapDataObject readMapDataObject(int left, int right, int top, int bottom, SearchRequest<BinaryMapDataObject> req) throws IOException {
int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
if(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER != tag) {
throw new IllegalArgumentException();
@ -1071,8 +1387,8 @@ public class BinaryMapIndexReader {
}
public static SearchRequest buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom){
SearchRequest request = new SearchRequest();
public static SearchRequest<BinaryMapDataObject> buildSearchRequest(int sleft, int sright, int stop, int sbottom, int zoom){
SearchRequest<BinaryMapDataObject> request = new SearchRequest<BinaryMapDataObject>();
request.left = sleft;
request.right = sright;
request.top = stop;
@ -1086,21 +1402,24 @@ public class BinaryMapIndexReader {
raf.close();
codedIS = null;
mapIndexes.clear();
addressIndexes.clear();
transportIndexes.clear();
}
}
public static interface SearchFilter {
public boolean accept(TIntArrayList types);
}
public static class SearchRequest {
public static class SearchRequest<T> {
int left = 0;
int right = 0;
int top = 0;
int bottom = 0;
int zoom = 15;
List<BinaryMapDataObject> searchResults = new ArrayList<BinaryMapDataObject>();
List<T> searchResults = new ArrayList<T>();
TIntArrayList cacheCoordinates = new TIntArrayList();
TIntArrayList cacheTypes = new TIntArrayList();
SearchFilter searchFilter = null;
@ -1122,7 +1441,7 @@ public class BinaryMapIndexReader {
this.searchFilter = searchFilter;
}
public List<BinaryMapDataObject> getSearchResults() {
public List<T> getSearchResults() {
return searchResults;
}
@ -1162,6 +1481,37 @@ public class BinaryMapIndexReader {
}
private static class TransportIndex {
int fileOffset = 0;
int length = 0;
int left = 0;
int right = 0;
int top = 0;
int bottom = 0;
int stopsFileOffset = 0;
int stopsFileLength = 0;
IndexStringTable stringTable = null;
}
private static class IndexStringTable {
private static final int SIZE_OFFSET_ARRAY = 4;
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>();
}
private static class AddressRegion {
String name;
@ -1176,10 +1526,11 @@ public class BinaryMapIndexReader {
}
public static void main(String[] args) throws IOException {
// RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Belarus.map.pbf"), "r");
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
// RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Belarus_4.map.pbf"), "r");
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
System.out.println("VERSION " + reader.getVersion());
long time = System.currentTimeMillis();
// test search
// int sleft = MapUtils.get31TileNumberX(27.596);
@ -1195,9 +1546,8 @@ public class BinaryMapIndexReader {
// }
// test address index search
String reg = reader.getRegionNames().get(0);
long time = System.currentTimeMillis();
List<City> cs = reader.getCities(reg);
// String reg = reader.getRegionNames().get(0);
// List<City> cs = reader.getCities(reg);
// for(City c : cs){
// reader.preloadStreets(c);
// int buildings = 0;
@ -1212,11 +1562,19 @@ public class BinaryMapIndexReader {
// reader.preloadStreets(c);
//// System.out.println(c.getName());
// }
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
List<City> villages = reader.getVillages(reg, "кост", false);
// List<City> villages = reader.getVillages(reg, "коче", false);
// System.out.println("Villages " + villages.size());
System.out.println("Villages " + villages.size());
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
// test transport
for(TransportIndex i : reader.transportIndexes){
System.out.println(i.left + " " + i.right + " " + i.top + " " + i.bottom);
System.out.println(i.stringTable.cacheOfStrings);
System.out.println(reader.getStringFromStringTable(i.stringTable, 58));
System.out.println(i.stringTable.offsets);
System.out.println(i.stringTable.window);
}
System.out.println("MEMORY " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
System.out.println("Time " + (System.currentTimeMillis() - time));
}

View file

@ -78,6 +78,7 @@ public class BinaryMapIndexWriter {
private final static int TRANSPORT_INDEX_INIT = 9;
private final static int TRANSPORT_STOPS_TREE = 10;
private final static int TRANSPORT_ROUTES = 11;
public BinaryMapIndexWriter(final RandomAccessFile raf) throws IOException{
this.raf = raf;
@ -528,18 +529,15 @@ public class BinaryMapIndexWriter {
return streetBuilder.build();
}
public void startWriteTransportIndex() throws IOException {
pushState(TRANSPORT_INDEX_INIT, OSMAND_STRUCTURE_INIT);
codedOutStream.writeTag(OsmandOdb.OsmAndStructure.TRANSPORTINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
stackBounds.push(new Bounds(0, 0, 0, 0)); // for transport stops tree
public void startWriteTransportRoutes() throws IOException {
pushState(TRANSPORT_ROUTES, TRANSPORT_INDEX_INIT);
codedOutStream.writeTag(OsmandOdb.OsmAndTransportIndex.ROUTES_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
preserveInt32Size();
}
public void endWriteTransportIndex() throws IOException {
popState(TRANSPORT_INDEX_INIT);
int len = writeInt32Size();
stackBounds.pop();
System.out.println("TRANSPORT INDEX SIZE : " + len);
public void endWriteTransportRoutes() throws IOException {
popState(TRANSPORT_ROUTES);
writeInt32Size();
}
private int registerString(Map<String, Integer> stringTable, String s) {
@ -554,10 +552,24 @@ public class BinaryMapIndexWriter {
return size;
}
public void startWriteTransportIndex() throws IOException {
pushState(TRANSPORT_INDEX_INIT, OSMAND_STRUCTURE_INIT);
codedOutStream.writeTag(OsmandOdb.OsmAndStructure.TRANSPORTINDEX_FIELD_NUMBER, WireFormat.WIRETYPE_FIXED32_LENGTH_DELIMITED);
stackBounds.push(new Bounds(0, 0, 0, 0)); // for transport stops tree
preserveInt32Size();
}
public void endWriteTransportIndex() throws IOException {
popState(TRANSPORT_INDEX_INIT);
int len = writeInt32Size();
stackBounds.pop();
System.out.println("TRANSPORT INDEX SIZE : " + len);
}
public void writeTransportRoute(long idRoute, String routeName, String routeEnName, String ref, String operator, String type,
int dist, List<TransportStop> directStops, List<TransportStop> reverseStops,
Map<String, Integer> stringTable, Map<Long, Long> transportRoutesRegistry) throws IOException {
checkPeekState(TRANSPORT_INDEX_INIT);
checkPeekState(TRANSPORT_ROUTES);
TransportRoute.Builder tRoute = OsmandOdb.TransportRoute.newBuilder();
tRoute.setRef(ref);
tRoute.setOperator(registerString(stringTable, operator));
@ -595,7 +607,7 @@ public class BinaryMapIndexWriter {
}
}
}
codedOutStream.writeTag(OsmandOdb.OsmAndTransportIndex.ROUTES_FIELD_NUMBER, FieldType.MESSAGE.getWireType());
codedOutStream.writeTag(OsmandOdb.TransportRoutes.ROUTES_FIELD_NUMBER, FieldType.MESSAGE.getWireType());
codedOutStream.flush();
if(transportRoutesRegistry != null){
transportRoutesRegistry.put(idRoute, raf.getFilePointer());

View file

@ -7077,6 +7077,340 @@ public final class OsmandOdb {
// @@protoc_insertion_point(class_scope:BuildingIndex)
}
public static final class TransportRoutes extends
com.google.protobuf.GeneratedMessage {
// Use TransportRoutes.newBuilder() to construct.
private TransportRoutes() {
initFields();
}
private TransportRoutes(boolean noInit) {}
private static final TransportRoutes defaultInstance;
public static TransportRoutes getDefaultInstance() {
return defaultInstance;
}
public TransportRoutes getDefaultInstanceForType() {
return defaultInstance;
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return net.osmand.binary.OsmandOdb.internal_static_TransportRoutes_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
return net.osmand.binary.OsmandOdb.internal_static_TransportRoutes_fieldAccessorTable;
}
// repeated .TransportRoute routes = 6;
public static final int ROUTES_FIELD_NUMBER = 6;
private java.util.List<net.osmand.binary.OsmandOdb.TransportRoute> routes_ =
java.util.Collections.emptyList();
public java.util.List<net.osmand.binary.OsmandOdb.TransportRoute> getRoutesList() {
return routes_;
}
public int getRoutesCount() { return routes_.size(); }
public net.osmand.binary.OsmandOdb.TransportRoute getRoutes(int index) {
return routes_.get(index);
}
private void initFields() {
}
public final boolean isInitialized() {
for (net.osmand.binary.OsmandOdb.TransportRoute element : getRoutesList()) {
if (!element.isInitialized()) return false;
}
return true;
}
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
for (net.osmand.binary.OsmandOdb.TransportRoute element : getRoutesList()) {
output.writeMessage(6, element);
}
getUnknownFields().writeTo(output);
}
private int memoizedSerializedSize = -1;
public int getSerializedSize() {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
for (net.osmand.binary.OsmandOdb.TransportRoute element : getRoutesList()) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(6, element);
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data).buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data, extensionRegistry)
.buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data).buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return newBuilder().mergeFrom(data, extensionRegistry)
.buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(java.io.InputStream input)
throws java.io.IOException {
return newBuilder().mergeFrom(input).buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return newBuilder().mergeFrom(input, extensionRegistry)
.buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
Builder builder = newBuilder();
if (builder.mergeDelimitedFrom(input)) {
return builder.buildParsed();
} else {
return null;
}
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
Builder builder = newBuilder();
if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
return builder.buildParsed();
} else {
return null;
}
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return newBuilder().mergeFrom(input).buildParsed();
}
public static net.osmand.binary.OsmandOdb.TransportRoutes parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return newBuilder().mergeFrom(input, extensionRegistry)
.buildParsed();
}
public static Builder newBuilder() { return Builder.create(); }
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder(net.osmand.binary.OsmandOdb.TransportRoutes prototype) {
return newBuilder().mergeFrom(prototype);
}
public Builder toBuilder() { return newBuilder(this); }
public static final class Builder extends
com.google.protobuf.GeneratedMessage.Builder<Builder> {
private net.osmand.binary.OsmandOdb.TransportRoutes result;
// Construct using net.osmand.binary.OsmandOdb.TransportRoutes.newBuilder()
private Builder() {}
private static Builder create() {
Builder builder = new Builder();
builder.result = new net.osmand.binary.OsmandOdb.TransportRoutes();
return builder;
}
protected net.osmand.binary.OsmandOdb.TransportRoutes internalGetResult() {
return result;
}
public Builder clear() {
if (result == null) {
throw new IllegalStateException(
"Cannot call clear() after build().");
}
result = new net.osmand.binary.OsmandOdb.TransportRoutes();
return this;
}
public Builder clone() {
return create().mergeFrom(result);
}
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return net.osmand.binary.OsmandOdb.TransportRoutes.getDescriptor();
}
public net.osmand.binary.OsmandOdb.TransportRoutes getDefaultInstanceForType() {
return net.osmand.binary.OsmandOdb.TransportRoutes.getDefaultInstance();
}
public boolean isInitialized() {
return result.isInitialized();
}
public net.osmand.binary.OsmandOdb.TransportRoutes build() {
if (result != null && !isInitialized()) {
throw newUninitializedMessageException(result);
}
return buildPartial();
}
private net.osmand.binary.OsmandOdb.TransportRoutes buildParsed()
throws com.google.protobuf.InvalidProtocolBufferException {
if (!isInitialized()) {
throw newUninitializedMessageException(
result).asInvalidProtocolBufferException();
}
return buildPartial();
}
public net.osmand.binary.OsmandOdb.TransportRoutes buildPartial() {
if (result == null) {
throw new IllegalStateException(
"build() has already been called on this Builder.");
}
if (result.routes_ != java.util.Collections.EMPTY_LIST) {
result.routes_ =
java.util.Collections.unmodifiableList(result.routes_);
}
net.osmand.binary.OsmandOdb.TransportRoutes returnMe = result;
result = null;
return returnMe;
}
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof net.osmand.binary.OsmandOdb.TransportRoutes) {
return mergeFrom((net.osmand.binary.OsmandOdb.TransportRoutes)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(net.osmand.binary.OsmandOdb.TransportRoutes other) {
if (other == net.osmand.binary.OsmandOdb.TransportRoutes.getDefaultInstance()) return this;
if (!other.routes_.isEmpty()) {
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
result.routes_.addAll(other.routes_);
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder(
this.getUnknownFields());
while (true) {
int tag = input.readTag();
switch (tag) {
case 0:
this.setUnknownFields(unknownFields.build());
return this;
default: {
if (!parseUnknownField(input, unknownFields,
extensionRegistry, tag)) {
this.setUnknownFields(unknownFields.build());
return this;
}
break;
}
case 50: {
net.osmand.binary.OsmandOdb.TransportRoute.Builder subBuilder = net.osmand.binary.OsmandOdb.TransportRoute.newBuilder();
input.readMessage(subBuilder, extensionRegistry);
addRoutes(subBuilder.buildPartial());
break;
}
}
}
}
// repeated .TransportRoute routes = 6;
public java.util.List<net.osmand.binary.OsmandOdb.TransportRoute> getRoutesList() {
return java.util.Collections.unmodifiableList(result.routes_);
}
public int getRoutesCount() {
return result.getRoutesCount();
}
public net.osmand.binary.OsmandOdb.TransportRoute getRoutes(int index) {
return result.getRoutes(index);
}
public Builder setRoutes(int index, net.osmand.binary.OsmandOdb.TransportRoute value) {
if (value == null) {
throw new NullPointerException();
}
result.routes_.set(index, value);
return this;
}
public Builder setRoutes(int index, net.osmand.binary.OsmandOdb.TransportRoute.Builder builderForValue) {
result.routes_.set(index, builderForValue.build());
return this;
}
public Builder addRoutes(net.osmand.binary.OsmandOdb.TransportRoute value) {
if (value == null) {
throw new NullPointerException();
}
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
result.routes_.add(value);
return this;
}
public Builder addRoutes(net.osmand.binary.OsmandOdb.TransportRoute.Builder builderForValue) {
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
result.routes_.add(builderForValue.build());
return this;
}
public Builder addAllRoutes(
java.lang.Iterable<? extends net.osmand.binary.OsmandOdb.TransportRoute> values) {
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
super.addAll(values, result.routes_);
return this;
}
public Builder clearRoutes() {
result.routes_ = java.util.Collections.emptyList();
return this;
}
// @@protoc_insertion_point(builder_scope:TransportRoutes)
}
static {
defaultInstance = new TransportRoutes(true);
net.osmand.binary.OsmandOdb.internalForceInit();
defaultInstance.initFields();
}
// @@protoc_insertion_point(class_scope:TransportRoutes)
}
public static final class TransportRoute extends
com.google.protobuf.GeneratedMessage {
// Use TransportRoute.newBuilder() to construct.
@ -8248,27 +8582,27 @@ public final class OsmandOdb {
return net.osmand.binary.OsmandOdb.internal_static_TransportStop_fieldAccessorTable;
}
// required sint64 id = 1;
public static final int ID_FIELD_NUMBER = 1;
private boolean hasId;
private long id_ = 0L;
public boolean hasId() { return hasId; }
public long getId() { return id_; }
// required sint32 dx = 2;
public static final int DX_FIELD_NUMBER = 2;
// required sint32 dx = 1;
public static final int DX_FIELD_NUMBER = 1;
private boolean hasDx;
private int dx_ = 0;
public boolean hasDx() { return hasDx; }
public int getDx() { return dx_; }
// required sint32 dy = 3;
public static final int DY_FIELD_NUMBER = 3;
// required sint32 dy = 2;
public static final int DY_FIELD_NUMBER = 2;
private boolean hasDy;
private int dy_ = 0;
public boolean hasDy() { return hasDy; }
public int getDy() { return dy_; }
// required sint64 id = 5;
public static final int ID_FIELD_NUMBER = 5;
private boolean hasId;
private long id_ = 0L;
public boolean hasId() { return hasId; }
public long getId() { return id_; }
// required uint32 name = 6;
public static final int NAME_FIELD_NUMBER = 6;
private boolean hasName;
@ -8298,9 +8632,9 @@ public final class OsmandOdb {
private void initFields() {
}
public final boolean isInitialized() {
if (!hasId) return false;
if (!hasDx) return false;
if (!hasDy) return false;
if (!hasId) return false;
if (!hasName) return false;
return true;
}
@ -8308,14 +8642,14 @@ public final class OsmandOdb {
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
if (hasId()) {
output.writeSInt64(1, getId());
}
if (hasDx()) {
output.writeSInt32(2, getDx());
output.writeSInt32(1, getDx());
}
if (hasDy()) {
output.writeSInt32(3, getDy());
output.writeSInt32(2, getDy());
}
if (hasId()) {
output.writeSInt64(5, getId());
}
if (hasName()) {
output.writeUInt32(6, getName());
@ -8335,17 +8669,17 @@ public final class OsmandOdb {
if (size != -1) return size;
size = 0;
if (hasId()) {
size += com.google.protobuf.CodedOutputStream
.computeSInt64Size(1, getId());
}
if (hasDx()) {
size += com.google.protobuf.CodedOutputStream
.computeSInt32Size(2, getDx());
.computeSInt32Size(1, getDx());
}
if (hasDy()) {
size += com.google.protobuf.CodedOutputStream
.computeSInt32Size(3, getDy());
.computeSInt32Size(2, getDy());
}
if (hasId()) {
size += com.google.protobuf.CodedOutputStream
.computeSInt64Size(5, getId());
}
if (hasName()) {
size += com.google.protobuf.CodedOutputStream
@ -8526,15 +8860,15 @@ public final class OsmandOdb {
public Builder mergeFrom(net.osmand.binary.OsmandOdb.TransportStop other) {
if (other == net.osmand.binary.OsmandOdb.TransportStop.getDefaultInstance()) return this;
if (other.hasId()) {
setId(other.getId());
}
if (other.hasDx()) {
setDx(other.getDx());
}
if (other.hasDy()) {
setDy(other.getDy());
}
if (other.hasId()) {
setId(other.getId());
}
if (other.hasName()) {
setName(other.getName());
}
@ -8573,17 +8907,17 @@ public final class OsmandOdb {
break;
}
case 8: {
setId(input.readSInt64());
break;
}
case 16: {
setDx(input.readSInt32());
break;
}
case 24: {
case 16: {
setDy(input.readSInt32());
break;
}
case 40: {
setId(input.readSInt64());
break;
}
case 48: {
setName(input.readUInt32());
break;
@ -8610,25 +8944,7 @@ public final class OsmandOdb {
}
// required sint64 id = 1;
public boolean hasId() {
return result.hasId();
}
public long getId() {
return result.getId();
}
public Builder setId(long value) {
result.hasId = true;
result.id_ = value;
return this;
}
public Builder clearId() {
result.hasId = false;
result.id_ = 0L;
return this;
}
// required sint32 dx = 2;
// required sint32 dx = 1;
public boolean hasDx() {
return result.hasDx();
}
@ -8646,7 +8962,7 @@ public final class OsmandOdb {
return this;
}
// required sint32 dy = 3;
// required sint32 dy = 2;
public boolean hasDy() {
return result.hasDy();
}
@ -8664,6 +8980,24 @@ public final class OsmandOdb {
return this;
}
// required sint64 id = 5;
public boolean hasId() {
return result.hasId();
}
public long getId() {
return result.getId();
}
public Builder setId(long value) {
result.hasId = true;
result.id_ = value;
return this;
}
public Builder clearId() {
result.hasId = false;
result.id_ = 0L;
return this;
}
// required uint32 name = 6;
public boolean hasName() {
return result.hasName();
@ -9395,17 +9729,12 @@ public final class OsmandOdb {
return net.osmand.binary.OsmandOdb.internal_static_OsmAndTransportIndex_fieldAccessorTable;
}
// repeated .TransportRoute routes = 3;
// optional .TransportRoutes routes = 3;
public static final int ROUTES_FIELD_NUMBER = 3;
private java.util.List<net.osmand.binary.OsmandOdb.TransportRoute> routes_ =
java.util.Collections.emptyList();
public java.util.List<net.osmand.binary.OsmandOdb.TransportRoute> getRoutesList() {
return routes_;
}
public int getRoutesCount() { return routes_.size(); }
public net.osmand.binary.OsmandOdb.TransportRoute getRoutes(int index) {
return routes_.get(index);
}
private boolean hasRoutes;
private net.osmand.binary.OsmandOdb.TransportRoutes routes_;
public boolean hasRoutes() { return hasRoutes; }
public net.osmand.binary.OsmandOdb.TransportRoutes getRoutes() { return routes_; }
// optional .TransportStopsTree stops = 6;
public static final int STOPS_FIELD_NUMBER = 6;
@ -9422,13 +9751,14 @@ public final class OsmandOdb {
public net.osmand.binary.OsmandOdb.StringTable getStringTable() { return stringTable_; }
private void initFields() {
routes_ = net.osmand.binary.OsmandOdb.TransportRoutes.getDefaultInstance();
stops_ = net.osmand.binary.OsmandOdb.TransportStopsTree.getDefaultInstance();
stringTable_ = net.osmand.binary.OsmandOdb.StringTable.getDefaultInstance();
}
public final boolean isInitialized() {
if (!hasStringTable) return false;
for (net.osmand.binary.OsmandOdb.TransportRoute element : getRoutesList()) {
if (!element.isInitialized()) return false;
if (hasRoutes()) {
if (!getRoutes().isInitialized()) return false;
}
if (hasStops()) {
if (!getStops().isInitialized()) return false;
@ -9439,8 +9769,8 @@ public final class OsmandOdb {
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
for (net.osmand.binary.OsmandOdb.TransportRoute element : getRoutesList()) {
output.writeMessage(3, element);
if (hasRoutes()) {
output.writeMessage(3, getRoutes());
}
if (hasStops()) {
output.writeMessage(6, getStops());
@ -9457,9 +9787,9 @@ public final class OsmandOdb {
if (size != -1) return size;
size = 0;
for (net.osmand.binary.OsmandOdb.TransportRoute element : getRoutesList()) {
if (hasRoutes()) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(3, element);
.computeMessageSize(3, getRoutes());
}
if (hasStops()) {
size += com.google.protobuf.CodedOutputStream
@ -9611,10 +9941,6 @@ public final class OsmandOdb {
throw new IllegalStateException(
"build() has already been called on this Builder.");
}
if (result.routes_ != java.util.Collections.EMPTY_LIST) {
result.routes_ =
java.util.Collections.unmodifiableList(result.routes_);
}
net.osmand.binary.OsmandOdb.OsmAndTransportIndex returnMe = result;
result = null;
return returnMe;
@ -9631,11 +9957,8 @@ public final class OsmandOdb {
public Builder mergeFrom(net.osmand.binary.OsmandOdb.OsmAndTransportIndex other) {
if (other == net.osmand.binary.OsmandOdb.OsmAndTransportIndex.getDefaultInstance()) return this;
if (!other.routes_.isEmpty()) {
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
result.routes_.addAll(other.routes_);
if (other.hasRoutes()) {
mergeRoutes(other.getRoutes());
}
if (other.hasStops()) {
mergeStops(other.getStops());
@ -9669,9 +9992,12 @@ public final class OsmandOdb {
break;
}
case 26: {
net.osmand.binary.OsmandOdb.TransportRoute.Builder subBuilder = net.osmand.binary.OsmandOdb.TransportRoute.newBuilder();
net.osmand.binary.OsmandOdb.TransportRoutes.Builder subBuilder = net.osmand.binary.OsmandOdb.TransportRoutes.newBuilder();
if (hasRoutes()) {
subBuilder.mergeFrom(getRoutes());
}
input.readMessage(subBuilder, extensionRegistry);
addRoutes(subBuilder.buildPartial());
setRoutes(subBuilder.buildPartial());
break;
}
case 50: {
@ -9697,54 +10023,40 @@ public final class OsmandOdb {
}
// repeated .TransportRoute routes = 3;
public java.util.List<net.osmand.binary.OsmandOdb.TransportRoute> getRoutesList() {
return java.util.Collections.unmodifiableList(result.routes_);
// optional .TransportRoutes routes = 3;
public boolean hasRoutes() {
return result.hasRoutes();
}
public int getRoutesCount() {
return result.getRoutesCount();
public net.osmand.binary.OsmandOdb.TransportRoutes getRoutes() {
return result.getRoutes();
}
public net.osmand.binary.OsmandOdb.TransportRoute getRoutes(int index) {
return result.getRoutes(index);
}
public Builder setRoutes(int index, net.osmand.binary.OsmandOdb.TransportRoute value) {
public Builder setRoutes(net.osmand.binary.OsmandOdb.TransportRoutes value) {
if (value == null) {
throw new NullPointerException();
}
result.routes_.set(index, value);
result.hasRoutes = true;
result.routes_ = value;
return this;
}
public Builder setRoutes(int index, net.osmand.binary.OsmandOdb.TransportRoute.Builder builderForValue) {
result.routes_.set(index, builderForValue.build());
public Builder setRoutes(net.osmand.binary.OsmandOdb.TransportRoutes.Builder builderForValue) {
result.hasRoutes = true;
result.routes_ = builderForValue.build();
return this;
}
public Builder addRoutes(net.osmand.binary.OsmandOdb.TransportRoute value) {
if (value == null) {
throw new NullPointerException();
public Builder mergeRoutes(net.osmand.binary.OsmandOdb.TransportRoutes value) {
if (result.hasRoutes() &&
result.routes_ != net.osmand.binary.OsmandOdb.TransportRoutes.getDefaultInstance()) {
result.routes_ =
net.osmand.binary.OsmandOdb.TransportRoutes.newBuilder(result.routes_).mergeFrom(value).buildPartial();
} else {
result.routes_ = value;
}
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
result.routes_.add(value);
return this;
}
public Builder addRoutes(net.osmand.binary.OsmandOdb.TransportRoute.Builder builderForValue) {
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
result.routes_.add(builderForValue.build());
return this;
}
public Builder addAllRoutes(
java.lang.Iterable<? extends net.osmand.binary.OsmandOdb.TransportRoute> values) {
if (result.routes_.isEmpty()) {
result.routes_ = new java.util.ArrayList<net.osmand.binary.OsmandOdb.TransportRoute>();
}
super.addAll(values, result.routes_);
result.hasRoutes = true;
return this;
}
public Builder clearRoutes() {
result.routes_ = java.util.Collections.emptyList();
result.hasRoutes = false;
result.routes_ = net.osmand.binary.OsmandOdb.TransportRoutes.getDefaultInstance();
return this;
}
@ -9909,6 +10221,11 @@ public final class OsmandOdb {
private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_BuildingIndex_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor
internal_static_TransportRoutes_descriptor;
private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_TransportRoutes_fieldAccessorTable;
private static com.google.protobuf.Descriptors.Descriptor
internal_static_TransportRoute_descriptor;
private static
@ -9983,25 +10300,26 @@ public final class OsmandOdb {
"\002id\030\006 \001(\004\022!\n\tbuildings\030\022 \003(\0132\016.BuildingI" +
"ndex\"b\n\rBuildingIndex\022\014\n\004name\030\001 \002(\t\022\017\n\007n" +
"ame_en\030\002 \001(\t\022\n\n\002id\030\005 \001(\004\022\020\n\010postcode\030\006 \001",
"(\t\022\t\n\001x\030\003 \002(\021\022\t\n\001y\030\004 \002(\021\"\317\001\n\016TransportRo" +
"ute\022\n\n\002id\030\001 \002(\004\022\014\n\004type\030\003 \001(\r\022\020\n\010operato" +
"r\030\004 \001(\r\022\013\n\003ref\030\005 \001(\t\022\014\n\004name\030\006 \001(\r\022\017\n\007na" +
"me_en\030\007 \001(\r\022\020\n\010distance\030\010 \001(\r\022(\n\013directS" +
"tops\030\017 \003(\0132\023.TransportRouteStop\022)\n\014rever" +
"seStops\030\020 \003(\0132\023.TransportRouteStop\"W\n\022Tr" +
"ansportRouteStop\022\n\n\002id\030\001 \002(\022\022\n\n\002dx\030\002 \002(\021" +
"\022\n\n\002dy\030\003 \002(\021\022\014\n\004name\030\006 \002(\r\022\017\n\007name_en\030\007 " +
"\001(\r\"b\n\rTransportStop\022\n\n\002id\030\001 \002(\022\022\n\n\002dx\030\002" +
" \002(\021\022\n\n\002dy\030\003 \002(\021\022\014\n\004name\030\006 \002(\r\022\017\n\007name_e",
"n\030\007 \001(\r\022\016\n\006routes\030\020 \003(\r\"\244\001\n\022TransportSto" +
"psTree\022\014\n\004left\030\001 \002(\021\022\r\n\005right\030\002 \002(\021\022\013\n\003t" +
"op\030\003 \002(\021\022\016\n\006bottom\030\004 \002(\021\022%\n\010subtrees\030\007 \003" +
"(\0132\023.TransportStopsTree\022\035\n\005leafs\030\010 \003(\0132\016" +
".TransportStop\022\016\n\006baseId\030\020 \001(\004\"~\n\024OsmAnd" +
"TransportIndex\022\037\n\006routes\030\003 \003(\0132\017.Transpo" +
"rtRoute\022\"\n\005stops\030\006 \001(\0132\023.TransportStopsT" +
"ree\022!\n\013stringTable\030\t \002(\0132\014.StringTableB\023" +
"\n\021net.osmand.binary"
"(\t\022\t\n\001x\030\003 \002(\021\022\t\n\001y\030\004 \002(\021\"2\n\017TransportRou" +
"tes\022\037\n\006routes\030\006 \003(\0132\017.TransportRoute\"\317\001\n" +
"\016TransportRoute\022\n\n\002id\030\001 \002(\004\022\014\n\004type\030\003 \001(" +
"\r\022\020\n\010operator\030\004 \001(\r\022\013\n\003ref\030\005 \001(\t\022\014\n\004name" +
"\030\006 \001(\r\022\017\n\007name_en\030\007 \001(\r\022\020\n\010distance\030\010 \001(" +
"\r\022(\n\013directStops\030\017 \003(\0132\023.TransportRouteS" +
"top\022)\n\014reverseStops\030\020 \003(\0132\023.TransportRou" +
"teStop\"W\n\022TransportRouteStop\022\n\n\002id\030\001 \002(\022" +
"\022\n\n\002dx\030\002 \002(\021\022\n\n\002dy\030\003 \002(\021\022\014\n\004name\030\006 \002(\r\022\017" +
"\n\007name_en\030\007 \001(\r\"b\n\rTransportStop\022\n\n\002dx\030\001",
" \002(\021\022\n\n\002dy\030\002 \002(\021\022\n\n\002id\030\005 \002(\022\022\014\n\004name\030\006 \002" +
"(\r\022\017\n\007name_en\030\007 \001(\r\022\016\n\006routes\030\020 \003(\r\"\244\001\n\022" +
"TransportStopsTree\022\014\n\004left\030\001 \002(\021\022\r\n\005righ" +
"t\030\002 \002(\021\022\013\n\003top\030\003 \002(\021\022\016\n\006bottom\030\004 \002(\021\022%\n\010" +
"subtrees\030\007 \003(\0132\023.TransportStopsTree\022\035\n\005l" +
"eafs\030\010 \003(\0132\016.TransportStop\022\016\n\006baseId\030\020 \001" +
"(\004\"\177\n\024OsmAndTransportIndex\022 \n\006routes\030\003 \001" +
"(\0132\020.TransportRoutes\022\"\n\005stops\030\006 \001(\0132\023.Tr" +
"ansportStopsTree\022!\n\013stringTable\030\t \002(\0132\014." +
"StringTableB\023\n\021net.osmand.binary"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@ -10128,8 +10446,16 @@ public final class OsmandOdb {
new java.lang.String[] { "Name", "NameEn", "Id", "Postcode", "X", "Y", },
net.osmand.binary.OsmandOdb.BuildingIndex.class,
net.osmand.binary.OsmandOdb.BuildingIndex.Builder.class);
internal_static_TransportRoute_descriptor =
internal_static_TransportRoutes_descriptor =
getDescriptor().getMessageTypes().get(15);
internal_static_TransportRoutes_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_TransportRoutes_descriptor,
new java.lang.String[] { "Routes", },
net.osmand.binary.OsmandOdb.TransportRoutes.class,
net.osmand.binary.OsmandOdb.TransportRoutes.Builder.class);
internal_static_TransportRoute_descriptor =
getDescriptor().getMessageTypes().get(16);
internal_static_TransportRoute_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_TransportRoute_descriptor,
@ -10137,7 +10463,7 @@ public final class OsmandOdb {
net.osmand.binary.OsmandOdb.TransportRoute.class,
net.osmand.binary.OsmandOdb.TransportRoute.Builder.class);
internal_static_TransportRouteStop_descriptor =
getDescriptor().getMessageTypes().get(16);
getDescriptor().getMessageTypes().get(17);
internal_static_TransportRouteStop_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_TransportRouteStop_descriptor,
@ -10145,15 +10471,15 @@ public final class OsmandOdb {
net.osmand.binary.OsmandOdb.TransportRouteStop.class,
net.osmand.binary.OsmandOdb.TransportRouteStop.Builder.class);
internal_static_TransportStop_descriptor =
getDescriptor().getMessageTypes().get(17);
getDescriptor().getMessageTypes().get(18);
internal_static_TransportStop_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_TransportStop_descriptor,
new java.lang.String[] { "Id", "Dx", "Dy", "Name", "NameEn", "Routes", },
new java.lang.String[] { "Dx", "Dy", "Id", "Name", "NameEn", "Routes", },
net.osmand.binary.OsmandOdb.TransportStop.class,
net.osmand.binary.OsmandOdb.TransportStop.Builder.class);
internal_static_TransportStopsTree_descriptor =
getDescriptor().getMessageTypes().get(18);
getDescriptor().getMessageTypes().get(19);
internal_static_TransportStopsTree_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_TransportStopsTree_descriptor,
@ -10161,7 +10487,7 @@ public final class OsmandOdb {
net.osmand.binary.OsmandOdb.TransportStopsTree.class,
net.osmand.binary.OsmandOdb.TransportStopsTree.Builder.class);
internal_static_OsmAndTransportIndex_descriptor =
getDescriptor().getMessageTypes().get(19);
getDescriptor().getMessageTypes().get(20);
internal_static_OsmAndTransportIndex_fieldAccessorTable = new
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_OsmAndTransportIndex_descriptor,

View file

@ -3,6 +3,7 @@ package net.osmand.data;
import net.osmand.osm.Entity;
public class TransportStop extends MapObject {
int[] referencesToRoutes = null;
public TransportStop(Entity e){
super(e);
@ -11,4 +12,12 @@ public class TransportStop extends MapObject {
public TransportStop(){
}
public int[] getReferencesToRoutes() {
return referencesToRoutes;
}
public void setReferencesToRoutes(int[] referencesToRoutes) {
this.referencesToRoutes = referencesToRoutes;
}
}

View file

@ -27,8 +27,6 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.osmand.Algoritms;
import net.osmand.IProgress;
@ -127,9 +125,9 @@ public class IndexCreator {
private PreparedStatement pselectTags;
// constants to start process from the middle and save temporary results
private boolean recreateOnlyBinaryFile = true; //false;
private boolean recreateOnlyBinaryFile = false; //false;
private boolean deleteOsmDB = false;
private boolean deleteDatabaseIndexes = false;
private boolean deleteDatabaseIndexes = true;
private Connection dbConn;
private File dbFile;
@ -1647,6 +1645,8 @@ public class IndexCreator {
writer.startWriteTransportIndex();
writer.startWriteTransportRoutes();
// expect that memory would be enough
Map<String, Integer> stringTable = createStringTableForTransport();
Map<Long, Long> transportRoutes = new LinkedHashMap<Long, Long>();
@ -1697,6 +1697,7 @@ public class IndexCreator {
}
rs.close();
selectTransportRouteData.close();
writer.endWriteTransportRoutes();
PreparedStatement selectTransportStop = mapConnection.prepareStatement(
"SELECT A.id, A.latitude, A.longitude, A.name, A.name_en FROM transport_stop A where A.id = ?");
@ -1839,7 +1840,6 @@ public class IndexCreator {
normalizeSuffixes = DataExtractionSettings.getSettings().getSuffixesToNormalizeStreets();
}
boolean success = false;
// Main generation method
try {
//////////////////////////////////////////////////////////////////////////
@ -2014,7 +2014,6 @@ public class IndexCreator {
writer.close();
log.info("Finish writing binary file");
}
success = true;
} finally {
try {
if (pselectNode != null) {
@ -2336,6 +2335,8 @@ public class IndexCreator {
// creator.setIndexPOI(true);
creator.setIndexTransport(true);
creator.recreateOnlyBinaryFile = true;
creator.deleteDatabaseIndexes = false;
creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb"));
creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null);

View file

@ -167,6 +167,10 @@ message BuildingIndex {
// transport messages
message TransportRoutes {
repeated TransportRoute routes = 6;
}
message TransportRoute {
required uint64 id = 1;
@ -191,9 +195,10 @@ message TransportRouteStop {
}
message TransportStop {
required sint64 id = 1; // delta encoded to parent base id
required sint32 dx = 2; // delta encoded to parent (24 zoom) to left
required sint32 dy = 3; // delta encoded to parent (24 zoom) to top
required sint32 dx = 1; // delta encoded to parent (24 zoom) to left
required sint32 dy = 2; // delta encoded to parent (24 zoom) to top
required sint64 id = 5; // delta encoded to parent base id
required uint32 name = 6; // index in message table
optional uint32 name_en = 7; // index in message table
@ -221,7 +226,8 @@ message TransportStopsTree {
message OsmAndTransportIndex {
repeated TransportRoute routes = 3; // routes
// encoded as fixed32 length delimited
optional TransportRoutes routes = 3; // routes
// encoded as fixed32 length delimited
optional TransportStopsTree stops = 6;

View file

@ -468,7 +468,7 @@ public class ResourceManager {
public void indexingTransport(final IProgress progress, List<String> warnings, File f) {
if (f.getName().endsWith(IndexConstants.TRANSPORT_INDEX_EXT)) {
TransportIndexRepository repository = new TransportIndexRepository();
TransportIndexRepositoryOdb repository = new TransportIndexRepositoryOdb();
progress.startTask(Messages.getMessage("indexing_transport") + f.getName(), -1); //$NON-NLS-1$
try {
boolean initialized = repository.initialize(progress, f);

View file

@ -1,346 +1,39 @@
package net.osmand;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.osmand.data.TransportRoute;
import net.osmand.data.TransportStop;
import net.osmand.data.index.IndexConstants;
import net.osmand.data.index.IndexConstants.IndexTransportRoute;
import net.osmand.data.index.IndexConstants.IndexTransportRouteStop;
import net.osmand.data.index.IndexConstants.IndexTransportStop;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import org.apache.commons.logging.Log;
public interface TransportIndexRepository {
import android.database.Cursor;
public boolean checkContains(double latitude, double longitude);
public class TransportIndexRepository extends BaseLocationIndexRepository<TransportStop> {
private static final Log log = LogUtil.getLog(TransportIndexRepository.class);
public boolean checkContains(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude);
public boolean checkCachedObjects(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, List<TransportStop> toFill);
public boolean checkCachedObjects(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, List<TransportStop> toFill, boolean fillFound);
public boolean initialize(final IProgress progress, File file) {
return super.initialize(progress, file, IndexConstants.TRANSPORT_TABLE_VERSION, IndexTransportStop.getTable());
}
public List<TransportStop> searchTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, List<TransportStop> stops);
private final String[] columns = IndexConstants.generateColumnNames(IndexTransportStop.values());
public List<TransportStop> searchTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, List<TransportStop> stops){
long now = System.currentTimeMillis();
String squery = "? < latitude AND latitude < ? AND ? < longitude AND longitude < ?"; //$NON-NLS-1$
if(limit != -1){
squery += " ORDER BY RANDOM() LIMIT " +limit; //$NON-NLS-1$
}
Cursor query = db.query(IndexTransportStop.getTable(), columns, squery,
new String[]{Double.toString(bottomLatitude),
Double.toString(topLatitude), Double.toString(leftLongitude), Double.toString(rightLongitude)}, null, null, null);
if(query.moveToFirst()){
do {
TransportStop st = new TransportStop();
st.setId(query.getLong(IndexTransportStop.ID.ordinal()));
st.setLocation(query.getDouble(IndexTransportStop.LATITUDE.ordinal()),
query.getDouble(IndexTransportStop.LONGITUDE.ordinal()));
st.setName(query.getString(IndexTransportStop.NAME.ordinal() ));
st.setEnName(query.getString(IndexTransportStop.NAME_EN.ordinal()));
stops.add(st);
if(limit != -1 && stops.size() >= limit){
break;
}
} while(query.moveToNext());
}
query.close();
if (log.isDebugEnabled()) {
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, stops.size())); //$NON-NLS-1$
}
return stops;
}
private static String cacheSQLRouteDescriptions = null;
/**
*
* @param stop
* @param format {0} - ref, {1} - type, {2} - name, {3} - name_en
* @return
*/
public List<String> getRouteDescriptionsForStop(TransportStop stop, String format) {
long now = System.currentTimeMillis();
List<String> res = new ArrayList<String>();
MessageFormat f = new MessageFormat(format);
if (cacheSQLRouteDescriptions == null) {
StringBuilder sql = new StringBuilder(200);
sql.append("SELECT DISTINCT ").append(IndexTransportRoute.REF).append(",").append(IndexTransportRoute.TYPE) //$NON-NLS-1$//$NON-NLS-2$
.append(",").append(IndexTransportRoute.NAME).append(",").append(IndexTransportRoute.NAME_EN); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" FROM ").append(IndexTransportRoute.getTable()).append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" ON ").append(IndexTransportRoute.getTable()).append(".").append(IndexTransportRoute.ID).append(" = "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
sql.append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$
sql.append(" WHERE ").append(IndexTransportRouteStop.STOP).append(" = ?"); //$NON-NLS-1$ //$NON-NLS-2$
cacheSQLRouteDescriptions = sql.toString();
}
Cursor query = db.rawQuery(cacheSQLRouteDescriptions, new String[] { stop.getId() + "" }); //$NON-NLS-1$
if (query.moveToFirst()) {
do {
res.add(f.format(new String[] { query.getString(0), query.getString(1), query.getString(2), query.getString(3) }));
} while (query.moveToNext());
}
query.close();
if (log.isDebugEnabled()) {
log.debug(String.format("Search for stop %s done in %s ms found %s.", //$NON-NLS-1$
stop.getId() + "", System.currentTimeMillis() - now, res.size())); //$NON-NLS-1$
}
return res;
}
public List<String> getRouteDescriptionsForStop(TransportStop stop, String format);
public void evaluateCachedTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, int limit, List<TransportStop> toFill){
cTopLatitude = topLatitude + (topLatitude -bottomLatitude);
cBottomLatitude = bottomLatitude - (topLatitude -bottomLatitude);
cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude);
cRightLongitude = rightLongitude + (rightLongitude - leftLongitude);
cZoom = zoom;
// first of all put all entities in temp list in order to not freeze other read threads
ArrayList<TransportStop> tempList = new ArrayList<TransportStop>();
searchTransportStops(cTopLatitude, cLeftLongitude, cBottomLatitude, cRightLongitude, limit, tempList);
synchronized (this) {
cachedObjects.clear();
cachedObjects.addAll(tempList);
}
checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, cZoom, toFill);
}
public void evaluateCachedTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, int limit, List<TransportStop> toFill);
private static String cacheSQLRoutes = null;
public List<RouteInfoLocation> searchTransportRouteStops(double latitude, double longitude, LatLon locationToGo, int zoom) {
long now = System.currentTimeMillis();
LatLon loc = new LatLon(latitude, longitude);
double tileNumberX = MapUtils.getTileNumberX(zoom, longitude);
double tileNumberY = MapUtils.getTileNumberY(zoom, latitude);
double topLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY - 0.5);
double bottomLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY + 0.5);
double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5);
double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5);
assert IndexTransportRoute.values().length == 7;
int shift = IndexTransportRoute.values().length;
assert IndexTransportStop.values().length == 5;
int shift2 = IndexTransportStop.values().length;
if(cacheSQLRoutes == null){
StringBuilder sql = new StringBuilder(200);
sql.append("SELECT "); //$NON-NLS-1$
String[] cols = IndexConstants.generateColumnNames(IndexTransportRoute.values());
for(int i=0; i<cols.length; i++){
if(i>0){
sql.append(", "); //$NON-NLS-1$
}
sql.append(IndexTransportRoute.getTable()).append(".").append(cols[i]); //$NON-NLS-1$
}
cols = IndexConstants.generateColumnNames(IndexTransportStop.values());
for(int i=0; i<cols.length; i++){
sql.append(", ").append(IndexTransportStop.getTable()).append(".").append(cols[i]); //$NON-NLS-1$ //$NON-NLS-2$
}
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
public List<RouteInfoLocation> searchTransportRouteStops(double latitude, double longitude, LatLon locationToGo, int zoom);
sql.append(" FROM ").append(IndexTransportStop.getTable()); //$NON-NLS-1$
// join with stops table
sql.append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportStop.getTable()).append(".").append(IndexTransportStop.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.STOP); //$NON-NLS-1$ //$NON-NLS-2$
// join with route table
sql.append(" JOIN ").append(IndexTransportRoute.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportRoute.getTable()).append(".").append(IndexTransportRoute.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" WHERE ").append("? < latitude AND latitude < ? AND ? < longitude AND longitude < ?"); //$NON-NLS-1$ //$NON-NLS-2$
cacheSQLRoutes = sql.toString();
}
Cursor query = db.rawQuery(cacheSQLRoutes,
new String[] {bottomLatitude + "" , topLatitude + "" , leftLongitude + "" , rightLongitude + "" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Map<Long, RouteInfoLocation> registeredRoutes = new LinkedHashMap<Long, RouteInfoLocation>();
if (query.moveToFirst()) {
do {
TransportRoute route = new TransportRoute();
route.setId(query.getLong(IndexTransportRoute.ID.ordinal()));
route.setDistance(query.getInt(IndexTransportRoute.DIST.ordinal()));
route.setName(query.getString(IndexTransportRoute.NAME.ordinal()));
route.setEnName(query.getString(IndexTransportRoute.NAME_EN.ordinal()));
route.setRef(query.getString(IndexTransportRoute.REF.ordinal()));
route.setOperator(query.getString(IndexTransportRoute.OPERATOR.ordinal()));
route.setType(query.getString(IndexTransportRoute.TYPE.ordinal()));
TransportStop s = new TransportStop();
s.setId(query.getLong(shift + IndexTransportStop.ID.ordinal()));
s.setName(query.getString(shift + IndexTransportStop.NAME.ordinal()));
s.setEnName(query.getString(shift + IndexTransportStop.NAME_EN.ordinal()));
s.setLocation(query.getDouble(shift + IndexTransportStop.LATITUDE.ordinal()),
query.getDouble(shift + IndexTransportStop.LONGITUDE.ordinal()));
boolean direction = query.getInt(shift2 + shift) > 0;
long idToPut = route.getId() << 1 + (direction ? 1 : 0);
if(registeredRoutes.containsKey(idToPut)){
TransportStop st = registeredRoutes.get(idToPut).getStart();
if(MapUtils.getDistance(loc, st.getLocation()) < MapUtils.getDistance(loc, s.getLocation())){
continue;
}
}
RouteInfoLocation r = new RouteInfoLocation();
r.setRoute(route);
r.setStart(s);
r.setDirection(direction);
registeredRoutes.put(idToPut, r);
} while (query.moveToNext());
}
query.close();
if (log.isDebugEnabled()) {
log.debug(String.format("Search for routes done in %s ms found %s.", //$NON-NLS-1$
System.currentTimeMillis() - now, registeredRoutes.size()));
}
List<RouteInfoLocation> list = preloadRouteStopsAndCalculateDistance(loc, locationToGo, registeredRoutes);
return list;
}
protected List<RouteInfoLocation> preloadRouteStopsAndCalculateDistance(final LatLon loc, LatLon locationToGo,
Map<Long, RouteInfoLocation> registeredRoutes) {
if(registeredRoutes.isEmpty()){
return Collections.emptyList();
}
long now = System.currentTimeMillis();
StringBuilder sql = new StringBuilder(200);
sql.append("SELECT "); //$NON-NLS-1$
String[] cols = IndexConstants.generateColumnNames(IndexTransportStop.values());
for (int i = 0; i < cols.length; i++) {
if (i > 0) {
sql.append(", "); //$NON-NLS-1$
}
sql.append(IndexTransportStop.getTable()).append(".").append(cols[i]); //$NON-NLS-1$
}
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" FROM ").append(IndexTransportStop.getTable()); //$NON-NLS-1$
// join with stops table
sql.append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportStop.getTable()).append(".").append(IndexTransportStop.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.STOP); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" WHERE "); //$NON-NLS-1$
boolean f = true;
for (RouteInfoLocation il : registeredRoutes.values()) {
if (f) {
f = false;
} else {
sql.append(" OR "); //$NON-NLS-1$
}
sql.append("("); //$NON-NLS-1$
sql.append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$
sql.append(" = ").append(il.getRoute().getId()); //$NON-NLS-1$
sql.append(" AND ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(il.getDirection() ? 1 : 0); //$NON-NLS-1$
sql.append(")"); //$NON-NLS-1$
}
sql.append(" ORDER BY ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ORD).append(" ASC"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
int qShift = IndexTransportStop.values().length;
Map<Long, TransportStop> distanceToLoc = new LinkedHashMap<Long, TransportStop>();
Cursor query = db.rawQuery(sql.toString(), new String[] {});
if (query.moveToFirst()) {
// load only part of the route
do {
TransportStop st = null;
long routeId = query.getLong(qShift);
int direction = query.getInt(qShift + 1);
long id = routeId << 1 + direction;
boolean found = distanceToLoc.containsKey(id);
RouteInfoLocation i = registeredRoutes.get(id);
if (found) {
st = new TransportStop();
st.setId(query.getLong(IndexTransportStop.ID.ordinal()));
st.setLocation(query.getDouble(IndexTransportStop.LATITUDE.ordinal()), query.getDouble(IndexTransportStop.LONGITUDE
.ordinal()));
st.setName(query.getString(IndexTransportStop.NAME.ordinal()));
st.setEnName(query.getString(IndexTransportStop.NAME_EN.ordinal()));
} else if (query.getLong(IndexTransportStop.ID.ordinal()) == i.getStart().getId()) {
st = i.getStart();
found = true;
distanceToLoc.put(id, st);
}
if (found) {
if (locationToGo != null) {
double d = MapUtils.getDistance(locationToGo, st.getLocation());
double dbase = MapUtils.getDistance(locationToGo, distanceToLoc.get(id).getLocation());
if (d < dbase) {
distanceToLoc.put(id, st);
}
}
if (i.direction) {
i.getRoute().getForwardStops().add(st);
} else {
i.getRoute().getBackwardStops().add(st);
}
}
} while (query.moveToNext());
query.close();
}
if (locationToGo != null) {
for (Long l : registeredRoutes.keySet()) {
Integer dist = (int) MapUtils.getDistance(locationToGo, distanceToLoc.get(l).getLocation());
if (dist != null) {
registeredRoutes.get(l).setDistToLocation(dist);
}
registeredRoutes.get(l).setStop(distanceToLoc.get(l));
}
}
ArrayList<RouteInfoLocation> listRoutes = new ArrayList<RouteInfoLocation>(registeredRoutes.values());
if (log.isDebugEnabled()) {
log.debug(String.format("Loading routes done in %s ms for %s routes.", //$NON-NLS-1$
System.currentTimeMillis() - now, listRoutes.size()));
}
if (locationToGo != null) {
Collections.sort(listRoutes, new Comparator<RouteInfoLocation>() {
@Override
public int compare(RouteInfoLocation object1, RouteInfoLocation object2) {
int x = (int) (MapUtils.getDistance(loc, object1.getStart().getLocation()) + object1.getDistToLocation());
int y = (int) (MapUtils.getDistance(loc, object2.getStart().getLocation()) + object2.getDistToLocation());
return x - y;
}
});
} else {
Collections.sort(listRoutes, new Comparator<RouteInfoLocation>() {
@Override
public int compare(RouteInfoLocation object1, RouteInfoLocation object2) {
return Double.compare(MapUtils.getDistance(loc, object1.getStart().getLocation()), MapUtils.getDistance(loc, object2
.getStart().getLocation()));
}
});
}
return listRoutes;
}
public void close();
public static class RouteInfoLocation {
private TransportStop start;

View file

@ -0,0 +1,345 @@
package net.osmand;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.osmand.data.TransportRoute;
import net.osmand.data.TransportStop;
import net.osmand.data.index.IndexConstants;
import net.osmand.data.index.IndexConstants.IndexTransportRoute;
import net.osmand.data.index.IndexConstants.IndexTransportRouteStop;
import net.osmand.data.index.IndexConstants.IndexTransportStop;
import net.osmand.osm.LatLon;
import net.osmand.osm.MapUtils;
import org.apache.commons.logging.Log;
import android.database.Cursor;
public class TransportIndexRepositoryOdb extends BaseLocationIndexRepository<TransportStop> implements TransportIndexRepository {
private static final Log log = LogUtil.getLog(TransportIndexRepositoryOdb.class);
public boolean initialize(final IProgress progress, File file) {
return super.initialize(progress, file, IndexConstants.TRANSPORT_TABLE_VERSION, IndexTransportStop.getTable());
}
private final String[] columns = IndexConstants.generateColumnNames(IndexTransportStop.values());
public List<TransportStop> searchTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, List<TransportStop> stops){
long now = System.currentTimeMillis();
String squery = "? < latitude AND latitude < ? AND ? < longitude AND longitude < ?"; //$NON-NLS-1$
if(limit != -1){
squery += " ORDER BY RANDOM() LIMIT " +limit; //$NON-NLS-1$
}
Cursor query = db.query(IndexTransportStop.getTable(), columns, squery,
new String[]{Double.toString(bottomLatitude),
Double.toString(topLatitude), Double.toString(leftLongitude), Double.toString(rightLongitude)}, null, null, null);
if(query.moveToFirst()){
do {
TransportStop st = new TransportStop();
st.setId(query.getLong(IndexTransportStop.ID.ordinal()));
st.setLocation(query.getDouble(IndexTransportStop.LATITUDE.ordinal()),
query.getDouble(IndexTransportStop.LONGITUDE.ordinal()));
st.setName(query.getString(IndexTransportStop.NAME.ordinal() ));
st.setEnName(query.getString(IndexTransportStop.NAME_EN.ordinal()));
stops.add(st);
if(limit != -1 && stops.size() >= limit){
break;
}
} while(query.moveToNext());
}
query.close();
if (log.isDebugEnabled()) {
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, stops.size())); //$NON-NLS-1$
}
return stops;
}
private static String cacheSQLRouteDescriptions = null;
/**
*
* @param stop
* @param format {0} - ref, {1} - type, {2} - name, {3} - name_en
* @return
*/
public List<String> getRouteDescriptionsForStop(TransportStop stop, String format) {
long now = System.currentTimeMillis();
List<String> res = new ArrayList<String>();
MessageFormat f = new MessageFormat(format);
if (cacheSQLRouteDescriptions == null) {
StringBuilder sql = new StringBuilder(200);
sql.append("SELECT DISTINCT ").append(IndexTransportRoute.REF).append(",").append(IndexTransportRoute.TYPE) //$NON-NLS-1$//$NON-NLS-2$
.append(",").append(IndexTransportRoute.NAME).append(",").append(IndexTransportRoute.NAME_EN); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" FROM ").append(IndexTransportRoute.getTable()).append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" ON ").append(IndexTransportRoute.getTable()).append(".").append(IndexTransportRoute.ID).append(" = "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
sql.append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$
sql.append(" WHERE ").append(IndexTransportRouteStop.STOP).append(" = ?"); //$NON-NLS-1$ //$NON-NLS-2$
cacheSQLRouteDescriptions = sql.toString();
}
Cursor query = db.rawQuery(cacheSQLRouteDescriptions, new String[] { stop.getId() + "" }); //$NON-NLS-1$
if (query.moveToFirst()) {
do {
res.add(f.format(new String[] { query.getString(0), query.getString(1), query.getString(2), query.getString(3) }));
} while (query.moveToNext());
}
query.close();
if (log.isDebugEnabled()) {
log.debug(String.format("Search for stop %s done in %s ms found %s.", //$NON-NLS-1$
stop.getId() + "", System.currentTimeMillis() - now, res.size())); //$NON-NLS-1$
}
return res;
}
public void evaluateCachedTransportStops(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, int limit, List<TransportStop> toFill){
cTopLatitude = topLatitude + (topLatitude -bottomLatitude);
cBottomLatitude = bottomLatitude - (topLatitude -bottomLatitude);
cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude);
cRightLongitude = rightLongitude + (rightLongitude - leftLongitude);
cZoom = zoom;
// first of all put all entities in temp list in order to not freeze other read threads
ArrayList<TransportStop> tempList = new ArrayList<TransportStop>();
searchTransportStops(cTopLatitude, cLeftLongitude, cBottomLatitude, cRightLongitude, limit, tempList);
synchronized (this) {
cachedObjects.clear();
cachedObjects.addAll(tempList);
}
checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, cZoom, toFill);
}
private static String cacheSQLRoutes = null;
public List<RouteInfoLocation> searchTransportRouteStops(double latitude, double longitude, LatLon locationToGo, int zoom) {
long now = System.currentTimeMillis();
LatLon loc = new LatLon(latitude, longitude);
double tileNumberX = MapUtils.getTileNumberX(zoom, longitude);
double tileNumberY = MapUtils.getTileNumberY(zoom, latitude);
double topLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY - 0.5);
double bottomLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY + 0.5);
double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5);
double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5);
assert IndexTransportRoute.values().length == 7;
int shift = IndexTransportRoute.values().length;
assert IndexTransportStop.values().length == 5;
int shift2 = IndexTransportStop.values().length;
if(cacheSQLRoutes == null){
StringBuilder sql = new StringBuilder(200);
sql.append("SELECT "); //$NON-NLS-1$
String[] cols = IndexConstants.generateColumnNames(IndexTransportRoute.values());
for(int i=0; i<cols.length; i++){
if(i>0){
sql.append(", "); //$NON-NLS-1$
}
sql.append(IndexTransportRoute.getTable()).append(".").append(cols[i]); //$NON-NLS-1$
}
cols = IndexConstants.generateColumnNames(IndexTransportStop.values());
for(int i=0; i<cols.length; i++){
sql.append(", ").append(IndexTransportStop.getTable()).append(".").append(cols[i]); //$NON-NLS-1$ //$NON-NLS-2$
}
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" FROM ").append(IndexTransportStop.getTable()); //$NON-NLS-1$
// join with stops table
sql.append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportStop.getTable()).append(".").append(IndexTransportStop.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.STOP); //$NON-NLS-1$ //$NON-NLS-2$
// join with route table
sql.append(" JOIN ").append(IndexTransportRoute.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportRoute.getTable()).append(".").append(IndexTransportRoute.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" WHERE ").append("? < latitude AND latitude < ? AND ? < longitude AND longitude < ?"); //$NON-NLS-1$ //$NON-NLS-2$
cacheSQLRoutes = sql.toString();
}
Cursor query = db.rawQuery(cacheSQLRoutes,
new String[] {bottomLatitude + "" , topLatitude + "" , leftLongitude + "" , rightLongitude + "" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Map<Long, RouteInfoLocation> registeredRoutes = new LinkedHashMap<Long, RouteInfoLocation>();
if (query.moveToFirst()) {
do {
TransportRoute route = new TransportRoute();
route.setId(query.getLong(IndexTransportRoute.ID.ordinal()));
route.setDistance(query.getInt(IndexTransportRoute.DIST.ordinal()));
route.setName(query.getString(IndexTransportRoute.NAME.ordinal()));
route.setEnName(query.getString(IndexTransportRoute.NAME_EN.ordinal()));
route.setRef(query.getString(IndexTransportRoute.REF.ordinal()));
route.setOperator(query.getString(IndexTransportRoute.OPERATOR.ordinal()));
route.setType(query.getString(IndexTransportRoute.TYPE.ordinal()));
TransportStop s = new TransportStop();
s.setId(query.getLong(shift + IndexTransportStop.ID.ordinal()));
s.setName(query.getString(shift + IndexTransportStop.NAME.ordinal()));
s.setEnName(query.getString(shift + IndexTransportStop.NAME_EN.ordinal()));
s.setLocation(query.getDouble(shift + IndexTransportStop.LATITUDE.ordinal()),
query.getDouble(shift + IndexTransportStop.LONGITUDE.ordinal()));
boolean direction = query.getInt(shift2 + shift) > 0;
long idToPut = route.getId() << 1 + (direction ? 1 : 0);
if(registeredRoutes.containsKey(idToPut)){
TransportStop st = registeredRoutes.get(idToPut).getStart();
if(MapUtils.getDistance(loc, st.getLocation()) < MapUtils.getDistance(loc, s.getLocation())){
continue;
}
}
RouteInfoLocation r = new RouteInfoLocation();
r.setRoute(route);
r.setStart(s);
r.setDirection(direction);
registeredRoutes.put(idToPut, r);
} while (query.moveToNext());
}
query.close();
if (log.isDebugEnabled()) {
log.debug(String.format("Search for routes done in %s ms found %s.", //$NON-NLS-1$
System.currentTimeMillis() - now, registeredRoutes.size()));
}
List<RouteInfoLocation> list = preloadRouteStopsAndCalculateDistance(loc, locationToGo, registeredRoutes);
return list;
}
protected List<RouteInfoLocation> preloadRouteStopsAndCalculateDistance(final LatLon loc, LatLon locationToGo,
Map<Long, RouteInfoLocation> registeredRoutes) {
if(registeredRoutes.isEmpty()){
return Collections.emptyList();
}
long now = System.currentTimeMillis();
StringBuilder sql = new StringBuilder(200);
sql.append("SELECT "); //$NON-NLS-1$
String[] cols = IndexConstants.generateColumnNames(IndexTransportStop.values());
for (int i = 0; i < cols.length; i++) {
if (i > 0) {
sql.append(", "); //$NON-NLS-1$
}
sql.append(IndexTransportStop.getTable()).append(".").append(cols[i]); //$NON-NLS-1$
}
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(", ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" FROM ").append(IndexTransportStop.getTable()); //$NON-NLS-1$
// join with stops table
sql.append(" JOIN ").append(IndexTransportRouteStop.getTable()); //$NON-NLS-1$
sql.append(" ON ").append(IndexTransportStop.getTable()).append(".").append(IndexTransportStop.ID); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.STOP); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" WHERE "); //$NON-NLS-1$
boolean f = true;
for (RouteInfoLocation il : registeredRoutes.values()) {
if (f) {
f = false;
} else {
sql.append(" OR "); //$NON-NLS-1$
}
sql.append("("); //$NON-NLS-1$
sql.append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ROUTE); //$NON-NLS-1$
sql.append(" = ").append(il.getRoute().getId()); //$NON-NLS-1$
sql.append(" AND ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.DIRECTION); //$NON-NLS-1$ //$NON-NLS-2$
sql.append(" = ").append(il.getDirection() ? 1 : 0); //$NON-NLS-1$
sql.append(")"); //$NON-NLS-1$
}
sql.append(" ORDER BY ").append(IndexTransportRouteStop.getTable()).append(".").append(IndexTransportRouteStop.ORD).append(" ASC"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
int qShift = IndexTransportStop.values().length;
Map<Long, TransportStop> distanceToLoc = new LinkedHashMap<Long, TransportStop>();
Cursor query = db.rawQuery(sql.toString(), new String[] {});
if (query.moveToFirst()) {
// load only part of the route
do {
TransportStop st = null;
long routeId = query.getLong(qShift);
int direction = query.getInt(qShift + 1);
long id = routeId << 1 + direction;
boolean found = distanceToLoc.containsKey(id);
RouteInfoLocation i = registeredRoutes.get(id);
if (found) {
st = new TransportStop();
st.setId(query.getLong(IndexTransportStop.ID.ordinal()));
st.setLocation(query.getDouble(IndexTransportStop.LATITUDE.ordinal()), query.getDouble(IndexTransportStop.LONGITUDE
.ordinal()));
st.setName(query.getString(IndexTransportStop.NAME.ordinal()));
st.setEnName(query.getString(IndexTransportStop.NAME_EN.ordinal()));
} else if (query.getLong(IndexTransportStop.ID.ordinal()) == i.getStart().getId()) {
st = i.getStart();
found = true;
distanceToLoc.put(id, st);
}
if (found) {
if (locationToGo != null) {
double d = MapUtils.getDistance(locationToGo, st.getLocation());
double dbase = MapUtils.getDistance(locationToGo, distanceToLoc.get(id).getLocation());
if (d < dbase) {
distanceToLoc.put(id, st);
}
}
if (i.getDirection()) {
i.getRoute().getForwardStops().add(st);
} else {
i.getRoute().getBackwardStops().add(st);
}
}
} while (query.moveToNext());
query.close();
}
if (locationToGo != null) {
for (Long l : registeredRoutes.keySet()) {
Integer dist = (int) MapUtils.getDistance(locationToGo, distanceToLoc.get(l).getLocation());
if (dist != null) {
registeredRoutes.get(l).setDistToLocation(dist);
}
registeredRoutes.get(l).setStop(distanceToLoc.get(l));
}
}
ArrayList<RouteInfoLocation> listRoutes = new ArrayList<RouteInfoLocation>(registeredRoutes.values());
if (log.isDebugEnabled()) {
log.debug(String.format("Loading routes done in %s ms for %s routes.", //$NON-NLS-1$
System.currentTimeMillis() - now, listRoutes.size()));
}
if (locationToGo != null) {
Collections.sort(listRoutes, new Comparator<RouteInfoLocation>() {
@Override
public int compare(RouteInfoLocation object1, RouteInfoLocation object2) {
int x = (int) (MapUtils.getDistance(loc, object1.getStart().getLocation()) + object1.getDistToLocation());
int y = (int) (MapUtils.getDistance(loc, object2.getStart().getLocation()) + object2.getDistToLocation());
return x - y;
}
});
} else {
Collections.sort(listRoutes, new Comparator<RouteInfoLocation>() {
@Override
public int compare(RouteInfoLocation object1, RouteInfoLocation object2) {
return Double.compare(MapUtils.getDistance(loc, object1.getStart().getLocation()), MapUtils.getDistance(loc, object2
.getStart().getLocation()));
}
});
}
return listRoutes;
}
}

View file

@ -61,7 +61,7 @@ public class MapRenderRepositories {
private boolean interrupted = false;
private RenderingContext currentRenderingContext;
private SearchRequest searchRequest;
private SearchRequest<BinaryMapDataObject> searchRequest;
public MapRenderRepositories(Context context){