Native routing
This commit is contained in:
parent
657a9b7d94
commit
7068dd3b61
18 changed files with 437 additions and 250 deletions
|
@ -109,7 +109,8 @@ public class NativeLibrary {
|
||||||
return closeBinaryMapFile(filePath);
|
return closeBinaryMapFile(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RouteSegmentResult[] runNativeRouting(int sx31, int sy31, int ex31, int ey31, RoutingConfiguration config) {
|
public RouteSegmentResult[] runNativeRouting(int sx31, int sy31, int ex31, int ey31, RoutingConfiguration config,
|
||||||
|
RouteRegion[] regions) {
|
||||||
TIntArrayList state = new TIntArrayList();
|
TIntArrayList state = new TIntArrayList();
|
||||||
List<String> keys = new ArrayList<String>();
|
List<String> keys = new ArrayList<String>();
|
||||||
List<String> values = new ArrayList<String>();
|
List<String> values = new ArrayList<String>();
|
||||||
|
@ -124,7 +125,8 @@ public class NativeLibrary {
|
||||||
fillObjects(state, keys, values, 5, attrs);
|
fillObjects(state, keys, values, 5, attrs);
|
||||||
|
|
||||||
return nativeRouting(new int[]{sx31, sy31, ex31, ey31}, state.toArray(), keys.toArray(new String[keys.size()]),
|
return nativeRouting(new int[]{sx31, sy31, ex31, ey31}, state.toArray(), keys.toArray(new String[keys.size()]),
|
||||||
values.toArray(new String[values.size()]));
|
values.toArray(new String[values.size()]), config.initialDirection == null ? -360 : config.initialDirection.floatValue(),
|
||||||
|
regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void fillObjects(TIntArrayList state, List<String> keys, List<String> values, int s, Map<String, T> map) {
|
public <T> void fillObjects(TIntArrayList state, List<String> keys, List<String> values, int s, Map<String, T> map) {
|
||||||
|
@ -156,7 +158,8 @@ public class NativeLibrary {
|
||||||
|
|
||||||
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
|
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
|
||||||
|
|
||||||
protected static native RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig);
|
protected static native RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig,
|
||||||
|
float initDirection, RouteRegion[] regions);
|
||||||
|
|
||||||
protected static native void deleteSearchResult(long searchResultHandle);
|
protected static native void deleteSearchResult(long searchResultHandle);
|
||||||
|
|
||||||
|
|
|
@ -845,7 +845,7 @@ public class BinaryMapRouteReaderAdapter {
|
||||||
RouteBorderLine ln = readBorderLine();
|
RouteBorderLine ln = readBorderLine();
|
||||||
if(ln.hasTox() && req.intersects(ln.getX(), ln.getY(), ln.getTox(), ln.getY())) {
|
if(ln.hasTox() && req.intersects(ln.getX(), ln.getY(), ln.getTox(), ln.getY())) {
|
||||||
blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
||||||
// FIXME
|
// FIXME borders approach
|
||||||
// } else if(ln.hasToy() && req.intersects(ln.getX(), ln.getY(), ln.getX(), ln.getToy())) {
|
// } else if(ln.hasToy() && req.intersects(ln.getX(), ln.getY(), ln.getX(), ln.getToy())) {
|
||||||
// blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
// blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class RouteDataObject {
|
||||||
|
|
||||||
public final RouteRegion region;
|
public final RouteRegion region;
|
||||||
// all these arrays supposed to be immutable!
|
// all these arrays supposed to be immutable!
|
||||||
// These feilds accessible from C++
|
// These fields accessible from C++
|
||||||
public int[] types;
|
public int[] types;
|
||||||
public int[] pointsX;
|
public int[] pointsX;
|
||||||
public int[] pointsY;
|
public int[] pointsY;
|
||||||
|
@ -213,6 +213,7 @@ public class RouteDataObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public double directionRoute(int startPoint, boolean plus) {
|
public double directionRoute(int startPoint, boolean plus) {
|
||||||
|
// same goes to C++
|
||||||
// Victor : the problem to put more than 5 meters that BinaryRoutePlanner will treat
|
// Victor : the problem to put more than 5 meters that BinaryRoutePlanner will treat
|
||||||
// 2 consequent Turn Right as UT and here 2 points will have same turn angle
|
// 2 consequent Turn Right as UT and here 2 points will have same turn angle
|
||||||
// So it should be fix in both places
|
// So it should be fix in both places
|
||||||
|
|
|
@ -422,6 +422,7 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
|
||||||
routeTree, false);
|
routeTree, false);
|
||||||
TLongObjectHashMap<BinaryFileReference> base = writeBinaryRouteIndexHeader(writer,
|
TLongObjectHashMap<BinaryFileReference> base = writeBinaryRouteIndexHeader(writer,
|
||||||
baserouteTree, true);
|
baserouteTree, true);
|
||||||
|
// FIXME borders should not be committed in master branch
|
||||||
// writeBorderBox(writer, routeBorders);
|
// writeBorderBox(writer, routeBorders);
|
||||||
// writeBorderBox(writer, baseRouteBorders);
|
// writeBorderBox(writer, baseRouteBorders);
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@ public class BinaryRoutePlanner {
|
||||||
int px = MapUtils.get31TileNumberX(lon);
|
int px = MapUtils.get31TileNumberX(lon);
|
||||||
int py = MapUtils.get31TileNumberY(lat);
|
int py = MapUtils.get31TileNumberY(lat);
|
||||||
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
||||||
ctx.loadTileData(px, py, 16, dataObjects);
|
ctx.loadTileData(px, py, 17, dataObjects);
|
||||||
if (dataObjects.isEmpty()) {
|
if (dataObjects.isEmpty()) {
|
||||||
ctx.loadTileData(px, py, 14, dataObjects);
|
ctx.loadTileData(px, py, 15, dataObjects);
|
||||||
}
|
}
|
||||||
RouteSegment road = null;
|
RouteSegment road = null;
|
||||||
double sdist = 0;
|
double sdist = 0;
|
||||||
|
@ -334,10 +334,6 @@ public class BinaryRoutePlanner {
|
||||||
graphSegments = graphDirectSegments;
|
graphSegments = graphDirectSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx.runRelaxingStrategy() ) {
|
|
||||||
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
|
||||||
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
|
||||||
}
|
|
||||||
// check if interrupted
|
// check if interrupted
|
||||||
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
||||||
throw new InterruptedException("Route calculation interrupted");
|
throw new InterruptedException("Route calculation interrupted");
|
||||||
|
@ -349,12 +345,12 @@ public class BinaryRoutePlanner {
|
||||||
|
|
||||||
|
|
||||||
private RouteSegment smartRecalculationEnabled(final RoutingContext ctx, TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
|
private RouteSegment smartRecalculationEnabled(final RoutingContext ctx, TLongObjectHashMap<RouteSegment> visitedOppositeSegments) {
|
||||||
boolean runRecalculation = ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() > 0;
|
boolean runRecalculation = ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() > 0
|
||||||
|
&& ctx.config.recalculateDistance != 0;
|
||||||
if (runRecalculation) {
|
if (runRecalculation) {
|
||||||
RouteSegment previous = null;
|
RouteSegment previous = null;
|
||||||
List<RouteSegmentResult> rlist = new ArrayList<RouteSegmentResult>();
|
List<RouteSegmentResult> rlist = new ArrayList<RouteSegmentResult>();
|
||||||
// always recalculate first 7 km
|
float distanceThreshold = ctx.config.recalculateDistance;
|
||||||
int distanceThreshold = 7000;
|
|
||||||
float threshold = 0;
|
float threshold = 0;
|
||||||
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
|
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
|
||||||
threshold += rr.getDistance();
|
threshold += rr.getDistance();
|
||||||
|
@ -489,16 +485,6 @@ public class BinaryRoutePlanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
double result = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed();
|
double result = distToFinalPoint / ctx.getRouter().getMaxDefaultSpeed();
|
||||||
if(ctx.isUseDynamicRoadPrioritising() && next != null){
|
|
||||||
double priority = ctx.getRouter().getFutureRoadPriority(next.road);
|
|
||||||
result /= priority;
|
|
||||||
int dist = ctx.getDynamicRoadPriorityDistance();
|
|
||||||
// only first N km-s count by dynamic priority
|
|
||||||
if(distToFinalPoint > dist && dist != 0){
|
|
||||||
result = (distToFinalPoint - dist) / ctx.getRouter().getMaxDefaultSpeed() +
|
|
||||||
dist / (ctx.getRouter().getMaxDefaultSpeed() * priority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (float) result;
|
return (float) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,6 +970,30 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Iterator<RouteSegment> getIterator() {
|
||||||
|
return new Iterator<BinaryRoutePlanner.RouteSegment>() {
|
||||||
|
RouteSegment next = RouteSegment.this;
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RouteSegment next() {
|
||||||
|
RouteSegment c = next;
|
||||||
|
if(next != null) {
|
||||||
|
next = next.next;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return next != null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class FinalRouteSegment extends RouteSegment {
|
static class FinalRouteSegment extends RouteSegment {
|
||||||
|
|
|
@ -5,12 +5,15 @@ import gnu.trove.map.hash.TLongObjectHashMap;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
import net.osmand.LogUtil;
|
import net.osmand.LogUtil;
|
||||||
|
import net.osmand.binary.BinaryMapRouteReaderAdapter;
|
||||||
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.osm.MapRenderingTypes;
|
import net.osmand.osm.MapRenderingTypes;
|
||||||
import net.osmand.osm.MapUtils;
|
import net.osmand.osm.MapUtils;
|
||||||
|
@ -73,9 +76,9 @@ public class BinaryRoutePlannerOld {
|
||||||
int px = MapUtils.get31TileNumberX(lon);
|
int px = MapUtils.get31TileNumberX(lon);
|
||||||
int py = MapUtils.get31TileNumberY(lat);
|
int py = MapUtils.get31TileNumberY(lat);
|
||||||
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
||||||
ctx.loadTileData(px, py, 16, dataObjects);
|
ctx.loadTileData(px, py, 17, dataObjects);
|
||||||
if (dataObjects.isEmpty()) {
|
if (dataObjects.isEmpty()) {
|
||||||
ctx.loadTileData(px, py, 14, dataObjects);
|
ctx.loadTileData(px, py, 15, dataObjects);
|
||||||
}
|
}
|
||||||
RouteSegment road = null;
|
RouteSegment road = null;
|
||||||
double sdist = 0;
|
double sdist = 0;
|
||||||
|
@ -201,17 +204,31 @@ public class BinaryRoutePlannerOld {
|
||||||
|
|
||||||
|
|
||||||
private List<RouteSegmentResult> searchRouteInternalPrepare(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
|
private List<RouteSegmentResult> searchRouteInternalPrepare(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
|
||||||
|
if (ctx.nativeLib != null) {
|
||||||
|
int ex31 = end.getRoad().getPoint31XTile(end.getSegmentStart());
|
||||||
|
int ey31 = end.getRoad().getPoint31YTile(end.getSegmentStart());
|
||||||
|
int sx31 = start.getRoad().getPoint31XTile(start.getSegmentStart());
|
||||||
|
int sy31 = start.getRoad().getPoint31YTile(start.getSegmentStart());
|
||||||
|
RouteRegion[] regions = ctx.reverseMap.keySet().toArray(new BinaryMapRouteReaderAdapter.RouteRegion[ctx.reverseMap.size()]);
|
||||||
|
RouteSegmentResult[] res = ctx.nativeLib.runNativeRouting(sx31, sy31, ex31, ey31, ctx.config, regions);
|
||||||
|
ArrayList<RouteSegmentResult> result = new ArrayList<RouteSegmentResult>(Arrays.asList(res));
|
||||||
|
|
||||||
|
return new RouteResultPreparation().prepareResult(ctx, leftSideNavigation, result);
|
||||||
|
} else {
|
||||||
// Split into 2 methods to let GC work in between
|
// Split into 2 methods to let GC work in between
|
||||||
searchRouteInternal(ctx, start, end, leftSideNavigation);
|
searchRouteInternal(ctx, start, end);
|
||||||
// 4. Route is found : collect all segments and prepare result
|
// 4. Route is found : collect all segments and prepare result
|
||||||
return new RouteResultPreparation().prepareResult(ctx, ctx.finalRouteSegment, leftSideNavigation);
|
return new RouteResultPreparation().prepareResult(ctx, ctx.finalRouteSegment, leftSideNavigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
||||||
* return list of segments
|
* return list of segments
|
||||||
*/
|
*/
|
||||||
private void searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end, boolean leftSideNavigation) throws IOException, InterruptedException {
|
private void searchRouteInternal(final RoutingContext ctx, RouteSegment start, RouteSegment end) throws IOException, InterruptedException {
|
||||||
// measure time
|
// measure time
|
||||||
ctx.timeToLoad = 0;
|
ctx.timeToLoad = 0;
|
||||||
ctx.visitedSegments = 0;
|
ctx.visitedSegments = 0;
|
||||||
|
@ -250,12 +267,12 @@ public class BinaryRoutePlannerOld {
|
||||||
TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>();
|
TLongObjectHashMap<RouteSegment> visitedDirectSegments = new TLongObjectHashMap<RouteSegment>();
|
||||||
TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>();
|
TLongObjectHashMap<RouteSegment> visitedOppositeSegments = new TLongObjectHashMap<RouteSegment>();
|
||||||
|
|
||||||
boolean runRecalculation = ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() > 0;
|
boolean runRecalculation = ctx.previouslyCalculatedRoute != null && ctx.previouslyCalculatedRoute.size() > 0
|
||||||
|
&& ctx.config.recalculateDistance != 0;
|
||||||
if (runRecalculation) {
|
if (runRecalculation) {
|
||||||
RouteSegment previous = null;
|
RouteSegment previous = null;
|
||||||
List<RouteSegmentResult> rlist = new ArrayList<RouteSegmentResult>();
|
List<RouteSegmentResult> rlist = new ArrayList<RouteSegmentResult>();
|
||||||
// always recalculate first 7 km
|
float distanceThreshold = ctx.config.recalculateDistance;
|
||||||
int distanceThreshold = 7000;
|
|
||||||
float threshold = 0;
|
float threshold = 0;
|
||||||
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
|
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
|
||||||
threshold += rr.getDistance();
|
threshold += rr.getDistance();
|
||||||
|
@ -340,11 +357,6 @@ public class BinaryRoutePlannerOld {
|
||||||
} else {
|
} else {
|
||||||
graphSegments = graphDirectSegments;
|
graphSegments = graphDirectSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ctx.runRelaxingStrategy() ) {
|
|
||||||
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
|
||||||
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
|
||||||
}
|
|
||||||
// check if interrupted
|
// check if interrupted
|
||||||
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
||||||
throw new InterruptedException("Route calculation interrupted");
|
throw new InterruptedException("Route calculation interrupted");
|
||||||
|
@ -356,35 +368,6 @@ public class BinaryRoutePlannerOld {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void relaxNotNeededSegments(RoutingContext ctx, PriorityQueue<RouteSegment> graphSegments, boolean inverse) {
|
|
||||||
RouteSegment next = graphSegments.peek();
|
|
||||||
double mine = next.distanceToEnd;
|
|
||||||
// int before = graphSegments.size();
|
|
||||||
// SegmentStat statStart = new SegmentStat("Distance from start (" + inverse + ") ");
|
|
||||||
// SegmentStat statEnd = new SegmentStat("Distance to end (" + inverse + ") ");
|
|
||||||
Iterator<RouteSegment> iterator = graphSegments.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
RouteSegment s = iterator.next();
|
|
||||||
// statStart.addNumber((float) s.distanceFromStart);
|
|
||||||
// statEnd.addNumber((float) s.distanceToEnd);
|
|
||||||
if (s.distanceToEnd < mine) {
|
|
||||||
mine = s.distanceToEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double d = mine * ctx.config.RELAX_NODES_IF_START_DIST_COEF;
|
|
||||||
iterator = graphSegments.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
RouteSegment s = iterator.next();
|
|
||||||
if (s.distanceToEnd > d) {
|
|
||||||
ctx.relaxedSegments++;
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// int after = graphSegments.size();
|
|
||||||
// println(statStart.toString());
|
|
||||||
// println(statEnd.toString());
|
|
||||||
// println("Relaxing : before " + before + " after " + after + " minend " + ((float) mine));
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -394,16 +377,6 @@ public class BinaryRoutePlannerOld {
|
||||||
|
|
||||||
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){
|
|
||||||
double priority = ctx.getRouter().getFutureRoadPriority(next.road);
|
|
||||||
result /= priority;
|
|
||||||
int dist = ctx.getDynamicRoadPriorityDistance();
|
|
||||||
// only first N km-s count by dynamic priority
|
|
||||||
if(distToFinalPoint > dist && dist != 0){
|
|
||||||
result = (distToFinalPoint - dist) / ctx.getRouter().getMaxDefaultSpeed() +
|
|
||||||
dist / (ctx.getRouter().getMaxDefaultSpeed() * priority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
|
@ -20,9 +21,12 @@ public class RouteResultPreparation {
|
||||||
*/
|
*/
|
||||||
List<RouteSegmentResult> prepareResult(RoutingContext ctx, FinalRouteSegment finalSegment,boolean leftside) {
|
List<RouteSegmentResult> prepareResult(RoutingContext ctx, FinalRouteSegment finalSegment,boolean leftside) {
|
||||||
List<RouteSegmentResult> result = convertFinalSegmentToResults(ctx, finalSegment);
|
List<RouteSegmentResult> result = convertFinalSegmentToResults(ctx, finalSegment);
|
||||||
|
prepareResult(ctx, leftside, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RouteSegmentResult> prepareResult(RoutingContext ctx, boolean leftside, List<RouteSegmentResult> result) {
|
||||||
validateAllPointsConnected(result);
|
validateAllPointsConnected(result);
|
||||||
|
|
||||||
// calculate time
|
// calculate time
|
||||||
calculateTimeSpeedAndAttachRoadSegments(ctx, result);
|
calculateTimeSpeedAndAttachRoadSegments(ctx, result);
|
||||||
|
|
||||||
|
@ -81,6 +85,7 @@ public class RouteResultPreparation {
|
||||||
if (isSplit) {
|
if (isSplit) {
|
||||||
int endPointIndex = rr.getEndPointIndex();
|
int endPointIndex = rr.getEndPointIndex();
|
||||||
RouteSegmentResult split = new RouteSegmentResult(rr.getObject(), next, endPointIndex);
|
RouteSegmentResult split = new RouteSegmentResult(rr.getObject(), next, endPointIndex);
|
||||||
|
split.copyPreattachedRoutes(rr, Math.abs(next - rr.getStartPointIndex()));
|
||||||
rr.setSegmentTime((float) distOnRoadToPass);
|
rr.setSegmentTime((float) distOnRoadToPass);
|
||||||
rr.setSegmentSpeed((float) speed);
|
rr.setSegmentSpeed((float) speed);
|
||||||
rr.setDistance((float) distance);
|
rr.setDistance((float) distance);
|
||||||
|
@ -496,12 +501,35 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RouteSegment routeSegment = ctx.loadRouteSegment(road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd), ctx.config.memoryLimitation);
|
Iterator<RouteSegment> it;
|
||||||
|
if(rr.getPreAttachedRoutes(pointInd) != null) {
|
||||||
|
final RouteSegmentResult[] list = rr.getPreAttachedRoutes(pointInd);
|
||||||
|
it = new Iterator<BinaryRoutePlanner.RouteSegment>() {
|
||||||
|
int i = 0;
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return i < list.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RouteSegment next() {
|
||||||
|
RouteSegmentResult r = list[i++];
|
||||||
|
return new RouteSegment(r.getObject(), r.getStartPointIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
RouteSegment rt = ctx.loadRouteSegment(road.getPoint31XTile(pointInd), road.getPoint31YTile(pointInd), ctx.config.memoryLimitation);
|
||||||
|
it = rt.getIterator();
|
||||||
|
}
|
||||||
// try to attach all segments except with current id
|
// try to attach all segments except with current id
|
||||||
while (routeSegment != null) {
|
while (it.hasNext()) {
|
||||||
|
RouteSegment routeSegment = it.next();
|
||||||
if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) {
|
if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) {
|
||||||
RouteDataObject addRoad = routeSegment.road;
|
RouteDataObject addRoad = routeSegment.road;
|
||||||
|
|
||||||
// TODO restrictions can be considered as well
|
// TODO restrictions can be considered as well
|
||||||
int oneWay = ctx.getRouter().isOneWay(addRoad);
|
int oneWay = ctx.getRouter().isOneWay(addRoad);
|
||||||
if (oneWay >= 0 && routeSegment.getSegmentStart() < addRoad.getPointsLength() - 1) {
|
if (oneWay >= 0 && routeSegment.getSegmentStart() < addRoad.getPointsLength() - 1) {
|
||||||
|
@ -519,7 +547,6 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
routeSegment = routeSegment.next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class RouteSegmentResult {
|
||||||
private int startPointIndex;
|
private int startPointIndex;
|
||||||
private int endPointIndex;
|
private int endPointIndex;
|
||||||
private List<RouteSegmentResult>[] attachedRoutes;
|
private List<RouteSegmentResult>[] attachedRoutes;
|
||||||
|
private RouteSegmentResult[][] preAttachedRoutes;
|
||||||
private float segmentTime;
|
private float segmentTime;
|
||||||
private float speed;
|
private float speed;
|
||||||
private float distance;
|
private float distance;
|
||||||
|
@ -29,6 +30,7 @@ public class RouteSegmentResult {
|
||||||
updateCapacity();
|
updateCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void updateCapacity() {
|
private void updateCapacity() {
|
||||||
int capacity = Math.abs(endPointIndex - startPointIndex) + 1;
|
int capacity = Math.abs(endPointIndex - startPointIndex) + 1;
|
||||||
|
@ -43,6 +45,20 @@ public class RouteSegmentResult {
|
||||||
attachedRoutes[st].add(r);
|
attachedRoutes[st].add(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void copyPreattachedRoutes(RouteSegmentResult toCopy, int shift) {
|
||||||
|
int l = toCopy.preAttachedRoutes.length - shift;
|
||||||
|
preAttachedRoutes = new RouteSegmentResult[l][];
|
||||||
|
System.arraycopy(toCopy.preAttachedRoutes, shift, preAttachedRoutes, 0, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RouteSegmentResult[] getPreAttachedRoutes(int routeInd) {
|
||||||
|
int st = Math.abs(routeInd - startPointIndex);
|
||||||
|
if(st < preAttachedRoutes.length) {
|
||||||
|
return preAttachedRoutes[st];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<RouteSegmentResult> getAttachedRoutes(int routeInd) {
|
public List<RouteSegmentResult> getAttachedRoutes(int routeInd) {
|
||||||
int st = Math.abs(routeInd - startPointIndex);
|
int st = Math.abs(routeInd - startPointIndex);
|
||||||
List<RouteSegmentResult> list = attachedRoutes[st];
|
List<RouteSegmentResult> list = attachedRoutes[st];
|
||||||
|
|
|
@ -39,6 +39,9 @@ public class RoutingConfiguration {
|
||||||
// 1.4 Used to calculate route in movement
|
// 1.4 Used to calculate route in movement
|
||||||
public Double initialDirection;
|
public Double initialDirection;
|
||||||
|
|
||||||
|
// 1.5 Recalculate distance help
|
||||||
|
public float recalculateDistance = 10000f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
@ -67,6 +70,7 @@ public class RoutingConfiguration {
|
||||||
attributes.put("routerName", router);
|
attributes.put("routerName", router);
|
||||||
i.attributes.putAll(attributes);
|
i.attributes.putAll(attributes);
|
||||||
i.initialDirection = direction;
|
i.initialDirection = direction;
|
||||||
|
i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ;
|
||||||
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
|
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||||
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
|
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
|
||||||
|
@ -78,7 +82,7 @@ public class RoutingConfiguration {
|
||||||
}
|
}
|
||||||
i.memoryLimitation = memoryLimitMB * (1 << 20);
|
i.memoryLimitation = memoryLimitMB * (1 << 20);
|
||||||
}
|
}
|
||||||
i.planRoadDirection = parseSilentInt(getAttribute(router, "planRoadDirection"), i.planRoadDirection);
|
i.planRoadDirection = parseSilentInt(getAttribute(i.router, "planRoadDirection"), i.planRoadDirection);
|
||||||
|
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
|
@ -54,7 +54,6 @@ public class RoutingContext {
|
||||||
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
|
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
|
||||||
|
|
||||||
// 1. Initial variables
|
// 1. Initial variables
|
||||||
private int relaxingIteration = 0;
|
|
||||||
public long firstRoadId = 0;
|
public long firstRoadId = 0;
|
||||||
public int firstRoadDirection = 0;
|
public int firstRoadDirection = 0;
|
||||||
|
|
||||||
|
@ -179,42 +178,11 @@ public class RoutingContext {
|
||||||
return global.size;
|
return global.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runRelaxingStrategy(){
|
|
||||||
if(!isUseRelaxingStrategy()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
relaxingIteration++;
|
|
||||||
if(relaxingIteration > config.ITERATIONS_TO_RELAX_NODES){
|
|
||||||
relaxingIteration = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisitor(RouteSegmentVisitor visitor) {
|
public void setVisitor(RouteSegmentVisitor visitor) {
|
||||||
this.visitor = visitor;
|
this.visitor = visitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUseDynamicRoadPrioritising() {
|
|
||||||
return config.useDynamicRoadPrioritising;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDynamicRoadPriorityDistance() {
|
|
||||||
return config.dynamicRoadPriorityDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUseRelaxingStrategy() {
|
|
||||||
return config.useRelaxingStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUseRelaxingStrategy(boolean useRelaxingStrategy) {
|
|
||||||
config.useRelaxingStrategy = useRelaxingStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUseDynamicRoadPrioritising(boolean useDynamicRoadPrioritising) {
|
|
||||||
config.useDynamicRoadPrioritising = useDynamicRoadPrioritising;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRouter(VehicleRouter router) {
|
public void setRouter(VehicleRouter router) {
|
||||||
config.router = router;
|
config.router = router;
|
||||||
}
|
}
|
||||||
|
@ -350,7 +318,7 @@ public class RoutingContext {
|
||||||
borderLineCoordinates = new int[borderLines.length];
|
borderLineCoordinates = new int[borderLines.length];
|
||||||
for(int i=0; i<borderLineCoordinates.length; i++) {
|
for(int i=0; i<borderLineCoordinates.length; i++) {
|
||||||
borderLineCoordinates[i] = borderLines[i].borderLine;
|
borderLineCoordinates[i] = borderLines[i].borderLine;
|
||||||
// FIXME
|
// FIXME borders approach
|
||||||
// not less then 14th zoom
|
// not less then 14th zoom
|
||||||
if(i > 0 && borderLineCoordinates[i - 1] >> 17 == borderLineCoordinates[i] >> 17) {
|
if(i > 0 && borderLineCoordinates[i - 1] >> 17 == borderLineCoordinates[i] >> 17) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
@ -517,13 +485,15 @@ public class RoutingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadTileData(int x31, int y31, int zoomAround, final List<RouteDataObject> toFillIn) {
|
public void loadTileData(int x31, int y31, int zoomAround, final List<RouteDataObject> toFillIn) {
|
||||||
int t = zoomAround - config.ZOOM_TO_LOAD_TILES;
|
int t = config.ZOOM_TO_LOAD_TILES - zoomAround;
|
||||||
|
int coordinatesShift = (1 << (31 - config.ZOOM_TO_LOAD_TILES));
|
||||||
if(t <= 0) {
|
if(t <= 0) {
|
||||||
t = 1;
|
t = 1;
|
||||||
|
coordinatesShift = (1 << (31 - zoomAround));
|
||||||
} else {
|
} else {
|
||||||
t = 1 << t;
|
t = 1 << t;
|
||||||
}
|
}
|
||||||
int coordinatesShift = (1 << (31 - config.ZOOM_TO_LOAD_TILES));
|
|
||||||
TLongHashSet ts = new TLongHashSet();
|
TLongHashSet ts = new TLongHashSet();
|
||||||
long now = System.nanoTime();
|
long now = System.nanoTime();
|
||||||
for(int i = -t; i <= t; i++) {
|
for(int i = -t; i <= t; i++) {
|
||||||
|
|
|
@ -12,23 +12,24 @@
|
||||||
(don't specify here ! it is device dependent) -->
|
(don't specify here ! it is device dependent) -->
|
||||||
<attribute name="memoryLimitInMB" value="155" />
|
<attribute name="memoryLimitInMB" value="155" />
|
||||||
|
|
||||||
<!-- 1.4 Build A* graph in backward/forward direction (can affect results) -->
|
<!-- 1.2 Build A* graph in backward/forward direction (can affect results) -->
|
||||||
<!-- 0 - 2 ways, 1 - direct way, -1 - reverse way -->
|
<!-- 0 - 2 ways, 1 - direct way, -1 - reverse way -->
|
||||||
<attribute name="planRoadDirection" value="0" />
|
<attribute name="planRoadDirection" value="0" />
|
||||||
|
|
||||||
|
<!-- 1.3 When there is a query to recalculate route, -->
|
||||||
|
<!-- recalculate smart using old route withot N-meters (0 recalculate fresh, default 10km) -->
|
||||||
|
<attribute name="recalculateDistanceHelp" value="10000" />
|
||||||
|
|
||||||
<!-- HELP INFORMATION ABOUT FILE -->
|
<!-- HELP INFORMATION ABOUT FILE -->
|
||||||
<!-- 1) Highway defines acceptable route for routingProfile, speed in km/h (if it is not specified on level road) -->
|
<!-- 1) Highway defines acceptable route for routingProfile, speed in km/h (if it is not specified on level road) -->
|
||||||
<!-- priority is multiplicator for already passed road (consider it is an accelerator of the road) -->
|
<!-- priority is multiplicator for already passed road (consider it is an accelerator of the road) -->
|
||||||
<!-- dynamicPriority is multiplicator for future roads used by heuristic useDynamicRoadPrioritising -->
|
|
||||||
<!-- <road tag="highway" value="living_street" speed="25" priority="0.5" dynamicPriority="0.5"/> -->
|
<!-- <road tag="highway" value="living_street" speed="25" priority="0.5" dynamicPriority="0.5"/> -->
|
||||||
<!-- <road tag="route" value="ferry" speed="15" priority="1.0" dynamicPriority="0.7"/> -->
|
<!-- <road tag="route" value="ferry" speed="15" priority="1.0" /> -->
|
||||||
<!-- 2) Obstacle defines a point of the road and how it could be passed by vehicle -->
|
<!-- 2) Obstacle defines a point of the road and how it could be passed by vehicle -->
|
||||||
<!-- penalty is measured in time and -1 means it could not be passed! -->
|
<!-- penalty is measured in time and -1 means it could not be passed! -->
|
||||||
<!-- <obstacle tag="highway" value="traffic_signals" penalty="35"/> -->
|
<!-- <obstacle tag="highway" value="traffic_signals" penalty="35"/> -->
|
||||||
<!-- 3) Avoid describes what road should be completely avoided or passed with multiplied (decreased) priority -->
|
<!-- 3) Avoid describes what road should be completely avoided or passed with multiplied (decreased) priority -->
|
||||||
<!-- <avoid tag="access" value="no" decreasedPriority="0.9"/> -->
|
<!-- <avoid tag="access" value="no" decreasedPriority="0.9"/> -->
|
||||||
|
|
||||||
|
|
||||||
<!-- obstacle tag="highway" value="traffic_signals" penalty="35", penalty measured in seconds -->
|
<!-- obstacle tag="highway" value="traffic_signals" penalty="35", penalty measured in seconds -->
|
||||||
<routingProfile name="car" baseProfile="car" restrictionsAware="true" minDefaultSpeed="45.0" maxDefaultSpeed="130.0"
|
<routingProfile name="car" baseProfile="car" restrictionsAware="true" minDefaultSpeed="45.0" maxDefaultSpeed="130.0"
|
||||||
leftTurn="0" rightTurn="0" roundaboutTurn="0" followSpeedLimitations="true" onewayAware="true">
|
leftTurn="0" rightTurn="0" roundaboutTurn="0" followSpeedLimitations="true" onewayAware="true">
|
||||||
|
@ -36,55 +37,55 @@
|
||||||
<attribute name="heuristicCoefficient" value="1.5" />
|
<attribute name="heuristicCoefficient" value="1.5" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<road tag="highway" value="motorway" speed="110" priority="1.2" dynamicPriority="1">
|
<road tag="highway" value="motorway" speed="110" priority="1.2">
|
||||||
<specialization input="avoid_motorway" speed="0"/>
|
<specialization input="avoid_motorway" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
<road tag="highway" value="motorway_link" speed="80" priority="1.2" dynamicPriority="1">
|
<road tag="highway" value="motorway_link" speed="80" priority="1.2" >
|
||||||
<specialization input="avoid_motorway" speed="0"/>
|
<specialization input="avoid_motorway" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
|
|
||||||
<road tag="highway" value="trunk" speed="100" priority="1.2" dynamicPriority="0.9"/>
|
<road tag="highway" value="trunk" speed="100" priority="1.2" />
|
||||||
<road tag="highway" value="trunk_link" speed="75" priority="1.2" dynamicPriority="0.9"/>
|
<road tag="highway" value="trunk_link" speed="75" priority="1.2" />
|
||||||
|
|
||||||
<!-- generally linking larger towns. -->
|
<!-- generally linking larger towns. -->
|
||||||
<road tag="highway" value="primary" speed="65" priority="1.1" dynamicPriority="0.7"/>
|
<road tag="highway" value="primary" speed="65" priority="1.05" />
|
||||||
<road tag="highway" value="primary_link" speed="50" priority="1.1" dynamicPriority="0.7"/>
|
<road tag="highway" value="primary_link" speed="50" priority="1.05" />
|
||||||
|
|
||||||
<!-- generally linking smaller towns and villages -->
|
<!-- generally linking smaller towns and villages -->
|
||||||
<road tag="highway" value="secondary" speed="60" priority="1.05" dynamicPriority="0.6"/>
|
<road tag="highway" value="secondary" speed="60" priority="1" />
|
||||||
<road tag="highway" value="secondary_link" speed="50" priority="1.05" dynamicPriority="0.6"/>
|
<road tag="highway" value="secondary_link" speed="50" priority="1" />
|
||||||
<!-- important urban roads -->
|
<!-- important urban roads -->
|
||||||
<road tag="highway" value="tertiary" speed="45" priority="1" dynamicPriority="0.5"/>
|
<road tag="highway" value="tertiary" speed="45" priority="0.95" />
|
||||||
<road tag="highway" value="tertiary_link" speed="40" priority="1" dynamicPriority="0.5"/>
|
<road tag="highway" value="tertiary_link" speed="40" priority="0.95" />
|
||||||
<!-- lowest form of grid network, usually 90% of urban roads -->
|
<!-- lowest form of grid network, usually 90% of urban roads -->
|
||||||
<road tag="highway" value="unclassified" speed="35" priority="0.7" dynamicPriority="0.3">
|
<road tag="highway" value="unclassified" speed="35" priority="0.7" >
|
||||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
|
<specialization input="short_way" priority="1" speed="45"/>
|
||||||
</road>
|
</road>
|
||||||
<!-- road = no type, no review and may be not accurate -->
|
<!-- road = no type, no review and may be not accurate -->
|
||||||
<road tag="highway" value="road" speed="35" priority="0.7" dynamicPriority="0.3">
|
<road tag="highway" value="road" speed="35" priority="0.7" >
|
||||||
<specialization input="short_way" priority="1" speed="45"/>
|
<specialization input="short_way" priority="1" speed="45"/>
|
||||||
</road>
|
</road>
|
||||||
<!-- primarily for access to properties, small roads with 1/2 intersections -->
|
<!-- primarily for access to properties, small roads with 1/2 intersections -->
|
||||||
<road tag="highway" value="residential" speed="35" priority="0.7" dynamicPriority="0.3">
|
<road tag="highway" value="residential" speed="35" priority="0.7" >
|
||||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
|
<specialization input="short_way" priority="1" speed="45"/>
|
||||||
</road>
|
</road>
|
||||||
<!-- parking + private roads -->
|
<!-- parking + private roads -->
|
||||||
<road tag="highway" value="service" speed="30" priority="0.5" dynamicPriority="0.3">
|
<road tag="highway" value="service" speed="30" priority="0.5" >
|
||||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
|
<specialization input="short_way" priority="1" speed="45"/>
|
||||||
</road>
|
</road>
|
||||||
<!-- very bad roads -->
|
<!-- very bad roads -->
|
||||||
<road tag="highway" value="track" speed="15" priority="0.3" dynamicPriority="0.2">
|
<road tag="highway" value="track" speed="15" priority="0.3" >
|
||||||
<specialization input="short_way" priority="0.7" speed="45" dynamicPriority="0.7" />
|
<specialization input="short_way" priority="0.7" speed="45" />
|
||||||
<specialization input="avoid_unpaved" priority="0.1"/>
|
<specialization input="avoid_unpaved" priority="0.1"/>
|
||||||
</road>
|
</road>
|
||||||
|
|
||||||
<!-- too small for cars usually -->
|
<!-- too small for cars usually -->
|
||||||
<road tag="highway" value="living_street" speed="25" priority="0.5" dynamicPriority="0.3">
|
<road tag="highway" value="living_street" speed="25" priority="0.5" >
|
||||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="35"/>
|
<specialization input="short_way" priority="1" speed="35"/>
|
||||||
</road>
|
</road>
|
||||||
<!-- car are able to enter in highway=pedestrian with restrictions -->
|
<!-- car are able to enter in highway=pedestrian with restrictions -->
|
||||||
<!-- Time actually is uknown. Currently unsupported -->
|
<!-- Time actually is uknown. Currently unsupported -->
|
||||||
<road tag="route" value="ferry" speed="15" priority="1.0" dynamicPriority="0.9">
|
<road tag="route" value="ferry" speed="15" priority="1.0" >
|
||||||
<specialization input="avoid_ferries" speed="0"/>
|
<specialization input="avoid_ferries" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
|
|
||||||
|
@ -121,36 +122,36 @@
|
||||||
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
|
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
|
||||||
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->
|
<!-- <attribute name="relaxNodesIfStartDistSmallCoeff" value="2.5"/> -->
|
||||||
|
|
||||||
<road tag="highway" value="motorway" speed="16" priority="0.4" dynamicPriority="0.9">
|
<road tag="highway" value="motorway" speed="16" priority="0.4" >
|
||||||
<specialization input="avoid_motorway" speed="0"/>
|
<specialization input="avoid_motorway" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
<road tag="highway" value="motorway_link" speed="16" priority="0.4" dynamicPriority="0.9">
|
<road tag="highway" value="motorway_link" speed="16" priority="0.4" >
|
||||||
<specialization input="avoid_motorway" speed="0"/>
|
<specialization input="avoid_motorway" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
|
|
||||||
<road tag="highway" value="trunk" speed="16" priority="0.6" dynamicPriority="0.9"/>
|
<road tag="highway" value="trunk" speed="16" priority="0.6" />
|
||||||
<road tag="highway" value="trunk_link" speed="16" priority="0.7" dynamicPriority="0.9"/>
|
<road tag="highway" value="trunk_link" speed="16" priority="0.7" />
|
||||||
<road tag="highway" value="primary" speed="16" priority="0.8" dynamicPriority="0.9"/>
|
<road tag="highway" value="primary" speed="16" priority="0.8" />
|
||||||
<road tag="highway" value="primary_link" speed="16" priority="0.8" dynamicPriority="0.9"/>
|
<road tag="highway" value="primary_link" speed="16" priority="0.8" />
|
||||||
<road tag="highway" value="secondary" speed="16" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="secondary" speed="16" priority="1" />
|
||||||
<road tag="highway" value="secondary_link" speed="16" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="secondary_link" speed="16" priority="1" />
|
||||||
<road tag="highway" value="tertiary" speed="16" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="tertiary" speed="16" priority="1" />
|
||||||
<road tag="highway" value="tertiary_link" speed="16" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="tertiary_link" speed="16" priority="1" />
|
||||||
<road tag="highway" value="road" speed="16" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="road" speed="16" priority="1" />
|
||||||
<road tag="highway" value="residential" speed="16" priority="1.1" dynamicPriority="1"/>
|
<road tag="highway" value="residential" speed="16" priority="1.1" />
|
||||||
<road tag="highway" value="cycleway" speed="16" priority="1.5" dynamicPriority="1.3"/>
|
<road tag="highway" value="cycleway" speed="16" priority="1.5" />
|
||||||
|
|
||||||
<road tag="highway" value="unclassified" speed="13" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="unclassified" speed="13" priority="1" />
|
||||||
<road tag="highway" value="service" speed="13" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="service" speed="13" priority="1" />
|
||||||
<road tag="highway" value="track" speed="12" priority="1.5" dynamicPriority="1.5"/>
|
<road tag="highway" value="track" speed="12" priority="1.5" />
|
||||||
<road tag="highway" value="path" speed="12" priority="1.5" dynamicPriority="1.5"/>
|
<road tag="highway" value="path" speed="12" priority="1.5" />
|
||||||
<road tag="highway" value="living_street" speed="15" priority="1.1" dynamicPriority="1"/>
|
<road tag="highway" value="living_street" speed="15" priority="1.1" />
|
||||||
<road tag="highway" value="pedestrian" speed="10" priority="0.9" dynamicPriority="1"/>
|
<road tag="highway" value="pedestrian" speed="10" priority="0.9" />
|
||||||
<road tag="highway" value="footway" speed="8" priority="0.9" dynamicPriority="1"/>
|
<road tag="highway" value="footway" speed="8" priority="0.9" />
|
||||||
<road tag="highway" value="byway" speed="8" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="byway" speed="8" priority="1" />
|
||||||
<road tag="highway" value="services" speed="13" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="services" speed="13" priority="1" />
|
||||||
<road tag="highway" value="bridleway" speed="8" priority="0.8" dynamicPriority="1"/>
|
<road tag="highway" value="bridleway" speed="8" priority="0.8" />
|
||||||
<road tag="highway" value="steps" speed="3" priority="0.5" dynamicPriority="0.9"/>
|
<road tag="highway" value="steps" speed="3" priority="0.5" />
|
||||||
|
|
||||||
<obstacle tag="highway" value="traffic_signals" penalty="25" routingPenalty="10"/>
|
<obstacle tag="highway" value="traffic_signals" penalty="25" routingPenalty="10"/>
|
||||||
<obstacle tag="railway" value="crossing" penalty="15"/>
|
<obstacle tag="railway" value="crossing" penalty="15"/>
|
||||||
|
@ -171,36 +172,36 @@
|
||||||
|
|
||||||
<attribute name="heuristicCoefficient" value="1.2" />
|
<attribute name="heuristicCoefficient" value="1.2" />
|
||||||
|
|
||||||
<road tag="highway" value="motorway" speed="5" priority="0.7" dynamicPriority="0.7">
|
<road tag="highway" value="motorway" speed="5" priority="0.7" >
|
||||||
<specialization input="avoid_motorway" speed="0"/>
|
<specialization input="avoid_motorway" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
<road tag="highway" value="motorway_link" speed="5" priority="0.7" dynamicPriority="0.7">
|
<road tag="highway" value="motorway_link" speed="5" priority="0.7" >
|
||||||
<specialization input="avoid_motorway" speed="0"/>
|
<specialization input="avoid_motorway" speed="0"/>
|
||||||
</road>
|
</road>
|
||||||
|
|
||||||
<road tag="highway" value="trunk" speed="5" priority="0.7" dynamicPriority="0.7"/>
|
<road tag="highway" value="trunk" speed="5" priority="0.7" />
|
||||||
<road tag="highway" value="trunk_link" speed="5" priority="0.7" dynamicPriority="0.7"/>
|
<road tag="highway" value="trunk_link" speed="5" priority="0.7" />
|
||||||
<road tag="highway" value="primary" speed="5" priority="0.9" dynamicPriority="0.9"/>
|
<road tag="highway" value="primary" speed="5" priority="0.9" />
|
||||||
<road tag="highway" value="primary_link" speed="5" priority="0.9" dynamicPriority="0.9"/>
|
<road tag="highway" value="primary_link" speed="5" priority="0.9" />
|
||||||
<road tag="highway" value="secondary" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="secondary" speed="5" priority="1" />
|
||||||
<road tag="highway" value="secondary_link" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="secondary_link" speed="5" priority="1" />
|
||||||
<road tag="highway" value="tertiary" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="tertiary" speed="5" priority="1" />
|
||||||
<road tag="highway" value="tertiary_link" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="tertiary_link" speed="5" priority="1" />
|
||||||
<road tag="highway" value="road" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="road" speed="5" priority="1" />
|
||||||
<road tag="highway" value="residential" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="residential" speed="5" priority="1" />
|
||||||
<road tag="highway" value="cycleway" speed="5" priority="1" dynamicPriority="1.1"/>
|
<road tag="highway" value="cycleway" speed="5" priority="1" />
|
||||||
|
|
||||||
<road tag="highway" value="unclassified" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="unclassified" speed="5" priority="1" />
|
||||||
<road tag="highway" value="service" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="service" speed="5" priority="1" />
|
||||||
<road tag="highway" value="track" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="track" speed="5" priority="1" />
|
||||||
<road tag="highway" value="path" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="path" speed="5" priority="1" />
|
||||||
<road tag="highway" value="living_street" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="living_street" speed="5" priority="1" />
|
||||||
<road tag="highway" value="pedestrian" speed="5" priority="1.2" dynamicPriority="1.1"/>
|
<road tag="highway" value="pedestrian" speed="5" priority="1.2" />
|
||||||
<road tag="highway" value="footway" speed="5" priority="1.2" dynamicPriority="1.1"/>
|
<road tag="highway" value="footway" speed="5" priority="1.2" />
|
||||||
<road tag="highway" value="byway" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="byway" speed="5" priority="1" />
|
||||||
<road tag="highway" value="services" speed="5" priority="1" dynamicPriority="1"/>
|
<road tag="highway" value="services" speed="5" priority="1" />
|
||||||
<road tag="highway" value="bridleway" speed="5" priority="0.8" dynamicPriority="0.8"/>
|
<road tag="highway" value="bridleway" speed="5" priority="0.8" />
|
||||||
<road tag="highway" value="steps" speed="4" priority="1.2" dynamicPriority="1"/>
|
<road tag="highway" value="steps" speed="4" priority="1.2" />
|
||||||
|
|
||||||
<obstacle tag="highway" value="traffic_signals" penalty="30"/>
|
<obstacle tag="highway" value="traffic_signals" penalty="30"/>
|
||||||
<obstacle tag="railway" value="crossing" penalty="15"/>
|
<obstacle tag="railway" value="crossing" penalty="15"/>
|
||||||
|
|
|
@ -716,14 +716,11 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
int ex31 = e.getRoad().getPoint31XTile(e.getSegmentStart());
|
|
||||||
int ey31 = e.getRoad().getPoint31YTile(e.getSegmentStart());
|
// Choose native or not native
|
||||||
int sx31 = st.getRoad().getPoint31XTile(st.getSegmentStart());
|
long nt = System.nanoTime();
|
||||||
int sy31 = st.getRoad().getPoint31YTile(st.getSegmentStart());
|
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, inters, false);
|
||||||
// FIXME
|
System.out.println("External native time " + (System.nanoTime() - nt) / 1e9f);
|
||||||
RouteSegmentResult[] searchRoute = ctx.nativeLib.runNativeRouting(sx31, sy31, ex31, ey31, ctx.config);
|
|
||||||
// /*List<RouteSegmentResult> searchRoute = */router.searchRoute(ctx, st, e, inters, false);
|
|
||||||
// this.previousRoute = searchRoute;
|
|
||||||
if (animateRoutingCalculation) {
|
if (animateRoutingCalculation) {
|
||||||
playPauseButton.setVisible(false);
|
playPauseButton.setVisible(false);
|
||||||
nextTurn.setText("FINISH");
|
nextTurn.setText("FINISH");
|
||||||
|
@ -742,7 +739,6 @@ public class MapRouterLayer implements MapPanelLayer {
|
||||||
// String name = String.format("beg %.2f end %.2f ", s.getBearingBegin(), s.getBearingEnd());
|
// String name = String.format("beg %.2f end %.2f ", s.getBearingBegin(), s.getBearingEnd());
|
||||||
way.putTag(OSMTagKey.NAME.getValue(),name);
|
way.putTag(OSMTagKey.NAME.getValue(),name);
|
||||||
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
|
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
|
||||||
System.out.println("Segment " + s.getObject().id + " "+s.getStartPointIndex() + " -> " + s.getEndPointIndex());
|
|
||||||
int i = s.getStartPointIndex();
|
int i = s.getStartPointIndex();
|
||||||
while (true) {
|
while (true) {
|
||||||
LatLon l = s.getPoint(i);
|
LatLon l = s.getPoint(i);
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
#include "mapObjects.h"
|
#include "mapObjects.h"
|
||||||
#include "multipolygons.h"
|
#include "multipolygons.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -108,6 +106,61 @@ struct RouteDataObject {
|
||||||
|
|
||||||
UNORDERED(map)<int, std::string > names;
|
UNORDERED(map)<int, std::string > names;
|
||||||
vector<pair<uint32_t, uint32_t> > namesIds;
|
vector<pair<uint32_t, uint32_t> > namesIds;
|
||||||
|
|
||||||
|
string getName() {
|
||||||
|
if(names.size() > 0) {
|
||||||
|
return names.begin()->second;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSize() {
|
||||||
|
int s = sizeof(this);
|
||||||
|
s += pointsX.capacity()*sizeof(uint32_t);
|
||||||
|
s += pointsY.capacity()*sizeof(uint32_t);
|
||||||
|
s += types.capacity()*sizeof(uint32_t);
|
||||||
|
s += restrictions.capacity()*sizeof(uint64_t);
|
||||||
|
std::vector<std::vector<uint32_t> >::iterator t = pointTypes.begin();
|
||||||
|
for(;t!=pointTypes.end(); t++) {
|
||||||
|
s+= (*t).capacity() * sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
s += namesIds.capacity()*sizeof(pair<uint32_t, uint32_t>);
|
||||||
|
s += names.size()*sizeof(pair<int, string>)*10;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
double directionRoute(int startPoint, bool plus){
|
||||||
|
// look at comment JAVA
|
||||||
|
return directionRoute(startPoint, plus, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gives route direction of EAST degrees from NORTH ]-PI, PI]
|
||||||
|
double directionRoute(int startPoint, bool plus, float dist) {
|
||||||
|
int x = pointsX[startPoint];
|
||||||
|
int y = pointsY[startPoint];
|
||||||
|
int nx = startPoint;
|
||||||
|
int px = x;
|
||||||
|
int py = y;
|
||||||
|
double total = 0;
|
||||||
|
do {
|
||||||
|
if (plus) {
|
||||||
|
nx++;
|
||||||
|
if (nx >= pointsX.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nx--;
|
||||||
|
if (nx < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
px = pointsX[nx];
|
||||||
|
py = pointsY[nx];
|
||||||
|
// translate into meters
|
||||||
|
total += abs(px - x) * 0.011 + abs(py - y) * 0.01863;
|
||||||
|
} while (total < dist);
|
||||||
|
return -atan2( (float)x - px, (float) y - py ) + M_PI/2;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
static bool PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
static bool PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
||||||
static const int REVERSE_WAY_RESTRICTION_ONLY = 1024;
|
static const int REVERSE_WAY_RESTRICTION_ONLY = 1024;
|
||||||
static const int STANDARD_ROAD_IN_QUEUE_OVERHEAD = 900;
|
|
||||||
|
|
||||||
static const int ROUTE_POINTS = 11;
|
static const int ROUTE_POINTS = 11;
|
||||||
static const float TURN_DEGREE_MIN = 45;
|
static const float TURN_DEGREE_MIN = 45;
|
||||||
|
@ -18,6 +17,7 @@ static const short RESTRICTION_NO_STRAIGHT_ON = 4;
|
||||||
static const short RESTRICTION_ONLY_RIGHT_TURN = 5;
|
static const short RESTRICTION_ONLY_RIGHT_TURN = 5;
|
||||||
static const short RESTRICTION_ONLY_LEFT_TURN = 6;
|
static const short RESTRICTION_ONLY_LEFT_TURN = 6;
|
||||||
static const short RESTRICTION_ONLY_STRAIGHT_ON = 7;
|
static const short RESTRICTION_ONLY_STRAIGHT_ON = 7;
|
||||||
|
static const bool TRACE_ROUTING = false;
|
||||||
|
|
||||||
inline int roadPriorityComparator(float o1DistanceFromStart, float o1DistanceToEnd,
|
inline int roadPriorityComparator(float o1DistanceFromStart, float o1DistanceToEnd,
|
||||||
float o2DistanceFromStart, float o2DistanceToEnd, float heuristicCoefficient) {
|
float o2DistanceFromStart, float o2DistanceToEnd, float heuristicCoefficient) {
|
||||||
|
@ -66,8 +66,9 @@ struct SegmentsComparator : public std::binary_function<SHARED_PTR<RouteSegment>
|
||||||
}
|
}
|
||||||
bool operator()(const SHARED_PTR<RouteSegment> lhs, const SHARED_PTR<RouteSegment> rhs) const
|
bool operator()(const SHARED_PTR<RouteSegment> lhs, const SHARED_PTR<RouteSegment> rhs) const
|
||||||
{
|
{
|
||||||
return roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart,
|
int cmp = roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart,
|
||||||
rhs.get()->distanceToEnd, ctx->getHeuristicCoefficient()) > 0;
|
rhs.get()->distanceToEnd, ctx->getHeuristicCoefficient());
|
||||||
|
return cmp > 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct NonHeuristicSegmentsComparator : public std::binary_function<SHARED_PTR<RouteSegment>, SHARED_PTR<RouteSegment>, bool>
|
struct NonHeuristicSegmentsComparator : public std::binary_function<SHARED_PTR<RouteSegment>, SHARED_PTR<RouteSegment>, bool>
|
||||||
|
@ -89,26 +90,36 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
||||||
SHARED_PTR<RouteSegment> segment, int segmentEnd, SHARED_PTR<RouteSegment> inputNext,
|
SHARED_PTR<RouteSegment> segment, int segmentEnd, SHARED_PTR<RouteSegment> inputNext,
|
||||||
bool reverseWay);
|
bool reverseWay);
|
||||||
|
|
||||||
|
|
||||||
|
int calculateSizeOfSearchMaps(SEGMENTS_QUEUE graphDirectSegments,
|
||||||
|
SEGMENTS_QUEUE graphReverseSegments, VISITED_MAP visitedDirectSegments,
|
||||||
|
VISITED_MAP visitedOppositeSegments){
|
||||||
|
int sz = visitedDirectSegments.size()*sizeof(pair<int64_t, SHARED_PTR<RouteSegment> > );
|
||||||
|
sz += visitedOppositeSegments.size()*sizeof(pair<int64_t, SHARED_PTR<RouteSegment> >);
|
||||||
|
sz += graphDirectSegments.size()*sizeof(SHARED_PTR<RouteSegment>);
|
||||||
|
sz += graphReverseSegments.size()*sizeof(SHARED_PTR<RouteSegment>);
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
||||||
* return list of segments
|
* return list of segments
|
||||||
*/
|
*/
|
||||||
void searchRouteInternal(RoutingContext* ctx, SHARED_PTR<RouteSegment> start, SHARED_PTR<RouteSegment> end, bool leftSideNavigation) {
|
void searchRouteInternal(RoutingContext* ctx, SHARED_PTR<RouteSegment> start, SHARED_PTR<RouteSegment> end, bool leftSideNavigation) {
|
||||||
|
// FIXME intermediate points
|
||||||
// measure time
|
// measure time
|
||||||
ctx->visitedSegments = 0;
|
ctx->visitedSegments = 0;
|
||||||
ctx->timeToCalculate.start();
|
ctx->timeToCalculate.start();
|
||||||
// FIXME initial direction
|
if(ctx->config.initialDirection != -360) {
|
||||||
// if(ctx.config.initialDirection != null) {
|
ctx->firstRoadId = (start->road->id << ROUTE_POINTS) + start->getSegmentStart();
|
||||||
// ctx.firstRoadId = (start->road->id << ROUTE_POINTS) + start.getSegmentStart();
|
double plusDir = start->road->directionRoute(start->getSegmentStart(), true);
|
||||||
// double plusDir = start->road->directionRoute(start.segmentStart, true);
|
double diff = plusDir - ctx->config.initialDirection;
|
||||||
// double diff = plusDir - ctx.config.initialDirection;
|
if(abs(alignAngleDifference(diff)) <= M_PI / 3) {
|
||||||
// if(Math.abs(MapUtils.alignAngleDifference(diff)) <= Math.PI / 3) {
|
ctx->firstRoadDirection = 1;
|
||||||
// ctx.firstRoadDirection = 1;
|
} else if(abs(alignAngleDifference(diff - M_PI )) <= M_PI / 3) {
|
||||||
// } else if(Math.abs(MapUtils.alignAngleDifference(diff - Math.PI)) <= Math.PI / 3) {
|
ctx->firstRoadDirection = -1;
|
||||||
// ctx.firstRoadDirection = -1;
|
}
|
||||||
// }
|
|
||||||
//
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
SegmentsComparator sgmCmp(ctx);
|
SegmentsComparator sgmCmp(ctx);
|
||||||
SEGMENTS_QUEUE graphDirectSegments(sgmCmp);
|
SEGMENTS_QUEUE graphDirectSegments(sgmCmp);
|
||||||
|
@ -189,7 +200,14 @@ void searchRouteInternal(RoutingContext* ctx, SHARED_PTR<RouteSegment> start, SH
|
||||||
osmand_log_print(LOG_WARN, "[Native] Result visited (visited roads %d, visited segments %d / %d , queue sizes %d / %d ) ",
|
osmand_log_print(LOG_WARN, "[Native] Result visited (visited roads %d, visited segments %d / %d , queue sizes %d / %d ) ",
|
||||||
ctx-> visitedSegments, visitedDirectSegments.size(), visitedOppositeSegments.size(),
|
ctx-> visitedSegments, visitedDirectSegments.size(), visitedOppositeSegments.size(),
|
||||||
graphDirectSegments.size(),graphReverseSegments.size());
|
graphDirectSegments.size(),graphReverseSegments.size());
|
||||||
|
osmand_log_print(LOG_WARN, "[Native] Result timing (time to load %d, time to calc %d, loaded tiles %d) ", ctx->timeToLoad.getElapsedTime()
|
||||||
|
, ctx->timeToCalculate.getElapsedTime(), ctx->loadedTiles);
|
||||||
|
int sz = calculateSizeOfSearchMaps(graphDirectSegments, graphReverseSegments, visitedDirectSegments, visitedOppositeSegments);
|
||||||
|
osmand_log_print(LOG_WARN, "[Native] Memory occupied (Routing context %d Kb, search %d Kb)", ctx->getSize()/ 1024, sz/1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
||||||
SEGMENTS_QUEUE& graphSegments, VISITED_MAP& visitedSegments, int targetEndX, int targetEndY,
|
SEGMENTS_QUEUE& graphSegments, VISITED_MAP& visitedSegments, int targetEndX, int targetEndY,
|
||||||
SHARED_PTR<RouteSegment> segment, VISITED_MAP& oppositeSegments) {
|
SHARED_PTR<RouteSegment> segment, VISITED_MAP& oppositeSegments) {
|
||||||
|
@ -206,6 +224,10 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
||||||
if(visitedSegments.find(nt) != visitedSegments.end()) {
|
if(visitedSegments.find(nt) != visitedSegments.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if(TRACE_ROUTING) {
|
||||||
|
osmand_log_print(LOG_DEBUG, "Process segment id=%lld name=%s dist=%f", road->id, road->getName().c_str(), segment->distanceFromStart);
|
||||||
|
}
|
||||||
|
|
||||||
ctx->visitedSegments++;
|
ctx->visitedSegments++;
|
||||||
// avoid empty segments to connect but mark the point as visited
|
// avoid empty segments to connect but mark the point as visited
|
||||||
visitedSegments[nt] = SHARED_PTR<RouteSegment>();
|
visitedSegments[nt] = SHARED_PTR<RouteSegment>();
|
||||||
|
@ -303,7 +325,6 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
||||||
// throw new OutOfMemoryError("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
|
// throw new OutOfMemoryError("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
|
||||||
// }
|
// }
|
||||||
SHARED_PTR<RouteSegment> next = ctx->loadRouteSegment(x, y);
|
SHARED_PTR<RouteSegment> next = ctx->loadRouteSegment(x, y);
|
||||||
|
|
||||||
// 3. get intersected ways
|
// 3. get intersected ways
|
||||||
if (next.get() != NULL) {
|
if (next.get() != NULL) {
|
||||||
if((next.get() == segment.get() || next->road->id == road->id) && next->next.get() == NULL) {
|
if((next.get() == segment.get() || next->road->id == road->id) && next->next.get() == NULL) {
|
||||||
|
@ -447,6 +468,7 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// road.id could be equal on roundabout, but we should accept them
|
// road.id could be equal on roundabout, but we should accept them
|
||||||
bool alreadyVisited = visitedSegments.find(nts) != visitedSegments.end();
|
bool alreadyVisited = visitedSegments.find(nts) != visitedSegments.end();
|
||||||
if (!alreadyVisited) {
|
if (!alreadyVisited) {
|
||||||
|
@ -463,6 +485,9 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
||||||
// put additional information to recover whole route after
|
// put additional information to recover whole route after
|
||||||
next->parentRoute = segment;
|
next->parentRoute = segment;
|
||||||
next->parentSegmentEnd = segmentEnd;
|
next->parentSegmentEnd = segmentEnd;
|
||||||
|
if(TRACE_ROUTING) {
|
||||||
|
osmand_log_print(LOG_DEBUG, ">> next segment id=%lld name=%s dist=%f", next->road->id, next->road->getName().c_str(), next->distanceFromStart);
|
||||||
|
}
|
||||||
graphSegments.push(next);
|
graphSegments.push(next);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -490,9 +515,9 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
||||||
|
|
||||||
SHARED_PTR<RouteSegment> findRouteSegment(int px, int py, RoutingContext* ctx) {
|
SHARED_PTR<RouteSegment> findRouteSegment(int px, int py, RoutingContext* ctx) {
|
||||||
vector<SHARED_PTR<RouteDataObject> > dataObjects;
|
vector<SHARED_PTR<RouteDataObject> > dataObjects;
|
||||||
ctx->loadTileData(px, py, 16, dataObjects);
|
ctx->loadTileData(px, py, 17, dataObjects);
|
||||||
if (dataObjects.size() == 0) {
|
if (dataObjects.size() == 0) {
|
||||||
ctx->loadTileData(px, py, 14, dataObjects);
|
ctx->loadTileData(px, py, 15, dataObjects);
|
||||||
}
|
}
|
||||||
SHARED_PTR<RouteSegment> road;
|
SHARED_PTR<RouteSegment> road;
|
||||||
double sdist = 0;
|
double sdist = 0;
|
||||||
|
@ -566,6 +591,26 @@ void addRouteSegmentToResult(vector<RouteSegmentResult>& result, RouteSegmentRes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void attachConnectedRoads(RoutingContext* ctx, vector<RouteSegmentResult>& res ) {
|
||||||
|
vector<RouteSegmentResult>::iterator it = res.begin();
|
||||||
|
for(; it != res.end(); it++){
|
||||||
|
bool plus = it->startPointIndex < it->endPointIndex;
|
||||||
|
int j = it->startPointIndex;
|
||||||
|
do {
|
||||||
|
SHARED_PTR<RouteSegment> s = ctx->loadRouteSegment(it->object->pointsX[j], it->object->pointsY[j]);
|
||||||
|
vector<RouteSegmentResult> r;
|
||||||
|
while(s.get() != NULL) {
|
||||||
|
RouteSegmentResult res(s->road, s->getSegmentStart(), s->getSegmentStart());
|
||||||
|
r.push_back(res);
|
||||||
|
s = s->next;
|
||||||
|
}
|
||||||
|
it->attachedRoutes.push_back(r);
|
||||||
|
j = plus ? j + 1 : j - 1;
|
||||||
|
} while(j != it->endPointIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
vector<RouteSegmentResult> convertFinalSegmentToResults(RoutingContext* ctx) {
|
vector<RouteSegmentResult> convertFinalSegmentToResults(RoutingContext* ctx) {
|
||||||
vector<RouteSegmentResult> result;
|
vector<RouteSegmentResult> result;
|
||||||
if (ctx->finalRouteSegment.get() != NULL) {
|
if (ctx->finalRouteSegment.get() != NULL) {
|
||||||
|
@ -620,9 +665,9 @@ vector<RouteSegmentResult> searchRouteInternal(RoutingContext* ctx, bool leftSid
|
||||||
osmand_log_print(LOG_WARN, "End point was found %lld [Native]", end->road->id);
|
osmand_log_print(LOG_WARN, "End point was found %lld [Native]", end->road->id);
|
||||||
}
|
}
|
||||||
searchRouteInternal(ctx, start, end, leftSideNavigation);
|
searchRouteInternal(ctx, start, end, leftSideNavigation);
|
||||||
osmand_log_print(LOG_WARN, "[Native] Result timing (time to load %d, time to calc %d, loaded tiles %d) ", ctx->timeToLoad.getElapsedTime()
|
vector<RouteSegmentResult> res = convertFinalSegmentToResults(ctx);
|
||||||
, ctx->timeToCalculate.getElapsedTime(), ctx->loadedTiles);
|
attachConnectedRoads(ctx, res);
|
||||||
return convertFinalSegmentToResults(ctx);
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ struct RouteSegmentResult {
|
||||||
SHARED_PTR<RouteDataObject> object;
|
SHARED_PTR<RouteDataObject> object;
|
||||||
int startPointIndex;
|
int startPointIndex;
|
||||||
int endPointIndex;
|
int endPointIndex;
|
||||||
|
vector<vector<RouteSegmentResult> > attachedRoutes;
|
||||||
RouteSegmentResult(SHARED_PTR<RouteDataObject> object, int startPointIndex, int endPointIndex) :
|
RouteSegmentResult(SHARED_PTR<RouteDataObject> object, int startPointIndex, int endPointIndex) :
|
||||||
object(object), startPointIndex(startPointIndex), endPointIndex (endPointIndex) {
|
object(object), startPointIndex(startPointIndex), endPointIndex (endPointIndex) {
|
||||||
|
|
||||||
|
@ -62,10 +63,11 @@ struct RoutingSubregionTile {
|
||||||
// make it without get/set for fast access
|
// make it without get/set for fast access
|
||||||
int access;
|
int access;
|
||||||
int loaded;
|
int loaded;
|
||||||
|
int size ;
|
||||||
UNORDERED(map)<int64_t, SHARED_PTR<RouteSegment> > routes;
|
UNORDERED(map)<int64_t, SHARED_PTR<RouteSegment> > routes;
|
||||||
|
|
||||||
RoutingSubregionTile(RouteSubregion& sub) : access(0), loaded(0), subregion(sub) {
|
RoutingSubregionTile(RouteSubregion& sub) : access(0), loaded(0), subregion(sub) {
|
||||||
|
size = sizeof(RoutingSubregionTile);
|
||||||
}
|
}
|
||||||
~RoutingSubregionTile(){
|
~RoutingSubregionTile(){
|
||||||
}
|
}
|
||||||
|
@ -77,7 +79,12 @@ struct RoutingSubregionTile {
|
||||||
loaded++;
|
loaded++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getSize(){
|
||||||
|
return size + routes.size() * sizeof(std::pair<int64_t, SHARED_PTR<RouteSegment> >);
|
||||||
|
}
|
||||||
|
|
||||||
void add(SHARED_PTR<RouteDataObject> o) {
|
void add(SHARED_PTR<RouteDataObject> o) {
|
||||||
|
size += o->getSize() + sizeof(RouteSegment)* o->pointsX.size();
|
||||||
for (int i = 0; i < o->pointsX.size(); i++) {
|
for (int i = 0; i < o->pointsX.size(); i++) {
|
||||||
uint64_t x31 = o->pointsX[i];
|
uint64_t x31 = o->pointsX[i];
|
||||||
uint64_t y31 = o->pointsY[i];
|
uint64_t y31 = o->pointsY[i];
|
||||||
|
@ -98,7 +105,7 @@ struct RoutingSubregionTile {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static int64_t calcRouteId(SHARED_PTR<RouteDataObject> o, int ind) {
|
static int64_t calcRouteId(SHARED_PTR<RouteDataObject> o, int ind) {
|
||||||
return (o->id << 10) + ind;
|
return ((int64_t) o->id << 10) + ind;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::pair<int, std::pair<string, string> > ROUTE_TRIPLE;
|
typedef std::pair<int, std::pair<string, string> > ROUTE_TRIPLE;
|
||||||
|
@ -127,6 +134,7 @@ struct RoutingConfiguration {
|
||||||
int planRoadDirection;
|
int planRoadDirection;
|
||||||
string routerName;
|
string routerName;
|
||||||
float initialDirection;
|
float initialDirection;
|
||||||
|
float distanceRecalculate;
|
||||||
string routerProfile;
|
string routerProfile;
|
||||||
float roundaboutTurn;
|
float roundaboutTurn;
|
||||||
float leftTurn;
|
float leftTurn;
|
||||||
|
@ -166,9 +174,10 @@ struct RoutingConfiguration {
|
||||||
zoomToLoad = (int)parseFloat("zoomToLoadTiles", 16);
|
zoomToLoad = (int)parseFloat("zoomToLoadTiles", 16);
|
||||||
routerName = parseString("name", "default");
|
routerName = parseString("name", "default");
|
||||||
routerProfile = parseString("baseProfile", "car");
|
routerProfile = parseString("baseProfile", "car");
|
||||||
|
distanceRecalculate = parseFloat("recalculateDistanceHelp", 10000) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoutingConfiguration(vector<ROUTE_TRIPLE>& config, int memLimit = 30, float initDirection = 0) :
|
RoutingConfiguration(vector<ROUTE_TRIPLE>& config, float initDirection = -360, int memLimit = 30) :
|
||||||
memoryLimitation(memLimit), initialDirection(initDirection) {
|
memoryLimitation(memLimit), initialDirection(initDirection) {
|
||||||
for(int j = 0; j<config.size(); j++) {
|
for(int j = 0; j<config.size(); j++) {
|
||||||
ROUTE_TRIPLE r = config[j];
|
ROUTE_TRIPLE r = config[j];
|
||||||
|
@ -341,6 +350,8 @@ struct RoutingConfiguration {
|
||||||
|
|
||||||
|
|
||||||
struct RoutingContext {
|
struct RoutingContext {
|
||||||
|
typedef UNORDERED(map)<int64_t, SHARED_PTR<RoutingSubregionTile> > MAP_SUBREGION_TILES;
|
||||||
|
|
||||||
int visitedSegments;
|
int visitedSegments;
|
||||||
int loadedTiles;
|
int loadedTiles;
|
||||||
ElapsedTimer timeToLoad;
|
ElapsedTimer timeToLoad;
|
||||||
|
@ -358,7 +369,7 @@ struct RoutingContext {
|
||||||
vector<SHARED_PTR<RouteSegment> > segmentsToVisitPrescripted;
|
vector<SHARED_PTR<RouteSegment> > segmentsToVisitPrescripted;
|
||||||
|
|
||||||
SHARED_PTR<FinalRouteSegment> finalRouteSegment;
|
SHARED_PTR<FinalRouteSegment> finalRouteSegment;
|
||||||
UNORDERED(map)<int64_t, SHARED_PTR<RoutingSubregionTile> > subregionTiles;
|
MAP_SUBREGION_TILES subregionTiles;
|
||||||
UNORDERED(map)<int64_t, std::vector<SHARED_PTR<RoutingSubregionTile> > > indexedSubregions;
|
UNORDERED(map)<int64_t, std::vector<SHARED_PTR<RoutingSubregionTile> > > indexedSubregions;
|
||||||
|
|
||||||
RoutingContext(RoutingConfiguration& config) : finalRouteSegment(), firstRoadDirection(0), loadedTiles(0), visitedSegments(0),
|
RoutingContext(RoutingConfiguration& config) : finalRouteSegment(), firstRoadDirection(0), loadedTiles(0), visitedSegments(0),
|
||||||
|
@ -369,6 +380,16 @@ struct RoutingContext {
|
||||||
return config.acceptLine(r);
|
return config.acceptLine(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getSize() {
|
||||||
|
// multiply 2 for to maps
|
||||||
|
int sz = subregionTiles.size() * sizeof(pair< int64_t, SHARED_PTR<RoutingSubregionTile> >) * 2;
|
||||||
|
MAP_SUBREGION_TILES::iterator it = subregionTiles.begin();
|
||||||
|
for(;it != subregionTiles.end(); it++) {
|
||||||
|
sz += it->second->getSize();
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
void loadHeaderObjects(int64_t tileId) {
|
void loadHeaderObjects(int64_t tileId) {
|
||||||
vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions[tileId];
|
vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions[tileId];
|
||||||
for(int j = 0; j<subregions.size(); j++) {
|
for(int j = 0; j<subregions.size(); j++) {
|
||||||
|
@ -404,13 +425,12 @@ struct RoutingContext {
|
||||||
std::vector<SHARED_PTR<RoutingSubregionTile> > collection;
|
std::vector<SHARED_PTR<RoutingSubregionTile> > collection;
|
||||||
for(int i=0; i<tempResult.size(); i++) {
|
for(int i=0; i<tempResult.size(); i++) {
|
||||||
RouteSubregion& rs = tempResult[i];
|
RouteSubregion& rs = tempResult[i];
|
||||||
int64_t key = ((int64_t)rs.left << 31)+ rs.length;
|
int64_t key = ((int64_t)rs.left << 31)+ rs.filePointer;
|
||||||
if(subregionTiles.find(key) == subregionTiles.end()) {
|
if(subregionTiles.find(key) == subregionTiles.end()) {
|
||||||
subregionTiles[key] = SHARED_PTR<RoutingSubregionTile>(new RoutingSubregionTile(rs));
|
subregionTiles[key] = SHARED_PTR<RoutingSubregionTile>(new RoutingSubregionTile(rs));
|
||||||
}
|
}
|
||||||
collection.push_back(subregionTiles[key]);
|
collection.push_back(subregionTiles[key]);
|
||||||
}
|
}
|
||||||
//osmand_log_print(LOG_INFO, "Native load %d %d (%d)", xloc, yloc, tempResult.size());
|
|
||||||
indexedSubregions[tileId] = collection;
|
indexedSubregions[tileId] = collection;
|
||||||
}
|
}
|
||||||
loadHeaderObjects(tileId);
|
loadHeaderObjects(tileId);
|
||||||
|
@ -418,13 +438,14 @@ struct RoutingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadTileData(int x31, int y31, int zoomAround, vector<SHARED_PTR<RouteDataObject> >& dataObjects ) {
|
void loadTileData(int x31, int y31, int zoomAround, vector<SHARED_PTR<RouteDataObject> >& dataObjects ) {
|
||||||
int t = zoomAround - config.zoomToLoad;
|
int t = config.zoomToLoad - zoomAround;
|
||||||
|
int coordinatesShift = (1 << (31 - config.zoomToLoad));
|
||||||
if(t <= 0) {
|
if(t <= 0) {
|
||||||
t = 1;
|
t = 1;
|
||||||
|
coordinatesShift = (1 << (31 - zoomAround));
|
||||||
} else {
|
} else {
|
||||||
t = 1 << t;
|
t = 1 << t;
|
||||||
}
|
}
|
||||||
int coordinatesShift = (1 << (31 - config.zoomToLoad));
|
|
||||||
UNORDERED(set)<int64_t> ids;
|
UNORDERED(set)<int64_t> ids;
|
||||||
int z = config.zoomToLoad;
|
int z = config.zoomToLoad;
|
||||||
for(int i = -t; i <= t; i++) {
|
for(int i = -t; i <= t; i++) {
|
||||||
|
|
|
@ -300,3 +300,14 @@ double getDistance(double lat1, double lon1, double lat2, double lon2) {
|
||||||
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
||||||
return R * c * 1000;
|
return R * c * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double alignAngleDifference(double diff) {
|
||||||
|
while (diff > M_PI) {
|
||||||
|
diff -= 2 * M_PI;
|
||||||
|
}
|
||||||
|
while (diff <= -M_PI) {
|
||||||
|
diff += 2 * M_PI;
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -322,6 +322,7 @@ double calculateProjection31TileMetric(int xA, int yA, int xB, int yB, int xC, i
|
||||||
double squareDist31TileMetric(int x1, int y1, int x2, int y2) ;
|
double squareDist31TileMetric(int x1, int y1, int x2, int y2) ;
|
||||||
double convert31YToMeters(int y1, int y2);
|
double convert31YToMeters(int y1, int y2);
|
||||||
double convert31XToMeters(int y1, int y2);
|
double convert31XToMeters(int y1, int y2);
|
||||||
|
double alignAngleDifference(double diff);
|
||||||
|
|
||||||
|
|
||||||
#endif /*_OSMAND_COMMON_H*/
|
#endif /*_OSMAND_COMMON_H*/
|
||||||
|
|
|
@ -410,17 +410,25 @@ jfieldID jfield_RouteSubregion_top = NULL;
|
||||||
jfieldID jfield_RouteSubregion_bottom = NULL;
|
jfieldID jfield_RouteSubregion_bottom = NULL;
|
||||||
jfieldID jfield_RouteSubregion_shiftToData = NULL;
|
jfieldID jfield_RouteSubregion_shiftToData = NULL;
|
||||||
|
|
||||||
|
jclass jclass_RouteRegion = NULL;
|
||||||
|
jfieldID jfield_RouteRegion_length = NULL;
|
||||||
|
jfieldID jfield_RouteRegion_filePointer= NULL;
|
||||||
|
|
||||||
jclass jclass_RouteSegmentResult = NULL;
|
jclass jclass_RouteSegmentResult = NULL;
|
||||||
|
jclass jclass_RouteSegmentResultAr = NULL;
|
||||||
jmethodID jmethod_RouteSegmentResult_ctor = NULL;
|
jmethodID jmethod_RouteSegmentResult_ctor = NULL;
|
||||||
|
jfieldID jfield_RouteSegmentResult_preAttachedRoutes = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void loadJniRenderingContext(JNIEnv* env)
|
void loadJniRenderingContext(JNIEnv* env)
|
||||||
{
|
{
|
||||||
jclass_RouteSegmentResult = findClass(env, "net/osmand/router/RouteSegmentResult");
|
jclass_RouteSegmentResult = findClass(env, "net/osmand/router/RouteSegmentResult");
|
||||||
|
jclass_RouteSegmentResultAr = findClass(env, "[Lnet/osmand/router/RouteSegmentResult;");
|
||||||
jmethod_RouteSegmentResult_ctor = env->GetMethodID(jclass_RouteSegmentResult,
|
jmethod_RouteSegmentResult_ctor = env->GetMethodID(jclass_RouteSegmentResult,
|
||||||
"<init>", "(Lnet/osmand/binary/RouteDataObject;II)V");
|
"<init>", "(Lnet/osmand/binary/RouteDataObject;II)V");
|
||||||
|
jfield_RouteSegmentResult_preAttachedRoutes = getFid(env, jclass_RouteSegmentResult, "preAttachedRoutes",
|
||||||
|
"[[Lnet/osmand/router/RouteSegmentResult;");
|
||||||
|
|
||||||
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
|
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
|
||||||
jfield_RenderingContext_interrupted = getFid(env, jclass_RenderingContext, "interrupted", "Z");
|
jfield_RenderingContext_interrupted = getFid(env, jclass_RenderingContext, "interrupted", "Z");
|
||||||
|
@ -467,6 +475,10 @@ void loadJniRenderingContext(JNIEnv* env)
|
||||||
jmethod_RouteDataObject_init = env->GetMethodID(jclass_RouteDataObject, "<init>", "(Lnet/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion;[I[Ljava/lang/String;)V");
|
jmethod_RouteDataObject_init = env->GetMethodID(jclass_RouteDataObject, "<init>", "(Lnet/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion;[I[Ljava/lang/String;)V");
|
||||||
|
|
||||||
|
|
||||||
|
jclass_RouteRegion = findClass(env, "net/osmand/binary/BinaryMapRouteReaderAdapter$RouteRegion");
|
||||||
|
jfield_RouteRegion_length= getFid(env, jclass_RouteRegion, "length", "I" );
|
||||||
|
jfield_RouteRegion_filePointer= getFid(env, jclass_RouteRegion, "filePointer", "I" );
|
||||||
|
|
||||||
jclass_RouteSubregion = findClass(env, "net/osmand/binary/BinaryMapRouteReaderAdapter$RouteSubregion");
|
jclass_RouteSubregion = findClass(env, "net/osmand/binary/BinaryMapRouteReaderAdapter$RouteSubregion");
|
||||||
jfield_RouteSubregion_length= getFid(env, jclass_RouteSubregion, "length", "I" );
|
jfield_RouteSubregion_length= getFid(env, jclass_RouteSubregion, "length", "I" );
|
||||||
jfield_RouteSubregion_filePointer= getFid(env, jclass_RouteSubregion, "filePointer", "I" );
|
jfield_RouteSubregion_filePointer= getFid(env, jclass_RouteSubregion, "filePointer", "I" );
|
||||||
|
@ -563,6 +575,38 @@ jobject convertRouteDataObjectToJava(JNIEnv* ienv, RouteDataObject* route, jobje
|
||||||
return robj;
|
return robj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobject convertRouteSegmentResultToJava(JNIEnv* ienv, RouteSegmentResult& r, UNORDERED(map)<int64_t, int>& indexes,
|
||||||
|
jobjectArray regions) {
|
||||||
|
RouteDataObject* rdo = r.object.get();
|
||||||
|
jobject reg = NULL;
|
||||||
|
int64_t fp = rdo->region->filePointer;
|
||||||
|
int64_t ln = rdo->region->length;
|
||||||
|
if(indexes.find((fp <<31) + ln) != indexes.end()) {
|
||||||
|
reg = ienv->GetObjectArrayElement(regions, indexes[(fp <<31) + ln]);
|
||||||
|
}
|
||||||
|
jobjectArray ar = ienv->NewObjectArray(r.attachedRoutes.size(), jclass_RouteSegmentResultAr, NULL);
|
||||||
|
for(jsize k = 0; k < r.attachedRoutes.size(); k++) {
|
||||||
|
jobjectArray art = ienv->NewObjectArray(r.attachedRoutes[k].size(), jclass_RouteSegmentResult, NULL);
|
||||||
|
for(jsize kj = 0; kj < r.attachedRoutes[k].size(); kj++) {
|
||||||
|
jobject jo = convertRouteSegmentResultToJava(ienv, r.attachedRoutes[k][kj], indexes, regions);
|
||||||
|
ienv->SetObjectArrayElement(art, kj, jo);
|
||||||
|
ienv->DeleteLocalRef(jo);
|
||||||
|
}
|
||||||
|
ienv->SetObjectArrayElement(ar, k, art);
|
||||||
|
ienv->DeleteLocalRef(art);
|
||||||
|
}
|
||||||
|
jobject robj = convertRouteDataObjectToJava(ienv, rdo, reg);
|
||||||
|
jobject resobj = ienv->NewObject(jclass_RouteSegmentResult, jmethod_RouteSegmentResult_ctor, robj,
|
||||||
|
r.startPointIndex, r.endPointIndex);
|
||||||
|
ienv->SetObjectField(resobj, jfield_RouteSegmentResult_preAttachedRoutes, ar);
|
||||||
|
if(reg != NULL) {
|
||||||
|
ienv->DeleteLocalRef(reg);
|
||||||
|
}
|
||||||
|
ienv->DeleteLocalRef(robj);
|
||||||
|
ienv->DeleteLocalRef(ar);
|
||||||
|
return resobj;
|
||||||
|
}
|
||||||
|
|
||||||
class NativeRoutingTile {
|
class NativeRoutingTile {
|
||||||
public:
|
public:
|
||||||
std::vector<RouteDataObject*> result;
|
std::vector<RouteDataObject*> result;
|
||||||
|
@ -583,20 +627,25 @@ extern "C" JNIEXPORT void JNICALL Java_net_osmand_NativeLibrary_deleteRouteSearc
|
||||||
//p RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig);
|
//p RouteSegmentResult[] nativeRouting(int[] coordinates, int[] state, String[] keyConfig, String[] valueConfig);
|
||||||
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_nativeRouting(JNIEnv* ienv,
|
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_nativeRouting(JNIEnv* ienv,
|
||||||
jobject obj, jintArray coordinates,
|
jobject obj, jintArray coordinates,
|
||||||
jintArray stateConfig, jobjectArray keyConfig, jobjectArray valueConfig) {
|
jintArray stateConfig, jobjectArray keyConfig, jobjectArray valueConfig, jfloat initDirection,
|
||||||
|
jobjectArray regions) {
|
||||||
|
|
||||||
vector<ROUTE_TRIPLE> cfg;
|
vector<ROUTE_TRIPLE> cfg;
|
||||||
int* data = ienv->GetIntArrayElements(stateConfig, NULL);
|
int* data = ienv->GetIntArrayElements(stateConfig, NULL);
|
||||||
for(int k = 0; k < ienv->GetArrayLength(stateConfig); k++) {
|
for(int k = 0; k < ienv->GetArrayLength(stateConfig); k++) {
|
||||||
|
jstring kl = (jstring)ienv->GetObjectArrayElement(keyConfig, k);
|
||||||
|
jstring vl = (jstring)ienv->GetObjectArrayElement(valueConfig, k);
|
||||||
ROUTE_TRIPLE t = ROUTE_TRIPLE (data[k], std::pair<string, string>(
|
ROUTE_TRIPLE t = ROUTE_TRIPLE (data[k], std::pair<string, string>(
|
||||||
getString(ienv, (jstring) ienv->GetObjectArrayElement(keyConfig, k)),
|
getString(ienv, kl),
|
||||||
getString(ienv, (jstring) ienv->GetObjectArrayElement(valueConfig, k)))
|
getString(ienv, vl))
|
||||||
);
|
);
|
||||||
|
ienv->DeleteLocalRef(kl);
|
||||||
|
ienv->DeleteLocalRef(vl);
|
||||||
cfg.push_back(t);
|
cfg.push_back(t);
|
||||||
}
|
}
|
||||||
ienv->ReleaseIntArrayElements(stateConfig, data, 0);
|
ienv->ReleaseIntArrayElements(stateConfig, data, 0);
|
||||||
|
|
||||||
RoutingConfiguration config(cfg);
|
RoutingConfiguration config(cfg, initDirection);
|
||||||
RoutingContext c(config);
|
RoutingContext c(config);
|
||||||
data = ienv->GetIntArrayElements(coordinates, NULL);
|
data = ienv->GetIntArrayElements(coordinates, NULL);
|
||||||
c.startX = data[0];
|
c.startX = data[0];
|
||||||
|
@ -606,16 +655,21 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_nativeRo
|
||||||
ienv->ReleaseIntArrayElements(coordinates, data, 0);
|
ienv->ReleaseIntArrayElements(coordinates, data, 0);
|
||||||
|
|
||||||
vector<RouteSegmentResult> r = searchRouteInternal(&c, false);
|
vector<RouteSegmentResult> r = searchRouteInternal(&c, false);
|
||||||
|
UNORDERED(map)<int64_t, int> indexes;
|
||||||
|
for (int t = 0; t< ienv->GetArrayLength(regions); t++) {
|
||||||
|
jobject oreg = ienv->GetObjectArrayElement(regions, t);
|
||||||
|
int64_t fp = ienv->GetIntField(oreg, jfield_RouteRegion_filePointer);
|
||||||
|
int64_t ln = ienv->GetIntField(oreg, jfield_RouteRegion_length);
|
||||||
|
ienv->DeleteLocalRef(oreg);
|
||||||
|
indexes[(fp <<31) + ln] = t;
|
||||||
|
}
|
||||||
|
|
||||||
// convert results
|
// convert results
|
||||||
jobjectArray res = ienv->NewObjectArray(r.size(), jclass_RouteSegmentResult, NULL);
|
jobjectArray res = ienv->NewObjectArray(r.size(), jclass_RouteSegmentResult, NULL);
|
||||||
for (int i = 0; i < r.size(); i++) {
|
for (int i = 0; i < r.size(); i++) {
|
||||||
jobject robj = convertRouteDataObjectToJava(ienv, r[i].object.get(), NULL);
|
jobject resobj = convertRouteSegmentResultToJava(ienv, r[i], indexes, regions);
|
||||||
jobject resobj = ienv->NewObject(jclass_RouteSegmentResult, jmethod_RouteSegmentResult_ctor, robj,
|
|
||||||
r[i].startPointIndex, r[i].endPointIndex);
|
|
||||||
ienv->SetObjectArrayElement(res, i, resobj);
|
ienv->SetObjectArrayElement(res, i, resobj);
|
||||||
ienv->DeleteLocalRef(robj);
|
|
||||||
ienv->DeleteLocalRef(resobj);
|
ienv->DeleteLocalRef(resobj);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (r.size() == 0) {
|
if (r.size() == 0) {
|
||||||
osmand_log_print(LOG_INFO, "No route found");
|
osmand_log_print(LOG_INFO, "No route found");
|
||||||
|
|
Loading…
Reference in a new issue