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);
|
||||
}
|
||||
|
||||
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();
|
||||
List<String> keys = new ArrayList<String>();
|
||||
List<String> values = new ArrayList<String>();
|
||||
|
@ -124,7 +125,8 @@ public class NativeLibrary {
|
|||
fillObjects(state, keys, values, 5, attrs);
|
||||
|
||||
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) {
|
||||
|
@ -156,7 +158,8 @@ public class NativeLibrary {
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -845,7 +845,7 @@ public class BinaryMapRouteReaderAdapter {
|
|||
RouteBorderLine ln = readBorderLine();
|
||||
if(ln.hasTox() && req.intersects(ln.getX(), ln.getY(), ln.getTox(), ln.getY())) {
|
||||
blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
||||
// FIXME
|
||||
// FIXME borders approach
|
||||
// } else if(ln.hasToy() && req.intersects(ln.getX(), ln.getY(), ln.getX(), ln.getToy())) {
|
||||
// blocksToRead.add(ln.getShiftToPointsBlock() + fp);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public class RouteDataObject {
|
|||
|
||||
public final RouteRegion region;
|
||||
// all these arrays supposed to be immutable!
|
||||
// These feilds accessible from C++
|
||||
// These fields accessible from C++
|
||||
public int[] types;
|
||||
public int[] pointsX;
|
||||
public int[] pointsY;
|
||||
|
@ -213,6 +213,7 @@ public class RouteDataObject {
|
|||
}
|
||||
|
||||
public double directionRoute(int startPoint, boolean plus) {
|
||||
// same goes to C++
|
||||
// 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
|
||||
// So it should be fix in both places
|
||||
|
|
|
@ -422,6 +422,7 @@ public class IndexRouteCreator extends AbstractIndexPartCreator {
|
|||
routeTree, false);
|
||||
TLongObjectHashMap<BinaryFileReference> base = writeBinaryRouteIndexHeader(writer,
|
||||
baserouteTree, true);
|
||||
// FIXME borders should not be committed in master branch
|
||||
// writeBorderBox(writer, routeBorders);
|
||||
// writeBorderBox(writer, baseRouteBorders);
|
||||
|
||||
|
|
|
@ -43,9 +43,9 @@ public class BinaryRoutePlanner {
|
|||
int px = MapUtils.get31TileNumberX(lon);
|
||||
int py = MapUtils.get31TileNumberY(lat);
|
||||
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
||||
ctx.loadTileData(px, py, 16, dataObjects);
|
||||
ctx.loadTileData(px, py, 17, dataObjects);
|
||||
if (dataObjects.isEmpty()) {
|
||||
ctx.loadTileData(px, py, 14, dataObjects);
|
||||
ctx.loadTileData(px, py, 15, dataObjects);
|
||||
}
|
||||
RouteSegment road = null;
|
||||
double sdist = 0;
|
||||
|
@ -334,10 +334,6 @@ public class BinaryRoutePlanner {
|
|||
graphSegments = graphDirectSegments;
|
||||
}
|
||||
|
||||
if(ctx.runRelaxingStrategy() ) {
|
||||
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
||||
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
||||
}
|
||||
// check if interrupted
|
||||
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
||||
throw new InterruptedException("Route calculation interrupted");
|
||||
|
@ -349,12 +345,12 @@ public class BinaryRoutePlanner {
|
|||
|
||||
|
||||
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) {
|
||||
RouteSegment previous = null;
|
||||
List<RouteSegmentResult> rlist = new ArrayList<RouteSegmentResult>();
|
||||
// always recalculate first 7 km
|
||||
int distanceThreshold = 7000;
|
||||
float distanceThreshold = ctx.config.recalculateDistance;
|
||||
float threshold = 0;
|
||||
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
|
||||
threshold += rr.getDistance();
|
||||
|
@ -489,16 +485,6 @@ public class BinaryRoutePlanner {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -984,6 +970,30 @@ public class BinaryRoutePlanner {
|
|||
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 {
|
||||
|
|
|
@ -5,12 +5,15 @@ import gnu.trove.map.hash.TLongObjectHashMap;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
@ -73,9 +76,9 @@ public class BinaryRoutePlannerOld {
|
|||
int px = MapUtils.get31TileNumberX(lon);
|
||||
int py = MapUtils.get31TileNumberY(lat);
|
||||
ArrayList<RouteDataObject> dataObjects = new ArrayList<RouteDataObject>();
|
||||
ctx.loadTileData(px, py, 16, dataObjects);
|
||||
ctx.loadTileData(px, py, 17, dataObjects);
|
||||
if (dataObjects.isEmpty()) {
|
||||
ctx.loadTileData(px, py, 14, dataObjects);
|
||||
ctx.loadTileData(px, py, 15, dataObjects);
|
||||
}
|
||||
RouteSegment road = null;
|
||||
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 {
|
||||
// Split into 2 methods to let GC work in between
|
||||
searchRouteInternal(ctx, start, end, leftSideNavigation);
|
||||
// 4. Route is found : collect all segments and prepare result
|
||||
return new RouteResultPreparation().prepareResult(ctx, ctx.finalRouteSegment, leftSideNavigation);
|
||||
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
|
||||
searchRouteInternal(ctx, start, end);
|
||||
// 4. Route is found : collect all segments and prepare result
|
||||
return new RouteResultPreparation().prepareResult(ctx, ctx.finalRouteSegment, leftSideNavigation);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
|
||||
* 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
|
||||
ctx.timeToLoad = 0;
|
||||
ctx.visitedSegments = 0;
|
||||
|
@ -250,12 +267,12 @@ public class BinaryRoutePlannerOld {
|
|||
TLongObjectHashMap<RouteSegment> visitedDirectSegments = 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) {
|
||||
RouteSegment previous = null;
|
||||
List<RouteSegmentResult> rlist = new ArrayList<RouteSegmentResult>();
|
||||
// always recalculate first 7 km
|
||||
int distanceThreshold = 7000;
|
||||
float distanceThreshold = ctx.config.recalculateDistance;
|
||||
float threshold = 0;
|
||||
for(RouteSegmentResult rr : ctx.previouslyCalculatedRoute) {
|
||||
threshold += rr.getDistance();
|
||||
|
@ -340,11 +357,6 @@ public class BinaryRoutePlannerOld {
|
|||
} else {
|
||||
graphSegments = graphDirectSegments;
|
||||
}
|
||||
|
||||
if(ctx.runRelaxingStrategy() ) {
|
||||
relaxNotNeededSegments(ctx, graphDirectSegments, true);
|
||||
relaxNotNeededSegments(ctx, graphReverseSegments, false);
|
||||
}
|
||||
// check if interrupted
|
||||
if(ctx.interruptable != null && ctx.interruptable.isCancelled()) {
|
||||
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,
|
||||
int startX, int startY) {
|
||||
|
@ -394,16 +377,6 @@ public class BinaryRoutePlannerOld {
|
|||
|
||||
protected static double h(RoutingContext ctx, double distToFinalPoint, RouteSegment next) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.text.MessageFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
|
@ -20,9 +21,12 @@ public class RouteResultPreparation {
|
|||
*/
|
||||
List<RouteSegmentResult> prepareResult(RoutingContext ctx, FinalRouteSegment finalSegment,boolean leftside) {
|
||||
List<RouteSegmentResult> result = convertFinalSegmentToResults(ctx, finalSegment);
|
||||
prepareResult(ctx, leftside, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
List<RouteSegmentResult> prepareResult(RoutingContext ctx, boolean leftside, List<RouteSegmentResult> result) {
|
||||
validateAllPointsConnected(result);
|
||||
|
||||
// calculate time
|
||||
calculateTimeSpeedAndAttachRoadSegments(ctx, result);
|
||||
|
||||
|
@ -47,12 +51,12 @@ public class RouteResultPreparation {
|
|||
double distance = 0;
|
||||
for (int j = rr.getStartPointIndex(); j != rr.getEndPointIndex(); j = next) {
|
||||
next = plus ? j + 1 : j - 1;
|
||||
if(j == rr.getStartPointIndex()) {
|
||||
attachRoadSegments(ctx, result, i, j, plus);
|
||||
}
|
||||
if(next != rr.getEndPointIndex()) {
|
||||
attachRoadSegments(ctx, result, i, next, plus);
|
||||
}
|
||||
if (j == rr.getStartPointIndex()) {
|
||||
attachRoadSegments(ctx, result, i, j, plus);
|
||||
}
|
||||
if (next != rr.getEndPointIndex()) {
|
||||
attachRoadSegments(ctx, result, i, next, plus);
|
||||
}
|
||||
|
||||
double d = measuredDist(road.getPoint31XTile(j), road.getPoint31YTile(j), road.getPoint31XTile(next),
|
||||
road.getPoint31YTile(next));
|
||||
|
@ -81,6 +85,7 @@ public class RouteResultPreparation {
|
|||
if (isSplit) {
|
||||
int endPointIndex = rr.getEndPointIndex();
|
||||
RouteSegmentResult split = new RouteSegmentResult(rr.getObject(), next, endPointIndex);
|
||||
split.copyPreattachedRoutes(rr, Math.abs(next - rr.getStartPointIndex()));
|
||||
rr.setSegmentTime((float) distOnRoadToPass);
|
||||
rr.setSegmentSpeed((float) speed);
|
||||
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
|
||||
while (routeSegment != null) {
|
||||
while (it.hasNext()) {
|
||||
RouteSegment routeSegment = it.next();
|
||||
if (routeSegment.road.getId() != road.getId() && routeSegment.road.getId() != previousRoadId) {
|
||||
RouteDataObject addRoad = routeSegment.road;
|
||||
|
||||
// TODO restrictions can be considered as well
|
||||
int oneWay = ctx.getRouter().isOneWay(addRoad);
|
||||
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 endPointIndex;
|
||||
private List<RouteSegmentResult>[] attachedRoutes;
|
||||
private RouteSegmentResult[][] preAttachedRoutes;
|
||||
private float segmentTime;
|
||||
private float speed;
|
||||
private float distance;
|
||||
|
@ -28,6 +29,7 @@ public class RouteSegmentResult {
|
|||
this.endPointIndex = endPointIndex;
|
||||
updateCapacity();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void updateCapacity() {
|
||||
|
@ -43,6 +45,20 @@ public class RouteSegmentResult {
|
|||
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) {
|
||||
int st = Math.abs(routeInd - startPointIndex);
|
||||
List<RouteSegmentResult> list = attachedRoutes[st];
|
||||
|
|
|
@ -39,6 +39,9 @@ public class RoutingConfiguration {
|
|||
// 1.4 Used to calculate route in movement
|
||||
public Double initialDirection;
|
||||
|
||||
// 1.5 Recalculate distance help
|
||||
public float recalculateDistance = 10000f;
|
||||
|
||||
|
||||
|
||||
public static class Builder {
|
||||
|
@ -67,6 +70,7 @@ public class RoutingConfiguration {
|
|||
attributes.put("routerName", router);
|
||||
i.attributes.putAll(attributes);
|
||||
i.initialDirection = direction;
|
||||
i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ;
|
||||
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
|
||||
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
|
||||
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
|
||||
|
@ -78,7 +82,7 @@ public class RoutingConfiguration {
|
|||
}
|
||||
i.memoryLimitation = memoryLimitMB * (1 << 20);
|
||||
}
|
||||
i.planRoadDirection = parseSilentInt(getAttribute(router, "planRoadDirection"), i.planRoadDirection);
|
||||
i.planRoadDirection = parseSilentInt(getAttribute(i.router, "planRoadDirection"), i.planRoadDirection);
|
||||
|
||||
|
||||
return i;
|
||||
|
|
|
@ -54,7 +54,6 @@ public class RoutingContext {
|
|||
public final Map<RouteRegion, BinaryMapIndexReader> reverseMap = new LinkedHashMap<RouteRegion, BinaryMapIndexReader>();
|
||||
|
||||
// 1. Initial variables
|
||||
private int relaxingIteration = 0;
|
||||
public long firstRoadId = 0;
|
||||
public int firstRoadDirection = 0;
|
||||
|
||||
|
@ -179,42 +178,11 @@ public class RoutingContext {
|
|||
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) {
|
||||
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) {
|
||||
config.router = router;
|
||||
}
|
||||
|
@ -350,7 +318,7 @@ public class RoutingContext {
|
|||
borderLineCoordinates = new int[borderLines.length];
|
||||
for(int i=0; i<borderLineCoordinates.length; i++) {
|
||||
borderLineCoordinates[i] = borderLines[i].borderLine;
|
||||
// FIXME
|
||||
// FIXME borders approach
|
||||
// not less then 14th zoom
|
||||
if(i > 0 && borderLineCoordinates[i - 1] >> 17 == borderLineCoordinates[i] >> 17) {
|
||||
throw new IllegalStateException();
|
||||
|
@ -517,13 +485,15 @@ public class RoutingContext {
|
|||
}
|
||||
|
||||
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) {
|
||||
t = 1;
|
||||
coordinatesShift = (1 << (31 - zoomAround));
|
||||
} else {
|
||||
t = 1 << t;
|
||||
}
|
||||
int coordinatesShift = (1 << (31 - config.ZOOM_TO_LOAD_TILES));
|
||||
|
||||
TLongHashSet ts = new TLongHashSet();
|
||||
long now = System.nanoTime();
|
||||
for(int i = -t; i <= t; i++) {
|
||||
|
|
|
@ -12,23 +12,24 @@
|
|||
(don't specify here ! it is device dependent) -->
|
||||
<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 -->
|
||||
<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 -->
|
||||
<!-- 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) -->
|
||||
<!-- 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="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 -->
|
||||
<!-- penalty is measured in time and -1 means it could not be passed! -->
|
||||
<!-- <obstacle tag="highway" value="traffic_signals" penalty="35"/> -->
|
||||
<!-- 3) Avoid describes what road should be completely avoided or passed with multiplied (decreased) priority -->
|
||||
<!-- <avoid tag="access" value="no" decreasedPriority="0.9"/> -->
|
||||
|
||||
|
||||
<!-- 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"
|
||||
leftTurn="0" rightTurn="0" roundaboutTurn="0" followSpeedLimitations="true" onewayAware="true">
|
||||
|
@ -36,55 +37,55 @@
|
|||
<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"/>
|
||||
</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"/>
|
||||
</road>
|
||||
|
||||
<road tag="highway" value="trunk" speed="100" priority="1.2" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="trunk_link" speed="75" 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" />
|
||||
|
||||
<!-- generally linking larger towns. -->
|
||||
<road tag="highway" value="primary" speed="65" priority="1.1" dynamicPriority="0.7"/>
|
||||
<road tag="highway" value="primary_link" speed="50" 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.05" />
|
||||
|
||||
<!-- generally linking smaller towns and villages -->
|
||||
<road tag="highway" value="secondary" speed="60" priority="1.05" dynamicPriority="0.6"/>
|
||||
<road tag="highway" value="secondary_link" speed="50" 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" />
|
||||
<!-- important urban roads -->
|
||||
<road tag="highway" value="tertiary" speed="45" priority="1" dynamicPriority="0.5"/>
|
||||
<road tag="highway" value="tertiary_link" speed="40" priority="1" dynamicPriority="0.5"/>
|
||||
<road tag="highway" value="tertiary" speed="45" priority="0.95" />
|
||||
<road tag="highway" value="tertiary_link" speed="40" priority="0.95" />
|
||||
<!-- lowest form of grid network, usually 90% of urban roads -->
|
||||
<road tag="highway" value="unclassified" speed="35" priority="0.7" dynamicPriority="0.3">
|
||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
|
||||
<road tag="highway" value="unclassified" speed="35" priority="0.7" >
|
||||
<specialization input="short_way" priority="1" speed="45"/>
|
||||
</road>
|
||||
<!-- 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"/>
|
||||
</road>
|
||||
<!-- primarily for access to properties, small roads with 1/2 intersections -->
|
||||
<road tag="highway" value="residential" speed="35" priority="0.7" dynamicPriority="0.3">
|
||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
|
||||
<road tag="highway" value="residential" speed="35" priority="0.7" >
|
||||
<specialization input="short_way" priority="1" speed="45"/>
|
||||
</road>
|
||||
<!-- parking + private roads -->
|
||||
<road tag="highway" value="service" speed="30" priority="0.5" dynamicPriority="0.3">
|
||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="45"/>
|
||||
<road tag="highway" value="service" speed="30" priority="0.5" >
|
||||
<specialization input="short_way" priority="1" speed="45"/>
|
||||
</road>
|
||||
<!-- very bad roads -->
|
||||
<road tag="highway" value="track" speed="15" priority="0.3" dynamicPriority="0.2">
|
||||
<specialization input="short_way" priority="0.7" speed="45" dynamicPriority="0.7" />
|
||||
<road tag="highway" value="track" speed="15" priority="0.3" >
|
||||
<specialization input="short_way" priority="0.7" speed="45" />
|
||||
<specialization input="avoid_unpaved" priority="0.1"/>
|
||||
</road>
|
||||
|
||||
<!-- too small for cars usually -->
|
||||
<road tag="highway" value="living_street" speed="25" priority="0.5" dynamicPriority="0.3">
|
||||
<specialization input="short_way" priority="1" dynamicPriority="1" speed="35"/>
|
||||
<road tag="highway" value="living_street" speed="25" priority="0.5" >
|
||||
<specialization input="short_way" priority="1" speed="35"/>
|
||||
</road>
|
||||
<!-- car are able to enter in highway=pedestrian with restrictions -->
|
||||
<!-- 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"/>
|
||||
</road>
|
||||
|
||||
|
@ -121,36 +122,36 @@
|
|||
leftTurn="0" rightTurn="0" followSpeedLimitations="false" onewayAware="true">
|
||||
<!-- <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"/>
|
||||
</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"/>
|
||||
</road>
|
||||
|
||||
<road tag="highway" value="trunk" speed="16" priority="0.6" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="trunk_link" speed="16" priority="0.7" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="primary" speed="16" priority="0.8" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="primary_link" speed="16" priority="0.8" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="secondary" speed="16" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="secondary_link" speed="16" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="tertiary" speed="16" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="tertiary_link" speed="16" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="road" speed="16" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="residential" speed="16" priority="1.1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="cycleway" speed="16" priority="1.5" dynamicPriority="1.3"/>
|
||||
<road tag="highway" value="trunk" speed="16" priority="0.6" />
|
||||
<road tag="highway" value="trunk_link" speed="16" priority="0.7" />
|
||||
<road tag="highway" value="primary" speed="16" priority="0.8" />
|
||||
<road tag="highway" value="primary_link" speed="16" priority="0.8" />
|
||||
<road tag="highway" value="secondary" speed="16" priority="1" />
|
||||
<road tag="highway" value="secondary_link" speed="16" priority="1" />
|
||||
<road tag="highway" value="tertiary" speed="16" priority="1" />
|
||||
<road tag="highway" value="tertiary_link" speed="16" priority="1" />
|
||||
<road tag="highway" value="road" speed="16" priority="1" />
|
||||
<road tag="highway" value="residential" speed="16" priority="1.1" />
|
||||
<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="service" speed="13" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="track" speed="12" priority="1.5" dynamicPriority="1.5"/>
|
||||
<road tag="highway" value="path" speed="12" priority="1.5" dynamicPriority="1.5"/>
|
||||
<road tag="highway" value="living_street" speed="15" priority="1.1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="pedestrian" speed="10" priority="0.9" dynamicPriority="1"/>
|
||||
<road tag="highway" value="footway" speed="8" priority="0.9" dynamicPriority="1"/>
|
||||
<road tag="highway" value="byway" speed="8" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="services" speed="13" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="bridleway" speed="8" priority="0.8" dynamicPriority="1"/>
|
||||
<road tag="highway" value="steps" speed="3" priority="0.5" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="unclassified" speed="13" priority="1" />
|
||||
<road tag="highway" value="service" speed="13" priority="1" />
|
||||
<road tag="highway" value="track" speed="12" priority="1.5" />
|
||||
<road tag="highway" value="path" speed="12" priority="1.5" />
|
||||
<road tag="highway" value="living_street" speed="15" priority="1.1" />
|
||||
<road tag="highway" value="pedestrian" speed="10" priority="0.9" />
|
||||
<road tag="highway" value="footway" speed="8" priority="0.9" />
|
||||
<road tag="highway" value="byway" speed="8" priority="1" />
|
||||
<road tag="highway" value="services" speed="13" priority="1" />
|
||||
<road tag="highway" value="bridleway" speed="8" priority="0.8" />
|
||||
<road tag="highway" value="steps" speed="3" priority="0.5" />
|
||||
|
||||
<obstacle tag="highway" value="traffic_signals" penalty="25" routingPenalty="10"/>
|
||||
<obstacle tag="railway" value="crossing" penalty="15"/>
|
||||
|
@ -171,36 +172,36 @@
|
|||
|
||||
<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"/>
|
||||
</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"/>
|
||||
</road>
|
||||
|
||||
<road tag="highway" value="trunk" speed="5" priority="0.7" dynamicPriority="0.7"/>
|
||||
<road tag="highway" value="trunk_link" speed="5" priority="0.7" dynamicPriority="0.7"/>
|
||||
<road tag="highway" value="primary" speed="5" priority="0.9" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="primary_link" speed="5" priority="0.9" dynamicPriority="0.9"/>
|
||||
<road tag="highway" value="secondary" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="secondary_link" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="tertiary" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="tertiary_link" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="road" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="residential" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="cycleway" speed="5" priority="1" dynamicPriority="1.1"/>
|
||||
<road tag="highway" value="trunk" speed="5" priority="0.7" />
|
||||
<road tag="highway" value="trunk_link" speed="5" priority="0.7" />
|
||||
<road tag="highway" value="primary" speed="5" priority="0.9" />
|
||||
<road tag="highway" value="primary_link" speed="5" priority="0.9" />
|
||||
<road tag="highway" value="secondary" speed="5" priority="1" />
|
||||
<road tag="highway" value="secondary_link" speed="5" priority="1" />
|
||||
<road tag="highway" value="tertiary" speed="5" priority="1" />
|
||||
<road tag="highway" value="tertiary_link" speed="5" priority="1" />
|
||||
<road tag="highway" value="road" speed="5" priority="1" />
|
||||
<road tag="highway" value="residential" speed="5" priority="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="service" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="track" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="path" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="living_street" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="pedestrian" speed="5" priority="1.2" dynamicPriority="1.1"/>
|
||||
<road tag="highway" value="footway" speed="5" priority="1.2" dynamicPriority="1.1"/>
|
||||
<road tag="highway" value="byway" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="services" speed="5" priority="1" dynamicPriority="1"/>
|
||||
<road tag="highway" value="bridleway" speed="5" priority="0.8" dynamicPriority="0.8"/>
|
||||
<road tag="highway" value="steps" speed="4" priority="1.2" dynamicPriority="1"/>
|
||||
<road tag="highway" value="unclassified" speed="5" priority="1" />
|
||||
<road tag="highway" value="service" speed="5" priority="1" />
|
||||
<road tag="highway" value="track" speed="5" priority="1" />
|
||||
<road tag="highway" value="path" speed="5" priority="1" />
|
||||
<road tag="highway" value="living_street" speed="5" priority="1" />
|
||||
<road tag="highway" value="pedestrian" speed="5" priority="1.2" />
|
||||
<road tag="highway" value="footway" speed="5" priority="1.2" />
|
||||
<road tag="highway" value="byway" speed="5" priority="1" />
|
||||
<road tag="highway" value="services" speed="5" priority="1" />
|
||||
<road tag="highway" value="bridleway" speed="5" priority="0.8" />
|
||||
<road tag="highway" value="steps" speed="4" priority="1.2" />
|
||||
|
||||
<obstacle tag="highway" value="traffic_signals" penalty="30"/>
|
||||
<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());
|
||||
int sx31 = st.getRoad().getPoint31XTile(st.getSegmentStart());
|
||||
int sy31 = st.getRoad().getPoint31YTile(st.getSegmentStart());
|
||||
// FIXME
|
||||
RouteSegmentResult[] searchRoute = ctx.nativeLib.runNativeRouting(sx31, sy31, ex31, ey31, ctx.config);
|
||||
// /*List<RouteSegmentResult> searchRoute = */router.searchRoute(ctx, st, e, inters, false);
|
||||
// this.previousRoute = searchRoute;
|
||||
|
||||
// Choose native or not native
|
||||
long nt = System.nanoTime();
|
||||
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, inters, false);
|
||||
System.out.println("External native time " + (System.nanoTime() - nt) / 1e9f);
|
||||
if (animateRoutingCalculation) {
|
||||
playPauseButton.setVisible(false);
|
||||
nextTurn.setText("FINISH");
|
||||
|
@ -742,7 +739,6 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
// String name = String.format("beg %.2f end %.2f ", s.getBearingBegin(), s.getBearingEnd());
|
||||
way.putTag(OSMTagKey.NAME.getValue(),name);
|
||||
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
|
||||
System.out.println("Segment " + s.getObject().id + " "+s.getStartPointIndex() + " -> " + s.getEndPointIndex());
|
||||
int i = s.getStartPointIndex();
|
||||
while (true) {
|
||||
LatLon l = s.getPoint(i);
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <map>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#include "mapObjects.h"
|
||||
#include "multipolygons.h"
|
||||
#include "common.h"
|
||||
|
@ -108,6 +106,61 @@ struct RouteDataObject {
|
|||
|
||||
UNORDERED(map)<int, std::string > names;
|
||||
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 const int REVERSE_WAY_RESTRICTION_ONLY = 1024;
|
||||
static const int STANDARD_ROAD_IN_QUEUE_OVERHEAD = 900;
|
||||
|
||||
static const int ROUTE_POINTS = 11;
|
||||
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_LEFT_TURN = 6;
|
||||
static const short RESTRICTION_ONLY_STRAIGHT_ON = 7;
|
||||
static const bool TRACE_ROUTING = false;
|
||||
|
||||
inline int roadPriorityComparator(float o1DistanceFromStart, float o1DistanceToEnd,
|
||||
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
|
||||
{
|
||||
return roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart,
|
||||
rhs.get()->distanceToEnd, ctx->getHeuristicCoefficient()) > 0;
|
||||
int cmp = roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart,
|
||||
rhs.get()->distanceToEnd, ctx->getHeuristicCoefficient());
|
||||
return cmp > 0;
|
||||
}
|
||||
};
|
||||
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,
|
||||
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)
|
||||
* return list of segments
|
||||
*/
|
||||
void searchRouteInternal(RoutingContext* ctx, SHARED_PTR<RouteSegment> start, SHARED_PTR<RouteSegment> end, bool leftSideNavigation) {
|
||||
// FIXME intermediate points
|
||||
// measure time
|
||||
ctx->visitedSegments = 0;
|
||||
ctx->timeToCalculate.start();
|
||||
// FIXME initial direction
|
||||
// if(ctx.config.initialDirection != null) {
|
||||
// ctx.firstRoadId = (start->road->id << ROUTE_POINTS) + start.getSegmentStart();
|
||||
// double plusDir = start->road->directionRoute(start.segmentStart, true);
|
||||
// double diff = plusDir - ctx.config.initialDirection;
|
||||
// if(Math.abs(MapUtils.alignAngleDifference(diff)) <= Math.PI / 3) {
|
||||
// ctx.firstRoadDirection = 1;
|
||||
// } else if(Math.abs(MapUtils.alignAngleDifference(diff - Math.PI)) <= Math.PI / 3) {
|
||||
// ctx.firstRoadDirection = -1;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
if(ctx->config.initialDirection != -360) {
|
||||
ctx->firstRoadId = (start->road->id << ROUTE_POINTS) + start->getSegmentStart();
|
||||
double plusDir = start->road->directionRoute(start->getSegmentStart(), true);
|
||||
double diff = plusDir - ctx->config.initialDirection;
|
||||
if(abs(alignAngleDifference(diff)) <= M_PI / 3) {
|
||||
ctx->firstRoadDirection = 1;
|
||||
} else if(abs(alignAngleDifference(diff - M_PI )) <= M_PI / 3) {
|
||||
ctx->firstRoadDirection = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SegmentsComparator sgmCmp(ctx);
|
||||
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 ) ",
|
||||
ctx-> visitedSegments, visitedDirectSegments.size(), visitedOppositeSegments.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,
|
||||
SEGMENTS_QUEUE& graphSegments, VISITED_MAP& visitedSegments, int targetEndX, int targetEndY,
|
||||
SHARED_PTR<RouteSegment> segment, VISITED_MAP& oppositeSegments) {
|
||||
|
@ -206,6 +224,10 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
|
|||
if(visitedSegments.find(nt) != visitedSegments.end()) {
|
||||
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++;
|
||||
// avoid empty segments to connect but mark the point as visited
|
||||
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");
|
||||
// }
|
||||
SHARED_PTR<RouteSegment> next = ctx->loadRouteSegment(x, y);
|
||||
|
||||
// 3. get intersected ways
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
||||
// road.id could be equal on roundabout, but we should accept them
|
||||
bool alreadyVisited = visitedSegments.find(nts) != visitedSegments.end();
|
||||
if (!alreadyVisited) {
|
||||
|
@ -463,6 +485,9 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
|||
// put additional information to recover whole route after
|
||||
next->parentRoute = segment;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
|
@ -490,9 +515,9 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|
|||
|
||||
SHARED_PTR<RouteSegment> findRouteSegment(int px, int py, RoutingContext* ctx) {
|
||||
vector<SHARED_PTR<RouteDataObject> > dataObjects;
|
||||
ctx->loadTileData(px, py, 16, dataObjects);
|
||||
ctx->loadTileData(px, py, 17, dataObjects);
|
||||
if (dataObjects.size() == 0) {
|
||||
ctx->loadTileData(px, py, 14, dataObjects);
|
||||
ctx->loadTileData(px, py, 15, dataObjects);
|
||||
}
|
||||
SHARED_PTR<RouteSegment> road;
|
||||
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> result;
|
||||
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);
|
||||
}
|
||||
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()
|
||||
, ctx->timeToCalculate.getElapsedTime(), ctx->loadedTiles);
|
||||
return convertFinalSegmentToResults(ctx);
|
||||
vector<RouteSegmentResult> res = convertFinalSegmentToResults(ctx);
|
||||
attachConnectedRoads(ctx, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ struct RouteSegmentResult {
|
|||
SHARED_PTR<RouteDataObject> object;
|
||||
int startPointIndex;
|
||||
int endPointIndex;
|
||||
vector<vector<RouteSegmentResult> > attachedRoutes;
|
||||
RouteSegmentResult(SHARED_PTR<RouteDataObject> object, int startPointIndex, int endPointIndex) :
|
||||
object(object), startPointIndex(startPointIndex), endPointIndex (endPointIndex) {
|
||||
|
||||
|
@ -62,10 +63,11 @@ struct RoutingSubregionTile {
|
|||
// make it without get/set for fast access
|
||||
int access;
|
||||
int loaded;
|
||||
int size ;
|
||||
UNORDERED(map)<int64_t, SHARED_PTR<RouteSegment> > routes;
|
||||
|
||||
RoutingSubregionTile(RouteSubregion& sub) : access(0), loaded(0), subregion(sub) {
|
||||
|
||||
size = sizeof(RoutingSubregionTile);
|
||||
}
|
||||
~RoutingSubregionTile(){
|
||||
}
|
||||
|
@ -77,7 +79,12 @@ struct RoutingSubregionTile {
|
|||
loaded++;
|
||||
}
|
||||
|
||||
int getSize(){
|
||||
return size + routes.size() * sizeof(std::pair<int64_t, SHARED_PTR<RouteSegment> >);
|
||||
}
|
||||
|
||||
void add(SHARED_PTR<RouteDataObject> o) {
|
||||
size += o->getSize() + sizeof(RouteSegment)* o->pointsX.size();
|
||||
for (int i = 0; i < o->pointsX.size(); i++) {
|
||||
uint64_t x31 = o->pointsX[i];
|
||||
uint64_t y31 = o->pointsY[i];
|
||||
|
@ -98,7 +105,7 @@ struct RoutingSubregionTile {
|
|||
}
|
||||
};
|
||||
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;
|
||||
|
@ -127,6 +134,7 @@ struct RoutingConfiguration {
|
|||
int planRoadDirection;
|
||||
string routerName;
|
||||
float initialDirection;
|
||||
float distanceRecalculate;
|
||||
string routerProfile;
|
||||
float roundaboutTurn;
|
||||
float leftTurn;
|
||||
|
@ -166,9 +174,10 @@ struct RoutingConfiguration {
|
|||
zoomToLoad = (int)parseFloat("zoomToLoadTiles", 16);
|
||||
routerName = parseString("name", "default");
|
||||
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) {
|
||||
for(int j = 0; j<config.size(); j++) {
|
||||
ROUTE_TRIPLE r = config[j];
|
||||
|
@ -341,6 +350,8 @@ struct RoutingConfiguration {
|
|||
|
||||
|
||||
struct RoutingContext {
|
||||
typedef UNORDERED(map)<int64_t, SHARED_PTR<RoutingSubregionTile> > MAP_SUBREGION_TILES;
|
||||
|
||||
int visitedSegments;
|
||||
int loadedTiles;
|
||||
ElapsedTimer timeToLoad;
|
||||
|
@ -358,7 +369,7 @@ struct RoutingContext {
|
|||
vector<SHARED_PTR<RouteSegment> > segmentsToVisitPrescripted;
|
||||
|
||||
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;
|
||||
|
||||
RoutingContext(RoutingConfiguration& config) : finalRouteSegment(), firstRoadDirection(0), loadedTiles(0), visitedSegments(0),
|
||||
|
@ -369,6 +380,16 @@ struct RoutingContext {
|
|||
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) {
|
||||
vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions[tileId];
|
||||
for(int j = 0; j<subregions.size(); j++) {
|
||||
|
@ -404,27 +425,27 @@ struct RoutingContext {
|
|||
std::vector<SHARED_PTR<RoutingSubregionTile> > collection;
|
||||
for(int i=0; i<tempResult.size(); 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()) {
|
||||
subregionTiles[key] = SHARED_PTR<RoutingSubregionTile>(new RoutingSubregionTile(rs));
|
||||
}
|
||||
collection.push_back(subregionTiles[key]);
|
||||
}
|
||||
//osmand_log_print(LOG_INFO, "Native load %d %d (%d)", xloc, yloc, tempResult.size());
|
||||
indexedSubregions[tileId] = collection;
|
||||
}
|
||||
loadHeaderObjects(tileId);
|
||||
timeToLoad.pause();
|
||||
}
|
||||
|
||||
void loadTileData(int x31, int y31, int zoomAround, vector<SHARED_PTR<RouteDataObject> >& dataObjects ){
|
||||
int t = zoomAround - config.zoomToLoad;
|
||||
void loadTileData(int x31, int y31, int zoomAround, vector<SHARED_PTR<RouteDataObject> >& dataObjects ) {
|
||||
int t = config.zoomToLoad - zoomAround;
|
||||
int coordinatesShift = (1 << (31 - config.zoomToLoad));
|
||||
if(t <= 0) {
|
||||
t = 1;
|
||||
coordinatesShift = (1 << (31 - zoomAround));
|
||||
} else {
|
||||
t = 1 << t;
|
||||
}
|
||||
int coordinatesShift = (1 << (31 - config.zoomToLoad));
|
||||
UNORDERED(set)<int64_t> ids;
|
||||
int z = config.zoomToLoad;
|
||||
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));
|
||||
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 convert31YToMeters(int y1, int y2);
|
||||
double convert31XToMeters(int y1, int y2);
|
||||
double alignAngleDifference(double diff);
|
||||
|
||||
|
||||
#endif /*_OSMAND_COMMON_H*/
|
||||
|
|
|
@ -410,17 +410,25 @@ jfieldID jfield_RouteSubregion_top = NULL;
|
|||
jfieldID jfield_RouteSubregion_bottom = 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_RouteSegmentResultAr = NULL;
|
||||
jmethodID jmethod_RouteSegmentResult_ctor = NULL;
|
||||
jfieldID jfield_RouteSegmentResult_preAttachedRoutes = NULL;
|
||||
|
||||
|
||||
|
||||
void loadJniRenderingContext(JNIEnv* env)
|
||||
{
|
||||
jclass_RouteSegmentResult = findClass(env, "net/osmand/router/RouteSegmentResult");
|
||||
jclass_RouteSegmentResultAr = findClass(env, "[Lnet/osmand/router/RouteSegmentResult;");
|
||||
jmethod_RouteSegmentResult_ctor = env->GetMethodID(jclass_RouteSegmentResult,
|
||||
"<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");
|
||||
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");
|
||||
|
||||
|
||||
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");
|
||||
jfield_RouteSubregion_length= getFid(env, jclass_RouteSubregion, "length", "I" );
|
||||
jfield_RouteSubregion_filePointer= getFid(env, jclass_RouteSubregion, "filePointer", "I" );
|
||||
|
@ -563,6 +575,38 @@ jobject convertRouteDataObjectToJava(JNIEnv* ienv, RouteDataObject* route, jobje
|
|||
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 {
|
||||
public:
|
||||
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);
|
||||
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_nativeRouting(JNIEnv* ienv,
|
||||
jobject obj, jintArray coordinates,
|
||||
jintArray stateConfig, jobjectArray keyConfig, jobjectArray valueConfig) {
|
||||
jintArray stateConfig, jobjectArray keyConfig, jobjectArray valueConfig, jfloat initDirection,
|
||||
jobjectArray regions) {
|
||||
|
||||
vector<ROUTE_TRIPLE> cfg;
|
||||
int* data = ienv->GetIntArrayElements(stateConfig, NULL);
|
||||
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>(
|
||||
getString(ienv, (jstring) ienv->GetObjectArrayElement(keyConfig, k)),
|
||||
getString(ienv, (jstring) ienv->GetObjectArrayElement(valueConfig, k)))
|
||||
getString(ienv, kl),
|
||||
getString(ienv, vl))
|
||||
);
|
||||
ienv->DeleteLocalRef(kl);
|
||||
ienv->DeleteLocalRef(vl);
|
||||
cfg.push_back(t);
|
||||
}
|
||||
ienv->ReleaseIntArrayElements(stateConfig, data, 0);
|
||||
|
||||
RoutingConfiguration config(cfg);
|
||||
RoutingConfiguration config(cfg, initDirection);
|
||||
RoutingContext c(config);
|
||||
data = ienv->GetIntArrayElements(coordinates, NULL);
|
||||
c.startX = data[0];
|
||||
|
@ -606,16 +655,21 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_nativeRo
|
|||
ienv->ReleaseIntArrayElements(coordinates, data, 0);
|
||||
|
||||
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
|
||||
jobjectArray res = ienv->NewObjectArray(r.size(), jclass_RouteSegmentResult, NULL);
|
||||
for (int i = 0; i < r.size(); i++) {
|
||||
jobject robj = convertRouteDataObjectToJava(ienv, r[i].object.get(), NULL);
|
||||
jobject resobj = ienv->NewObject(jclass_RouteSegmentResult, jmethod_RouteSegmentResult_ctor, robj,
|
||||
r[i].startPointIndex, r[i].endPointIndex);
|
||||
jobject resobj = convertRouteSegmentResultToJava(ienv, r[i], indexes, regions);
|
||||
ienv->SetObjectArrayElement(res, i, resobj);
|
||||
ienv->DeleteLocalRef(robj);
|
||||
ienv->DeleteLocalRef(resobj);
|
||||
|
||||
}
|
||||
if (r.size() == 0) {
|
||||
osmand_log_print(LOG_INFO, "No route found");
|
||||
|
|
Loading…
Reference in a new issue