Update transport route creator

This commit is contained in:
Victor Shcherb 2018-08-15 15:43:47 +03:00
parent d02dcefae4
commit 070edbd764
7 changed files with 335 additions and 474 deletions

View file

@ -468,11 +468,15 @@ public class BinaryMapIndexReader {
}
public TIntObjectHashMap<TransportRoute> getTransportRoutes(int[] filePointers) throws IOException {
TIntObjectHashMap<TransportRoute> result = new TIntObjectHashMap<TransportRoute>();
loadTransportRoutes(filePointers, result);
return result;
}
/**
* Transport public methods
*/
public TIntObjectHashMap<TransportRoute> getTransportRoutes(int[] filePointers) throws IOException {
TIntObjectHashMap<TransportRoute> result = new TIntObjectHashMap<TransportRoute>();
public void loadTransportRoutes(int[] filePointers, TIntObjectHashMap<TransportRoute> result) throws IOException {
Map<TransportIndex, TIntArrayList> groupPoints = new HashMap<TransportIndex, TIntArrayList>();
for (int filePointer : filePointers) {
TransportIndex ind = getTransportIndex(filePointer);
@ -500,7 +504,6 @@ public class BinaryMapIndexReader {
transportAdapter.initializeNames(false, r, stringTable);
}
}
return result;
}

View file

@ -8,12 +8,14 @@ import java.util.Arrays;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.binary.OsmandOdb.TransportRouteSchedule;
import net.osmand.data.TransportSchedule;
import net.osmand.data.TransportStop;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.Way;
import net.osmand.util.MapUtils;
import net.sf.junidecode.Junidecode;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.WireFormat;
@ -311,7 +313,7 @@ public class BinaryMapTransportReaderAdapter {
case OsmandOdb.TransportRoute.SCHEDULETRIP_FIELD_NUMBER:
sizeL = codedIS.readRawVarint32();
pold = codedIS.pushLimit(sizeL);
dataObject.setSchedule(TransportRouteSchedule.parseFrom(codedIS));
readTransportSchedule(dataObject.getOrCreateSchedule());
codedIS.popLimit(pold);
break;
case OsmandOdb.TransportRoute.DIRECTSTOPS_FIELD_NUMBER:
@ -340,6 +342,51 @@ public class BinaryMapTransportReaderAdapter {
return dataObject;
}
private void readTransportSchedule(TransportSchedule schedule) throws IOException {
while(true){
int t = codedIS.readTag();
int interval, sizeL, old;
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
return;
case OsmandOdb.TransportRouteSchedule.TRIPINTERVALS_FIELD_NUMBER:
sizeL = codedIS.readRawVarint32();
old = codedIS.pushLimit(sizeL);
while (codedIS.getBytesUntilLimit() > 0) {
interval = codedIS.readRawVarint32();
schedule.tripIntervals.add(interval);
}
codedIS.popLimit(old);
break;
case OsmandOdb.TransportRouteSchedule.AVGSTOPINTERVALS_FIELD_NUMBER:
sizeL = codedIS.readRawVarint32();
old = codedIS.pushLimit(sizeL);
while (codedIS.getBytesUntilLimit() > 0) {
interval = codedIS.readRawVarint32();
schedule.avgStopIntervals.add(interval);
}
codedIS.popLimit(old);
break;
case OsmandOdb.TransportRouteSchedule.AVGWAITINTERVALS_FIELD_NUMBER:
sizeL = codedIS.readRawVarint32();
old = codedIS.pushLimit(sizeL);
while (codedIS.getBytesUntilLimit() > 0) {
interval = codedIS.readRawVarint32();
schedule.avgWaitIntervals.add(interval);
}
codedIS.popLimit(old);
break;
// case OsmandOdb.TransportRouteSchedule.EXCEPTIONS_FIELD_NUMBER:
// break;
default:
skipUnknownField(t);
break;
}
}
}
protected void initializeStringTable(TransportIndex ind, TIntObjectHashMap<String> stringTable) throws IOException {
int[] values = stringTable.keys();
Arrays.sort(values);
@ -382,13 +429,13 @@ public class BinaryMapTransportReaderAdapter {
if(dataObject.getName().length() > 0 && dataObject.getName("en").length() == 0){
dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
}
if(dataObject.getOperator().length() > 0){
if(dataObject.getOperator() != null && dataObject.getOperator().length() > 0){
dataObject.setOperator(stringTable.get(dataObject.getOperator().charAt(0)));
}
if(dataObject.getColor() != null && dataObject.getColor().length() > 0){
dataObject.setColor(stringTable.get(dataObject.getColor().charAt(0)));
}
if(dataObject.getType().length() > 0){
if(dataObject.getType() != null && dataObject.getType().length() > 0){
dataObject.setType(stringTable.get(dataObject.getType().charAt(0)));
}
if (!onlyDescription) {

View file

@ -31830,86 +31830,63 @@ public final class OsmandOdb {
public interface TransportRouteScheduleOrBuilder
extends com.google.protobuf.MessageOrBuilder {
// repeated uint32 avgStopIntervals = 1;
// optional bytes avgStopIntervals = 1;
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
java.util.List<java.lang.Integer> getAvgStopIntervalsList();
boolean hasAvgStopIntervals();
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
int getAvgStopIntervalsCount();
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
*
* <pre>
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
int getAvgStopIntervals(int index);
com.google.protobuf.ByteString getAvgStopIntervals();
// repeated uint32 avgWaitIntervals = 2;
// optional bytes avgWaitIntervals = 2;
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
java.util.List<java.lang.Integer> getAvgWaitIntervalsList();
boolean hasAvgWaitIntervals();
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
int getAvgWaitIntervalsCount();
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
int getAvgWaitIntervals(int index);
com.google.protobuf.ByteString getAvgWaitIntervals();
// repeated uint32 tripIntervals = 3;
// optional bytes tripIntervals = 3;
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
java.util.List<java.lang.Integer> getTripIntervalsList();
boolean hasTripIntervals();
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
int getTripIntervalsCount();
/**
* <code>repeated uint32 tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
int getTripIntervals(int index);
com.google.protobuf.ByteString getTripIntervals();
// repeated .OsmAnd.OBF.TransportRouteScheduleException exceptions = 8;
/**
@ -32007,67 +31984,19 @@ public final class OsmandOdb {
}
break;
}
case 8: {
if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
avgStopIntervals_ = new java.util.ArrayList<java.lang.Integer>();
mutable_bitField0_ |= 0x00000001;
}
avgStopIntervals_.add(input.readUInt32());
break;
}
case 10: {
int length = input.readRawVarint32();
int limit = input.pushLimit(length);
if (!((mutable_bitField0_ & 0x00000001) == 0x00000001) && input.getBytesUntilLimit() > 0) {
avgStopIntervals_ = new java.util.ArrayList<java.lang.Integer>();
mutable_bitField0_ |= 0x00000001;
}
while (input.getBytesUntilLimit() > 0) {
avgStopIntervals_.add(input.readUInt32());
}
input.popLimit(limit);
break;
}
case 16: {
if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
avgWaitIntervals_ = new java.util.ArrayList<java.lang.Integer>();
mutable_bitField0_ |= 0x00000002;
}
avgWaitIntervals_.add(input.readUInt32());
bitField0_ |= 0x00000001;
avgStopIntervals_ = input.readBytes();
break;
}
case 18: {
int length = input.readRawVarint32();
int limit = input.pushLimit(length);
if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) {
avgWaitIntervals_ = new java.util.ArrayList<java.lang.Integer>();
mutable_bitField0_ |= 0x00000002;
}
while (input.getBytesUntilLimit() > 0) {
avgWaitIntervals_.add(input.readUInt32());
}
input.popLimit(limit);
break;
}
case 24: {
if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
tripIntervals_ = new java.util.ArrayList<java.lang.Integer>();
mutable_bitField0_ |= 0x00000004;
}
tripIntervals_.add(input.readUInt32());
bitField0_ |= 0x00000002;
avgWaitIntervals_ = input.readBytes();
break;
}
case 26: {
int length = input.readRawVarint32();
int limit = input.pushLimit(length);
if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) {
tripIntervals_ = new java.util.ArrayList<java.lang.Integer>();
mutable_bitField0_ |= 0x00000004;
}
while (input.getBytesUntilLimit() > 0) {
tripIntervals_.add(input.readUInt32());
}
input.popLimit(limit);
bitField0_ |= 0x00000004;
tripIntervals_ = input.readBytes();
break;
}
case 66: {
@ -32086,15 +32015,6 @@ public final class OsmandOdb {
throw new com.google.protobuf.InvalidProtocolBufferException(
e.getMessage()).setUnfinishedMessage(this);
} finally {
if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
avgStopIntervals_ = java.util.Collections.unmodifiableList(avgStopIntervals_);
}
if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
avgWaitIntervals_ = java.util.Collections.unmodifiableList(avgWaitIntervals_);
}
if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
tripIntervals_ = java.util.Collections.unmodifiableList(tripIntervals_);
}
if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
exceptions_ = java.util.Collections.unmodifiableList(exceptions_);
}
@ -32129,113 +32049,82 @@ public final class OsmandOdb {
return PARSER;
}
// repeated uint32 avgStopIntervals = 1;
private int bitField0_;
// optional bytes avgStopIntervals = 1;
public static final int AVGSTOPINTERVALS_FIELD_NUMBER = 1;
private java.util.List<java.lang.Integer> avgStopIntervals_;
private com.google.protobuf.ByteString avgStopIntervals_;
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public java.util.List<java.lang.Integer>
getAvgStopIntervalsList() {
public boolean hasAvgStopIntervals() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public com.google.protobuf.ByteString getAvgStopIntervals() {
return avgStopIntervals_;
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
*
* <pre>
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public int getAvgStopIntervalsCount() {
return avgStopIntervals_.size();
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
*
* <pre>
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public int getAvgStopIntervals(int index) {
return avgStopIntervals_.get(index);
}
// repeated uint32 avgWaitIntervals = 2;
// optional bytes avgWaitIntervals = 2;
public static final int AVGWAITINTERVALS_FIELD_NUMBER = 2;
private java.util.List<java.lang.Integer> avgWaitIntervals_;
private com.google.protobuf.ByteString avgWaitIntervals_;
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public java.util.List<java.lang.Integer>
getAvgWaitIntervalsList() {
public boolean hasAvgWaitIntervals() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public com.google.protobuf.ByteString getAvgWaitIntervals() {
return avgWaitIntervals_;
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public int getAvgWaitIntervalsCount() {
return avgWaitIntervals_.size();
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public int getAvgWaitIntervals(int index) {
return avgWaitIntervals_.get(index);
}
// repeated uint32 tripIntervals = 3;
// optional bytes tripIntervals = 3;
public static final int TRIPINTERVALS_FIELD_NUMBER = 3;
private java.util.List<java.lang.Integer> tripIntervals_;
private com.google.protobuf.ByteString tripIntervals_;
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public java.util.List<java.lang.Integer>
getTripIntervalsList() {
public boolean hasTripIntervals() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public com.google.protobuf.ByteString getTripIntervals() {
return tripIntervals_;
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public int getTripIntervalsCount() {
return tripIntervals_.size();
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public int getTripIntervals(int index) {
return tripIntervals_.get(index);
}
// repeated .OsmAnd.OBF.TransportRouteScheduleException exceptions = 8;
public static final int EXCEPTIONS_FIELD_NUMBER = 8;
@ -32294,9 +32183,9 @@ public final class OsmandOdb {
}
private void initFields() {
avgStopIntervals_ = java.util.Collections.emptyList();
avgWaitIntervals_ = java.util.Collections.emptyList();
tripIntervals_ = java.util.Collections.emptyList();
avgStopIntervals_ = com.google.protobuf.ByteString.EMPTY;
avgWaitIntervals_ = com.google.protobuf.ByteString.EMPTY;
tripIntervals_ = com.google.protobuf.ByteString.EMPTY;
exceptions_ = java.util.Collections.emptyList();
}
private byte memoizedIsInitialized = -1;
@ -32311,14 +32200,14 @@ public final class OsmandOdb {
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
for (int i = 0; i < avgStopIntervals_.size(); i++) {
output.writeUInt32(1, avgStopIntervals_.get(i));
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeBytes(1, avgStopIntervals_);
}
for (int i = 0; i < avgWaitIntervals_.size(); i++) {
output.writeUInt32(2, avgWaitIntervals_.get(i));
if (((bitField0_ & 0x00000002) == 0x00000002)) {
output.writeBytes(2, avgWaitIntervals_);
}
for (int i = 0; i < tripIntervals_.size(); i++) {
output.writeUInt32(3, tripIntervals_.get(i));
if (((bitField0_ & 0x00000004) == 0x00000004)) {
output.writeBytes(3, tripIntervals_);
}
for (int i = 0; i < exceptions_.size(); i++) {
output.writeMessage(8, exceptions_.get(i));
@ -32332,32 +32221,17 @@ public final class OsmandOdb {
if (size != -1) return size;
size = 0;
{
int dataSize = 0;
for (int i = 0; i < avgStopIntervals_.size(); i++) {
dataSize += com.google.protobuf.CodedOutputStream
.computeUInt32SizeNoTag(avgStopIntervals_.get(i));
}
size += dataSize;
size += 1 * getAvgStopIntervalsList().size();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(1, avgStopIntervals_);
}
{
int dataSize = 0;
for (int i = 0; i < avgWaitIntervals_.size(); i++) {
dataSize += com.google.protobuf.CodedOutputStream
.computeUInt32SizeNoTag(avgWaitIntervals_.get(i));
}
size += dataSize;
size += 1 * getAvgWaitIntervalsList().size();
if (((bitField0_ & 0x00000002) == 0x00000002)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(2, avgWaitIntervals_);
}
{
int dataSize = 0;
for (int i = 0; i < tripIntervals_.size(); i++) {
dataSize += com.google.protobuf.CodedOutputStream
.computeUInt32SizeNoTag(tripIntervals_.get(i));
}
size += dataSize;
size += 1 * getTripIntervalsList().size();
if (((bitField0_ & 0x00000004) == 0x00000004)) {
size += com.google.protobuf.CodedOutputStream
.computeBytesSize(3, tripIntervals_);
}
for (int i = 0; i < exceptions_.size(); i++) {
size += com.google.protobuf.CodedOutputStream
@ -32480,11 +32354,11 @@ public final class OsmandOdb {
public Builder clear() {
super.clear();
avgStopIntervals_ = java.util.Collections.emptyList();
avgStopIntervals_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000001);
avgWaitIntervals_ = java.util.Collections.emptyList();
avgWaitIntervals_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000002);
tripIntervals_ = java.util.Collections.emptyList();
tripIntervals_ = com.google.protobuf.ByteString.EMPTY;
bitField0_ = (bitField0_ & ~0x00000004);
if (exceptionsBuilder_ == null) {
exceptions_ = java.util.Collections.emptyList();
@ -32519,19 +32393,17 @@ public final class OsmandOdb {
public net.osmand.binary.OsmandOdb.TransportRouteSchedule buildPartial() {
net.osmand.binary.OsmandOdb.TransportRouteSchedule result = new net.osmand.binary.OsmandOdb.TransportRouteSchedule(this);
int from_bitField0_ = bitField0_;
if (((bitField0_ & 0x00000001) == 0x00000001)) {
avgStopIntervals_ = java.util.Collections.unmodifiableList(avgStopIntervals_);
bitField0_ = (bitField0_ & ~0x00000001);
int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
to_bitField0_ |= 0x00000001;
}
result.avgStopIntervals_ = avgStopIntervals_;
if (((bitField0_ & 0x00000002) == 0x00000002)) {
avgWaitIntervals_ = java.util.Collections.unmodifiableList(avgWaitIntervals_);
bitField0_ = (bitField0_ & ~0x00000002);
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
to_bitField0_ |= 0x00000002;
}
result.avgWaitIntervals_ = avgWaitIntervals_;
if (((bitField0_ & 0x00000004) == 0x00000004)) {
tripIntervals_ = java.util.Collections.unmodifiableList(tripIntervals_);
bitField0_ = (bitField0_ & ~0x00000004);
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
to_bitField0_ |= 0x00000004;
}
result.tripIntervals_ = tripIntervals_;
if (exceptionsBuilder_ == null) {
@ -32543,6 +32415,7 @@ public final class OsmandOdb {
} else {
result.exceptions_ = exceptionsBuilder_.build();
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
}
@ -32558,35 +32431,14 @@ public final class OsmandOdb {
public Builder mergeFrom(net.osmand.binary.OsmandOdb.TransportRouteSchedule other) {
if (other == net.osmand.binary.OsmandOdb.TransportRouteSchedule.getDefaultInstance()) return this;
if (!other.avgStopIntervals_.isEmpty()) {
if (avgStopIntervals_.isEmpty()) {
avgStopIntervals_ = other.avgStopIntervals_;
bitField0_ = (bitField0_ & ~0x00000001);
} else {
ensureAvgStopIntervalsIsMutable();
avgStopIntervals_.addAll(other.avgStopIntervals_);
}
onChanged();
if (other.hasAvgStopIntervals()) {
setAvgStopIntervals(other.getAvgStopIntervals());
}
if (!other.avgWaitIntervals_.isEmpty()) {
if (avgWaitIntervals_.isEmpty()) {
avgWaitIntervals_ = other.avgWaitIntervals_;
bitField0_ = (bitField0_ & ~0x00000002);
} else {
ensureAvgWaitIntervalsIsMutable();
avgWaitIntervals_.addAll(other.avgWaitIntervals_);
}
onChanged();
if (other.hasAvgWaitIntervals()) {
setAvgWaitIntervals(other.getAvgWaitIntervals());
}
if (!other.tripIntervals_.isEmpty()) {
if (tripIntervals_.isEmpty()) {
tripIntervals_ = other.tripIntervals_;
bitField0_ = (bitField0_ & ~0x00000004);
} else {
ensureTripIntervalsIsMutable();
tripIntervals_.addAll(other.tripIntervals_);
}
onChanged();
if (other.hasTripIntervals()) {
setTripIntervals(other.getTripIntervals());
}
if (exceptionsBuilder_ == null) {
if (!other.exceptions_.isEmpty()) {
@ -32641,282 +32493,157 @@ public final class OsmandOdb {
}
private int bitField0_;
// repeated uint32 avgStopIntervals = 1;
private java.util.List<java.lang.Integer> avgStopIntervals_ = java.util.Collections.emptyList();
private void ensureAvgStopIntervalsIsMutable() {
if (!((bitField0_ & 0x00000001) == 0x00000001)) {
avgStopIntervals_ = new java.util.ArrayList<java.lang.Integer>(avgStopIntervals_);
bitField0_ |= 0x00000001;
}
}
// optional bytes avgStopIntervals = 1;
private com.google.protobuf.ByteString avgStopIntervals_ = com.google.protobuf.ByteString.EMPTY;
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public java.util.List<java.lang.Integer>
getAvgStopIntervalsList() {
return java.util.Collections.unmodifiableList(avgStopIntervals_);
public boolean hasAvgStopIntervals() {
return ((bitField0_ & 0x00000001) == 0x00000001);
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public int getAvgStopIntervalsCount() {
return avgStopIntervals_.size();
public com.google.protobuf.ByteString getAvgStopIntervals() {
return avgStopIntervals_;
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public int getAvgStopIntervals(int index) {
return avgStopIntervals_.get(index);
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
*
* <pre>
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public Builder setAvgStopIntervals(
int index, int value) {
ensureAvgStopIntervalsIsMutable();
avgStopIntervals_.set(index, value);
public Builder setAvgStopIntervals(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
avgStopIntervals_ = value;
onChanged();
return this;
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
*
* <pre>
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public Builder addAvgStopIntervals(int value) {
ensureAvgStopIntervalsIsMutable();
avgStopIntervals_.add(value);
onChanged();
return this;
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
*
* <pre>
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public Builder addAllAvgStopIntervals(
java.lang.Iterable<? extends java.lang.Integer> values) {
ensureAvgStopIntervalsIsMutable();
super.addAll(values, avgStopIntervals_);
onChanged();
return this;
}
/**
* <code>repeated uint32 avgStopIntervals = 1;</code>
* <code>optional bytes avgStopIntervals = 1;</code>
*
* <pre>
* array of raw var int
* 10-seconds based intervals between stops arrivals;
* </pre>
*/
public Builder clearAvgStopIntervals() {
avgStopIntervals_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000001);
avgStopIntervals_ = getDefaultInstance().getAvgStopIntervals();
onChanged();
return this;
}
// repeated uint32 avgWaitIntervals = 2;
private java.util.List<java.lang.Integer> avgWaitIntervals_ = java.util.Collections.emptyList();
private void ensureAvgWaitIntervalsIsMutable() {
if (!((bitField0_ & 0x00000002) == 0x00000002)) {
avgWaitIntervals_ = new java.util.ArrayList<java.lang.Integer>(avgWaitIntervals_);
bitField0_ |= 0x00000002;
}
}
// optional bytes avgWaitIntervals = 2;
private com.google.protobuf.ByteString avgWaitIntervals_ = com.google.protobuf.ByteString.EMPTY;
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public java.util.List<java.lang.Integer>
getAvgWaitIntervalsList() {
return java.util.Collections.unmodifiableList(avgWaitIntervals_);
public boolean hasAvgWaitIntervals() {
return ((bitField0_ & 0x00000002) == 0x00000002);
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public int getAvgWaitIntervalsCount() {
return avgWaitIntervals_.size();
public com.google.protobuf.ByteString getAvgWaitIntervals() {
return avgWaitIntervals_;
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public int getAvgWaitIntervals(int index) {
return avgWaitIntervals_.get(index);
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public Builder setAvgWaitIntervals(
int index, int value) {
ensureAvgWaitIntervalsIsMutable();
avgWaitIntervals_.set(index, value);
public Builder setAvgWaitIntervals(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000002;
avgWaitIntervals_ = value;
onChanged();
return this;
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public Builder addAvgWaitIntervals(int value) {
ensureAvgWaitIntervalsIsMutable();
avgWaitIntervals_.add(value);
onChanged();
return this;
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public Builder addAllAvgWaitIntervals(
java.lang.Iterable<? extends java.lang.Integer> values) {
ensureAvgWaitIntervalsIsMutable();
super.addAll(values, avgWaitIntervals_);
onChanged();
return this;
}
/**
* <code>repeated uint32 avgWaitIntervals = 2;</code>
* <code>optional bytes avgWaitIntervals = 2;</code>
*
* <pre>
* optional 10-seconds based (0, if non-provided or less &lt; 10 seconds)
* </pre>
*/
public Builder clearAvgWaitIntervals() {
avgWaitIntervals_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000002);
avgWaitIntervals_ = getDefaultInstance().getAvgWaitIntervals();
onChanged();
return this;
}
// repeated uint32 tripIntervals = 3;
private java.util.List<java.lang.Integer> tripIntervals_ = java.util.Collections.emptyList();
private void ensureTripIntervalsIsMutable() {
if (!((bitField0_ & 0x00000004) == 0x00000004)) {
tripIntervals_ = new java.util.ArrayList<java.lang.Integer>(tripIntervals_);
bitField0_ |= 0x00000004;
}
}
// optional bytes tripIntervals = 3;
private com.google.protobuf.ByteString tripIntervals_ = com.google.protobuf.ByteString.EMPTY;
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public java.util.List<java.lang.Integer>
getTripIntervalsList() {
return java.util.Collections.unmodifiableList(tripIntervals_);
public boolean hasTripIntervals() {
return ((bitField0_ & 0x00000004) == 0x00000004);
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public int getTripIntervalsCount() {
return tripIntervals_.size();
public com.google.protobuf.ByteString getTripIntervals() {
return tripIntervals_;
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public int getTripIntervals(int index) {
return tripIntervals_.get(index);
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public Builder setTripIntervals(
int index, int value) {
ensureTripIntervalsIsMutable();
tripIntervals_.set(index, value);
public Builder setTripIntervals(com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000004;
tripIntervals_ = value;
onChanged();
return this;
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public Builder addTripIntervals(int value) {
ensureTripIntervalsIsMutable();
tripIntervals_.add(value);
onChanged();
return this;
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
* 1st trip is diff from 00:00:00
* </pre>
*/
public Builder addAllTripIntervals(
java.lang.Iterable<? extends java.lang.Integer> values) {
ensureTripIntervalsIsMutable();
super.addAll(values, tripIntervals_);
onChanged();
return this;
}
/**
* <code>repeated uint32 tripIntervals = 3;</code>
* <code>optional bytes tripIntervals = 3;</code>
*
* <pre>
* 10-seconds delta based intervals for trips departing from first stop
@ -32924,8 +32651,8 @@ public final class OsmandOdb {
* </pre>
*/
public Builder clearTripIntervals() {
tripIntervals_ = java.util.Collections.emptyList();
bitField0_ = (bitField0_ & ~0x00000004);
tripIntervals_ = getDefaultInstance().getTripIntervals();
onChanged();
return this;
}
@ -61503,8 +61230,8 @@ public final class OsmandOdb {
"teStop\022\020\n\010geometry\030\021 \001(\014\0228\n\014scheduleTrip" +
"\030\022 \003(\0132\".OsmAnd.OBF.TransportRouteSchedu" +
"le\"\244\001\n\026TransportRouteSchedule\022\030\n\020avgStop" +
"Intervals\030\001 \003(\r\022\030\n\020avgWaitIntervals\030\002 \003(" +
"\r\022\025\n\rtripIntervals\030\003 \003(\r\022?\n\nexceptions\030\010" +
"Intervals\030\001 \001(\014\022\030\n\020avgWaitIntervals\030\002 \001(" +
"\014\022\025\n\rtripIntervals\030\003 \001(\014\022?\n\nexceptions\030\010" +
" \003(\0132+.OsmAnd.OBF.TransportRouteSchedule" +
"Exception\"\313\001\n\037TransportRouteScheduleExce" +
"ption\022\023\n\013tripIndexes\030\001 \003(\r\022\023\n\013stopIndexe" +

View file

@ -8,7 +8,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.osmand.binary.OsmandOdb.TransportRouteSchedule;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.Way;
import net.osmand.util.MapUtils;
@ -21,13 +20,20 @@ public class TransportRoute extends MapObject {
private Integer dist = null;
private String color;
private List<Way> forwardWays;
private TransportRouteSchedule schedule;
private TransportSchedule schedule;
public static final double SAME_STOP = 25;
public TransportRoute(){
}
public TransportRouteSchedule getSchedule() {
public TransportSchedule getSchedule() {
return schedule;
}
public TransportSchedule getOrCreateSchedule() {
if(schedule == null) {
schedule = new TransportSchedule();
}
return schedule;
}
@ -203,7 +209,4 @@ public class TransportRoute extends MapObject {
return d;
}
public void setSchedule(TransportRouteSchedule schedule) {
this.schedule = schedule;
}
}

View file

@ -0,0 +1,23 @@
package net.osmand.data;
import gnu.trove.list.array.TIntArrayList;
public class TransportSchedule {
public TIntArrayList tripIntervals = new TIntArrayList();
public TIntArrayList avgStopIntervals = new TIntArrayList();
public TIntArrayList avgWaitIntervals = new TIntArrayList();
public int[] getTripIntervals() {
return tripIntervals.toArray();
}
public int[] getAvgStopIntervals() {
return avgStopIntervals.toArray();
}
public int[] getAvgWaitIntervals() {
return avgWaitIntervals.toArray();
}
}

View file

@ -18,6 +18,7 @@ import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
import net.osmand.data.LatLon;
import net.osmand.data.TransportRoute;
import net.osmand.data.TransportSchedule;
import net.osmand.data.TransportStop;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.Way;
@ -76,7 +77,13 @@ public class TransportRoutePlanner {
// could be geometry size
double segmentDist = MapUtils.getDistance(prevStop.getLocation(), stop.getLocation());
travelDist += segmentDist;
travelTime += ctx.cfg.stopTime + segmentDist / ctx.cfg.travelSpeed;
if(ctx.cfg.useSchedule) {
TransportSchedule sc = segment.road.getSchedule();
int interval = sc.avgStopIntervals.get(ind - 1);
travelTime += interval * 10;
} else {
travelTime += ctx.cfg.stopTime + segmentDist / ctx.cfg.travelSpeed;
}
sgms.clear();
sgms = ctx.getTransportStops(stop.x31, stop.y31, true, sgms);
for (TransportRouteSegment sgm : sgms) {
@ -322,6 +329,16 @@ public class TransportRoutePlanner {
}
public double getTravelTime() {
if(cfg.useSchedule) {
int t = 0;
for(TransportRouteResultSegment s : segments) {
TransportSchedule sts = s.route.getSchedule();
for (int k = s.start; k < s.end; k++) {
t += sts.getAvgStopIntervals()[k] * 10;
}
}
return t;
}
return getTravelDist() / cfg.travelSpeed + cfg.stopTime * getStops() +
cfg.changeTime * getChanges();
}
@ -356,6 +373,7 @@ public class TransportRoutePlanner {
final int segStart;
final TransportRoute road;
final int departureTime;
private static final int SHIFT = 10; // assume less than 1024 stops
TransportRouteSegment parentRoute = null;
@ -369,14 +387,24 @@ public class TransportRoutePlanner {
double distFromStart = 0;
public TransportRouteSegment(TransportRoute road, int stopIndex) {
this.road = road;
this.segStart = (short) stopIndex;
this.departureTime = -1;
}
public TransportRouteSegment(TransportRoute road, int stopIndex, int depTime) {
this.road = road;
this.segStart = (short) stopIndex;
this.departureTime = depTime;
}
public TransportRouteSegment(TransportRouteSegment c) {
this.road = c.road;
this.segStart = c.segStart;
this.departureTime = c.departureTime;
}
@ -440,7 +468,7 @@ public class TransportRoutePlanner {
public TLongObjectHashMap<List<TransportRouteSegment>> quadTree;
public final Map<BinaryMapIndexReader, TIntObjectHashMap<TransportRoute>> map =
public final Map<BinaryMapIndexReader, TIntObjectHashMap<TransportRoute>> routeMap =
new LinkedHashMap<BinaryMapIndexReader, TIntObjectHashMap<TransportRoute>>();
// stats
@ -465,7 +493,7 @@ public class TransportRoutePlanner {
walkChangeRadiusIn31 = (int) (cfg.walkChangeRadius / MapUtils.getTileDistanceWidth(31));
quadTree = new TLongObjectHashMap<List<TransportRouteSegment>>();
for (BinaryMapIndexReader r : readers) {
map.put(r, new TIntObjectHashMap<TransportRoute>());
routeMap.put(r, new TIntObjectHashMap<TransportRoute>());
}
}
@ -517,11 +545,14 @@ public class TransportRoutePlanner {
SearchRequest<TransportStop> sr = BinaryMapIndexReader.buildSearchTransportRequest(x << pz, (x + 1) << pz,
y << pz, (y + 1) << pz, -1, null);
TIntArrayList allPoints = new TIntArrayList();
TIntArrayList allPointsUnique = new TIntArrayList();
TIntArrayList allPointsLoad = new TIntArrayList();
// should it be global?
TLongObjectHashMap<TransportStop> loadedTransportStops = new TLongObjectHashMap<TransportStop>();
for(BinaryMapIndexReader r : map.keySet()) {
for(BinaryMapIndexReader r : routeMap.keySet()) {
sr.clearSearchResults();
allPoints.clear();
allPointsLoad.clear();
List<TransportStop> stops = r.searchTransportIndex(sr);
for(TransportStop s : stops) {
if(!loadedTransportStops.contains(s.getId())) {
@ -529,19 +560,34 @@ public class TransportRoutePlanner {
allPoints.addAll(s.getReferencesToRoutes());
}
}
makeUnique(allPoints, allPointsUnique);
if(allPointsUnique.size() > 0) {
loadTransportSegments(allPointsUnique, r, stops, lst);
if(allPoints.size() > 0) {
allPoints.sort();
TIntObjectHashMap<TransportRoute> loadedRoutes = routeMap.get(r);
TIntObjectHashMap<TransportRoute> routes = new TIntObjectHashMap<TransportRoute>();
TIntIterator it = allPoints.iterator();
int p = allPoints.get(0) + 1; // different
while(it.hasNext()) {
int nxt = it.next();
if (p != nxt) {
if (loadedRoutes.contains(nxt)) {
routes.put(nxt, loadedRoutes.get(nxt));
} else {
allPointsLoad.add(nxt);
}
}
}
r.loadTransportRoutes(allPointsLoad.toArray(), routes);
loadedRoutes.putAll(routes);
loadTransportSegments(routes, r, stops, lst);
}
}
readTime += System.nanoTime() - nanoTime;
return lst;
}
private void loadTransportSegments(TIntArrayList allPointsUnique, BinaryMapIndexReader r,
private void loadTransportSegments(TIntObjectHashMap<TransportRoute> routes, BinaryMapIndexReader r,
List<TransportStop> stops, List<TransportRouteSegment> lst) throws IOException {
TIntObjectHashMap<TransportRoute> routes = r.getTransportRoutes(allPointsUnique.toArray());
map.get(r).putAll(routes);
for(TransportStop s : stops) {
for (int ref : s.getReferencesToRoutes()) {
TransportRoute route = routes.get(ref);
@ -557,10 +603,26 @@ public class TransportRoutePlanner {
}
}
if (stopIndex != -1) {
TransportRouteSegment segment = new TransportRouteSegment(route, stopIndex);
lst.add(segment);
if(cfg.useSchedule) {
if(route.getSchedule() != null) {
TIntArrayList ti = route.getSchedule().tripIntervals;
int cnt = ti.size();
int t = 0;
for(int i = 0; i < cnt; i++) {
t += ti.getQuick(i);
if(t >= cfg.scheduleTimeOfDay) {
TransportRouteSegment segment = new TransportRouteSegment(route, stopIndex, t);
lst.add(segment);
break;
}
}
}
} else {
TransportRouteSegment segment = new TransportRouteSegment(route, stopIndex);
lst.add(segment);
}
} else {
System.err.println("missing");
System.err.println("Routing error: missing stop in route");
}
}
@ -568,18 +630,7 @@ public class TransportRoutePlanner {
}
}
private void makeUnique(TIntArrayList allPoints, TIntArrayList allPointsUnique) {
allPoints.sort();
int p = 0;
TIntIterator it = allPoints.iterator();
while(it.hasNext()) {
int nxt = it.next();
if(p != nxt) {
allPointsUnique.add(nxt);
p = nxt;
}
}
}
}

View file

@ -23,6 +23,15 @@ public class TransportRoutingConfiguration {
public int finishTimeSeconds = 1200;
public int maxRouteTime = 60 * 60 * 1000; // 1000 hours
public boolean useSchedule;
// 10 seconds based
public int scheduleTimeOfDay = 60 * 6 * 12; // 12:00 - 60*6*12
// day since 2000
public int scheduleDayNumber;
public TransportRoutingConfiguration(RoutingConfiguration.Builder builder) {
@ -38,8 +47,6 @@ public class TransportRoutingConfiguration {
walkSpeed = router.getFloatAttribute("defaultWalkSpeed", (float) walkSpeed);
stopTime = router.getIntAttribute("defaultStopTime", stopTime);
changeTime = router.getIntAttribute("defaultChangeTime", changeTime);
}
}