/** * Create a {@link Route} from an {@link Iterable} of {@link Edge}s that are already in the * proper order to be connected. * * @param edges * The {@link Edge}s to link in a {@link Route} * @return The corresponding {@link Route} */ public static Route forEdges(final Edge... edges) { return forEdges(Iterables.asList(edges)); }
/** * Creates a new {@link Route} from the original route based on the start and end indexes passed * in * * @param startIndex * The starting index to create the new route from * @param endIndex * The ending index (exclusive) of the new route * @return a new route based which is a subset of the original route */ public Route subRoute(final int startIndex, final int endIndex) { // Create a new ArrayList for safety reasons because subList returns a list backed by the // original list. return Route .forEdges(new ArrayList<>(Iterables.asList(this).subList(startIndex, endIndex))); }
/** * This method uses the provided {@link Atlas} to return the {@link Route} corresponding to this * {@link AtlasPrimitiveRoute} * * @param atlas * {@link Atlas} containing the {@link Route} {@link Edge}s * @return {@link Route} corresponding to this {@link AtlasPrimitiveRoute} */ public Optional<Route> getRoute(final Atlas atlas) { final List<Edge> edges = new ArrayList<>(); for (final AtlasPrimitiveEdge primitiveEdge : this.primitiveRoute) { final Edge edge = atlas.edge(primitiveEdge.getIdentifier()); if (edge == null) { return Optional.empty(); } edges.add(edge); } return Optional.of(Route.forEdges(edges)); }
routes.add(Route.forEdges(path));
@Test public void testSingleRouteFromStartToEnd() { final Atlas atlas = this.rule.getSingleRouteAtlas(); final Set<Route> routes = AllPathsRouter.allRoutes(atlas.edge(315932590), atlas.edge(317932590), Route.ROUTE_COMPARATOR); final Set<Route> expectedRoutes = new TreeSet<>(Route.ROUTE_COMPARATOR); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(316932590), atlas.edge(317932590))); Assert.assertEquals("Expect a single route between start and end", 1, routes.size()); Assert.assertEquals("Expect deterministic results from the router", expectedRoutes, routes); Assert.assertEquals( "Total number of edges in the Atlas equals the number of edges in the route", Route.forEdges(atlas.edges()), routes.iterator().next()); } }
/** * Before the addition of the start and end {@link Node}s to the {@link Route #hashCode()}, the * {@link Route}s in this test would generate hash code collisions. This test verifies the * collisions no longer occur. */ @Test public void testHashCode() { final Atlas atlas = this.rule.getRouteHashCodeAtlas(); final Edge edge1 = atlas.edge(-206786592000008L); final Edge edge2 = atlas.edge(206786592000008L); final Edge edge3 = atlas.edge(206786592000007L); final Edge edge4 = atlas.edge(-206786592000007L); final Route route1 = Route.forEdges(edge1, edge2); final Route route2 = Route.forEdges(edge3, edge2); Assert.assertTrue("Route 1 and Route 2 no longer collide", route1.hashCode() != route2.hashCode()); final Route route3 = Route.forEdges(edge1, edge4); final Route route4 = Route.forEdges(edge3, edge4); Assert.assertTrue("Route 3 and Route 4 no longer collide", route3.hashCode() != route4.hashCode()); }
@Test public void testRoutingAlongCyclicalGraph() { final Atlas atlas = this.rule.getCyclicalRouteAtlas(); final Set<Route> routes = AllPathsRouter.allRoutes(atlas.edge(315932590), atlas.edge(317932590), Route.ROUTE_COMPARATOR); final Set<Route> expectedRoutes = new TreeSet<>(Route.ROUTE_COMPARATOR); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(316932590), atlas.edge(317932590))); Assert.assertEquals("Expect a single route between start and end", 1, routes.size()); Assert.assertEquals("Expect deterministic results from the router", expectedRoutes, routes); }
@Test public void testMultipleRoutesFromStartToEnd() { final Atlas atlas = this.rule.getMultipleRoutesAtlas(); final Set<Route> routes = AllPathsRouter.allRoutes(atlas.edge(314932590), atlas.edge(319932590), Route.ROUTE_COMPARATOR); final Set<Route> expectedRoutes = new TreeSet<>(Route.ROUTE_COMPARATOR); expectedRoutes.add(Route.forEdges(atlas.edge(314932590), atlas.edge(315932590), atlas.edge(316932590), atlas.edge(319932590))); expectedRoutes.add(Route.forEdges(atlas.edge(314932590), atlas.edge(317932590), atlas.edge(318932590), atlas.edge(319932590))); Assert.assertEquals("Expect two distinct routes between start and end", 2, routes.size()); Assert.assertEquals("Expect deterministic results from the router", expectedRoutes, routes); }
allRoutes.containsAll(shortestRoutes)); final Route nonShortestValidRoute = Route.forEdges(atlas.edge(-3), atlas.edge(-2), atlas.edge(2), atlas.edge(3)); Assert.assertTrue("Valid route should be absent from the shortest path set",
@Test public void testPathThroughBigNodeToTurnRestrictionCriteria() { final Atlas atlasNo = this.rule.getAtlasNo(); logger.trace("AtlasNo: {}", atlasNo); // All possible paths through this bigNode final Route path1 = Route.forEdges(atlasNo.edge(102), atlasNo.edge(205)); final Route path2 = Route.forEdges(atlasNo.edge(102), atlasNo.edge(204)); final Route path3 = Route.forEdges(atlasNo.edge(102), atlasNo.edge(203)); final Iterable<BigNode> bigNodes = new BigNodeFinder().find(atlasNo, Finder::ignore); for (final BigNode bigNode : bigNodes) { final Set<Route> allPaths = bigNode.allPaths(); if (allPaths.size() > 0) { final Set<RestrictedPath> restrictions = bigNode.turnRestrictions(); Assert.assertTrue(restrictions.size() == 1); final Route restrictedRoute = restrictions.iterator().next().getRoute(); Assert.assertNotEquals(restrictedRoute, path1); Assert.assertNotEquals(restrictedRoute, path2); // Only one path should be the restricted one as it fully covers the turn // restriction. The other paths all overlap the restriction, but only // partially. Assert.assertEquals(restrictedRoute, path3); } } }
@Test public void testBidirectionalSimpleRoutes() { final Atlas atlas = this.rule.getBiDirectionalCyclicRouteAtlas(); final Set<Route> routes = AllPathsRouter.allRoutes(atlas.edge(315932590), atlas.edge(317932590), Route.ROUTE_COMPARATOR); final Set<Route> expectedRoutes = new TreeSet<>(Route.ROUTE_COMPARATOR); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(316932590), atlas.edge(317932590))); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(-315932590), atlas.edge(-318932590), atlas.edge(-317932590), atlas.edge(-316932590), atlas.edge(316932590), atlas.edge(317932590))); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(316932590), atlas.edge(-316932590), atlas.edge(-315932590), atlas.edge(-318932590), atlas.edge(-317932590), atlas.edge(317932590))); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(-315932590), atlas.edge(-318932590), atlas.edge(-317932590), atlas.edge(317932590))); Assert.assertEquals("Expect four distinct routes between start and end", 4, routes.size()); Assert.assertEquals("Expect deterministic results from the router", expectedRoutes, routes); }
@Test public void testRoutingWithFilter() { final Atlas atlas = this.rule.getBiDirectionalCyclicRouteAtlas(); final Predicate<Edge> onlyMasterEdges = edge -> Edge .isMasterEdgeIdentifier(edge.getIdentifier()); final Set<Route> routes = AllPathsRouter.allRoutes(atlas.edge(315932590), atlas.edge(317932590), onlyMasterEdges, Route.ROUTE_COMPARATOR); final Set<Route> expectedRoutes = new TreeSet<>(Route.ROUTE_COMPARATOR); expectedRoutes.add(Route.forEdges(atlas.edge(315932590), atlas.edge(316932590), atlas.edge(317932590))); Assert.assertEquals( "Expect a single distinct route between start and end, since we've filtered out all routes that have a non-master edge", 1, routes.size()); Assert.assertEquals("Expect deterministic results from the router", expectedRoutes, routes); }
@Test public void testStartsWith() { final Atlas atlas = this.rule.getAtlas(); final Route route = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(128620796)); final Route duplicateRoute = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(128620796)); final Route multiRoute = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751)); final Route singleRoute = Route.forEdges(atlas.edge(159019301)); final Route incorrectMultiRoute = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(138620888)); final Route incorrectSingleRoute = Route.forEdge(atlas.edge(128620751)); Assert.assertTrue("Verify startsWith returns true when passing in the same route", route.startsWith(duplicateRoute)); Assert.assertTrue("Verify startsWith returns true for a multiRoute", route.startsWith(multiRoute)); Assert.assertTrue("Verify startsWith returns true for a singleRoute", route.startsWith(singleRoute)); Assert.assertFalse("Verify a startsWith negative case for a multiRoute", route.startsWith(incorrectMultiRoute)); Assert.assertFalse("Verify a startsWith negative case for a singleRoute", route.startsWith(incorrectSingleRoute)); Assert.assertFalse( "Verify startsWith returns false when other route is longer than current route", singleRoute.startsWith(multiRoute)); }
@Test public void testReverse() { final Atlas biDirectionalAtlas = this.rule.getBiDirectionalEdgeAtlas(); final Route singleBiDirectionalEdgeRoute = Route .forEdge(biDirectionalAtlas.edge(159019301)); Assert.assertEquals("There is a reverse route since it's a bi-directional edge", Route.forEdge(biDirectionalAtlas.edge(-159019301)), singleBiDirectionalEdgeRoute.reverse().get()); final Route multipleBirectionalEdgeRoute = Route.forEdges( biDirectionalAtlas.edge(159019301), biDirectionalAtlas.edge(28620796), biDirectionalAtlas.edge(138620888)); Assert.assertEquals("There is a reverse route since all the edges are bi-directional", Route.forEdges(biDirectionalAtlas.edge(-138620888), biDirectionalAtlas.edge(-28620796), biDirectionalAtlas.edge(-159019301)), multipleBirectionalEdgeRoute.reverse().get()); final Atlas uniDirectionalAtlas = this.rule.getUniDirectionalEdgeAtlas(); final Route singleUniDirectionalEdgeRoute = Route .forEdge(uniDirectionalAtlas.edge(28620796)); Assert.assertFalse("There is no reverse route since this is a one-way edge", singleUniDirectionalEdgeRoute.reverse().isPresent()); final Route routeWithUniDirectionalEdgeInBetween = Route.forEdges( uniDirectionalAtlas.edge(159019301), uniDirectionalAtlas.edge(28620796), uniDirectionalAtlas.edge(138620888)); Assert.assertFalse( "There is no reverse route since the middle edge is a uni-directional edge", routeWithUniDirectionalEdgeInBetween.reverse().isPresent()); }
@Test public void testAlgorithm() { final Atlas atlas = new MultiAtlasTest().getAtlas(); final Location start = Location.TEST_6.shiftAlongGreatCircle(Heading.NORTH, Distance.ONE_METER); final Location end = Location.TEST_2.shiftAlongGreatCircle(Heading.EAST, Distance.ONE_METER); final Route dijkstraRoute = AStarRouter.dijkstra(atlas, this.threshold).route(start, end); System.out.println(dijkstraRoute); Assert.assertEquals( Route.forEdges(atlas.edge(9), atlas.edge(-9), atlas.edge(5), atlas.edge(6)), dijkstraRoute); final Route balancedRoute = AStarRouter.balanced(atlas, this.threshold).route(start, end); System.out.println(balancedRoute); Assert.assertEquals( Route.forEdges(atlas.edge(9), atlas.edge(-9), atlas.edge(5), atlas.edge(6)), balancedRoute); }
@Test public void testOnlyRestriction() { final Atlas atlasOnly = this.rule.getAtlasOnly(); logger.trace("AtlasOnly: {}", atlasOnly); final Route candidate = Route.forEdges(atlasOnly.edge(102), atlasOnly.edge(203)); int counter = 0; for (final ComplexTurnRestriction restriction : new ComplexTurnRestrictionFinder() .find(atlasOnly, Finder::ignore)) { if (restriction.getTurnRestriction() .getTurnRestrictionType() == TurnRestrictionType.ONLY) { final Route route = restriction.route(); if (candidate.equals(route)) { counter++; } } } Assert.assertEquals(1, counter); final Set<RestrictedPath> paths = new HashSet<>(); for (final BigNode bigNode : new BigNodeFinder().find(atlasOnly, Finder::ignore)) { paths.addAll(bigNode.turnRestrictions()); } Assert.assertEquals(3, paths.size()); }
@Test public void testSimpleUTurn() { final Atlas atlas = this.rule.getUTurnAtlas(); final Route uTurnRoute1 = Route.forEdges(atlas.edge(159019301), atlas.edge(-159019301)); final Route uTurnRoute2 = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(128620796), atlas.edge(-128620796), atlas.edge(-128620751), atlas.edge(-159019301)); final Route nonUTurnRoute1 = Route.forEdges(atlas.edge(159019301)); final Route nonUTurnRoute2 = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(128620796), atlas.edge(138620888)); final Route nonUTurnRoute3 = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(128620796), atlas.edge(-128620796), atlas.edge(-128620751), atlas.edge(138620889)); Assert.assertTrue("Valid basic 2 edge UTurn is a simple UTurn", uTurnRoute1.isSimpleUTurn()); Assert.assertTrue( "Valid complex UTurn with even number of edges in route is a simple UTurn", uTurnRoute2.isSimpleUTurn()); Assert.assertFalse("Route with odd number of edges cannot be a simple UTurn", nonUTurnRoute1.isSimpleUTurn()); Assert.assertFalse("Non UTurn route cannot be a simple UTurn", nonUTurnRoute2.isSimpleUTurn()); Assert.assertFalse( "A route that is almost a UTurn (last edge is off), cannot be a simple UTurn", nonUTurnRoute3.isSimpleUTurn()); }
final Route shorterRoute = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751)); final Route longerRoute = Route.forEdges(atlas.edge(159019301), atlas.edge(128620751), atlas.edge(128620796)); final Route partialLongerRoute = Route.forEdges(atlas.edge(128620751), atlas.edge(128620796)); final Route middleEdgeRoute = Route.forEdge(atlas.edge(128620751));
final Route candidate = Route.forEdges(atlasNo.edge(102), atlasNo.edge(203)); int counter = 0; for (final ComplexTurnRestriction restriction : new ComplexTurnRestrictionFinder()
Assert.assertEquals(Route.forEdges(atlas.edge(1), atlas.edge(2)), router.route(atlas.node(1), atlas.node(3))); Assert.assertEquals(Route.forEdges(atlas.edge(1), atlas.edge(2)), router.route(atlas.edge(1), atlas.edge(2))); try Assert.assertEquals(Route.forEdges(atlas.edge(1), atlas.edge(2)), router.route(start, end));