Fix critical issue native routing
This commit is contained in:
parent
1c0c25db38
commit
83966b070f
4 changed files with 67 additions and 9 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue