Update router
This commit is contained in:
parent
f55dd373c4
commit
195655dc19
11 changed files with 218 additions and 143 deletions
|
@ -5,7 +5,6 @@ import gnu.trove.list.array.TIntArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||||
|
@ -99,9 +98,9 @@ public class BicycleRouter extends VehicleRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getRoadPriorityToCalculateRoute(RouteDataObject road) {
|
public double getFutureRoadPriority(RouteDataObject road) {
|
||||||
String highway = getHighway(road);
|
String highway = getHighway(road);
|
||||||
double priority = highway != null && bicyclePriorityValues.containsKey(highway) ? bicyclePriorityValues.get(highway) : 1d;
|
double priority = bicyclePriorityValues.containsKey(highway) ? bicyclePriorityValues.get(highway) : 1d;
|
||||||
return priority;
|
return priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,13 +109,18 @@ public class BicycleRouter extends VehicleRouter {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public double defineSpeed(RouteDataObject road) {
|
public double defineSpeed(RouteDataObject road) {
|
||||||
String highway = getHighway(road);
|
Double value = bicycleNotDefinedValues.get(getHighway(road));
|
||||||
double priority = highway != null && bicyclePriorityValues.containsKey(highway) ? bicyclePriorityValues.get(highway) : 0.5d;
|
|
||||||
Double value = bicycleNotDefinedValues.get(highway);
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = 4d;
|
value = 4d;
|
||||||
}
|
}
|
||||||
return value / 3.6d * priority;
|
return value / 3.6d ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double defineSpeedPriority(RouteDataObject road) {
|
||||||
|
String highway = getHighway(road);
|
||||||
|
double priority = bicyclePriorityValues.containsKey(highway) ? bicyclePriorityValues.get(highway) : 0.5d;
|
||||||
|
return priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import net.osmand.binary.BinaryMapRouteReaderAdapter;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||||
import net.osmand.osm.LatLon;
|
|
||||||
import net.osmand.osm.MapRenderingTypes;
|
import net.osmand.osm.MapRenderingTypes;
|
||||||
import net.osmand.osm.MapUtils;
|
import net.osmand.osm.MapUtils;
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
|
protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
|
||||||
|
|
||||||
public BinaryRoutePlanner(BinaryMapIndexReader... map) {
|
public BinaryRoutePlanner(BinaryMapIndexReader... map) {
|
||||||
for (BinaryMapIndexReader mr : map) {
|
for (BinaryMapIndexReader mr : map) {
|
||||||
|
@ -146,7 +145,7 @@ public class BinaryRoutePlanner {
|
||||||
* return list of segments
|
* return list of segments
|
||||||
*/
|
*/
|
||||||
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end) throws IOException {
|
public List<RouteSegmentResult> searchRoute(final RoutingContext ctx, RouteSegment start, RouteSegment end) throws IOException {
|
||||||
|
boolean relaxingStrategy = true;
|
||||||
// measure time
|
// measure time
|
||||||
ctx.timeToLoad = 0;
|
ctx.timeToLoad = 0;
|
||||||
ctx.visitedSegments = 0;
|
ctx.visitedSegments = 0;
|
||||||
|
@ -197,6 +196,10 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
while (!graphSegments.isEmpty()) {
|
while (!graphSegments.isEmpty()) {
|
||||||
RouteSegment segment = graphSegments.poll();
|
RouteSegment segment = graphSegments.poll();
|
||||||
|
|
||||||
|
if(relaxingStrategy) {
|
||||||
|
relaxNotNeededSegments(ctx, graphSegments, segment);
|
||||||
|
}
|
||||||
|
|
||||||
ctx.visitedSegments++;
|
ctx.visitedSegments++;
|
||||||
// for debug purposes
|
// for debug purposes
|
||||||
|
@ -219,10 +222,12 @@ public class BinaryRoutePlanner {
|
||||||
init = true;
|
init = true;
|
||||||
} else if (ctx.planRouteIn2Directions()) {
|
} else if (ctx.planRouteIn2Directions()) {
|
||||||
inverse = nonHeuristicSegmentsComparator.compare(graphDirectSegments.peek(), graphReverseSegments.peek()) > 0;
|
inverse = nonHeuristicSegmentsComparator.compare(graphDirectSegments.peek(), graphReverseSegments.peek()) > 0;
|
||||||
if (graphDirectSegments.size() * 1.3 > graphReverseSegments.size()) {
|
if (!relaxingStrategy) {
|
||||||
inverse = true;
|
if (graphDirectSegments.size() * 1.3 > graphReverseSegments.size()) {
|
||||||
} else if (graphDirectSegments.size() < 1.3 * graphReverseSegments.size()) {
|
inverse = true;
|
||||||
inverse = false;
|
} else if (graphDirectSegments.size() < 1.3 * graphReverseSegments.size()) {
|
||||||
|
inverse = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// different strategy : use onedirectional graph
|
// different strategy : use onedirectional graph
|
||||||
|
@ -234,7 +239,7 @@ public class BinaryRoutePlanner {
|
||||||
graphSegments = graphDirectSegments;
|
graphSegments = graphDirectSegments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printDebugMemoryInformation(ctx, graphDirectSegments, graphReverseSegments, visitedDirectSegments, visitedOppositeSegments);
|
||||||
|
|
||||||
// 4. Route is found : collect all segments and prepare result
|
// 4. Route is found : collect all segments and prepare result
|
||||||
return prepareResult(ctx, startNanoTime);
|
return prepareResult(ctx, startNanoTime);
|
||||||
|
@ -242,6 +247,34 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, RouteSegment currentSegment) {
|
||||||
|
int before = graphSegments.size();
|
||||||
|
if(before > 100) {
|
||||||
|
double maxd = currentSegment.distanceFromStart;
|
||||||
|
double mine = currentSegment.distanceToEnd;
|
||||||
|
Iterator<RouteSegment> iterator = graphSegments.iterator();
|
||||||
|
while(iterator.hasNext()){
|
||||||
|
RouteSegment s = iterator.next();
|
||||||
|
if(s.distanceToEnd < mine){
|
||||||
|
maxd = s.distanceFromStart;
|
||||||
|
mine = s.distanceToEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double d = maxd / 2;
|
||||||
|
iterator = graphSegments.iterator();
|
||||||
|
while(iterator.hasNext()){
|
||||||
|
RouteSegment s = iterator.next();
|
||||||
|
if(s.distanceFromStart < d){
|
||||||
|
ctx.relaxedSegments++;
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int after = graphSegments.size();
|
||||||
|
println("Relaxing : before " + before +" after " + after);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private double h(final RoutingContext ctx, int targetEndX, int targetEndY,
|
private double h(final RoutingContext ctx, int targetEndX, int targetEndY,
|
||||||
int startX, int startY) {
|
int startX, int startY) {
|
||||||
double distance = squareRootDist(startX, startY, targetEndX, targetEndY);
|
double distance = squareRootDist(startX, startY, targetEndX, targetEndY);
|
||||||
|
@ -251,7 +284,7 @@ public class BinaryRoutePlanner {
|
||||||
protected static double h(RoutingContext ctx, double distToFinalPoint, RouteSegment next) {
|
protected static double h(RoutingContext ctx, double distToFinalPoint, RouteSegment next) {
|
||||||
double result = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed();
|
double result = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed();
|
||||||
if(ctx.isUseDynamicRoadPrioritising() && next != null){
|
if(ctx.isUseDynamicRoadPrioritising() && next != null){
|
||||||
double priority = ctx.getRouter().getRoadPriorityToCalculateRoute(next.road);
|
double priority = ctx.getRouter().getFutureRoadPriority(next.road);
|
||||||
result /= priority;
|
result /= priority;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -295,6 +328,26 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void println(String logMsg) {
|
||||||
|
// log.info(logMsg);
|
||||||
|
System.out.println(logMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printDebugMemoryInformation(RoutingContext ctx,
|
||||||
|
PriorityQueue<RouteSegment> graphDirectSegments, PriorityQueue<RouteSegment> graphReverseSegments,
|
||||||
|
TLongObjectHashMap<RouteSegment> visitedDirectSegments, TLongObjectHashMap<RouteSegment> visitedOppositeSegments){
|
||||||
|
println("Time to calculate : " + ctx.timeToCalculate / 1e6 +", time to load : " + ctx.timeToLoad / 1e6 );
|
||||||
|
println("Loaded tiles : " + ctx.loadedTiles.size() + ", visited roads " + ctx.visitedSegments);
|
||||||
|
println("Relaxed roads: " + ctx.relaxedSegments);
|
||||||
|
if(graphDirectSegments != null && graphReverseSegments != null) {
|
||||||
|
println("Priority queues sizes : " + graphDirectSegments.size() +"/" + graphReverseSegments.size());
|
||||||
|
}
|
||||||
|
if(visitedDirectSegments != null && visitedOppositeSegments != null) {
|
||||||
|
println("Visited segments sizes: " + visitedDirectSegments.size() +"/" + visitedOppositeSegments.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void loadRoutes(final RoutingContext ctx, int tile31X, int tile31Y, final List<RouteDataObject> toFillIn) {
|
public void loadRoutes(final RoutingContext ctx, int tile31X, int tile31Y, final List<RouteDataObject> toFillIn) {
|
||||||
int zoomToLoad = 31 - ctx.getZoomToLoadTileWithRoads();
|
int zoomToLoad = 31 - ctx.getZoomToLoadTileWithRoads();
|
||||||
int tileX = tile31X >> zoomToLoad;
|
int tileX = tile31X >> zoomToLoad;
|
||||||
|
@ -424,9 +477,10 @@ public class BinaryRoutePlanner {
|
||||||
// Using A* routing algorithm
|
// Using A* routing algorithm
|
||||||
// g(x) - calculate distance to that point and calculate time
|
// g(x) - calculate distance to that point and calculate time
|
||||||
double distOnRoadToPass = squareRootDist(x, y, middlex, middley);
|
double distOnRoadToPass = squareRootDist(x, y, middlex, middley);
|
||||||
double speed = ctx.getRouter().defineSpeed(road);
|
double priority = ctx.getRouter().defineSpeedPriority(road);
|
||||||
|
double speed = ctx.getRouter().defineSpeed(road) * priority;
|
||||||
if (speed == 0) {
|
if (speed == 0) {
|
||||||
speed = ctx.getRouter().getMinDefaultSpeed();
|
speed = ctx.getRouter().getMinDefaultSpeed() * priority;
|
||||||
}
|
}
|
||||||
double distanceFromStart = segment.distanceFromStart + distOnRoadToPass / speed;
|
double distanceFromStart = segment.distanceFromStart + distOnRoadToPass / speed;
|
||||||
distanceFromStart += d > 0? obstaclePlusTime : obstacleMinusTime;
|
distanceFromStart += d > 0? obstaclePlusTime : obstacleMinusTime;
|
||||||
|
@ -589,7 +643,6 @@ public class BinaryRoutePlanner {
|
||||||
// next.distanceFromStart = gDistFromStart;
|
// next.distanceFromStart = gDistFromStart;
|
||||||
// next.parentRoute = segment;
|
// next.parentRoute = segment;
|
||||||
// next.parentSegmentEnd = segmentEnd;
|
// next.parentSegmentEnd = segmentEnd;
|
||||||
//
|
|
||||||
// if (ctx.visitor != null) {
|
// if (ctx.visitor != null) {
|
||||||
// ctx.visitor.visitSegment(next, false);
|
// ctx.visitor.visitSegment(next, false);
|
||||||
// }
|
// }
|
||||||
|
@ -643,7 +696,7 @@ public class BinaryRoutePlanner {
|
||||||
return String.format("s%.2f e%.2f", ((float)distanceFromStart), ((float)distanceToEnd));
|
return String.format("s%.2f e%.2f", ((float)distanceFromStart), ((float)distanceToEnd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to prepare final result
|
* Helper method to prepare final result
|
||||||
*/
|
*/
|
||||||
|
@ -652,40 +705,44 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
RouteSegment segment = ctx.finalReverseRoute;
|
RouteSegment segment = ctx.finalReverseRoute;
|
||||||
int parentSegmentStart = ctx.finalReverseEndSegment;
|
int parentSegmentStart = ctx.finalReverseEndSegment;
|
||||||
while(segment != null){
|
while (segment != null) {
|
||||||
RouteSegmentResult res = new RouteSegmentResult();
|
RouteSegmentResult res = new RouteSegmentResult(segment.road, parentSegmentStart, segment.segmentStart);
|
||||||
res.object = segment.road;
|
|
||||||
res.startPointIndex = segment.segmentStart;
|
|
||||||
res.endPointIndex = parentSegmentStart;
|
|
||||||
parentSegmentStart = segment.parentSegmentEnd;
|
parentSegmentStart = segment.parentSegmentEnd;
|
||||||
segment = segment.parentRoute;
|
segment = segment.parentRoute;
|
||||||
// do not add segments consists from 1 point
|
result.add(res);
|
||||||
if(res.startPointIndex != res.endPointIndex) {
|
|
||||||
result.add(res);
|
|
||||||
}
|
|
||||||
res.startPoint = convertPoint(res.object, res.startPointIndex);
|
|
||||||
res.endPoint = convertPoint(res.object, res.endPointIndex);
|
|
||||||
}
|
}
|
||||||
Collections.reverse(result);
|
Collections.reverse(result);
|
||||||
|
|
||||||
segment = ctx.finalDirectRoute;
|
segment = ctx.finalDirectRoute;
|
||||||
int parentSegmentEnd = ctx.finalDirectEndSegment;
|
int parentSegmentEnd = ctx.finalDirectEndSegment;
|
||||||
while(segment != null){
|
while (segment != null) {
|
||||||
RouteSegmentResult res = new RouteSegmentResult();
|
RouteSegmentResult res = new RouteSegmentResult(segment.road, segment.segmentStart, parentSegmentEnd);
|
||||||
res.object = segment.road;
|
|
||||||
res.startPointIndex = parentSegmentEnd;
|
|
||||||
res.endPointIndex = segment.segmentStart;
|
|
||||||
parentSegmentEnd = segment.parentSegmentEnd;
|
parentSegmentEnd = segment.parentSegmentEnd;
|
||||||
|
|
||||||
segment = segment.parentRoute;
|
segment = segment.parentRoute;
|
||||||
// do not add segments consists from 1 point
|
result.add(res);
|
||||||
if(res.startPointIndex != res.endPointIndex) {
|
}
|
||||||
result.add(res);
|
Collections.reverse(result);
|
||||||
}
|
// calculate time
|
||||||
res.startPoint = convertPoint(res.object, res.startPointIndex);
|
for (int i = 0; i < result.size(); i++) {
|
||||||
res.endPoint = convertPoint(res.object, res.endPointIndex);
|
RouteSegmentResult rr = result.get(i);
|
||||||
|
RouteDataObject road = rr.getObject();
|
||||||
|
double distOnRoadToPass = 0;
|
||||||
|
double speed = ctx.getRouter().defineSpeed(road);
|
||||||
|
if (speed == 0) {
|
||||||
|
speed = ctx.getRouter().getMinDefaultSpeed();
|
||||||
|
}
|
||||||
|
boolean plus = rr.getStartPointIndex() < rr.getEndPointIndex();
|
||||||
|
int next;
|
||||||
|
for (int j = rr.getStartPointIndex(); j != rr.getEndPointIndex(); j = next) {
|
||||||
|
next = plus ? j + 1 : j - 1;
|
||||||
|
double d = squareRootDist(road.getPoint31XTile(j), road.getPoint31YTile(j), road.getPoint31XTile(next),
|
||||||
|
road.getPoint31YTile(next));
|
||||||
|
distOnRoadToPass += d / speed + ctx.getRouter().defineObstacle(road, j);
|
||||||
|
}
|
||||||
|
// last point turn time can be added
|
||||||
|
// if(i + 1 < result.size()) { distOnRoadToPass += ctx.getRouter().calculateTurnTime(); }
|
||||||
|
rr.setSegmentTime((float) distOnRoadToPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST) {
|
if (PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST) {
|
||||||
System.out.println("ROUTE : ");
|
System.out.println("ROUTE : ");
|
||||||
|
@ -702,21 +759,16 @@ public class BinaryRoutePlanner {
|
||||||
if(ref != null) {
|
if(ref != null) {
|
||||||
name += " " + ref;
|
name += " " + ref;
|
||||||
}
|
}
|
||||||
System.out.println(MessageFormat.format("\t<segment id=\"{0}\" start=\"{1}\" end=\"{2}\" name=\"{3}\"/>",
|
System.out.println(MessageFormat.format("\t<segment id=\"{0}\" start=\"{1}\" end=\"{2}\" time=\"{4}\" name=\"{3}\"/>",
|
||||||
(res.object.getId())+"", res.startPointIndex, res.endPointIndex, name));
|
(res.getObject().getId())+"", res.getStartPointIndex()+"", res.getEndPointIndex()+"", name, res.getSegmentTime()));
|
||||||
}
|
}
|
||||||
System.out.println("</test>");
|
System.out.println("</test>");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.timeToCalculate = (System.nanoTime() - startNanoTime);
|
ctx.timeToCalculate = (System.nanoTime() - startNanoTime);
|
||||||
log.info("Time to calculate : " + ctx.timeToCalculate / 1e6 +", time to load : " + ctx.timeToLoad / 1e6 + ", loaded tiles : " + ctx.loadedTiles.size() +
|
|
||||||
", visited segments " + ctx.visitedSegments );
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LatLon convertPoint(RouteDataObject o, int ind){
|
|
||||||
return new LatLon(MapUtils.get31LatitudeY(o.getPoint31YTile(ind)), MapUtils.get31LongitudeX(o.getPoint31XTile(ind)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface RouteSegmentVisitor {
|
public interface RouteSegmentVisitor {
|
||||||
|
|
|
@ -74,36 +74,17 @@ public class CarRouter extends VehicleRouter {
|
||||||
for(int i=0; i<sz; i++) {
|
for(int i=0; i<sz; i++) {
|
||||||
RouteTypeRule r = reg.quickGetEncodingRule(pointTypes.getQuick(i));
|
RouteTypeRule r = reg.quickGetEncodingRule(pointTypes.getQuick(i));
|
||||||
if(r.getType() == RouteTypeRule.TRAFFIC_SIGNALS) {
|
if(r.getType() == RouteTypeRule.TRAFFIC_SIGNALS) {
|
||||||
return 20;
|
return 35;
|
||||||
} else if(r.getType() == RouteTypeRule.RAILWAY_CROSSING) {
|
} else if(r.getType() == RouteTypeRule.RAILWAY_CROSSING) {
|
||||||
return 25;
|
return 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getRoadPriorityHeuristicToIncrease(RouteDataObject road) {
|
|
||||||
String highway = getHighway(road);
|
|
||||||
double priority = highway !=null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
|
|
||||||
// allow to get out from motorway to primary roads
|
|
||||||
// if("motorway_link".equals(pair.value) || "trunk".equals(pair.value) ||
|
|
||||||
// "trunk_link".equals(pair.value) || "motorway".equals(pair.value)) {
|
|
||||||
// return 1.3d;
|
|
||||||
// } else
|
|
||||||
if(priority >= 1){
|
|
||||||
return 1;
|
|
||||||
} else if(priority >= 0.7){
|
|
||||||
return 0.7;
|
|
||||||
} else if(priority >= 0.5){
|
|
||||||
return 0.5;
|
|
||||||
} else {
|
|
||||||
return 0.3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getRoadPriorityToCalculateRoute(RouteDataObject road) {
|
public double getFutureRoadPriority(RouteDataObject road) {
|
||||||
String highway = getHighway(road);
|
String highway = getHighway(road);
|
||||||
double priority = highway != null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
|
double priority = highway != null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
|
||||||
// keep it in boundaries otherwise
|
// keep it in boundaries otherwise
|
||||||
|
@ -133,12 +114,19 @@ public class CarRouter extends VehicleRouter {
|
||||||
highway = r.highwayRoad();
|
highway = r.highwayRoad();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double priority = highway != null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
|
|
||||||
Double value = autoNotDefinedValues.get(highway);
|
Double value = autoNotDefinedValues.get(highway);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = 50d;
|
value = 45d;
|
||||||
}
|
}
|
||||||
return value / 3.6d * priority;
|
return value / 3.6d;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double defineSpeedPriority(RouteDataObject road) {
|
||||||
|
String highway = road.getHighway();
|
||||||
|
double priority = highway != null && autoPriorityValues.containsKey(highway) ? autoPriorityValues.get(highway) : 0.5d;
|
||||||
|
return priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,7 +136,7 @@ public class CarRouter extends VehicleRouter {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public double getMinDefaultSpeed() {
|
public double getMinDefaultSpeed() {
|
||||||
return 9;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,7 +191,7 @@ public class CarRouter extends VehicleRouter {
|
||||||
double a2 = directionRoute(next, next.segmentStart, true);
|
double a2 = directionRoute(next, next.segmentStart, true);
|
||||||
double diff = Math.abs(a1 - a2);
|
double diff = Math.abs(a1 - a2);
|
||||||
if (diff > Math.PI / 2 && diff < 3 * Math.PI / 2) {
|
if (diff > Math.PI / 2 && diff < 3 * Math.PI / 2) {
|
||||||
return 25;
|
return 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -5,7 +5,6 @@ import gnu.trove.list.array.TIntArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||||
|
@ -70,14 +69,21 @@ public class PedestrianRouter extends VehicleRouter {
|
||||||
pedestrianPriorityValues.put("services", 1d);
|
pedestrianPriorityValues.put("services", 1d);
|
||||||
pedestrianPriorityValues.put("steps", 1.2d);
|
pedestrianPriorityValues.put("steps", 1.2d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getFutureRoadPriority(RouteDataObject road) {
|
||||||
|
String highway = getHighway(road);
|
||||||
|
double priority = pedestrianPriorityValues.containsKey(highway) ? pedestrianPriorityValues.get(highway) : 1d;
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getRoadPriorityToCalculateRoute(RouteDataObject road) {
|
public double defineSpeedPriority(RouteDataObject road) {
|
||||||
String highway = getHighway(road);
|
String highway = getHighway(road);
|
||||||
double priority = highway!= null && pedestrianPriorityValues.containsKey(highway) ? pedestrianPriorityValues.get(highway) : 1d;
|
double priority = pedestrianPriorityValues.containsKey(highway) ? pedestrianPriorityValues.get(highway) : 1d;
|
||||||
return priority;
|
return priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int isOneWay(RouteDataObject road) {
|
public int isOneWay(RouteDataObject road) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -122,14 +128,13 @@ public class PedestrianRouter extends VehicleRouter {
|
||||||
public double defineSpeed(RouteDataObject road) {
|
public double defineSpeed(RouteDataObject road) {
|
||||||
double speed = 1.5d;
|
double speed = 1.5d;
|
||||||
String highway = getHighway(road);
|
String highway = getHighway(road);
|
||||||
double priority = highway != null && pedestrianPriorityValues.containsKey(highway) ? pedestrianPriorityValues.get(highway) : 1d;
|
|
||||||
if (highway != null) {
|
if (highway != null) {
|
||||||
Double value = pedestrianNotDefinedValues.get(highway);
|
Double value = pedestrianNotDefinedValues.get(highway);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
speed = value;
|
speed = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return speed * priority;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,12 +2,55 @@ package net.osmand.router;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteDataObject;
|
||||||
import net.osmand.osm.LatLon;
|
import net.osmand.osm.LatLon;
|
||||||
|
import net.osmand.osm.MapUtils;
|
||||||
|
|
||||||
|
|
||||||
public class RouteSegmentResult {
|
public class RouteSegmentResult {
|
||||||
public LatLon startPoint;
|
private RouteDataObject object;
|
||||||
public LatLon endPoint;
|
private int startPointIndex;
|
||||||
public RouteDataObject object;
|
private int endPointIndex;
|
||||||
public int startPointIndex;
|
private float segmentTime;
|
||||||
public int endPointIndex;
|
|
||||||
|
public RouteSegmentResult(RouteDataObject object, int startPointIndex, int endPointIndex) {
|
||||||
|
this.object = object;
|
||||||
|
this.startPointIndex = startPointIndex;
|
||||||
|
this.endPointIndex = endPointIndex;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteDataObject getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSegmentTime() {
|
||||||
|
return segmentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSegmentTime(float segmentTime) {
|
||||||
|
this.segmentTime = segmentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLon getStartPoint() {
|
||||||
|
return convertPoint(object, startPointIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStartPointIndex() {
|
||||||
|
return startPointIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndPointIndex() {
|
||||||
|
return endPointIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLon getPoint(int i) {
|
||||||
|
return convertPoint(object, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLon getEndPoint() {
|
||||||
|
return convertPoint(object, endPointIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LatLon convertPoint(RouteDataObject o, int ind){
|
||||||
|
return new LatLon(MapUtils.get31LatitudeY(o.getPoint31YTile(ind)), MapUtils.get31LongitudeX(o.getPoint31XTile(ind)));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -30,7 +30,7 @@ public class RoutingContext {
|
||||||
private boolean usingShortestWay = false;
|
private boolean usingShortestWay = false;
|
||||||
|
|
||||||
|
|
||||||
// 2. Routing memory cache
|
// 2. Routing memory cache (big objects)
|
||||||
TLongObjectMap<RouteSegment> routes = new TLongObjectHashMap<RouteSegment>();
|
TLongObjectMap<RouteSegment> routes = new TLongObjectHashMap<RouteSegment>();
|
||||||
TIntSet loadedTiles = new TIntHashSet();
|
TIntSet loadedTiles = new TIntHashSet();
|
||||||
// TODO delete this object ?
|
// TODO delete this object ?
|
||||||
|
@ -52,12 +52,12 @@ public class RoutingContext {
|
||||||
RouteSegment finalReverseRoute = null;
|
RouteSegment finalReverseRoute = null;
|
||||||
int finalReverseEndSegment = 0;
|
int finalReverseEndSegment = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 3. debug information (package accessor)
|
// 3. debug information (package accessor)
|
||||||
long timeToLoad = 0;
|
long timeToLoad = 0;
|
||||||
long timeToCalculate = 0;
|
long timeToCalculate = 0;
|
||||||
int visitedSegments = 0;
|
int visitedSegments = 0;
|
||||||
|
int relaxedSegments = 0;
|
||||||
// callback of processing segments
|
// callback of processing segments
|
||||||
RouteSegmentVisitor visitor = null;
|
RouteSegmentVisitor visitor = null;
|
||||||
|
|
||||||
|
|
|
@ -34,25 +34,11 @@ public abstract class VehicleRouter {
|
||||||
return road.getHighway();
|
return road.getHighway();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for algorithm of increasing road priorities (actually make sense only for car routing)
|
|
||||||
* other routers can increase/decrease road priorities in the middle of route
|
|
||||||
* @param road
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public double getRoadPriorityHeuristicToIncrease(RouteDataObject road) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for algorithm to estimate end distance
|
* Used for algorithm to multiply h(x) part A* based on current road
|
||||||
* @param road
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public double getRoadPriorityToCalculateRoute(RouteDataObject road) {
|
public abstract double getFutureRoadPriority(RouteDataObject road);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return delay in seconds
|
* return delay in seconds
|
||||||
|
@ -63,9 +49,14 @@ public abstract class VehicleRouter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return speed in m/s for vehicle
|
* return speed in m/s for vehicle for specified road
|
||||||
*/
|
*/
|
||||||
public abstract double defineSpeed(RouteDataObject road);
|
public abstract double defineSpeed(RouteDataObject road);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* define priority to multiply the speed for g(x) A*
|
||||||
|
*/
|
||||||
|
public abstract double defineSpeedPriority(RouteDataObject road);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for A* routing to calculate g(x)
|
* Used for A* routing to calculate g(x)
|
||||||
|
|
|
@ -119,17 +119,17 @@ public class RouterTestsSuite {
|
||||||
int expectedStart = Integer.parseInt(segment.getAttribute("start"));
|
int expectedStart = Integer.parseInt(segment.getAttribute("start"));
|
||||||
int expectedEnd = Integer.parseInt(segment.getAttribute("end"));
|
int expectedEnd = Integer.parseInt(segment.getAttribute("end"));
|
||||||
RouteSegmentResult segmentResult = route.get(i);
|
RouteSegmentResult segmentResult = route.get(i);
|
||||||
if (expectedId != segmentResult.object.getId() >> 1) {
|
if (expectedId != segmentResult.getObject().getId() >> 1) {
|
||||||
throw new IllegalArgumentException("Test : '" + testDescription + "' on segment " + (i + 1) + " : " + "\n"
|
throw new IllegalArgumentException("Test : '" + testDescription + "' on segment " + (i + 1) + " : " + "\n"
|
||||||
+ "(expected route id) " + expectedId + " != " + (segmentResult.object.getId() >> 1) + " (actual route id)");
|
+ "(expected route id) " + expectedId + " != " + (segmentResult.getObject().getId() >> 1) + " (actual route id)");
|
||||||
}
|
}
|
||||||
if (expectedStart != segmentResult.startPointIndex) {
|
if (expectedStart != segmentResult.getStartPointIndex()) {
|
||||||
throw new IllegalArgumentException("Test : '" + testDescription + "' on segment " + (i + 1) + " : " + "\n"
|
throw new IllegalArgumentException("Test : '" + testDescription + "' on segment " + (i + 1) + " : " + "\n"
|
||||||
+ "(expected start index) " + expectedStart + " != " + segmentResult.startPointIndex + " (actual start index)");
|
+ "(expected start index) " + expectedStart + " != " + segmentResult.getStartPointIndex() + " (actual start index)");
|
||||||
}
|
}
|
||||||
if (expectedEnd != segmentResult.endPointIndex) {
|
if (expectedEnd != segmentResult.getEndPointIndex()) {
|
||||||
throw new IllegalArgumentException("Test : '" + testDescription + "' on segment " + (i + 1) + " : " + "\n"
|
throw new IllegalArgumentException("Test : '" + testDescription + "' on segment " + (i + 1) + " : " + "\n"
|
||||||
+ "(expected end index) " + expectedEnd + " != " + segmentResult.endPointIndex + " (actual end index)");
|
+ "(expected end index) " + expectedEnd + " != " + segmentResult.getEndPointIndex() + " (actual end index)");
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -42,7 +42,6 @@ import net.osmand.router.CarRouter;
|
||||||
import net.osmand.router.PedestrianRouter;
|
import net.osmand.router.PedestrianRouter;
|
||||||
import net.osmand.router.RouteSegmentResult;
|
import net.osmand.router.RouteSegmentResult;
|
||||||
import net.osmand.router.RoutingContext;
|
import net.osmand.router.RoutingContext;
|
||||||
import net.osmand.router.VehicleRouter;
|
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||||
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
import net.osmand.router.BinaryRoutePlanner.RouteSegmentVisitor;
|
||||||
|
|
||||||
|
@ -546,7 +545,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
playPauseButton.setText("Play");
|
playPauseButton.setText("Play");
|
||||||
}
|
}
|
||||||
stop = false;
|
stop = false;
|
||||||
if(files == null){
|
if(files.isEmpty()){
|
||||||
JOptionPane.showMessageDialog(OsmExtractionUI.MAIN_APP.getFrame(), "Please specify obf file in settings", "Obf file not found",
|
JOptionPane.showMessageDialog(OsmExtractionUI.MAIN_APP.getFrame(), "Please specify obf file in settings", "Obf file not found",
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
return null;
|
return null;
|
||||||
|
@ -647,18 +646,10 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
// TODO delete this block after
|
|
||||||
net.osmand.osm.Node ns = createNode(st, st.getSegmentStart());
|
|
||||||
points.registerObject(ns.getLatitude(), ns.getLongitude(), ns);
|
|
||||||
ns = createNode(e, e.getSegmentStart());
|
|
||||||
points.registerObject(ns.getLatitude(), ns.getLongitude(), ns);
|
|
||||||
if (pause && animateRoutingCalculation) {
|
|
||||||
waitNextPress();
|
|
||||||
}
|
|
||||||
// TODO delete this block after
|
|
||||||
|
|
||||||
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e);
|
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e);
|
||||||
if (pause && animateRoutingCalculation) {
|
if (animateRoutingCalculation) {
|
||||||
|
playPauseButton.setVisible(false);
|
||||||
nextTurn.setText("FINISH");
|
nextTurn.setText("FINISH");
|
||||||
waitNextPress();
|
waitNextPress();
|
||||||
nextTurn.setText(">>");
|
nextTurn.setText(">>");
|
||||||
|
@ -667,20 +658,20 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
for (RouteSegmentResult s : searchRoute) {
|
for (RouteSegmentResult s : searchRoute) {
|
||||||
// double dist = MapUtils.getDistance(s.startPoint, s.endPoint);
|
// double dist = MapUtils.getDistance(s.startPoint, s.endPoint);
|
||||||
Way way = new Way(-1);
|
Way way = new Way(-1);
|
||||||
boolean plus = s.startPointIndex < s.endPointIndex;
|
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
|
||||||
int i = s.startPointIndex;
|
int i = s.getStartPointIndex();
|
||||||
while (true) {
|
while (true) {
|
||||||
net.osmand.osm.Node n = new net.osmand.osm.Node(MapUtils.get31LatitudeY(s.object.getPoint31YTile(i)), MapUtils
|
LatLon l = s.getPoint(i);
|
||||||
.get31LongitudeX(s.object.getPoint31XTile(i)), -1);
|
net.osmand.osm.Node n = new net.osmand.osm.Node(l.getLatitude(), l.getLongitude(), -1);
|
||||||
if (prevWayNode != null) {
|
if (prevWayNode != null) {
|
||||||
if (MapUtils.getDistance(prevWayNode, n) > 0) {
|
if (MapUtils.getDistance(prevWayNode, n) > 0) {
|
||||||
System.out.println("Warning not connected road " + " " + s.object.getHighway() + " dist "
|
System.out.println("Warning not connected road " + " " + s.getObject().getHighway() + " dist "
|
||||||
+ MapUtils.getDistance(prevWayNode, n));
|
+ MapUtils.getDistance(prevWayNode, n));
|
||||||
}
|
}
|
||||||
prevWayNode = null;
|
prevWayNode = null;
|
||||||
}
|
}
|
||||||
way.addNode(n);
|
way.addNode(n);
|
||||||
if (i == s.endPointIndex) {
|
if (i == s.getEndPointIndex()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (plus) {
|
if (plus) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class OsmExtractionPreferencesDialog extends JDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDialog(){
|
public void showDialog(){
|
||||||
setSize(700, 500);
|
setSize(700, 570);
|
||||||
double x = getParent().getBounds().getCenterX();
|
double x = getParent().getBounds().getCenterX();
|
||||||
double y = getParent().getBounds().getCenterY();
|
double y = getParent().getBounds().getCenterY();
|
||||||
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
|
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
|
||||||
|
@ -161,7 +161,7 @@ public class OsmExtractionPreferencesDialog extends JDialog {
|
||||||
constr.ipadx = 5;
|
constr.ipadx = 5;
|
||||||
constr.gridx = 1;
|
constr.gridx = 1;
|
||||||
constr.gridy = gridY++;
|
constr.gridy = gridY++;
|
||||||
l.setConstraints(directionPlanRoute, constr);
|
l.setConstraints(routingMode, constr);
|
||||||
|
|
||||||
label = new JLabel("Direction to plan route (0 - both, 1 - forward, -1 - backward) : ");
|
label = new JLabel("Direction to plan route (0 - both, 1 - forward, -1 - backward) : ");
|
||||||
panel.add(label);
|
panel.add(label);
|
||||||
|
|
|
@ -637,14 +637,15 @@ public class RouteProvider {
|
||||||
try {
|
try {
|
||||||
List<RouteSegmentResult> result = router.searchRoute(ctx, st, en);
|
List<RouteSegmentResult> result = router.searchRoute(ctx, st, en);
|
||||||
for (RouteSegmentResult s : result) {
|
for (RouteSegmentResult s : result) {
|
||||||
boolean plus = s.startPointIndex < s.endPointIndex;
|
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
|
||||||
int i = s.startPointIndex;
|
int i = s.getStartPointIndex();
|
||||||
while (true) {
|
while (true) {
|
||||||
Location n = new Location(""); //$NON-NLS-1$
|
Location n = new Location(""); //$NON-NLS-1$
|
||||||
n.setLatitude(MapUtils.get31LatitudeY(s.object.getPoint31YTile(i)));
|
LatLon point = s.getPoint(i);
|
||||||
n.setLongitude(MapUtils.get31LongitudeX(s.object.getPoint31XTile(i)));
|
n.setLatitude(point.getLatitude());
|
||||||
|
n.setLongitude(point.getLongitude());
|
||||||
res.add(n);
|
res.add(n);
|
||||||
if (i == s.endPointIndex) {
|
if (i == s.getEndPointIndex()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (plus) {
|
if (plus) {
|
||||||
|
|
Loading…
Reference in a new issue