1 package org.opentrafficsim.core.network;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNull;
6 import static org.junit.Assert.assertTrue;
7 import static org.junit.Assert.fail;
8
9 import java.rmi.RemoteException;
10 import java.util.ArrayList;
11 import java.util.List;
12
13 import org.junit.Test;
14 import org.opentrafficsim.core.compatibility.GTUCompatibility;
15 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
16 import org.opentrafficsim.core.geometry.OTSGeometryException;
17 import org.opentrafficsim.core.geometry.OTSLine3D;
18 import org.opentrafficsim.core.geometry.OTSPoint3D;
19 import org.opentrafficsim.core.gtu.GTU;
20 import org.opentrafficsim.core.gtu.GTUType;
21 import org.opentrafficsim.core.mock.MockGTU;
22 import org.opentrafficsim.core.mock.MockSimulator;
23 import org.opentrafficsim.core.network.route.CompleteRoute;
24 import org.opentrafficsim.core.network.route.Route;
25
26 import nl.tudelft.simulation.event.EventInterface;
27 import nl.tudelft.simulation.event.EventListenerInterface;
28 import nl.tudelft.simulation.event.EventType;
29
30
31
32
33
34
35
36
37
38
39
40 public class OTSNetworkTest implements EventListenerInterface
41 {
42
43
44 private int nodeAddedCount = 0;
45
46
47 private int nodeRemovedCount = 0;
48
49
50 private int linkAddedCount = 0;
51
52
53 private int linkRemovedCount = 0;
54
55
56 private int gtuAddedCount = 0;
57
58
59 private int gtuRemovedCount = 0;
60
61
62 private int otherEventCount = 0;
63
64
65
66
67
68
69 @Test
70 public final void testOTSNetwork() throws NetworkException, OTSGeometryException
71 {
72 String networkId = "testOTSNetwork";
73 OTSNetwork network = new OTSNetwork(networkId);
74 OTSSimulatorInterface simulator = MockSimulator.createMock();
75 assertTrue("Id must match", networkId.equals(network.getId()));
76 network.addListener(this, Network.LINK_ADD_EVENT);
77 network.addListener(this, Network.LINK_REMOVE_EVENT);
78 network.addListener(this, Network.NODE_ADD_EVENT);
79 network.addListener(this, Network.NODE_REMOVE_EVENT);
80 network.addListener(this, Network.GTU_ADD_EVENT);
81 network.addListener(this, Network.GTU_REMOVE_EVENT);
82 assertEquals("link add event count is 0", 0, this.linkAddedCount);
83 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
84 assertEquals("node add event count is 0", 0, this.nodeAddedCount);
85 assertEquals("node removed event count is 0", 0, this.nodeRemovedCount);
86 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
87 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
88 assertEquals("other event count is 0", 0, this.otherEventCount);
89 assertEquals("Node map is empty", 0, network.getNodeMap().size());
90 Node node1 = new OTSNode(network, "node1", new OTSPoint3D(10, 20, 30));
91 assertEquals("link add event count is 0", 0, this.linkAddedCount);
92 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
93 assertEquals("node add event count is 1", 1, this.nodeAddedCount);
94 assertEquals("node removed event count is 0", 0, this.nodeRemovedCount);
95 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
96 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
97 assertEquals("other event count is 0", 0, this.otherEventCount);
98 assertEquals("Node map now contains one node", 1, network.getNodeMap().size());
99 assertEquals("Node is node1", node1, network.getNodeMap().values().iterator().next());
100 assertEquals("Node can be retrieved by id", node1, network.getNode(node1.getId()));
101 assertTrue("network contains a node with id node1", network.containsNode("node1"));
102
103 OTSNetwork otherNetwork = new OTSNetwork("other network");
104 Node node2 = new OTSNode(otherNetwork, "node2", new OTSPoint3D(11, 12, 13));
105 assertFalse("node2 is NOT in network", network.containsNode(node2));
106 assertEquals("link add event count is 0", 0, this.linkAddedCount);
107 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
108 assertEquals("node add event count is 1", 1, this.nodeAddedCount);
109 assertEquals("node removed event count is 0", 0, this.nodeRemovedCount);
110 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
111 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
112 assertEquals("other event count is 0", 0, this.otherEventCount);
113 try
114 {
115 new OTSNode(network, "node1", new OTSPoint3D(110, 20, 30));
116 fail("duplicate node id should have thrown a NetworkException");
117 }
118 catch (NetworkException ne)
119 {
120
121 }
122 try
123 {
124 network.addNode(node1);
125 fail("duplicate node should have thrown a NetworkException");
126 }
127 catch (NetworkException ne)
128 {
129
130 }
131 network.removeNode(node1);
132 assertEquals("link add event count is 0", 0, this.linkAddedCount);
133 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
134 assertEquals("node add event count is 1", 1, this.nodeAddedCount);
135 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
136 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
137 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
138 assertEquals("other event count is 0", 0, this.otherEventCount);
139 assertEquals("Node map is empty", 0, network.getNodeMap().size());
140 assertEquals("network now had 0 nodes", 0, network.getNodeMap().size());
141 try
142 {
143 network.removeNode(node1);
144 fail("Attempt to remove an already removed node should have thrown a NetworkException");
145 }
146 catch (NetworkException ne)
147 {
148
149 }
150 network.addNode(node1);
151 assertEquals("Node map now contains one node", 1, network.getNodeMap().size());
152 assertEquals("Node is node1", node1, network.getNodeMap().values().iterator().next());
153 assertEquals("Node can be retrieved by id", node1, network.getNode(node1.getId()));
154 assertEquals("LinkMap is empty", 0, network.getLinkMap().size());
155 assertEquals("link add event count is 0", 0, this.linkAddedCount);
156 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
157 assertEquals("node add event count is 2", 2, this.nodeAddedCount);
158 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
159 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
160 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
161 assertEquals("other event count is 0", 0, this.otherEventCount);
162 try
163 {
164 new OTSLink(network, "link1", node1, node2, LinkType.ROAD, new OTSLine3D(node1.getPoint(), node2.getPoint()),
165 simulator);
166 fail("new OTSLink should have thrown an exception because node2 is not in network");
167 }
168 catch (NetworkException ne)
169 {
170
171 }
172 try
173 {
174 new OTSLink(network, "link1", node2, node1, LinkType.ROAD, new OTSLine3D(node2.getPoint(), node1.getPoint()),
175 simulator);
176 fail("new OTSLink should have thrown an exception because node2 is not in network");
177 }
178 catch (NetworkException ne)
179 {
180
181 }
182 Node node3 = new OTSNode(network, "node3", new OTSPoint3D(11, 12, 13));
183 assertEquals("link add event count is 0", 0, this.linkAddedCount);
184 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
185 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
186 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
187 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
188 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
189 assertEquals("other event count is 0", 0, this.otherEventCount);
190 Link link1 = new OTSLink(network, "link1", node1, node3, LinkType.ROAD,
191 new OTSLine3D(node1.getPoint(), node3.getPoint()), simulator);
192 assertEquals("LinkMap now contains 1 link", 1, network.getLinkMap().size());
193 assertTrue("LinkMap contains link1", network.containsLink(link1));
194 assertTrue("LinkMap.contain link with name link1", network.containsLink("link1"));
195 assertEquals("link add event count is 1", 1, this.linkAddedCount);
196 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
197 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
198 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
199 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
200 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
201 assertEquals("other event count is 0", 0, this.otherEventCount);
202 try
203 {
204 network.addLink(link1);
205 fail("Adding link1 again should have thrown a NetworkException");
206 }
207 catch (NetworkException ne)
208 {
209
210 }
211 assertEquals("link1 is the link connecting node1 to node3", link1, network.getLink(node1, node3));
212 assertEquals("link1 is the link connecting node named node1 to node named node3", link1,
213 network.getLink("node1", "node3"));
214 Node node4 = new OTSNode(otherNetwork, "node4", new OTSPoint3D(-2, -3, -4));
215 Link otherLink = new OTSLink(otherNetwork, "otherLink", node2, node4, LinkType.ROAD,
216 new OTSLine3D(node2.getPoint(), node4.getPoint()), simulator);
217 try
218 {
219 network.removeLink(otherLink);
220 fail("Removing a link that is in another network should have thrown a NetworkException");
221 }
222 catch (NetworkException ne)
223 {
224
225 }
226 try
227 {
228 network.addLink(otherLink);
229 fail("Adding a link that connects nodes not in the network should have thrown a NetworkException");
230 }
231 catch (NetworkException ne)
232 {
233
234 }
235 assertEquals("link add event count is 1", 1, this.linkAddedCount);
236 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
237 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
238 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
239 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
240 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
241 assertEquals("other event count is 0", 0, this.otherEventCount);
242 Link secondLink = new OTSLink(network, "reverseLink", node3, node1, LinkType.ROAD,
243 new OTSLine3D(node3.getPoint(), node1.getPoint()), simulator);
244 assertEquals("link add event count is 2", 2, this.linkAddedCount);
245 assertEquals("link removed event count is 0", 0, this.linkRemovedCount);
246 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
247 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
248 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
249 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
250 assertEquals("other event count is 0", 0, this.otherEventCount);
251 assertTrue("Network contains secondLink", network.containsLink(secondLink));
252 assertTrue("Network contains link named reverseLink", network.containsLink("reverseLink"));
253 assertFalse("Network does not contain link named junk", network.containsLink("junk"));
254 try
255 {
256 network.getLink("junk", "node3");
257 fail("looking up a link starting at nonexistent node should have thrown a NetworkException");
258 }
259 catch (NetworkException ne)
260 {
261
262 }
263 try
264 {
265 network.getLink("node1", "junk");
266 fail("looking up a link ending at nonexistent node should have thrown a NetworkException");
267 }
268 catch (NetworkException ne)
269 {
270
271 }
272 compareNetworkWithClone(network);
273 assertEquals("lookup link from node node1 to node node3", link1, network.getLink("node1", "node3"));
274 assertEquals("lookup link from node1 to node3", link1, network.getLink(node1, node3));
275 assertEquals("lookup link from node node3 to node node1", secondLink, network.getLink("node3", "node1"));
276 assertEquals("lookup link from node3 to node1", secondLink, network.getLink(node3, node1));
277 assertNull("lookup link that does not exist but both nodes do exist", network.getLink(node1, node1));
278 assertNull("lookup link that does not exist but both nodes do exist", network.getLink("node1", "node1"));
279 assertEquals("lookup link by name", link1, network.getLink("link1"));
280 assertEquals("lookup link by name", secondLink, network.getLink("reverseLink"));
281 network.removeLink(link1);
282 assertFalse("Network no longer contains link1", network.containsLink(link1));
283 assertFalse("Network no longer contains link with name link1", network.containsLink("link1"));
284 assertEquals("link add event count is 2", 2, this.linkAddedCount);
285 assertEquals("link removed event count is 1", 1, this.linkRemovedCount);
286 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
287 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
288 assertEquals("GTU add event count is 0", 0, this.gtuAddedCount);
289 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
290 assertEquals("other event count is 0", 0, this.otherEventCount);
291 assertEquals("network now contains one link", 1, network.getLinkMap().size());
292 MockGTU mockGtu1 = new MockGTU("gtu1");
293 GTU gtu1 = mockGtu1.getMock();
294 network.addGTU(gtu1);
295 assertEquals("link add event count is 2", 2, this.linkAddedCount);
296 assertEquals("link removed event count is 1", 1, this.linkRemovedCount);
297 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
298 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
299 assertEquals("GTU add event count is 1", 1, this.gtuAddedCount);
300 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
301 MockGTU mockGtu2 = new MockGTU("gtu2");
302 GTU gtu2 = mockGtu2.getMock();
303 network.addGTU(gtu2);
304 assertEquals("link add event count is 2", 2, this.linkAddedCount);
305 assertEquals("link removed event count is 1", 1, this.linkRemovedCount);
306 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
307 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
308 assertEquals("GTU add event count is 2", 2, this.gtuAddedCount);
309 assertEquals("GTU removed event count is 0", 0, this.gtuRemovedCount);
310 assertEquals("gtu1 can be retrieved", gtu1, network.getGTU("gtu1"));
311 assertEquals("gtu2 can be retrieved", gtu2, network.getGTU("gtu2"));
312 network.removeGTU(gtu1);
313 assertEquals("link add event count is 2", 2, this.linkAddedCount);
314 assertEquals("link removed event count is 1", 1, this.linkRemovedCount);
315 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
316 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
317 assertEquals("GTU add event count is 2", 2, this.gtuAddedCount);
318 assertEquals("GTU removed event count is 1", 1, this.gtuRemovedCount);
319 network.removeGTU(gtu2);
320 assertEquals("link add event count is 2", 2, this.linkAddedCount);
321 assertEquals("link removed event count is 1", 1, this.linkRemovedCount);
322 assertEquals("node add event count is 3", 3, this.nodeAddedCount);
323 assertEquals("node removed event count is 1", 1, this.nodeRemovedCount);
324 assertEquals("GTU add event count is 2", 2, this.gtuAddedCount);
325 assertEquals("GTU removed event count is 2", 2, this.gtuRemovedCount);
326 assertNull("gtu1 can no longer be retrieved", network.getGTU("gtu1"));
327 assertNull("gtu2 can no longer be retrieved", network.getGTU("gtu2"));
328 assertTrue("toString contains the name of the network", network.toString().contains(network.getId()));
329 }
330
331
332
333
334
335
336 private void compareNetworkWithClone(final OTSNetwork network) throws NetworkException
337 {
338 OTSSimulatorInterface oldSimulator = MockSimulator.createMock();
339 OTSSimulatorInterface newSimulator = MockSimulator.createMock();
340 OTSNetwork clone = OTSNetworkUtils.clone(network, "cloned network", oldSimulator, newSimulator);
341 assertTrue("nodes match", network.getNodeMap().equals(clone.getNodeMap()));
342 assertTrue("links match", network.getLinkMap().equals(clone.getLinkMap()));
343
344 }
345
346
347 @Override
348 public final void notify(final EventInterface event) throws RemoteException
349 {
350 EventType type = event.getType();
351 if (type.equals(Network.NODE_ADD_EVENT))
352 {
353 this.nodeAddedCount++;
354 }
355 else if (type.equals(Network.NODE_REMOVE_EVENT))
356 {
357 this.nodeRemovedCount++;
358 }
359 else if (type.equals(Network.LINK_ADD_EVENT))
360 {
361 this.linkAddedCount++;
362 }
363 else if (type.equals(Network.LINK_REMOVE_EVENT))
364 {
365 this.linkRemovedCount++;
366 }
367 else if (type.equals(Network.GTU_ADD_EVENT))
368 {
369 this.gtuAddedCount++;
370 }
371 else if (type.equals(Network.GTU_REMOVE_EVENT))
372 {
373 this.gtuRemovedCount++;
374 }
375 else
376 {
377 this.otherEventCount++;
378 }
379 }
380
381
382
383
384
385 @Test
386 public final void testRouteMap() throws NetworkException
387 {
388 OTSNetwork network = new OTSNetwork("Route map test network");
389 Node node1 = new OTSNode(network, "node1", new OTSPoint3D(10, 20, 30));
390 Node node2 = new OTSNode(network, "node2", new OTSPoint3D(110, 20, 30));
391 List<Node> nodeList = new ArrayList<>();
392 nodeList.add(node1);
393 nodeList.add(node2);
394 Route route1 = new Route("route1", nodeList);
395 Route route2 = new Route("route2");
396 Route route3 = new Route("route3");
397 GTUType carType = new GTUType("car", GTUType.VEHICLE);
398 GTUType bicycleType = new GTUType("bicycle", GTUType.BICYCLE);
399
400 assertEquals("initially the network has 0 routes", 0, network.getDefinedRouteMap(GTUType.VEHICLE).size());
401 network.addRoute(carType, route1);
402 assertEquals("list for carType contains one entry", 1, network.getDefinedRouteMap(carType).size());
403 assertEquals("route for carType route1 is route1", route1, network.getRoute(carType, "route1"));
404 assertNull("route for bycicleType route1 is null", network.getRoute(bicycleType, "route1"));
405 assertEquals("list for bicycleType contains 0 routes", 0, network.getDefinedRouteMap(bicycleType).size());
406 network.addRoute(carType, route2);
407 network.addRoute(bicycleType, route3);
408 assertEquals("list for carType contains two entries", 2, network.getDefinedRouteMap(carType).size());
409 assertEquals("list for bicycleType contains one entry", 1, network.getDefinedRouteMap(bicycleType).size());
410 assertEquals("route for carType route1 is route1", route1, network.getRoute(carType, "route1"));
411 assertEquals("route for carType route2 is route2", route2, network.getRoute(carType, "route2"));
412 assertEquals("route for bicycle route3 is route3", route3, network.getRoute(bicycleType, "route3"));
413 assertNull("route for bicycle route1 is null", network.getRoute(bicycleType, "route1"));
414 try
415 {
416 network.addRoute(carType, route2);
417 fail("adding route again should have thrown a NetworkException");
418 }
419 catch (NetworkException ne)
420 {
421
422 }
423 Network otherNetwork = new OTSNetwork("other Route map test network");
424 Node badNode = new OTSNode(otherNetwork, "nodeInOtherNetwork", new OTSPoint3D(100, 200, 0));
425 List<Node> badNodeList = new ArrayList<>();
426 badNodeList.add(node1);
427 badNodeList.add(node2);
428 badNodeList.add(badNode);
429 Route badRoute = new Route("badRoute", badNodeList);
430 try
431 {
432 network.addRoute(carType, badRoute);
433 fail("adding a route with a node that is not in the network should have thrown a NetworkException");
434 }
435 catch (NetworkException ne)
436 {
437
438 }
439 try
440 {
441 network.removeRoute(bicycleType, route1);
442 fail("attempt to remove a route that is not defined for this GTUType should have thrown a NetworkException");
443 }
444 catch (NetworkException ne)
445 {
446
447 }
448 assertEquals("there is one route from node1 to node2 for carType", 1,
449 network.getRoutesBetween(carType, node1, node2).size());
450 assertEquals("the one route from node1 to node2 is route1", route1,
451 network.getRoutesBetween(carType, node1, node2).iterator().next());
452 assertEquals("there are no routes from node1 to node2 for bicycleType", 0,
453 network.getRoutesBetween(bicycleType, node1, node2).size());
454 assertEquals("there are no routes from node2 to node1 for carTypecleType", 0,
455 network.getRoutesBetween(carType, node2, node1).size());
456 assertEquals("there are no routes from node1 to node1 for carTypecleType", 0,
457 network.getRoutesBetween(carType, node1, node1).size());
458 GTUType junkType = new GTUType("junk", GTUType.VEHICLE);
459 assertEquals("there are no routes from node1 to node2 for badType", 0,
460 network.getRoutesBetween(junkType, node1, node2).size());
461 compareNetworkWithClone(network);
462 network.removeRoute(carType, route1);
463 assertEquals("list for carType now contains one entry", 1, network.getDefinedRouteMap(carType).size());
464 assertEquals("list for bicycleType contains one entry", 1, network.getDefinedRouteMap(bicycleType).size());
465 assertNull("route for carType route1 is null", network.getRoute(carType, "route1"));
466 assertEquals("route for carType route2 is route2", route2, network.getRoute(carType, "route2"));
467 assertEquals("route for bicycle route3 is route3", route3, network.getRoute(bicycleType, "route3"));
468 assertTrue("network contains route2 for carType", network.containsRoute(carType, route2));
469 assertFalse("network does not contain route1 for carType", network.containsRoute(carType, route1));
470 assertTrue("network contains route with name route2 for carType", network.containsRoute(carType, "route2"));
471 assertFalse("network does not contain route with name route1 for carType", network.containsRoute(carType, "route1"));
472 assertFalse("network does not contain route with name route1 for junkType", network.containsRoute(junkType, "route1"));
473 }
474
475
476
477
478
479
480 @Test
481 public final void testShortestPathBiDirectional() throws NetworkException, OTSGeometryException
482 {
483 OTSNetwork network = new OTSNetwork("shortest path test network");
484 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_BOTH);
485 int maxNode = nodes.size();
486 for (int skip = 1; skip < maxNode / 2; skip++)
487 {
488 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
489 {
490 Node fromNode = nodes.get(fromNodeIndex);
491 Node toNode = nodes.get((fromNodeIndex + skip) % maxNode);
492 CompleteRoute route = network.getShortestRouteBetween(GTUType.VEHICLE, fromNode, toNode);
493 assertEquals("route size is skip + 1", skip + 1, route.size());
494 for (int i = 0; i < route.size(); i++)
495 {
496 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + i) % maxNode),
497 route.getNode(i));
498 }
499
500 route = network.getShortestRouteBetween(GTUType.VEHICLE, toNode, fromNode);
501
502 assertEquals("route size is skip + 1", skip + 1, route.size());
503 for (int i = 0; i < route.size(); i++)
504 {
505 assertEquals("node in route at position i should match",
506 nodes.get((fromNodeIndex + skip - i + maxNode) % maxNode), route.getNode(i));
507 }
508 }
509 }
510 compareNetworkWithClone(network);
511
512
513
514
515
516 }
517
518
519
520
521
522
523 @Test
524 public final void testShortestPathClockWise() throws NetworkException, OTSGeometryException
525 {
526 OTSNetwork network = new OTSNetwork("shortest path test network");
527 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_PLUS);
528 int maxNode = nodes.size();
529 for (int skip = 1; skip < maxNode; skip++)
530 {
531 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
532 {
533 Node fromNode = nodes.get(fromNodeIndex);
534 Node toNode = nodes.get((fromNodeIndex + skip) % maxNode);
535 CompleteRoute route = network.getShortestRouteBetween(GTUType.VEHICLE, fromNode, toNode);
536 assertEquals("route size is skip + 1", skip + 1, route.size());
537 for (int i = 0; i < route.size(); i++)
538 {
539 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + i) % maxNode),
540 route.getNode(i));
541 }
542
543 route = network.getShortestRouteBetween(GTUType.VEHICLE, toNode, fromNode);
544
545 assertEquals("route size is maxNode - skip + 1", maxNode - skip + 1, route.size());
546 for (int i = 0; i < route.size(); i++)
547 {
548 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + skip + i) % maxNode),
549 route.getNode(i));
550 }
551 }
552 }
553 compareNetworkWithClone(network);
554 }
555
556
557
558
559
560
561 @Test
562 public final void testShortestPathAntiClockWise() throws NetworkException, OTSGeometryException
563 {
564 OTSNetwork network = new OTSNetwork("shortest path test network");
565 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_MINUS);
566 int maxNode = nodes.size();
567 for (int skip = 1; skip < maxNode; skip++)
568 {
569 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
570 {
571 Node fromNode = nodes.get(fromNodeIndex);
572 Node toNode = nodes.get((fromNodeIndex + skip) % maxNode);
573 CompleteRoute route = network.getShortestRouteBetween(GTUType.VEHICLE, fromNode, toNode);
574 assertEquals("route size is maxNode - skip + 1", maxNode - skip + 1, route.size());
575 for (int i = 0; i < route.size(); i++)
576 {
577 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + maxNode - i) % maxNode),
578 route.getNode(i));
579 }
580
581 route = network.getShortestRouteBetween(GTUType.VEHICLE, toNode, fromNode);
582
583 assertEquals("route size is skip + 1", skip + 1, route.size());
584 for (int i = 0; i < route.size(); i++)
585 {
586 assertEquals("node in route at position i should match",
587 nodes.get((fromNodeIndex + skip + maxNode - i) % maxNode), route.getNode(i));
588 }
589 }
590 }
591 compareNetworkWithClone(network);
592 }
593
594
595
596
597
598
599 @Test
600 public final void testShortestPathWithIntermediateNodes() throws NetworkException, OTSGeometryException
601 {
602 OTSNetwork network = new OTSNetwork("shortest path test network");
603 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_BOTH, 5);
604 int maxNode = nodes.size();
605 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
606 {
607 Node fromNode = network.getNode("node" + fromNodeIndex);
608 for (int intermediateNodes = 0; intermediateNodes <= 2; intermediateNodes++)
609 {
610
611 int numPaths = (int) Math.pow(maxNode - 1, intermediateNodes);
612 for (int path = 0; path < numPaths; path++)
613 {
614 List<Node> viaNodes = new ArrayList<>();
615 int prevNodeIndex = fromNodeIndex;
616 int pathNumber = path;
617 for (int step = 0; step < intermediateNodes; step++)
618 {
619 int nextNodeIndex = pathNumber % (maxNode - 1);
620 if (nextNodeIndex >= prevNodeIndex)
621 {
622 nextNodeIndex = (nextNodeIndex + 1) % maxNode;
623 }
624 viaNodes.add(network.getNode("node" + nextNodeIndex));
625 prevNodeIndex = nextNodeIndex;
626 pathNumber /= (maxNode - 1);
627 }
628 for (int toNodeIndex = 0; toNodeIndex < maxNode; toNodeIndex++)
629 {
630 if (prevNodeIndex == toNodeIndex)
631 {
632 continue;
633 }
634
635
636
637
638
639
640 Node toNode = network.getNode("node" + toNodeIndex);
641 CompleteRoute route = network.getShortestRouteBetween(GTUType.VEHICLE, fromNode, toNode, viaNodes);
642
643 List<Node> expectedPath = new ArrayList<>();
644 expectedPath.add(fromNode);
645 viaNodes.add(network.getNode("node" + toNodeIndex));
646 int from = fromNodeIndex;
647 for (int positionInPlan = 0; positionInPlan < viaNodes.size(); positionInPlan++)
648 {
649 Node nextNode = viaNodes.get(positionInPlan);
650 int to = Integer.parseInt(nextNode.getId().substring(4));
651 int distance = (to + maxNode - from) % maxNode;
652 if (distance > maxNode / 2)
653 {
654 distance -= maxNode;
655 }
656 boolean clockWise = distance > 0;
657 while (from != to)
658 {
659 from = (from + (clockWise ? 1 : maxNode - 1)) % maxNode;
660 expectedPath.add(network.getNode("node" + from));
661 }
662 }
663
664
665
666
667
668
669
670
671
672
673
674
675
676 assertEquals("expected path should have same length as route", expectedPath.size(), route.size());
677 for (int i = 0; i < expectedPath.size(); i++)
678 {
679 assertEquals("node i should match", expectedPath.get(i), route.getNode(i));
680 }
681 }
682 }
683 }
684 }
685 }
686
687
688
689
690
691
692
693
694
695 private List<Node> createRingNodesAndLinks(final Network network, final LongitudinalDirectionality ld)
696 throws NetworkException, OTSGeometryException
697 {
698 return createRingNodesAndLinks(network, ld, 10);
699 }
700
701
702
703
704
705
706
707
708
709
710 private List<Node> createRingNodesAndLinks(final Network network, final LongitudinalDirectionality ld, final int maxNode)
711 throws NetworkException, OTSGeometryException
712 {
713 OTSSimulatorInterface simulator = MockSimulator.createMock();
714 GTUCompatibility<LinkType> compatibility =
715 new GTUCompatibility<>((LinkType) null).addAllowedGTUType(GTUType.ROAD_USER, ld);
716 LinkType linkType = new LinkType("linkType", null, compatibility);
717 List<Node> nodes = new ArrayList<>();
718 double radius = 500;
719 double centerX = 0;
720 double centerY = 0;
721 for (int i = 0; i < maxNode; i++)
722 {
723 double angle = i * Math.PI * 2 / maxNode;
724 nodes.add(new OTSNode(network, "node" + i,
725 new OTSPoint3D(centerX + radius * Math.cos(angle), centerY + radius * Math.sin(angle), 20)));
726 }
727
728 Node prevNode = nodes.get(maxNode - 1);
729 for (Node node : nodes)
730 {
731 new OTSLink(network, "from " + prevNode.getId() + " to " + node.getId(), prevNode, node, linkType,
732 new OTSLine3D(prevNode.getPoint(), node.getPoint()), simulator);
733 prevNode = node;
734 }
735 return nodes;
736 }
737
738 }