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, true);
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", true);
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, network.getLinkType(LinkType.DEFAULTS.ROAD),
165 new OTSLine3D(node1.getPoint(), node2.getPoint()), 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, network.getLinkType(LinkType.DEFAULTS.ROAD),
175 new OTSLine3D(node2.getPoint(), node1.getPoint()), 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, network.getLinkType(LinkType.DEFAULTS.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, network.getLinkType(LinkType.DEFAULTS.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, network.getLinkType(LinkType.DEFAULTS.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", true);
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", network.getGtuType(GTUType.DEFAULTS.VEHICLE));
398 GTUType bicycleType = new GTUType("bicycle", network.getGtuType(GTUType.DEFAULTS.BICYCLE));
399
400 assertEquals("initially the network has 0 routes", 0,
401 network.getDefinedRouteMap(network.getGtuType(GTUType.DEFAULTS.VEHICLE)).size());
402 network.addRoute(carType, route1);
403 assertEquals("list for carType contains one entry", 1, network.getDefinedRouteMap(carType).size());
404 assertEquals("route for carType route1 is route1", route1, network.getRoute(carType, "route1"));
405 assertNull("route for bycicleType route1 is null", network.getRoute(bicycleType, "route1"));
406 assertEquals("list for bicycleType contains 0 routes", 0, network.getDefinedRouteMap(bicycleType).size());
407 network.addRoute(carType, route2);
408 network.addRoute(bicycleType, route3);
409 assertEquals("list for carType contains two entries", 2, network.getDefinedRouteMap(carType).size());
410 assertEquals("list for bicycleType contains one entry", 1, network.getDefinedRouteMap(bicycleType).size());
411 assertEquals("route for carType route1 is route1", route1, network.getRoute(carType, "route1"));
412 assertEquals("route for carType route2 is route2", route2, network.getRoute(carType, "route2"));
413 assertEquals("route for bicycle route3 is route3", route3, network.getRoute(bicycleType, "route3"));
414 assertNull("route for bicycle route1 is null", network.getRoute(bicycleType, "route1"));
415 try
416 {
417 network.addRoute(carType, route2);
418 fail("adding route again should have thrown a NetworkException");
419 }
420 catch (NetworkException ne)
421 {
422
423 }
424 Network otherNetwork = new OTSNetwork("other Route map test network", true);
425 Node badNode = new OTSNode(otherNetwork, "nodeInOtherNetwork", new OTSPoint3D(100, 200, 0));
426 List<Node> badNodeList = new ArrayList<>();
427 badNodeList.add(node1);
428 badNodeList.add(node2);
429 badNodeList.add(badNode);
430 Route badRoute = new Route("badRoute", badNodeList);
431 try
432 {
433 network.addRoute(carType, badRoute);
434 fail("adding a route with a node that is not in the network should have thrown a NetworkException");
435 }
436 catch (NetworkException ne)
437 {
438
439 }
440 try
441 {
442 network.removeRoute(bicycleType, route1);
443 fail("attempt to remove a route that is not defined for this GTUType should have thrown a NetworkException");
444 }
445 catch (NetworkException ne)
446 {
447
448 }
449 assertEquals("there is one route from node1 to node2 for carType", 1,
450 network.getRoutesBetween(carType, node1, node2).size());
451 assertEquals("the one route from node1 to node2 is route1", route1,
452 network.getRoutesBetween(carType, node1, node2).iterator().next());
453 assertEquals("there are no routes from node1 to node2 for bicycleType", 0,
454 network.getRoutesBetween(bicycleType, node1, node2).size());
455 assertEquals("there are no routes from node2 to node1 for carTypecleType", 0,
456 network.getRoutesBetween(carType, node2, node1).size());
457 assertEquals("there are no routes from node1 to node1 for carTypecleType", 0,
458 network.getRoutesBetween(carType, node1, node1).size());
459 GTUType junkType = new GTUType("junk", network.getGtuType(GTUType.DEFAULTS.VEHICLE));
460 assertEquals("there are no routes from node1 to node2 for badType", 0,
461 network.getRoutesBetween(junkType, node1, node2).size());
462 compareNetworkWithClone(network);
463 network.removeRoute(carType, route1);
464 assertEquals("list for carType now contains one entry", 1, network.getDefinedRouteMap(carType).size());
465 assertEquals("list for bicycleType contains one entry", 1, network.getDefinedRouteMap(bicycleType).size());
466 assertNull("route for carType route1 is null", network.getRoute(carType, "route1"));
467 assertEquals("route for carType route2 is route2", route2, network.getRoute(carType, "route2"));
468 assertEquals("route for bicycle route3 is route3", route3, network.getRoute(bicycleType, "route3"));
469 assertTrue("network contains route2 for carType", network.containsRoute(carType, route2));
470 assertFalse("network does not contain route1 for carType", network.containsRoute(carType, route1));
471 assertTrue("network contains route with name route2 for carType", network.containsRoute(carType, "route2"));
472 assertFalse("network does not contain route with name route1 for carType", network.containsRoute(carType, "route1"));
473 assertFalse("network does not contain route with name route1 for junkType", network.containsRoute(junkType, "route1"));
474 }
475
476
477
478
479
480
481 @Test
482 public final void testShortestPathBiDirectional() throws NetworkException, OTSGeometryException
483 {
484 OTSNetwork network = new OTSNetwork("shortest path test network", true);
485 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_BOTH);
486 int maxNode = nodes.size();
487 for (int skip = 1; skip < maxNode / 2; skip++)
488 {
489 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
490 {
491 Node fromNode = nodes.get(fromNodeIndex);
492 Node toNode = nodes.get((fromNodeIndex + skip) % maxNode);
493 CompleteRoute route =
494 network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), fromNode, toNode);
495 assertEquals("route size is skip + 1", skip + 1, route.size());
496 for (int i = 0; i < route.size(); i++)
497 {
498 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + i) % maxNode),
499 route.getNode(i));
500 }
501
502 route = network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), toNode, fromNode);
503
504 assertEquals("route size is skip + 1", skip + 1, route.size());
505 for (int i = 0; i < route.size(); i++)
506 {
507 assertEquals("node in route at position i should match",
508 nodes.get((fromNodeIndex + skip - i + maxNode) % maxNode), route.getNode(i));
509 }
510 }
511 }
512 compareNetworkWithClone(network);
513
514
515
516
517
518 }
519
520
521
522
523
524
525 @Test
526 public final void testShortestPathClockWise() throws NetworkException, OTSGeometryException
527 {
528 OTSNetwork network = new OTSNetwork("shortest path test network", true);
529 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_PLUS);
530 int maxNode = nodes.size();
531 for (int skip = 1; skip < maxNode; skip++)
532 {
533 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
534 {
535 Node fromNode = nodes.get(fromNodeIndex);
536 Node toNode = nodes.get((fromNodeIndex + skip) % maxNode);
537 CompleteRoute route =
538 network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), fromNode, toNode);
539 assertEquals("route size is skip + 1", skip + 1, route.size());
540 for (int i = 0; i < route.size(); i++)
541 {
542 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + i) % maxNode),
543 route.getNode(i));
544 }
545
546 route = network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), toNode, fromNode);
547
548 assertEquals("route size is maxNode - skip + 1", maxNode - skip + 1, route.size());
549 for (int i = 0; i < route.size(); i++)
550 {
551 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + skip + i) % maxNode),
552 route.getNode(i));
553 }
554 }
555 }
556 compareNetworkWithClone(network);
557 }
558
559
560
561
562
563
564 @Test
565 public final void testShortestPathAntiClockWise() throws NetworkException, OTSGeometryException
566 {
567 OTSNetwork network = new OTSNetwork("shortest path test network", true);
568 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_MINUS);
569 int maxNode = nodes.size();
570 for (int skip = 1; skip < maxNode; skip++)
571 {
572 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
573 {
574 Node fromNode = nodes.get(fromNodeIndex);
575 Node toNode = nodes.get((fromNodeIndex + skip) % maxNode);
576 CompleteRoute route =
577 network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), fromNode, toNode);
578 assertEquals("route size is maxNode - skip + 1", maxNode - skip + 1, route.size());
579 for (int i = 0; i < route.size(); i++)
580 {
581 assertEquals("node in route at position i should match", nodes.get((fromNodeIndex + maxNode - i) % maxNode),
582 route.getNode(i));
583 }
584
585 route = network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), toNode, fromNode);
586
587 assertEquals("route size is skip + 1", skip + 1, route.size());
588 for (int i = 0; i < route.size(); i++)
589 {
590 assertEquals("node in route at position i should match",
591 nodes.get((fromNodeIndex + skip + maxNode - i) % maxNode), route.getNode(i));
592 }
593 }
594 }
595 compareNetworkWithClone(network);
596 }
597
598
599
600
601
602
603 @Test
604 public final void testShortestPathWithIntermediateNodes() throws NetworkException, OTSGeometryException
605 {
606 OTSNetwork network = new OTSNetwork("shortest path test network", true);
607 List<Node> nodes = createRingNodesAndLinks(network, LongitudinalDirectionality.DIR_BOTH, 5);
608 int maxNode = nodes.size();
609 for (int fromNodeIndex = 0; fromNodeIndex < maxNode; fromNodeIndex++)
610 {
611 Node fromNode = network.getNode("node" + fromNodeIndex);
612 for (int intermediateNodes = 0; intermediateNodes <= 2; intermediateNodes++)
613 {
614
615 int numPaths = (int) Math.pow(maxNode - 1, intermediateNodes);
616 for (int path = 0; path < numPaths; path++)
617 {
618 List<Node> viaNodes = new ArrayList<>();
619 int prevNodeIndex = fromNodeIndex;
620 int pathNumber = path;
621 for (int step = 0; step < intermediateNodes; step++)
622 {
623 int nextNodeIndex = pathNumber % (maxNode - 1);
624 if (nextNodeIndex >= prevNodeIndex)
625 {
626 nextNodeIndex = (nextNodeIndex + 1) % maxNode;
627 }
628 viaNodes.add(network.getNode("node" + nextNodeIndex));
629 prevNodeIndex = nextNodeIndex;
630 pathNumber /= (maxNode - 1);
631 }
632 for (int toNodeIndex = 0; toNodeIndex < maxNode; toNodeIndex++)
633 {
634 if (prevNodeIndex == toNodeIndex)
635 {
636 continue;
637 }
638
639
640
641
642
643
644 Node toNode = network.getNode("node" + toNodeIndex);
645 CompleteRoute route = network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE),
646 fromNode, toNode, viaNodes);
647
648 List<Node> expectedPath = new ArrayList<>();
649 expectedPath.add(fromNode);
650 viaNodes.add(network.getNode("node" + toNodeIndex));
651 int from = fromNodeIndex;
652 for (int positionInPlan = 0; positionInPlan < viaNodes.size(); positionInPlan++)
653 {
654 Node nextNode = viaNodes.get(positionInPlan);
655 int to = Integer.parseInt(nextNode.getId().substring(4));
656 int distance = (to + maxNode - from) % maxNode;
657 if (distance > maxNode / 2)
658 {
659 distance -= maxNode;
660 }
661 boolean clockWise = distance > 0;
662 while (from != to)
663 {
664 from = (from + (clockWise ? 1 : maxNode - 1)) % maxNode;
665 expectedPath.add(network.getNode("node" + from));
666 }
667 }
668
669
670
671
672
673
674
675
676
677
678
679
680
681 assertEquals("expected path should have same length as route", expectedPath.size(), route.size());
682 for (int i = 0; i < expectedPath.size(); i++)
683 {
684 assertEquals("node i should match", expectedPath.get(i), route.getNode(i));
685 }
686 }
687 }
688 }
689 }
690 }
691
692
693
694
695
696
697
698
699
700 private List<Node> createRingNodesAndLinks(final Network network, final LongitudinalDirectionality ld)
701 throws NetworkException, OTSGeometryException
702 {
703 return createRingNodesAndLinks(network, ld, 10);
704 }
705
706
707
708
709
710
711
712
713
714
715 private List<Node> createRingNodesAndLinks(final Network network, final LongitudinalDirectionality ld, final int maxNode)
716 throws NetworkException, OTSGeometryException
717 {
718 OTSSimulatorInterface simulator = MockSimulator.createMock();
719 GTUCompatibility<LinkType> compatibility =
720 new GTUCompatibility<>((LinkType) null).addAllowedGTUType(network.getGtuType(GTUType.DEFAULTS.ROAD_USER), ld);
721 LinkType linkType = new LinkType("linkType", null, compatibility, network);
722 List<Node> nodes = new ArrayList<>();
723 double radius = 500;
724 double centerX = 0;
725 double centerY = 0;
726 for (int i = 0; i < maxNode; i++)
727 {
728 double angle = i * Math.PI * 2 / maxNode;
729 nodes.add(new OTSNode(network, "node" + i,
730 new OTSPoint3D(centerX + radius * Math.cos(angle), centerY + radius * Math.sin(angle), 20)));
731 }
732
733 Node prevNode = nodes.get(maxNode - 1);
734 for (Node node : nodes)
735 {
736 new OTSLink(network, "from " + prevNode.getId() + " to " + node.getId(), prevNode, node, linkType,
737 new OTSLine3D(prevNode.getPoint(), node.getPoint()), simulator);
738 prevNode = node;
739 }
740 return nodes;
741 }
742
743 }