Fix critical issue native routing

This commit is contained in:
Victor Shcherb 2012-07-11 19:49:51 +02:00
parent 1c0c25db38
commit 83966b070f
4 changed files with 67 additions and 9 deletions

View file

@ -43,6 +43,8 @@ public class BinaryRoutePlanner {
protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class); protected static final Log log = LogUtil.getLog(BinaryRoutePlanner.class);
private static final int ROUTE_POINTS = 11;
public BinaryRoutePlanner(NativeLibrary nativeLib, BinaryMapIndexReader... map) { public BinaryRoutePlanner(NativeLibrary nativeLib, BinaryMapIndexReader... map) {
this.nativeLib = nativeLib; this.nativeLib = nativeLib;
@ -175,7 +177,7 @@ public class BinaryRoutePlanner {
ctx.visitedSegments = 0; ctx.visitedSegments = 0;
ctx.timeToCalculate = System.nanoTime(); ctx.timeToCalculate = System.nanoTime();
if(ctx.config.initialDirection != null) { if(ctx.config.initialDirection != null) {
ctx.firstRoadId = (start.getRoad().id << 8) + start.getSegmentStart(); ctx.firstRoadId = (start.getRoad().id << ROUTE_POINTS) + start.getSegmentStart();
double plusDir = start.getRoad().directionRoute(start.segmentStart, true); double plusDir = start.getRoad().directionRoute(start.segmentStart, true);
double diff = plusDir - ctx.config.initialDirection; double diff = plusDir - ctx.config.initialDirection;
if(Math.abs(MapUtils.alignAngleDifference(diff)) <= Math.PI / 3) { if(Math.abs(MapUtils.alignAngleDifference(diff)) <= Math.PI / 3) {
@ -208,6 +210,23 @@ public class BinaryRoutePlanner {
TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>(); TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>();
TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>(); TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>();
if(ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() >0) {
RouteSegment previous = null;
int previousSegmentEnd = 0;
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
RouteSegment segment = new RouteSegment(rr.getObject(), rr.getEndPointIndex());
if(previous != null) {
segment.parentRoute = previous;
segment.parentSegmentEnd = previousSegmentEnd;
}
previous = segment;
previousSegmentEnd = rr.getStartPointIndex();
long t = rr.getObject().getId() << ROUTE_POINTS + rr.getEndPointIndex();
visitedOppositeSegments.put(t, segment);
}
end = previous;
}
// for start : f(start) = g(start) + h(start) = 0 + h(start) = h(start) // for start : f(start) = g(start) + h(start) = 0 + h(start) = h(start)
int targetEndX = end.road.getPoint31XTile(end.segmentStart); int targetEndX = end.road.getPoint31XTile(end.segmentStart);
int targetEndY = end.road.getPoint31YTile(end.segmentStart); int targetEndY = end.road.getPoint31YTile(end.segmentStart);
@ -247,7 +266,9 @@ public class BinaryRoutePlanner {
if (graphReverseSegments.isEmpty() || graphDirectSegments.isEmpty() || routeFound) { if (graphReverseSegments.isEmpty() || graphDirectSegments.isEmpty() || routeFound) {
break; break;
} }
if (!init) { if(ctx.previouslyCalculatedRoute != null){
// nothing change
} else if (!init) {
inverse = !inverse; inverse = !inverse;
init = true; init = true;
} else if (ctx.planRouteIn2Directions()) { } else if (ctx.planRouteIn2Directions()) {
@ -543,7 +564,7 @@ public class BinaryRoutePlanner {
double obstacleMinusTime = 0; double obstacleMinusTime = 0;
// 0. mark route segment as visited // 0. mark route segment as visited
long nt = (road.getId() << 8l) + middle; long nt = (road.getId() << 11l) + middle;
// avoid empty segments to connect but mark the point as visited // avoid empty segments to connect but mark the point as visited
visitedSegments.put(nt, null); visitedSegments.put(nt, null);
@ -600,7 +621,7 @@ public class BinaryRoutePlanner {
} }
// if we found end point break cycle // if we found end point break cycle
long nts = (road.getId() << 8l) + segmentEnd; long nts = (road.getId() << ROUTE_POINTS) + segmentEnd;
visitedSegments.put(nts, segment); visitedSegments.put(nts, segment);
// 2. calculate point and try to load neighbor ways if they are not loaded // 2. calculate point and try to load neighbor ways if they are not loaded
@ -757,7 +778,7 @@ public class BinaryRoutePlanner {
if(nextIterator != null) { if(nextIterator != null) {
next = nextIterator.next(); next = nextIterator.next();
} }
long nts = (next.road.getId() << 8l) + next.segmentStart; long nts = (next.road.getId() << ROUTE_POINTS) + next.segmentStart;
// 1. Check if opposite segment found so we can stop calculations // 1. Check if opposite segment found so we can stop calculations
if (oppositeSegments.contains(nts) && oppositeSegments.get(nts) != null) { if (oppositeSegments.contains(nts) && oppositeSegments.get(nts) != null) {

View file

@ -9,6 +9,7 @@ import gnu.trove.set.hash.TLongHashSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import net.osmand.binary.RouteDataObject; import net.osmand.binary.RouteDataObject;
import net.osmand.router.BinaryRoutePlanner.RouteSegment; import net.osmand.router.BinaryRoutePlanner.RouteSegment;
@ -25,6 +26,8 @@ public class RoutingContext {
public long firstRoadId = 0; public long firstRoadId = 0;
public int firstRoadDirection = 0;; public int firstRoadDirection = 0;;
public List<RouteSegmentResult> previouslyCalculatedRoute;
// 2. Routing memory cache (big objects) // 2. Routing memory cache (big objects)
TIntObjectHashMap<RoutingTile> tiles = new TIntObjectHashMap<RoutingContext.RoutingTile>(); TIntObjectHashMap<RoutingTile> tiles = new TIntObjectHashMap<RoutingContext.RoutingTile>();

View file

@ -74,6 +74,8 @@ public class MapRouterLayer implements MapPanelLayer {
private JButton playPauseButton; private JButton playPauseButton;
private JButton stopButton; private JButton stopButton;
private List<RouteSegmentResult> previousRoute;
@Override @Override
public void destroyLayer() { public void destroyLayer() {
@ -172,7 +174,36 @@ public class MapRouterLayer implements MapPanelLayer {
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
List<Way> ways = selfRoute(startRoute, endRoute); List<Way> ways = selfRoute(startRoute, endRoute, null);
if (ways != null) {
DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11);
for (Way w : ways) {
LatLon n = w.getLatLon();
points.registerObject(n.getLatitude(), n.getLongitude(), w);
}
map.setPoints(points);
}
}
}.start();
}
};
Action recalculate = new AbstractAction("Recalculate OsmAnd route") {
private static final long serialVersionUID = 507156107455281238L;
@Override
public boolean isEnabled() {
// return previousRoute != null;
return true;
}
@Override
public void actionPerformed(ActionEvent e) {
new Thread() {
@Override
public void run() {
List<Way> ways = selfRoute(startRoute, endRoute, previousRoute);
if (ways != null) { if (ways != null) {
DataTileManager<Way> points = new DataTileManager<Way>(); DataTileManager<Way> points = new DataTileManager<Way>();
points.setZoom(11); points.setZoom(11);
@ -188,6 +219,7 @@ public class MapRouterLayer implements MapPanelLayer {
}; };
menu.add(selfRoute); menu.add(selfRoute);
menu.add(recalculate);
Action route_YOURS = new AbstractAction("Calculate YOURS route") { Action route_YOURS = new AbstractAction("Calculate YOURS route") {
private static final long serialVersionUID = 507156107455281238L; private static final long serialVersionUID = 507156107455281238L;
@ -507,7 +539,7 @@ public class MapRouterLayer implements MapPanelLayer {
return res; return res;
} }
public List<Way> selfRoute(LatLon start, LatLon end) { public List<Way> selfRoute(LatLon start, LatLon end, List<RouteSegmentResult> previousRoute) {
List<Way> res = new ArrayList<Way>(); List<Way> res = new ArrayList<Way>();
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
List<File> files = new ArrayList<File>(); List<File> files = new ArrayList<File>();
@ -556,6 +588,7 @@ public class MapRouterLayer implements MapPanelLayer {
BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs); BinaryRoutePlanner router = new BinaryRoutePlanner(NativeSwingRendering.getDefaultFromSettings(), rs);
RoutingConfiguration config = builder.build(m, true); RoutingConfiguration config = builder.build(m, true);
RoutingContext ctx = new RoutingContext(config); RoutingContext ctx = new RoutingContext(config);
ctx.previouslyCalculatedRoute = previousRoute;
log.info("Use " + config.routerName + "mode for routing"); log.info("Use " + config.routerName + "mode for routing");
// int dir = DataExtractionSettings.getSettings().getRouteDirection(); // int dir = DataExtractionSettings.getSettings().getRouteDirection();
@ -631,6 +664,7 @@ public class MapRouterLayer implements MapPanelLayer {
}); });
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, false); List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, false);
previousRoute = searchRoute;
if (animateRoutingCalculation) { if (animateRoutingCalculation) {
playPauseButton.setVisible(false); playPauseButton.setVisible(false);
nextTurn.setText("FINISH"); nextTurn.setText("FINISH");

View file

@ -441,8 +441,8 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_loadRout
RoutingIndex ind; RoutingIndex ind;
ind.filePointer = filepointer; ind.filePointer = filepointer;
ind.name = getString(ienv, regName); ind.name = getString(ienv, regName);
jclass jclIntArray = ienv->FindClass("[I"); jclass jclIntArray = findClass(ienv, "[I");
jclass jclstring = ienv->FindClass("Ljava/lang/String;"); jclass jclstring = findClass(ienv, "java/lang/String");
std::vector<RouteDataObject*> result; std::vector<RouteDataObject*> result;
SearchQuery q(left, right, top, bottom); SearchQuery q(left, right, top, bottom);