diff --git a/OsmAnd-java/src/main/java/net/osmand/router/BinaryRoutePlanner.java b/OsmAnd-java/src/main/java/net/osmand/router/BinaryRoutePlanner.java index cf7eacd2ee..fe7780ea0f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/BinaryRoutePlanner.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/BinaryRoutePlanner.java @@ -68,7 +68,6 @@ public class BinaryRoutePlanner { FinalRouteSegment searchRouteInternal(final RoutingContext ctx, RouteSegmentPoint start, RouteSegmentPoint end, RouteSegment recalculationEnd ) throws InterruptedException, IOException { // measure time - ctx.timeToLoad = 0; ctx.memoryOverhead = 1000; // Initializing priority queue to visit way segments @@ -120,7 +119,9 @@ public class BinaryRoutePlanner { if (ctx.memoryOverhead > ctx.config.memoryLimitation * 0.95) { throw new IllegalStateException("There is not enough memory " + ctx.config.memoryLimitation / (1 << 20) + " Mb"); } - ctx.visitedSegments ++; + if (ctx.calculationProgress != null) { + ctx.calculationProgress.visitedSegments++; + } if (forwardSearch) { boolean doNotAddIntersections = onlyBackward; processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, @@ -164,12 +165,14 @@ public class BinaryRoutePlanner { throw new InterruptedException("Route calculation interrupted"); } } - ctx.visitedSegments += visitedDirectSegments.size() + visitedOppositeSegments.size(); - ctx.visitedDirectSegments += visitedDirectSegments.size(); - ctx.visitedOppositeSegments += visitedOppositeSegments.size(); - ctx.directQueueSize = graphDirectSegments.size(); // Math.max(ctx.directQueueSize, graphDirectSegments.size()); - ctx.oppositeQueueSize = graphReverseSegments.size(); - ctx.visitedOppositeSegments += visitedOppositeSegments.size(); + if (ctx.calculationProgress != null) { + ctx.calculationProgress.visitedDirectSegments += visitedDirectSegments.size(); + ctx.calculationProgress.visitedOppositeSegments += visitedOppositeSegments.size(); + ctx.calculationProgress.directQueueSize = graphDirectSegments.size(); // Math.max(ctx.directQueueSize, + // graphDirectSegments.size()); + ctx.calculationProgress.oppositeQueueSize = graphReverseSegments.size(); + ctx.calculationProgress.visitedOppositeSegments += visitedOppositeSegments.size(); + } return finalSegment; } @@ -371,18 +374,21 @@ public class BinaryRoutePlanner { } public static void printDebugMemoryInformation(RoutingContext ctx) { - printInfo(String.format("Time. Total: %.2f, to load: %.2f, to load headers: %.2f, to calc dev: %.2f ", - (System.nanoTime() - ctx.timeToCalculate) / 1e6, ctx.timeToLoad / 1e6, - ctx.timeToLoadHeaders / 1e6, ctx.timeNanoToCalcDeviation / 1e6)); -// GeneralRouter.TIMER = 0; - int maxLoadedTiles = Math.max(ctx.maxLoadedTiles, ctx.getCurrentlyLoadedTiles()); - printInfo("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + maxLoadedTiles); - printInfo("Loaded tiles " + ctx.loadedTiles + " (distinct " + ctx.distinctLoadedTiles + "), unloaded tiles " + ctx.unloadedTiles + - ", loaded more than once same tiles " - + ctx.loadedPrevUnloadedTiles); - printInfo("Visited segments " + ctx.visitedSegments + ", relaxed roads " + ctx.relaxedSegments); - printInfo("Priority queues sizes : " + ctx.directQueueSize + "/" + ctx.oppositeQueueSize); - printInfo("Visited interval sizes: " + ctx.visitedDirectSegments + "/" + ctx.visitedOppositeSegments); + if (ctx.calculationProgress != null) { + RouteCalculationProgress p = ctx.calculationProgress; + printInfo(String.format("Time. Total: %.2f, to load: %.2f, to load headers: %.2f, to calc dev: %.2f ", + p.timeToCalculate / 1e6, p.timeToLoad / 1e6, p.timeToLoadHeaders / 1e6, + p.timeNanoToCalcDeviation / 1e6)); + // GeneralRouter.TIMER = 0; + int maxLoadedTiles = Math.max(p.maxLoadedTiles, ctx.getCurrentlyLoadedTiles()); + printInfo("Current loaded tiles : " + ctx.getCurrentlyLoadedTiles() + ", maximum loaded tiles " + + maxLoadedTiles); + printInfo("Loaded tiles " + p.loadedTiles + " (distinct " + p.distinctLoadedTiles + "), unloaded tiles " + + p.unloadedTiles + ", loaded more than once same tiles " + p.loadedPrevUnloadedTiles); + printInfo("Visited segments: " + ctx.getVisitedSegments() + ", relaxed roads " + p.relaxedSegments); + printInfo("Priority queues sizes : " + p.directQueueSize + "/" + p.oppositeQueueSize); + printInfo("Visited interval sizes: " + p.visitedDirectSegments + "/" + p.visitedOppositeSegments); + } } @@ -849,6 +855,7 @@ public class BinaryRoutePlanner { } public static class RouteSegmentPoint extends RouteSegment { + public RouteSegmentPoint(RouteDataObject road, int segmentStart, double distSquare) { super(road, segmentStart); this.distSquare = distSquare; @@ -873,6 +880,11 @@ public class BinaryRoutePlanner { } + @Override + public String toString() { + return String.format("%d (%s): %s", segStart, getPreciseLatLon(), road); + } + } public static class RouteSegment { diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteCalculationProgress.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteCalculationProgress.java index b34c2fd5bb..eb93e95699 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteCalculationProgress.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteCalculationProgress.java @@ -12,12 +12,29 @@ public class RouteCalculationProgress { public float totalEstimatedDistance = 0; public float routingCalculatedTime = 0; - public int loadedTiles = 0; + + public int relaxedSegments = 0; public int visitedSegments = 0; + public int visitedDirectSegments = 0; + public int visitedOppositeSegments = 0; + public int directQueueSize = 0; + public int oppositeQueueSize = 0; public int totalIterations = 1; public int iteration = -1; + public long timeNanoToCalcDeviation = 0; + public long timeToLoad = 0; + public long timeToLoadHeaders = 0; + public long timeToFindInitialSegments = 0; + public long timeToCalculate = 0; + + public int distinctLoadedTiles = 0; + public int maxLoadedTiles = 0; + public int loadedPrevUnloadedTiles = 0; + public int unloadedTiles = 0; + public int loadedTiles = 0; + public boolean isCancelled; public boolean requestPrivateAccessRouting; diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java index 7a56f82591..d6c6c6611f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutePlannerFrontEnd.java @@ -208,9 +208,8 @@ public class RoutePlannerFrontEnd { useSmartRouteRecalculation = use; } - // TODO native matches less roads public GpxRouteApproximation searchGpxRoute(GpxRouteApproximation gctx, List points) throws IOException, InterruptedException { - gctx.ctx.timeToCalculate = System.nanoTime(); + long timeToCalculate = System.nanoTime(); if (gctx.ctx.calculationProgress == null) { gctx.ctx.calculationProgress = new RouteCalculationProgress(); } @@ -275,6 +274,10 @@ public class RoutePlannerFrontEnd { } start = next; } + if(gctx.ctx.calculationProgress != null) { + // TODO + gctx.ctx.calculationProgress.timeToCalculate = System.nanoTime() - timeToCalculate; + } BinaryRoutePlanner.printDebugMemoryInformation(gctx.ctx); calculateGpxRoute(gctx, gpxPoints); if (!gctx.res.isEmpty()) { @@ -529,7 +532,9 @@ public class RoutePlannerFrontEnd { // start point could shift to +-1 due to direction res.get(0).setStartPointIndex(start.pnt.getSegmentStart()); } else { - //throw new IllegalStateException("TODO"); + // for native routing this is possible when point lies on intersection of 2 lines + // solution here could be to pass to native routing id of the route + // though it should not create any issue } } start.routeToTarget = res; @@ -590,7 +595,7 @@ public class RoutePlannerFrontEnd { public List searchRoute(final RoutingContext ctx, LatLon start, LatLon end, List intermediates, PrecalculatedRouteDirection routeDirection) throws IOException, InterruptedException { - ctx.timeToCalculate = System.nanoTime(); + long timeToCalculate = System.nanoTime(); if (ctx.calculationProgress == null) { ctx.calculationProgress = new RouteCalculationProgress(); } @@ -622,6 +627,7 @@ public class RoutePlannerFrontEnd { } routeDirection = PrecalculatedRouteDirection.build(ls, ctx.config.DEVIATION_RADIUS, ctx.getRouter().getMaxSpeed()); } + List res ; if (intermediatesEmpty && ctx.nativeLib != null) { ctx.startX = MapUtils.get31TileNumberX(start.getLongitude()); ctx.startY = MapUtils.get31TileNumberY(start.getLatitude()); @@ -635,31 +641,33 @@ public class RoutePlannerFrontEnd { ctx.precalculatedRouteDirection = routeDirection.adopt(ctx); } ctx.calculationProgress.nextIteration(); - List res = runNativeRouting(ctx, recalculationEnd); - if (res != null) { - new RouteResultPreparation().printResults(ctx, start, end, res); - } + res = runNativeRouting(ctx, recalculationEnd); makeStartEndPointsPrecise(res, start, end, intermediates); - return res; - } - int indexNotFound = 0; - List points = new ArrayList(); - if (!addSegment(start, ctx, indexNotFound++, points, ctx.startTransportStop)) { - return null; - } - if (intermediates != null) { - for (LatLon l : intermediates) { - if (!addSegment(l, ctx, indexNotFound++, points, false)) { - System.out.println(points.get(points.size() - 1).getRoad().toString()); - return null; + } else { + int indexNotFound = 0; + List points = new ArrayList(); + if (!addSegment(start, ctx, indexNotFound++, points, ctx.startTransportStop)) { + return null; + } + if (intermediates != null) { + for (LatLon l : intermediates) { + if (!addSegment(l, ctx, indexNotFound++, points, false)) { + System.out.println(points.get(points.size() - 1).getRoad().toString()); + return null; + } } } + if (!addSegment(end, ctx, indexNotFound++, points, ctx.targetTransportStop)) { + return null; + } + ctx.calculationProgress.nextIteration(); + res = searchRouteImpl(ctx, points, routeDirection); } - if (!addSegment(end, ctx, indexNotFound++, points, ctx.targetTransportStop)) { - return null; + if (ctx.calculationProgress != null) { + // TODO + ctx.calculationProgress.timeToCalculate = System.nanoTime() - timeToCalculate; } - ctx.calculationProgress.nextIteration(); - List res = searchRouteImpl(ctx, points, routeDirection); + BinaryRoutePlanner.printDebugMemoryInformation(ctx); if (res != null) { new RouteResultPreparation().printResults(ctx, start, end, res); } @@ -839,11 +847,11 @@ public class RoutePlannerFrontEnd { ctx.checkOldRoutingFiles(ctx.startX, ctx.startY); ctx.checkOldRoutingFiles(ctx.targetX, ctx.targetY); - long time = System.currentTimeMillis(); + // long time = System.currentTimeMillis(); RouteSegmentResult[] res = ctx.nativeLib.runNativeRouting(ctx.startX, ctx.startY, ctx.targetX, ctx.targetY, ctx.config, regions, ctx.calculationProgress, ctx.precalculatedRouteDirection, ctx.calculationMode == RouteCalculationMode.BASE, ctx.publicTransport, ctx.startTransportStop, ctx.targetTransportStop); - log.info("Native routing took " + (System.currentTimeMillis() - time) / 1000f + " seconds"); + // log.info("Native routing took " + (System.currentTimeMillis() - time) / 1000f + " seconds"); ArrayList result = new ArrayList(Arrays.asList(res)); if (recalculationEnd != null) { log.info("Native routing use precalculated route"); @@ -855,8 +863,6 @@ public class RoutePlannerFrontEnd { } } ctx.routingTime = ctx.calculationProgress.routingCalculatedTime; - ctx.visitedSegments = ctx.calculationProgress.visitedSegments; - ctx.loadedTiles = ctx.calculationProgress.loadedTiles; return new RouteResultPreparation().prepareResult(ctx, result, recalculationEnd != null); } @@ -870,7 +876,6 @@ public class RoutePlannerFrontEnd { } pringGC(ctx, true); List res = searchRouteInternalPrepare(ctx, points.get(0), points.get(1), routeDirection); - BinaryRoutePlanner.printDebugMemoryInformation(ctx); pringGC(ctx, false); makeStartEndPointsPrecise(res, points.get(0).getPreciseLatLon(), points.get(1).getPreciseLatLon(), null); return res; @@ -917,14 +922,11 @@ public class RoutePlannerFrontEnd { List res = searchRouteInternalPrepare(local, points.get(i), points.get(i + 1), routeDirection); makeStartEndPointsPrecise(res, points.get(i).getPreciseLatLon(), points.get(i + 1).getPreciseLatLon(), null); results.addAll(res); - ctx.distinctLoadedTiles += local.distinctLoadedTiles; - ctx.loadedTiles += local.loadedTiles; - ctx.visitedSegments += local.visitedSegments; - ctx.loadedPrevUnloadedTiles += local.loadedPrevUnloadedTiles; - ctx.timeToCalculate += local.timeToCalculate; - ctx.timeToLoad += local.timeToLoad; - ctx.timeToLoadHeaders += local.timeToLoadHeaders; - ctx.relaxedSegments += local.relaxedSegments; + if(ctx.calculationProgress != null) { + ctx.calculationProgress.distinctLoadedTiles += local.calculationProgress.distinctLoadedTiles; + ctx.calculationProgress.loadedTiles += local.calculationProgress.loadedTiles; + ctx.calculationProgress.loadedPrevUnloadedTiles += local.calculationProgress.loadedPrevUnloadedTiles; + } ctx.routingTime += local.routingTime; // local.unloadAllData(ctx); diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java index b0c32de648..9892bfb730 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteResultPreparation.java @@ -394,7 +394,7 @@ public class RouteResultPreparation { private List convertFinalSegmentToResults(RoutingContext ctx, FinalRouteSegment finalSegment) { List result = new ArrayList(); if (finalSegment != null) { - ctx.routingTime = finalSegment.distanceFromStart; + ctx.routingTime += finalSegment.distanceFromStart; println("Routing calculated time distance " + finalSegment.distanceFromStart); // Get results from opposite direction roads RouteSegment segment = finalSegment.reverseWaySearch ? finalSegment : @@ -496,8 +496,9 @@ public class RouteResultPreparation { String msg = String.format("", - ctx.config.routerName, startLat, startLon, endLat, endLon, ctx.routingTime, ctx.loadedTiles, - ctx.visitedSegments, completeDistance, completeTime); + ctx.config.routerName, startLat, startLon, endLat, endLon, ctx.routingTime, + ctx.getLoadedTiles(), + ctx.getVisitedSegments(), completeDistance, completeTime); // String msg = MessageFormat.format("", // startLat + "", startLon + "", endLat + "", endLon + "", ctx.config.routerName, diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java index 75a4295b5a..99d959265d 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RoutingContext.java @@ -40,8 +40,6 @@ public class RoutingContext { private final static Log log = PlatformUtil.getLog(RoutingContext.class); - - // Final context variables public final RoutingConfiguration config; @@ -82,26 +80,8 @@ public class RoutingContext { public TileStatistics global = new TileStatistics(); // updated by route planner in bytes public int memoryOverhead = 0; - - - long timeNanoToCalcDeviation = 0; - long timeToLoad = 0; - long timeToLoadHeaders = 0; - long timeToFindInitialSegments = 0; - public long timeToCalculate = 0; - - int distinctLoadedTiles = 0; - int maxLoadedTiles = 0; - int loadedPrevUnloadedTiles = 0; - int unloadedTiles = 0; public float routingTime = 0; - public int loadedTiles = 0; - public int visitedSegments = 0; - public int relaxedSegments = 0; - public int visitedDirectSegments = 0; - public int visitedOppositeSegments = 0; - public int directQueueSize = 0; - public int oppositeQueueSize = 0; + // callback of processing segments RouteSegmentVisitor visitor = null; @@ -224,7 +204,9 @@ public class RoutingContext { if (tl.isLoaded()) { if(except == null || except.searchSubregionTile(tl.subregion) < 0){ tl.unload(); - unloadedTiles ++; + if(calculationProgress != null) { + calculationProgress.unloadedTiles ++; + } global.size -= tl.tileStatistics.size; } } @@ -308,27 +290,37 @@ public class RoutingContext { } catch (IOException e) { throw new RuntimeException("Loading data exception", e); } - - timeToLoad += (System.nanoTime() - now); + if (calculationProgress != null) { + calculationProgress.timeToLoad += (System.nanoTime() - now); + } } else { long now = System.nanoTime(); NativeRouteSearchResult ns = nativeLib.loadRouteRegion(ts.subregion, loadObjectsInMemory); // System.out.println(ts.subregion.shiftToData + " " + Arrays.toString(ns.objects)); ts.setLoadedNative(ns, this); - timeToLoad += (System.nanoTime() - now); + if (calculationProgress != null) { + calculationProgress.timeToLoad += (System.nanoTime() - now); + } } - loadedTiles++; + if (calculationProgress != null) { + calculationProgress.loadedTiles++; + } + if (wasUnloaded) { if(ucount == 1) { - loadedPrevUnloadedTiles++; + if(calculationProgress != null) { + calculationProgress.loadedPrevUnloadedTiles++; + } } } else { if(global != null) { global.allRoutes += ts.tileStatistics.allRoutes; global.coordinates += ts.tileStatistics.coordinates; } - distinctLoadedTiles++; + if(calculationProgress != null) { + calculationProgress.distinctLoadedTiles++; + } } global.size += ts.tileStatistics.size; } @@ -402,7 +394,9 @@ public class RoutingContext { } collection.add(found); } - timeToLoadHeaders += (System.nanoTime() - now); + if (calculationProgress != null) { + calculationProgress.timeToLoadHeaders += (System.nanoTime() - now); + } } } catch (IOException e) { throw new RuntimeException("Loading data exception", e); @@ -440,7 +434,9 @@ public class RoutingContext { excludeDuplications.clear(); } } - timeToFindInitialSegments += (System.nanoTime() - now); + if (calculationProgress != null) { + calculationProgress.timeToFindInitialSegments += (System.nanoTime() - now); + } } @SuppressWarnings("unused") @@ -523,7 +519,9 @@ public class RoutingContext { loaded++; } } - maxLoadedTiles = Math.max(maxLoadedTiles, getCurrentlyLoadedTiles()); + if(calculationProgress != null) { + calculationProgress.maxLoadedTiles = Math.max(calculationProgress.maxLoadedTiles, getCurrentlyLoadedTiles()); + } Collections.sort(list, new Comparator() { private int pow(int base, int pw) { int r = 1; @@ -545,7 +543,9 @@ public class RoutingContext { i++; // System.out.println("Unload " + unload); unload.unload(); - unloadedTiles ++; + if(calculationProgress != null) { + calculationProgress.unloadedTiles ++; + } global.size -= unload.tileStatistics.size; // tile could be cleaned from routing tiles and deleted from whole list @@ -796,6 +796,20 @@ public class RoutingContext { return map.keySet().toArray(new BinaryMapIndexReader[map.size()]); } + public int getVisitedSegments() { + if(calculationProgress != null) { + return calculationProgress.visitedSegments; + } + return 0; + } + + public int getLoadedTiles() { + if (calculationProgress != null) { + return calculationProgress.loadedTiles; + } + return 0; + } + diff --git a/OsmAnd-java/src/main/java/net/osmand/router/TestRouting.java b/OsmAnd-java/src/main/java/net/osmand/router/TestRouting.java index 78222819d9..95e2e0d15c 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/TestRouting.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/TestRouting.java @@ -236,13 +236,13 @@ public class TestRouting { throw new IllegalArgumentException(MessageFormat.format("Complete routing time (expected) {0} != {1} (original) : {2}", routing_time, calcRoutingTime, testDescription)); } - if (visitedSegments > 0 && !isInOrLess(visitedSegments, ctx.visitedSegments, percent)) { + if (visitedSegments > 0 && !isInOrLess(visitedSegments, ctx.getVisitedSegments(), percent)) { throw new IllegalArgumentException(MessageFormat.format("Visited segments (expected) {0} != {1} (original) : {2}", visitedSegments, - ctx.visitedSegments, testDescription)); + ctx.getVisitedSegments(), testDescription)); } - if (loadedTiles > 0 && !isInOrLess(loadedTiles, ctx.loadedTiles, percent)) { + if (loadedTiles > 0 && !isInOrLess(loadedTiles, ctx.getLoadedTiles(), percent)) { throw new IllegalArgumentException(MessageFormat.format("Loaded tiles (expected) {0} != {1} (original) : {2}", loadedTiles, - ctx.loadedTiles, testDescription)); + ctx.getLoadedTiles(), testDescription)); } if(TEST_BOTH_DIRECTION){