Remove border lines & enable route precalculation
This commit is contained in:
parent
5dd8c35988
commit
fc11e13a1e
12 changed files with 26 additions and 482 deletions
|
@ -1373,14 +1373,7 @@ public class BinaryMapIndexReader {
|
|||
return request;
|
||||
}
|
||||
|
||||
public static SearchRequest<RouteDataBorderLinePoint> buildSearchRouteBorderRequest(int sleft, int sright, int stop, int sbottom){
|
||||
SearchRequest<RouteDataBorderLinePoint> request = new SearchRequest<RouteDataBorderLinePoint>();
|
||||
request.left = sleft;
|
||||
request.right = sright;
|
||||
request.top = stop;
|
||||
request.bottom = sbottom;
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static SearchRequest<Amenity> buildSearchPoiRequest(int x, int y, String nameFilter, int sleft, int sright, int stop, int sbottom, ResultMatcher<Amenity> resultMatcher){
|
||||
|
@ -2095,13 +2088,6 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
}
|
||||
|
||||
public List<RouteDataBorderLinePoint> searchBorderPoints(SearchRequest<RouteDataBorderLinePoint> req, RouteRegion r) throws IOException {
|
||||
if(routeAdapter != null){
|
||||
routeAdapter.searchBorderPoints(req, r);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public List<RouteDataObject> loadRouteIndexData(RouteSubregion rs) throws IOException {
|
||||
if(routeAdapter != null){
|
||||
return routeAdapter.loadRouteRegionData(rs);
|
||||
|
|
|
@ -790,165 +790,9 @@ public class BinaryMapRouteReaderAdapter {
|
|||
return toLoad;
|
||||
}
|
||||
|
||||
public List<RouteDataBorderLinePoint> searchBorderPoints(SearchRequest<RouteDataBorderLinePoint> req, RouteRegion r) throws IOException {
|
||||
if(r.borderBoxPointer != 0) {
|
||||
codedIS.seek(r.borderBoxPointer);
|
||||
int old = codedIS.pushLimit(r.borderBoxLength);
|
||||
TIntArrayList blocksToRead = new TIntArrayList();
|
||||
readBorderLines(req, blocksToRead);
|
||||
|
||||
blocksToRead.sort();
|
||||
for(int j = 0; j< blocksToRead.size() ; j++) {
|
||||
codedIS.seek(blocksToRead.get(j));
|
||||
int len = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(len);
|
||||
readBorderLinePoints(req, r);
|
||||
codedIS.popLimit(oldLimit);
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
|
||||
}
|
||||
return req.getSearchResults();
|
||||
}
|
||||
|
||||
|
||||
private void readBorderLinePoints(SearchRequest<RouteDataBorderLinePoint> req, RouteRegion r) throws IOException {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
long id = 0;
|
||||
while (true) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return;
|
||||
case RouteBorderPointsBlock.X_FIELD_NUMBER: {
|
||||
x = codedIS.readInt32();
|
||||
break;
|
||||
}
|
||||
case RouteBorderPointsBlock.Y_FIELD_NUMBER: {
|
||||
y = codedIS.readInt32();
|
||||
break;
|
||||
}
|
||||
case RouteBorderPointsBlock.BASEID_FIELD_NUMBER: {
|
||||
id = codedIS.readInt64();
|
||||
break;
|
||||
}
|
||||
case RouteBorderPointsBlock.POINTS_FIELD_NUMBER:
|
||||
int len = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(len);
|
||||
RouteDataBorderLinePoint p = readBorderLinePoint(new RouteDataBorderLinePoint(r), x, y, id);
|
||||
codedIS.popLimit(oldLimit);
|
||||
x = p.x;
|
||||
y = p.y;
|
||||
id = p.id;
|
||||
req.publish(p);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private RouteDataBorderLinePoint readBorderLinePoint(RouteDataBorderLinePoint p, int x, int y, long id) throws IOException {
|
||||
while (true) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return p;
|
||||
case RouteBorderPoint.DX_FIELD_NUMBER:
|
||||
p.x = x + codedIS.readInt32();
|
||||
break;
|
||||
case RouteBorderPoint.DY_FIELD_NUMBER:
|
||||
p.y = y + codedIS.readInt32();
|
||||
break;
|
||||
case RouteBorderPoint.ROADID_FIELD_NUMBER:
|
||||
p.id = id + codedIS.readSInt64();
|
||||
break;
|
||||
case RouteBorderPoint.DIRECTION_FIELD_NUMBER:
|
||||
p.direction = codedIS.readBool();
|
||||
break;
|
||||
case RouteBorderPoint.TYPES_FIELD_NUMBER:
|
||||
TIntArrayList types = new TIntArrayList();
|
||||
int len = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(len);
|
||||
while(codedIS.getBytesUntilLimit() > 0) {
|
||||
types.add(codedIS.readRawVarint32());
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
p.types = types.toArray();
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readBorderLines(SearchRequest<RouteDataBorderLinePoint> req, TIntArrayList blocksToRead) throws IOException {
|
||||
while (true) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return;
|
||||
case RouteBorderBox.BORDERLINES_FIELD_NUMBER: {
|
||||
int fp = codedIS.getTotalBytesRead();
|
||||
int length = codedIS.readRawVarint32();
|
||||
int old = codedIS.pushLimit(length);
|
||||
|
||||
RouteBorderLine ln = readBorderLine();
|
||||
if(ln.hasTox() && req.intersects(ln.getX(), ln.getY(), ln.getTox(), ln.getY())) {
|
||||
blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
||||
// FIXME borders approach
|
||||
// } else if(ln.hasToy() && req.intersects(ln.getX(), ln.getY(), ln.getX(), ln.getToy())) {
|
||||
// blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
break;
|
||||
}
|
||||
case RouteBorderBox.BLOCKS_FIELD_NUMBER:
|
||||
return;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private RouteBorderLine readBorderLine() throws IOException {
|
||||
Builder bld = RouteBorderLine.newBuilder();
|
||||
while (true) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return bld.build();
|
||||
case RouteBorderLine.X_FIELD_NUMBER:
|
||||
bld.setX(codedIS.readInt32());
|
||||
break;
|
||||
case RouteBorderLine.Y_FIELD_NUMBER:
|
||||
bld.setY(codedIS.readInt32());
|
||||
break;
|
||||
case RouteBorderLine.TOX_FIELD_NUMBER:
|
||||
bld.setTox(codedIS.readInt32());
|
||||
break;
|
||||
case RouteBorderLine.TOY_FIELD_NUMBER:
|
||||
bld.setToy(codedIS.readInt32());
|
||||
break;
|
||||
case RouteBorderLine.SHIFTTOPOINTSBLOCK_FIELD_NUMBER:
|
||||
bld.setShiftToPointsBlock(readInt());
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<RouteSubregion> loadInteresectedPoints(SearchRequest<RouteDataObject> req, List<RouteSubregion> list,
|
||||
List<RouteSubregion> toLoad) throws IOException {
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||
|
||||
public class RouteDataBorderLinePoint extends RouteDataObject {
|
||||
// all these arrays supposed to be immutable!
|
||||
// These feilds accessible from C++
|
||||
public int x;
|
||||
public int y;
|
||||
public boolean direction;
|
||||
|
||||
// used in context calculation
|
||||
public float distanceToStartPoint;
|
||||
public float distanceToEndPoint;
|
||||
|
||||
public RouteDataBorderLinePoint(RouteRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
public float getMaximumSpeed(){
|
||||
int sz = types.length;
|
||||
float maxSpeed = 0;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
RouteTypeRule r = region.quickGetEncodingRule(types[i]);
|
||||
float mx = r.maxSpeed();
|
||||
if (mx > 0) {
|
||||
maxSpeed = mx;
|
||||
// conditional has priority
|
||||
if(r.conditional()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxSpeed ;
|
||||
}
|
||||
|
||||
public int getOneway() {
|
||||
int sz = types.length;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
RouteTypeRule r = region.quickGetEncodingRule(types[i]);
|
||||
if (r.onewayDirection() != 0) {
|
||||
return r.onewayDirection();
|
||||
} else if (r.roundabout()) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getRoute() {
|
||||
int sz = types.length;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
RouteTypeRule r = region.quickGetEncodingRule(types[i]);
|
||||
if ("route".equals(r.getTag())) {
|
||||
return r.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getHighway() {
|
||||
String highway = null;
|
||||
int sz = types.length;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
RouteTypeRule r = region.quickGetEncodingRule(types[i]);
|
||||
highway = r.highwayRoad();
|
||||
if (highway != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return highway;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Border line " + id;
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ import java.util.List;
|
|||
import java.util.PriorityQueue;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.RouteDataBorderLinePoint;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
@ -115,9 +114,6 @@ public class BinaryRoutePlanner {
|
|||
} else {
|
||||
graphSegments = graphDirectSegments;
|
||||
}
|
||||
ctx.loadBorderPoints();
|
||||
/*RoutingContext baseCtx = new RoutingContext(ctx);
|
||||
baseCtx.newRoutingPoints();*/
|
||||
|
||||
FinalRouteSegment finalSegment = null;
|
||||
while (!graphSegments.isEmpty()) {
|
||||
|
@ -214,7 +210,7 @@ public class BinaryRoutePlanner {
|
|||
}
|
||||
if(graphReverseSegments.size() > 0) {
|
||||
ctx.calculationProgress.distanceFromEnd =
|
||||
Math.max(graphReverseSegments.peek().distanceFromStart, ctx.calculationProgress.distanceFromBegin);
|
||||
Math.max(graphReverseSegments.peek().distanceFromStart, ctx.calculationProgress.distanceFromEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -282,60 +278,7 @@ public class BinaryRoutePlanner {
|
|||
return te;
|
||||
}
|
||||
}
|
||||
|
||||
if (RoutingContext.USE_BORDER_LINES) {
|
||||
int begBorder = ctx.searchBorderLineIndex(begY);
|
||||
int endBorder = ctx.searchBorderLineIndex(endY);
|
||||
if (begBorder != endBorder) {
|
||||
double res = 0;
|
||||
boolean plus = begBorder < endBorder;
|
||||
boolean beginEqStart = begX == ctx.startX && begY == ctx.startY;
|
||||
boolean beginEqTarget = begX == ctx.targetX && begY == ctx.targetY;
|
||||
boolean endEqStart = endX == ctx.startX && endY == ctx.startY;
|
||||
boolean endEqTarget = endX == ctx.targetX && endY == ctx.targetY;
|
||||
if(endEqStart || endEqTarget) {
|
||||
// we start from intermediate point and end in target or start
|
||||
if (begX > ctx.leftBorderBoundary && begX < ctx.rightBorderBoundary) {
|
||||
List<RouteDataBorderLinePoint> pnts = ctx.borderLines[plus ? begBorder : begBorder - 1].borderPoints;
|
||||
for (RouteDataBorderLinePoint p : pnts) {
|
||||
double f = (endEqTarget ? p.distanceToEndPoint : p.distanceToStartPoint) + squareRootDist(p.x, p.y, begX, begY);
|
||||
if (res > f || res <= 0) {
|
||||
res = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(beginEqStart || beginEqTarget) {
|
||||
if (endX > ctx.leftBorderBoundary && endX < ctx.rightBorderBoundary) {
|
||||
List<RouteDataBorderLinePoint> pnts = ctx.borderLines[plus ? endBorder - 1 : endBorder].borderPoints;
|
||||
for (RouteDataBorderLinePoint p : pnts) {
|
||||
double f = (beginEqTarget ? p.distanceToEndPoint : p.distanceToStartPoint)
|
||||
+ squareRootDist(p.x, p.y, endX, endY);
|
||||
if (res > f || res <= 0) {
|
||||
res = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if(res > 0) {
|
||||
if(res < distToFinalPoint - 0.01) {
|
||||
throw new IllegalStateException("Estimated distance " + res + " > " + distToFinalPoint);
|
||||
}
|
||||
// if(endEqStart && res - distToFinalPoint > 13000) {
|
||||
// System.out.println(" Res="+res + " dist=" +distToFinalPoint);
|
||||
// }
|
||||
distToFinalPoint = res;
|
||||
|
||||
} else {
|
||||
// FIXME put penalty
|
||||
// distToFinalPoint = distToFinalPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double result = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed();
|
||||
// result *= 0.8;
|
||||
return (float) result;
|
||||
}
|
||||
|
||||
|
@ -366,10 +309,6 @@ public class BinaryRoutePlanner {
|
|||
printInfo("Visited interval sizes: " + visitedDirectSegments.size() + "/" + visitedOppositeSegments.size());
|
||||
}
|
||||
|
||||
for(int k=0; k<ctx.borderLines.length; k++) {
|
||||
System.out.println("Line " + (ctx.borderLineCoordinates[k] >> 17) + " points " + ctx.borderLines[k].borderPoints.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -416,29 +355,7 @@ public class BinaryRoutePlanner {
|
|||
if(x == prevx && y == prevy) {
|
||||
continue;
|
||||
}
|
||||
if(RoutingContext.USE_BORDER_LINES) {
|
||||
int st = ctx.searchBorderLineIndex(y);
|
||||
int tt = ctx.searchBorderLineIndex(prevy);
|
||||
if(st != tt){
|
||||
// System.out.print(" " + st + " != " + tt + " " + road.id + " ? ");
|
||||
for(int i = Math.min(st, tt); i < Math.max(st, tt) & i < ctx.borderLines.length ; i++) {
|
||||
Iterator<RouteDataBorderLinePoint> pnts = ctx.borderLines[i].borderPoints.iterator();
|
||||
boolean changed = false;
|
||||
while(pnts.hasNext()) {
|
||||
RouteDataBorderLinePoint o = pnts.next();
|
||||
if(o.id == road.id) {
|
||||
// System.out.println("Point removed !");
|
||||
pnts.remove();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if(changed){
|
||||
ctx.updateDistanceForBorderPoints(ctx.startX, ctx.startY, true);
|
||||
ctx.updateDistanceForBorderPoints(ctx.targetX, ctx.targetY, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. calculate point and try to load neighbor ways if they are not loaded
|
||||
segmentDist += squareRootDist(x, y, prevx, prevy);
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ public class PrecalculatedRouteDirection {
|
|||
private float avgSpeed;
|
||||
private float[] tms;
|
||||
private static final int SHIFT = (1 << (31 - 18));
|
||||
private static final int[] SHIFTS = new int[]{(1 << (31 - 17)), (1 << (31 - 15)), (1 << (31 - 13)), (1 << (31 - 12)),
|
||||
(1 << (31 - 11))};
|
||||
private static final int[] SHIFTS = new int[]{1 << (31 - 17), 1 << (31 - 15), 1 << (31 - 13), 1 << (31 - 12),
|
||||
1 << (31 - 11), 1 << (31 - 9)};
|
||||
|
||||
private List<Integer> cachedS = new ArrayList<Integer>();
|
||||
private float[] ct1 = new float[2];
|
||||
|
@ -38,6 +38,7 @@ public class PrecalculatedRouteDirection {
|
|||
for (int i = s1; i <= s2; i++) {
|
||||
pointsX.add(parent.pointsX.get(i));
|
||||
pointsY.add(parent.pointsY.get(i));
|
||||
indexedPoints.registerObjectXY(parent.pointsX.get(i), parent.pointsY.get(i), pointsX.size() - 1);
|
||||
tms[i - s1] = parent.tms[i] - parent.tms[s2];
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +144,7 @@ public class PrecalculatedRouteDirection {
|
|||
|
||||
public PrecalculatedRouteDirection adopt(RoutingContext ctx) {
|
||||
int ind1 = getIndex(ctx.startX, ctx.startY, ct1);
|
||||
int ind2 = getIndex(ctx.startX, ctx.startY, ct2);
|
||||
int ind2 = getIndex(ctx.targetX, ctx.targetY, ct2);
|
||||
if (ind1 < ind2) {
|
||||
PrecalculatedRouteDirection routeDirection = new PrecalculatedRouteDirection(this, ind1, ind2);
|
||||
routeDirection.preRegisterPoint(ctx.startX, ctx.startY);
|
||||
|
|
|
@ -90,10 +90,12 @@ public class RoutePlannerFrontEnd {
|
|||
ctx.calculationProgress = new RouteCalculationProgress();
|
||||
}
|
||||
boolean intermediatesEmpty = intermediates == null || intermediates.isEmpty();
|
||||
// TODO complex, progress, native, empty route, intermediates...
|
||||
// TODO native, empty route, intermediates...
|
||||
// + intermediates, + progress, +complex,
|
||||
PrecalculatedRouteDirection routeDirection = null;
|
||||
if(ctx.calculationMode == RouteCalculationMode.COMPLEX && intermediatesEmpty) {
|
||||
if(ctx.calculationMode == RouteCalculationMode.COMPLEX) {
|
||||
RoutingContext nctx = buildRoutingContext(ctx.config, ctx.nativeLib, ctx.getMaps(), RouteCalculationMode.BASE);
|
||||
nctx.calculationProgress = ctx.calculationProgress ;
|
||||
List<RouteSegmentResult> ls = searchRoute(nctx, start, end, intermediates);
|
||||
routeDirection = PrecalculatedRouteDirection.build(ls,
|
||||
5000, ctx.getRouter().getMaxDefaultSpeed() / 2);
|
||||
|
|
|
@ -13,6 +13,7 @@ import net.osmand.binary.RouteDataObject;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.router.BinaryRoutePlanner.FinalRouteSegment;
|
||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
public class RouteResultPreparation {
|
||||
|
@ -166,7 +167,7 @@ public class RouteResultPreparation {
|
|||
RouteSegmentResult res = new RouteSegmentResult(segment.road, parentSegmentStart, segment.getSegmentStart());
|
||||
parentSegmentStart = segment.getParentSegmentEnd();
|
||||
segment = segment.getParentRoute();
|
||||
addRouteSegmentToResult(result, res, false);
|
||||
addRouteSegmentToResult(ctx, result, res, false);
|
||||
}
|
||||
// reverse it just to attach good direction roads
|
||||
Collections.reverse(result);
|
||||
|
@ -179,7 +180,7 @@ public class RouteResultPreparation {
|
|||
parentSegmentEnd = segment.getParentSegmentEnd();
|
||||
segment = segment.getParentRoute();
|
||||
// happens in smart recalculation
|
||||
addRouteSegmentToResult(result, res, true);
|
||||
addRouteSegmentToResult(ctx, result, res, true);
|
||||
}
|
||||
Collections.reverse(result);
|
||||
|
||||
|
@ -187,11 +188,11 @@ public class RouteResultPreparation {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void addRouteSegmentToResult(List<RouteSegmentResult> result, RouteSegmentResult res, boolean reverse) {
|
||||
private void addRouteSegmentToResult(RoutingContext ctx, List<RouteSegmentResult> result, RouteSegmentResult res, boolean reverse) {
|
||||
if (res.getStartPointIndex() != res.getEndPointIndex()) {
|
||||
if (result.size() > 0) {
|
||||
RouteSegmentResult last = result.get(result.size() - 1);
|
||||
if (last.getObject().id == res.getObject().id) {
|
||||
if (last.getObject().id == res.getObject().id && ctx.calculationMode != RouteCalculationMode.BASE) {
|
||||
if (combineTwoSegmentResult(res, last, reverse)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -168,6 +168,10 @@ public class RouteSegmentResult {
|
|||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return object.toString() + " : " + startPointIndex + "-" + endPointIndex;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,13 +4,11 @@ package net.osmand.router;
|
|||
import gnu.trove.iterator.TIntObjectIterator;
|
||||
import gnu.trove.iterator.TLongIterator;
|
||||
import gnu.trove.map.TLongObjectMap;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
import gnu.trove.set.hash.TLongHashSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
|
@ -19,21 +17,19 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.NativeLibrary;
|
||||
import net.osmand.NativeLibrary.NativeRouteSearchResult;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||
import net.osmand.binary.RouteDataBorderLinePoint;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.router.BinaryRoutePlanner.FinalRouteSegment;
|
||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
||||
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -47,7 +43,6 @@ public class RoutingContext {
|
|||
public static final int OPTION_NO_LOAD = 0;
|
||||
public static final int OPTION_SMART_LOAD = 1;
|
||||
public static final int OPTION_IN_MEMORY_LOAD = 2;
|
||||
public static boolean USE_BORDER_LINES = false;
|
||||
// Final context variables
|
||||
public final RoutingConfiguration config;
|
||||
public final RouteCalculationMode calculationMode;
|
||||
|
@ -73,11 +68,6 @@ public class RoutingContext {
|
|||
TLongObjectHashMap<List<RoutingSubregionTile>> indexedSubregions = new TLongObjectHashMap<List<RoutingSubregionTile>>();
|
||||
TLongObjectHashMap<List<RouteDataObject>> tileRoutes = new TLongObjectHashMap<List<RouteDataObject>>();
|
||||
|
||||
RouteDataBorderLine[] borderLines = new RouteDataBorderLine[0];
|
||||
int[] borderLineCoordinates = new int[0];
|
||||
int leftBorderBoundary;
|
||||
int rightBorderBoundary;
|
||||
|
||||
// Needs to be a sorted array list . Another option to use hashmap but it will be more memory expensive
|
||||
List<RoutingSubregionTile> subregionTiles = new ArrayList<RoutingSubregionTile>();
|
||||
|
||||
|
@ -290,105 +280,8 @@ public class RoutingContext {
|
|||
System.out.println("Size of data objects " + dataObjects.size());
|
||||
}
|
||||
|
||||
public void loadBorderPoints() throws IOException {
|
||||
Iterator<Entry<RouteRegion, BinaryMapIndexReader>> it = reverseMap.entrySet().iterator();
|
||||
int sleft = Math.min(startX, targetX);
|
||||
int sright= Math.max(startX, targetX);
|
||||
int stop = Math.min(startY, targetY);
|
||||
int sbottom= Math.max(startY, targetY);
|
||||
// one tile of 12th zoom around (?)
|
||||
int zoomAround = 10;
|
||||
int distAround = 1 << (31 - zoomAround);
|
||||
leftBorderBoundary = sleft - distAround;
|
||||
rightBorderBoundary = sright + distAround;
|
||||
SearchRequest<RouteDataBorderLinePoint> req = BinaryMapIndexReader.buildSearchRouteBorderRequest(sleft, sright, stop, sbottom);
|
||||
while(it.hasNext()) {
|
||||
Entry<RouteRegion, BinaryMapIndexReader> entry = it.next();
|
||||
entry.getValue().searchBorderPoints(req, entry.getKey());
|
||||
}
|
||||
TIntObjectHashMap<RouteDataBorderLine> lines = new TIntObjectHashMap<RoutingContext.RouteDataBorderLine>();
|
||||
for(RouteDataBorderLinePoint p : req.getSearchResults()) {
|
||||
if(config.router.acceptLine(p) && p.x > leftBorderBoundary && p.x < rightBorderBoundary) {
|
||||
if(!lines.containsKey(p.y)) {
|
||||
RouteDataBorderLine line = new RouteDataBorderLine(p.y);
|
||||
lines.put(p.y, line);
|
||||
RouteDataBorderLinePoint lft = new RouteDataBorderLinePoint(p.region);
|
||||
lft.y = p.y;
|
||||
lft.id = Long.MIN_VALUE;
|
||||
lft.x = leftBorderBoundary;
|
||||
line.borderPoints.add(lft);
|
||||
RouteDataBorderLinePoint rht = new RouteDataBorderLinePoint(p.region);
|
||||
rht.y = p.y;
|
||||
rht.id = Long.MIN_VALUE;
|
||||
rht.x = rightBorderBoundary;
|
||||
line.borderPoints.add(rht);
|
||||
}
|
||||
lines.get(p.y).borderPoints.add(p);
|
||||
}
|
||||
}
|
||||
borderLines = lines.values(new RouteDataBorderLine[lines.size()]);
|
||||
Arrays.sort(borderLines);
|
||||
borderLineCoordinates = new int[borderLines.length];
|
||||
for(int i=0; i<borderLineCoordinates.length; i++) {
|
||||
borderLineCoordinates[i] = borderLines[i].borderLine;
|
||||
// FIXME borders approach
|
||||
// not less then 14th zoom
|
||||
if(i > 0 && borderLineCoordinates[i - 1] >> 17 == borderLineCoordinates[i] >> 17) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
System.out.println("Line " + (borderLineCoordinates[i] >> 17) +
|
||||
" points " + borderLines[i].borderPoints.size() /* + " " +borderLines[i].borderPoints*/);
|
||||
}
|
||||
|
||||
updateDistanceForBorderPoints(startX, startY, true);
|
||||
updateDistanceForBorderPoints(targetX, targetY, false);
|
||||
|
||||
}
|
||||
|
||||
protected void updateDistanceForBorderPoints(int sX, int sy, boolean distanceToStart) {
|
||||
boolean plus = borderLines.length > 0 && sy < borderLines[0].borderLine;
|
||||
if(borderLines.length > 0 && !plus && sy< borderLines[borderLines.length - 1].borderLine){
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
// calculate min distance to start
|
||||
for(int i=0; i<borderLines.length; i++) {
|
||||
int ind = plus ? i : borderLines.length - i - 1;
|
||||
for(RouteDataBorderLinePoint ps : borderLines[ind].borderPoints){
|
||||
float res = (float) Math.sqrt(MapUtils.squareDist31TileMetric(sX, sy, ps.x, ps.y)) ;
|
||||
if(i > 0){
|
||||
int prevInd = plus ? i - 1 : borderLines.length - i;
|
||||
double minDist = 0;
|
||||
for(RouteDataBorderLinePoint prevs : borderLines[prevInd].borderPoints){
|
||||
double d = Math.sqrt(MapUtils.squareDist31TileMetric(prevs.x, prevs.y, ps.x, ps.y)) +
|
||||
(distanceToStart? prevs.distanceToStartPoint : prevs.distanceToEndPoint);
|
||||
if(minDist == 0 || d < minDist) {
|
||||
minDist = d;
|
||||
}
|
||||
}
|
||||
if (minDist > 0) {
|
||||
System.out.println("Border line " + i + " exp="+res + " min="+ minDist);
|
||||
res = (float) minDist;
|
||||
}
|
||||
}
|
||||
if(distanceToStart){
|
||||
ps.distanceToStartPoint = res;
|
||||
} else {
|
||||
ps.distanceToEndPoint = res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// returns from 0 to borderLineCoordinates.length inclusive
|
||||
public int searchBorderLineIndex(int y) {
|
||||
int k = Arrays.binarySearch(borderLineCoordinates, y);
|
||||
if( k < 0) {
|
||||
k = -(k + 1);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
public RouteSegment loadRouteSegment(int x31, int y31, int memoryLimit) {
|
||||
long tileId = getRoutingTile(x31, y31, memoryLimit, OPTION_SMART_LOAD);
|
||||
TLongObjectHashMap<RouteDataObject> excludeDuplications = new TLongObjectHashMap<RouteDataObject>();
|
||||
|
@ -902,24 +795,6 @@ public class RoutingContext {
|
|||
|
||||
}
|
||||
|
||||
protected static class RouteDataBorderLine implements Comparable<RouteDataBorderLine>{
|
||||
final List<RouteDataBorderLinePoint> borderPoints = new ArrayList<RouteDataBorderLinePoint>();
|
||||
final int borderLine;
|
||||
|
||||
public RouteDataBorderLine(int borderLine) {
|
||||
this.borderLine = borderLine;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(RouteDataBorderLine o) {
|
||||
if(o.borderLine == borderLine) {
|
||||
return 0;
|
||||
}
|
||||
return borderLine < o.borderLine? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
public BinaryMapIndexReader[] getMaps() {
|
||||
return map.keySet().toArray(new BinaryMapIndexReader[map.size()]);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ public class RouteCalculationParams {
|
|||
public GPXRouteParams gpxRoute;
|
||||
public RouteCalculationResult previousToRecalculate;
|
||||
public boolean fast;
|
||||
public boolean optimal;
|
||||
public boolean leftSide;
|
||||
public RouteCalculationProgress calculationProgress;
|
||||
public boolean preciseRouting;
|
||||
|
|
|
@ -419,14 +419,10 @@ public class RouteProvider {
|
|||
RoutingConfiguration cf = config.build(p.name().toLowerCase(), params.start.hasBearing() ?
|
||||
params.start.getBearing() / 180d * Math.PI : null,
|
||||
memoryLimit, specialization);
|
||||
if(!params.optimal){
|
||||
cf.heuristicCoefficient *= 1.5;
|
||||
// native use
|
||||
cf.attributes.put("heuristicCoefficient", cf.heuristicCoefficient+"");
|
||||
}
|
||||
RoutingContext ctx = router.buildRoutingContext(cf, params.ctx.getInternalAPI().getNativeLibrary(), files,
|
||||
params.mode.isDerivedRoutingFrom(ApplicationMode.CAR) ?
|
||||
RouteCalculationMode.COMPLEX : RouteCalculationMode.NORMAL);
|
||||
// TODO introduce
|
||||
/*params.mode.isDerivedRoutingFrom(ApplicationMode.CAR) ?
|
||||
RouteCalculationMode.COMPLEX : */RouteCalculationMode.NORMAL);
|
||||
ctx.calculationProgress = params.calculationProgress;
|
||||
if(params.previousToRecalculate != null) {
|
||||
ctx.previouslyCalculatedRoute = params.previousToRecalculate.getOriginalRoute();
|
||||
|
|
|
@ -761,7 +761,6 @@ public class RoutingHelper {
|
|||
params.previousToRecalculate = previousRoute;
|
||||
params.leftSide = settings.DRIVING_REGION.get().leftHandDriving;
|
||||
params.preciseRouting = settings.PRECISE_ROUTING_MODE.getModeValue(mode);
|
||||
params.optimal = settings.OPTIMAL_ROUTE_MODE.getModeValue(mode);
|
||||
params.fast = settings.FAST_ROUTE_MODE.getModeValue(mode);
|
||||
params.type = settings.ROUTER_SERVICE.getModeValue(mode);
|
||||
params.mode = mode;
|
||||
|
|
Loading…
Reference in a new issue