add reading of incomplete routes. Add cache - work in progress
This commit is contained in:
parent
8e56faabd1
commit
7699e2061c
5 changed files with 192 additions and 42 deletions
|
@ -19,6 +19,7 @@ import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion;
|
|||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||
import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex;
|
||||
import net.osmand.binary.OsmandOdb.IncompleteTransportRoute;
|
||||
import net.osmand.binary.OsmandOdb.MapDataBlock;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapDataBox;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapEncodingRule;
|
||||
|
@ -54,6 +55,7 @@ import java.io.InputStreamReader;
|
|||
import java.io.RandomAccessFile;
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
@ -110,7 +112,8 @@ public class BinaryMapIndexReader {
|
|||
/*private*/ List<RouteRegion> routingIndexes = new ArrayList<RouteRegion>();
|
||||
/*private*/ List<BinaryIndexPart> indexes = new ArrayList<BinaryIndexPart>();
|
||||
|
||||
private final TLongObjectHashMap<int[]> incompleteRoutes = new TLongObjectHashMap<int[]>();
|
||||
private final TLongObjectHashMap<net.osmand.data.IncompleteTransportRoute> incompleteRoutes =
|
||||
new TLongObjectHashMap<net.osmand.data.IncompleteTransportRoute>();
|
||||
|
||||
protected CodedInputStream codedIS;
|
||||
|
||||
|
@ -225,7 +228,7 @@ public class BinaryMapIndexReader {
|
|||
ind.filePointer = codedIS.getTotalBytesRead();
|
||||
if (transportAdapter != null) {
|
||||
oldLimit = codedIS.pushLimit(ind.length);
|
||||
transportAdapter.readTransportIndex(ind);
|
||||
transportAdapter.readTransportIndex(ind, incompleteRoutes);
|
||||
codedIS.popLimit(oldLimit);
|
||||
transportIndexes.add(ind);
|
||||
indexes.add(ind);
|
||||
|
@ -2633,9 +2636,12 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
}
|
||||
|
||||
public int[] getIncompleteRoutesPointers(long id) {
|
||||
public net.osmand.data.IncompleteTransportRoute getIncompleteRoutePointers(long id) {
|
||||
return incompleteRoutes.get(id);
|
||||
}
|
||||
public Collection<net.osmand.data.IncompleteTransportRoute> getIncompleteRoutes() {
|
||||
return incompleteRoutes.valueCollection();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.WireFormat;
|
||||
|
||||
import gnu.trove.list.array.TLongArrayList;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.OsmandOdb.IncompleteTransportRoute;
|
||||
import net.osmand.data.TransportSchedule;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.data.TransportStopExit;
|
||||
|
@ -43,6 +48,8 @@ public class BinaryMapTransportReaderAdapter {
|
|||
|
||||
int stopsFileOffset = 0;
|
||||
int stopsFileLength = 0;
|
||||
int incompleteRoutesOffset = 0;
|
||||
int incompleteRoutesLength = 0;
|
||||
|
||||
public String getPartName() {
|
||||
return "Transport";
|
||||
|
@ -67,7 +74,8 @@ public class BinaryMapTransportReaderAdapter {
|
|||
public int getBottom() {
|
||||
return bottom;
|
||||
}
|
||||
|
||||
|
||||
|
||||
IndexStringTable stringTable = null;
|
||||
}
|
||||
|
||||
|
@ -79,7 +87,7 @@ public class BinaryMapTransportReaderAdapter {
|
|||
}
|
||||
|
||||
|
||||
protected void readTransportIndex(TransportIndex ind) throws IOException {
|
||||
protected void readTransportIndex(TransportIndex ind, TLongObjectHashMap<net.osmand.data.IncompleteTransportRoute> incompleteRoutes) throws IOException {
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
|
@ -108,6 +116,16 @@ public class BinaryMapTransportReaderAdapter {
|
|||
ind.stringTable = st;
|
||||
codedIS.seek(st.length + st.fileOffset);
|
||||
break;
|
||||
case OsmandOdb.OsmAndTransportIndex.INCOMPLETEROUTES_FIELD_NUMBER :
|
||||
TIntObjectHashMap<String> stab = new TIntObjectHashMap<String>();
|
||||
ind.incompleteRoutesLength = codedIS.readRawVarint32();
|
||||
ind.incompleteRoutesOffset = codedIS.getTotalBytesRead();
|
||||
int oldl = codedIS.pushLimit(ind.incompleteRoutesLength);
|
||||
//may be we should start caching stringTable in advance?
|
||||
readIncompleteRoutesList(incompleteRoutes, ind.incompleteRoutesLength, ind.incompleteRoutesOffset, stab);
|
||||
codedIS.popLimit(oldl);
|
||||
break;
|
||||
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
|
@ -240,6 +258,73 @@ public class BinaryMapTransportReaderAdapter {
|
|||
return ((char) i)+"";
|
||||
}
|
||||
|
||||
private void readIncompleteRoutesList(TLongObjectHashMap<net.osmand.data.IncompleteTransportRoute> incompleteRoutes,
|
||||
int length, int offset, TIntObjectHashMap<String> stringTable) throws IOException {
|
||||
codedIS.seek(offset);
|
||||
|
||||
List<net.osmand.data.IncompleteTransportRoute> irs = new ArrayList<>();
|
||||
boolean end = false;
|
||||
while (!end) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
end = true;
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoutes.ROUTES_FIELD_NUMBER:
|
||||
int l = codedIS.readRawVarint32();
|
||||
int olds = codedIS.pushLimit(l);
|
||||
net.osmand.data.IncompleteTransportRoute ir = readIncompleteRoute(stringTable);
|
||||
incompleteRoutes.put(ir.getRouteId(), ir);
|
||||
codedIS.popLimit(olds);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public net.osmand.data.IncompleteTransportRoute readIncompleteRoute(TIntObjectHashMap<String> stringTable) throws IOException {
|
||||
net.osmand.data.IncompleteTransportRoute dataObject = new net.osmand.data.IncompleteTransportRoute();
|
||||
boolean end = false;
|
||||
while(!end){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
end = true;
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoute.ID_FIELD_NUMBER :
|
||||
dataObject.setRouteId(codedIS.readUInt64());
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoute.ROUTEREF_FIELD_NUMBER :
|
||||
dataObject.setRouteOffset(codedIS.readRawVarint32());
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoute.OPERATOR_FIELD_NUMBER :
|
||||
dataObject.setOperator(regStr(stringTable));
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoute.REF_FIELD_NUMBER :
|
||||
dataObject.setRef(regStr(stringTable));
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoute.TYPE_FIELD_NUMBER :
|
||||
dataObject.setType(regStr(stringTable));
|
||||
break;
|
||||
case OsmandOdb.IncompleteTransportRoute.MISSINGSTOPS_FIELD_NUMBER :
|
||||
//// dataObject.getMissingStops().add(codedIS.readSInt32()); //skip for now
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dataObject;
|
||||
}
|
||||
|
||||
public net.osmand.data.TransportRoute getTransportRoute(int filePointer, TIntObjectHashMap<String> stringTable,
|
||||
boolean onlyDescription) throws IOException {
|
||||
codedIS.seek(filePointer);
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
public class IncompleteTransportRoute {
|
||||
private long routeId;
|
||||
private int routeOffset = -1;
|
||||
private String operator;
|
||||
private String type;
|
||||
private String ref;
|
||||
// private TIntArrayList missingStops; //not needed
|
||||
public long getRouteId() {
|
||||
return routeId;
|
||||
}
|
||||
public void setRouteId(long routeId) {
|
||||
this.routeId = routeId;
|
||||
}
|
||||
public int getRouteOffset() {
|
||||
return routeOffset;
|
||||
}
|
||||
public void setRouteOffset(int routeOffset) {
|
||||
this.routeOffset = routeOffset;
|
||||
}
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
public String getRef() {
|
||||
return ref;
|
||||
}
|
||||
public void setRef(String ref) {
|
||||
this.ref = ref;
|
||||
}
|
||||
// public TIntArrayList getMissingStops() {
|
||||
// return missingStops;
|
||||
// }
|
||||
// public void setMissingStops(TIntArrayList missingStops) {
|
||||
// this.missingStops = missingStops;
|
||||
// }
|
||||
|
||||
|
||||
}
|
|
@ -63,6 +63,10 @@ public class TransportRoute extends MapObject {
|
|||
return combined;
|
||||
}
|
||||
|
||||
public boolean isIncomplete() {
|
||||
return forwardStops.get(0).isMissingStop() || forwardStops.get(forwardStops.size()-1).isMissingStop();
|
||||
}
|
||||
|
||||
public void setCombined(boolean combined) {
|
||||
this.combined = combined;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import net.osmand.NativeLibrary;
|
|||
import net.osmand.binary.BinaryIndexPart;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.data.IncompleteTransportRoute;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.TransportRoute;
|
||||
|
@ -707,7 +708,7 @@ public class TransportRoutePlanner {
|
|||
public RouteCalculationProgress calculationProgress;
|
||||
public TLongObjectHashMap<TransportRouteSegment> visitedSegments = new TLongObjectHashMap<TransportRouteSegment>();
|
||||
public TransportRoutingConfiguration cfg;
|
||||
public TLongObjectHashMap<TransportRoute> combinedRoutes = new TLongObjectHashMap<TransportRoute>();
|
||||
public TLongObjectHashMap<TransportRoute> combinedRoutesCache = new TLongObjectHashMap<TransportRoute>();
|
||||
public Map<TransportStop, List<TransportRoute>> missingStopsCache = new HashMap<TransportStop, List<TransportRoute>>();
|
||||
|
||||
public TLongObjectHashMap<List<TransportRouteSegment>> quadTree;
|
||||
|
@ -926,55 +927,31 @@ public class TransportRoutePlanner {
|
|||
}
|
||||
|
||||
private TransportRoute getCombinedRoute(TransportRoute route, String fileName) throws IOException {
|
||||
if (!route.getForwardStops().get(0).isMissingStop() && !route.getForwardStops().get(route.getForwardStops().size()-1).isMissingStop()) {
|
||||
if (!route.isIncomplete()) {
|
||||
return route;
|
||||
}
|
||||
|
||||
TransportRoute c = combinedRoutes.get(route.getId());
|
||||
TransportRoute c = combinedRoutesCache.get(route.getId());
|
||||
|
||||
if (c == null) {
|
||||
c = combineRoute(route, fileName);
|
||||
combinedRoutes.put(route.getId(), c);
|
||||
combinedRoutesCache.put(route.getId(), c);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private TIntObjectHashMap<TransportRoute> findIncompleteRouteParts(TransportRoute baseRoute, String fileName) throws IOException {
|
||||
int ptrs[];
|
||||
TIntObjectHashMap<TransportRoute> res = new TIntObjectHashMap<TransportRoute>();
|
||||
TIntObjectHashMap<TransportRoute> localRes = new TIntObjectHashMap<TransportRoute>();
|
||||
// TODO check if valid comparsion by filename
|
||||
for (BinaryMapIndexReader bmir: routeMap.keySet()) {
|
||||
if (!bmir.getFile().getName().equals(fileName)) {
|
||||
/**
|
||||
* What about situation when one route has several parts in map?
|
||||
* MB check all readers and then sort it out?
|
||||
*
|
||||
* Should I check if those routes already loaded? But they shouldn't,
|
||||
* else we will already had a combined route and never get there!
|
||||
*/
|
||||
localRes.clear();
|
||||
ptrs = bmir.getIncompleteRoutesPointers(baseRoute.getId());
|
||||
if (ptrs != null && ptrs.length > 0) {
|
||||
localRes = bmir.getTransportRoutes(ptrs);
|
||||
|
||||
res.putAll(localRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private TransportRoute combineRoute(TransportRoute route, String fileName) throws IOException {
|
||||
TransportRoute cr = new TransportRoute(route, true);
|
||||
TIntObjectHashMap<TransportRoute> res = findIncompleteRouteParts(route, fileName);
|
||||
// for () {
|
||||
//TODO check for duplicates and subsets
|
||||
//TODO connect in right order
|
||||
Collection<TransportRoute> res = findIncompleteRouteParts(route, fileName);
|
||||
List<TransportStop> stops = route.getForwardStops();
|
||||
List<Way> ways = route.getForwardWays();
|
||||
for (TransportRoute tr : res.valueCollection()) {
|
||||
|
||||
// }
|
||||
//TODO check for duplicates and subsets
|
||||
//TODO connect routes in right order (stops/ways)
|
||||
|
||||
}
|
||||
// TransportRoute missingPart;
|
||||
// if (route.getForwardStops().get(0).isMissingStop()) {
|
||||
// missingPart = loadMissingTransportRoute(
|
||||
|
@ -995,6 +972,35 @@ public class TransportRoutePlanner {
|
|||
return cr;
|
||||
}
|
||||
|
||||
private Collection<TransportRoute> findIncompleteRouteParts(TransportRoute baseRoute, String fileName) throws IOException {
|
||||
IncompleteTransportRoute ptr;
|
||||
TIntObjectHashMap<TransportRoute> res = new TIntObjectHashMap<TransportRoute>();
|
||||
TIntObjectHashMap<TransportRoute> localRes = new TIntObjectHashMap<TransportRoute>();
|
||||
// TODO check if valid comparison by filename
|
||||
for (BinaryMapIndexReader bmir: routeMap.keySet()) {
|
||||
if (!bmir.getFile().getName().equals(fileName)) {
|
||||
/**
|
||||
* What about situation when one route has several parts in map?
|
||||
* MB check all readers and then sort it out?
|
||||
*
|
||||
* Should I check if those routes already loaded? But they shouldn't,
|
||||
* else we will already had a combined route and never get there!
|
||||
*/
|
||||
localRes.clear();
|
||||
ptr = bmir.getIncompleteRoutePointers(baseRoute.getId());
|
||||
if (ptr!= null && ptr.getRouteOffset() != -1) {
|
||||
localRes = bmir.getTransportRoutes(new int[] {ptr.getRouteOffset()});
|
||||
|
||||
res.putAll(localRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.valueCollection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private TransportRoute loadMissingTransportRoute(int sx, int sy, TransportRoute route) throws IOException {
|
||||
|
@ -1239,5 +1245,4 @@ public class TransportRoutePlanner {
|
|||
}
|
||||
return stops;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue