diff --git a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java index 6a7d1d9d16..31b090de2f 100644 --- a/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java +++ b/DataExtractionOSM/src/net/osmand/router/BinaryRoutePlanner.java @@ -26,9 +26,11 @@ import org.apache.commons.logging.Log; public class BinaryRoutePlanner { private final static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true; + private final int REVERSE_WAY_RESTRICTION_ONLY = 1024; private final BinaryMapIndexReader[] map; + private static final Log log = LogUtil.getLog(BinaryRoutePlanner.class); public BinaryRoutePlanner(BinaryMapIndexReader... map){ @@ -393,7 +395,7 @@ public class BinaryRoutePlanner { private RouteSegment processIntersectionsWithWays(RoutingContext ctx, PriorityQueue graphSegments, TLongObjectHashMap visitedSegments, TLongObjectHashMap oppositeSegments, double distOnRoadToPass, double distToFinalPoint, - RouteSegment segment, BinaryMapDataObject road, boolean firstOfSegment, int segmentEnd, RouteSegment next, + RouteSegment segment, BinaryMapDataObject road, boolean firstOfSegment, int segmentEnd, RouteSegment inputNext, boolean reverseWay) { // This variables can be in routing context @@ -406,7 +408,7 @@ public class BinaryRoutePlanner { // 3.1 calculate time for obstacles (bumps, traffic_signals, level_crossing) if (firstOfSegment) { - RouteSegment possibleObstacle = next; + RouteSegment possibleObstacle = inputNext; while (possibleObstacle != null) { obstaclesTime += ctx.getRouter().defineObstacle(possibleObstacle.road, possibleObstacle.segmentStart); possibleObstacle = possibleObstacle.next; @@ -415,6 +417,7 @@ public class BinaryRoutePlanner { // 3.2 calculate possible ways to put into priority queue // for debug next.road.getId() >> 1 == 33911427 && road.getId() >> 1 == 33911442 + RouteSegment next = inputNext; while (next != null) { long nts = (next.road.getId() << 8l) + next.segmentStart; boolean oppositeConnectionFound = oppositeSegments.containsKey(nts) && oppositeSegments.get(nts) != null; @@ -428,7 +431,7 @@ public class BinaryRoutePlanner { } } - /* next.road.getId() >> 3 (1) != road.getId() >> 1 (3) - used that line for debug with osm map */ + /* next.road.getId() >> 1 (3) != road.getId() >> 1 (3) - used that line for debug with osm map */ // road.id could be equal on roundabout, but we should accept them if ((!visitedSegments.contains(nts) && processRoad) || oppositeConnectionFound) { int type = -1; @@ -445,9 +448,24 @@ public class BinaryRoutePlanner { type = next.road.getRestrictionType(i); break; } + // Check if there is restriction only to the current road + if (next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_RIGHT_TURN + || next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_LEFT_TURN + || next.road.getRestrictionType(i) == MapRenderingTypes.RESTRICTION_ONLY_STRAIGHT_ON) { + // check if that restriction applies to considered junk + RouteSegment foundNext = inputNext; + while(foundNext != null && foundNext.getRoad().getId() != next.road.getRestriction(i)){ + foundNext = foundNext.next; + } + if(foundNext != null) { + type = REVERSE_WAY_RESTRICTION_ONLY; // special constant + } + } } } - if (type == -1 && exclusiveRestriction) { + if(type == REVERSE_WAY_RESTRICTION_ONLY){ + // next = next.next; continue; + } else if (type == -1 && exclusiveRestriction) { // next = next.next; continue; } else if (type == MapRenderingTypes.RESTRICTION_NO_LEFT_TURN || type == MapRenderingTypes.RESTRICTION_NO_RIGHT_TURN || type == MapRenderingTypes.RESTRICTION_NO_STRAIGHT_ON || type == MapRenderingTypes.RESTRICTION_NO_U_TURN) { @@ -479,7 +497,8 @@ public class BinaryRoutePlanner { // add obstacles time distanceFromStart += obstaclesTime; - + + // segment.getRoad().getId() >> 1 if (next.parentRoute == null || ctx.roadPriorityComparator(next.distanceFromStart, next.distanceToEnd, distanceFromStart, distanceToEnd) > 0) { next.distanceFromStart = distanceFromStart; @@ -496,9 +515,16 @@ public class BinaryRoutePlanner { segmentsToVisitNotForbidden.add(next); } else { // case exclusive restriction (only_right, only_straight, ...) - exclusiveRestriction = true; - segmentsToVisitNotForbidden.clear(); - segmentsToVisitPrescripted.add(next); + // 1. in case we are going backward we should not consider only_restriction + // as exclusive because we have main "in" roads and one "out" + // 2. in case we are going forward we have one "in" and many "out" + if (!reverseWay) { + exclusiveRestriction = true; + segmentsToVisitNotForbidden.clear(); + segmentsToVisitPrescripted.add(next); + } else { + segmentsToVisitNotForbidden.add(next); + } } } diff --git a/DataExtractionOSM/src/net/osmand/router/CarRouter.java b/DataExtractionOSM/src/net/osmand/router/CarRouter.java index 5cd12493a9..911ce1ee84 100644 --- a/DataExtractionOSM/src/net/osmand/router/CarRouter.java +++ b/DataExtractionOSM/src/net/osmand/router/CarRouter.java @@ -166,23 +166,46 @@ public class CarRouter extends VehicleRouter { public double getMaxDefaultSpeed() { return 30; } + + private double directionRoute(RouteSegment segment, int segmentEnd, boolean opp){ + boolean plus = segmentEnd == 0; + int x = segment.road.getPoint31XTile(segmentEnd); + int y = segment.road.getPoint31YTile(segmentEnd); + int nx = segmentEnd; + int px = x; + int py = y; + do { + if(plus){ + nx++; + if(nx >= segment.road.getPointsLength()){ + break; + } + } else { + nx--; + if(nx < 0){ + break; + } + } + px = segment.road.getPoint31XTile(nx); + py = segment.road.getPoint31YTile(nx); + } while(Math.abs(px - x) + Math.abs(py - y) < 100); + + if(opp){ + return Math.atan2(py - y, px - x); + } else { + return Math.atan2(y - py, x - px); + } + } public double calculateTurnTime(RouteSegment segment, RouteSegment next, int segmentEnd) { boolean end = (segmentEnd == segment.road.getPointsLength() - 1 || segmentEnd == 0); - boolean start = next.segmentStart == 0; + boolean start = next.segmentStart == 0 || next.segmentStart == next.getRoad().getPointsLength() - 1; // that addition highly affects to trunk roads !(prefer trunk/motorway) if (end && start) { + // next.road.getId() >> 1 != segment.road.getId() >> 1 if (next.road.getPointsLength() > 1) { - int x = segment.road.getPoint31XTile(segmentEnd); - int y = segment.road.getPoint31XTile(segmentEnd); - int prevSegmentEnd = segmentEnd - 1; - if(prevSegmentEnd < 0){ - prevSegmentEnd = segmentEnd + 1; - } - int px = segment.road.getPoint31XTile(prevSegmentEnd); - int py = segment.road.getPoint31XTile(prevSegmentEnd); - double a1 = Math.atan2(y - py, x - px); - double a2 = Math.atan2(y - next.road.getPoint31YTile(1), x - next.road.getPoint31XTile(1)); + double a1 = directionRoute(segment, segmentEnd, false); + double a2 = directionRoute(next, next.segmentStart, true); double diff = Math.abs(a1 - a2); if (diff > Math.PI / 2 && diff < 3 * Math.PI / 2) { return 25; diff --git a/DataExtractionOSM/src/net/osmand/router/RoutingContext.java b/DataExtractionOSM/src/net/osmand/router/RoutingContext.java index eb1e3bb285..a7204f3edd 100644 --- a/DataExtractionOSM/src/net/osmand/router/RoutingContext.java +++ b/DataExtractionOSM/src/net/osmand/router/RoutingContext.java @@ -25,6 +25,7 @@ public class RoutingContext { private Boolean planRoadDirection = null; private VehicleRouter router = new CarRouter(); private boolean useDynamicRoadPrioritising = true; + // not used right now private boolean usingShortestWay = false; diff --git a/DataExtractionOSM/src/net/osmand/router/test/RouterTestsSuite.java b/DataExtractionOSM/src/net/osmand/router/test/RouterTestsSuite.java index 95927555bb..acff662cda 100644 --- a/DataExtractionOSM/src/net/osmand/router/test/RouterTestsSuite.java +++ b/DataExtractionOSM/src/net/osmand/router/test/RouterTestsSuite.java @@ -38,6 +38,7 @@ public class RouterTestsSuite { properties.load(RouterTestsSuite.class.getResourceAsStream("sources.properties")); boolean allSuccess = true; allSuccess &= test("belarus_test.xml", properties); + allSuccess &= test("germany_test.xml", properties); if (allSuccess) { System.out.println("All is successfull"); } @@ -81,6 +82,12 @@ public class RouterTestsSuite { RoutingContext ctx = new RoutingContext(); String vehicle = testCase.getAttribute("vehicle"); String testDescription = testCase.getAttribute("description"); + String skip = testCase.getAttribute("skip_comment"); + if (skip != null && skip.length() > 0) { + System.err.println("\n\n!! Skipped test case '" + testDescription + "' because '" + skip + "'\n\n" ); + return; + } + if("bicycle".equals(vehicle)){ ctx.setRouter(new BicycleRouter()); } else if("pedestrian".equals(vehicle)){ diff --git a/DataExtractionOSM/src/net/osmand/router/test/belarus_test.xml b/DataExtractionOSM/src/net/osmand/router/test/belarus_test.xml index b785b366b6..973360850a 100644 --- a/DataExtractionOSM/src/net/osmand/router/test/belarus_test.xml +++ b/DataExtractionOSM/src/net/osmand/router/test/belarus_test.xml @@ -20,31 +20,33 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - + + + + + + @@ -63,9 +65,10 @@ + + target_lon="27.68131" skip_comment="Not work right now"> diff --git a/DataExtractionOSM/src/net/osmand/router/test/germany_test.xml b/DataExtractionOSM/src/net/osmand/router/test/germany_test.xml new file mode 100644 index 0000000000..bc12649391 --- /dev/null +++ b/DataExtractionOSM/src/net/osmand/router/test/germany_test.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/DataExtractionOSM/src/net/osmand/router/test/sources.properties b/DataExtractionOSM/src/net/osmand/router/test/sources.properties index 72d81697bd..9688a8b56d 100644 --- a/DataExtractionOSM/src/net/osmand/router/test/sources.properties +++ b/DataExtractionOSM/src/net/osmand/router/test/sources.properties @@ -1,5 +1,6 @@ BELARUS = /home/victor/projects/OsmAnd/data/osmand_index/Belarus.obf NETHERLANDS = /home/victor/projects/OsmAnd/data/osmand_index/Netherlands_europe.obf +GERMANY_NIEDERSACHSEN = /home/victor/projects/OsmAnd/data/osmand_index/Germany_niedersachsen_europe_1.obf # Not used for now DENMARK =/home/victor/projects/OsmAnd/data/osmand_index/Denmark_europe.obf -GERMANY_BAYERN = /home/victor/projects/OsmAnd/data/osmand_index/Germany_bayern_europe_1.obf \ No newline at end of file +GERMANY_BAYERN = /home/victor/projects/OsmAnd/data/osmand_index/Germany_bayern_europe_1.obf diff --git a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java index 2e10134a8a..5b5e49a336 100644 --- a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java +++ b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java @@ -48,16 +48,16 @@ import org.xml.sax.SAXException; public class MapRouterLayer implements MapPanelLayer { - private /*final */ static boolean ANIMATE_CALCULATING_ROUTE = false; - private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 50; + private /*final */ static boolean ANIMATE_CALCULATING_ROUTE = true; + private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 1; private MapPanel map; - private LatLon startRoute; - private LatLon endRoute; +// private LatLon startRoute; +// private LatLon endRoute; // test route purpose -// private LatLon startRoute = new LatLon(53.910886,27.579095); -// private LatLon endRoute = new LatLon(53.95386,27.68131); + private LatLon startRoute = new LatLon(53.9113, 27.5795); + private LatLon endRoute = new LatLon(53.95386, 27.68131); @Override @@ -349,6 +349,7 @@ public class MapRouterLayer implements MapPanelLayer { BinaryRoutePlanner router = new BinaryRoutePlanner(rs); RoutingContext ctx = new RoutingContext(); +// ctx.setPlanRoadDirection(true); // find closest way RouteSegment st = router.findRouteSegment(start.getLatitude(), start.getLongitude(), ctx); @@ -411,7 +412,7 @@ public class MapRouterLayer implements MapPanelLayer { List searchRoute = router.searchRoute(ctx, st, e); if (ANIMATE_CALCULATING_ROUTE) { try { - Thread.sleep(4000); + Thread.sleep(2000); } catch (InterruptedException e1) { } }