1 package org.opentrafficsim.road.network.factory.xml;
2
3 import java.awt.Color;
4 import java.lang.reflect.Constructor;
5 import java.lang.reflect.InvocationTargetException;
6 import java.rmi.RemoteException;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.LinkedHashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14 import java.util.UUID;
15
16 import javax.naming.NamingException;
17
18 import org.djunits.unit.AngleUnit;
19 import org.djunits.value.AngleUtil;
20 import org.djunits.value.vdouble.scalar.Direction;
21 import org.djunits.value.vdouble.scalar.Length;
22 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
23 import org.opentrafficsim.core.geometry.Bezier;
24 import org.opentrafficsim.core.geometry.OTSGeometryException;
25 import org.opentrafficsim.core.geometry.OTSLine3D;
26 import org.opentrafficsim.core.geometry.OTSPoint3D;
27 import org.opentrafficsim.core.gtu.GTUException;
28 import org.opentrafficsim.core.gtu.GTUType;
29 import org.opentrafficsim.core.gtu.RelativePosition;
30 import org.opentrafficsim.core.network.LinkType;
31 import org.opentrafficsim.core.network.LongitudinalDirectionality;
32 import org.opentrafficsim.core.network.NetworkException;
33 import org.opentrafficsim.core.network.animation.LinkAnimation;
34 import org.opentrafficsim.road.network.animation.LaneAnimation;
35 import org.opentrafficsim.road.network.animation.ShoulderAnimation;
36 import org.opentrafficsim.road.network.animation.StripeAnimation;
37 import org.opentrafficsim.road.network.factory.xml.ArcTag.ArcDirection;
38 import org.opentrafficsim.road.network.lane.CrossSectionElement;
39 import org.opentrafficsim.road.network.lane.CrossSectionLink;
40 import org.opentrafficsim.road.network.lane.Lane;
41 import org.opentrafficsim.road.network.lane.LaneType;
42 import org.opentrafficsim.road.network.lane.NoTrafficLane;
43 import org.opentrafficsim.road.network.lane.Shoulder;
44 import org.opentrafficsim.road.network.lane.Stripe;
45 import org.opentrafficsim.road.network.lane.Stripe.Permeable;
46 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
47 import org.opentrafficsim.road.network.lane.object.LaneBlock;
48 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
49 import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
50 import org.xml.sax.SAXException;
51
52 import nl.tudelft.simulation.dsol.SimRuntimeException;
53 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
54 import nl.tudelft.simulation.language.d2.Angle;
55 import nl.tudelft.simulation.language.d3.CartesianPoint;
56 import nl.tudelft.simulation.language.d3.DirectedPoint;
57 import nl.tudelft.simulation.language.reflection.ClassUtil;
58
59
60
61
62
63
64
65
66
67
68 final class Links
69 {
70
71 private Links()
72 {
73
74 }
75
76
77
78
79
80
81
82 @SuppressWarnings("methodlength")
83 static void calculateNodeCoordinates(final XmlNetworkLaneParser parser) throws NetworkException, NamingException
84 {
85
86 for (LinkTag linkTag : parser.linkTags.values())
87 {
88 if (linkTag.straightTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
89 {
90 if (linkTag.nodeStartTag.angle == null)
91 {
92 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
93 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
94 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), AngleUnit.RADIAN);
95 }
96 if (linkTag.nodeEndTag.angle == null)
97 {
98 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
99 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
100 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), AngleUnit.RADIAN);
101 }
102 }
103 }
104
105
106 for (LinkTag linkTag : parser.linkTags.values())
107 {
108 if (linkTag.polyLineTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
109 {
110 if (linkTag.nodeStartTag.angle == null)
111 {
112 double dx = linkTag.polyLineTag.coordinates[0].x - linkTag.nodeStartTag.coordinate.x;
113 double dy = linkTag.polyLineTag.coordinates[0].y - linkTag.nodeStartTag.coordinate.y;
114 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), AngleUnit.RADIAN);
115 }
116 if (linkTag.nodeEndTag.angle == null)
117 {
118 double dx = linkTag.nodeEndTag.coordinate.x
119 - linkTag.polyLineTag.coordinates[linkTag.polyLineTag.coordinates.length - 1].x;
120 double dy = linkTag.nodeEndTag.coordinate.y
121 - linkTag.polyLineTag.coordinates[linkTag.polyLineTag.coordinates.length - 1].y;
122 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), AngleUnit.RADIAN);
123 }
124 }
125 }
126
127
128 Set<NodeTag> nodeTags = new HashSet<>();
129 for (LinkTag linkTag : parser.linkTags.values())
130 {
131 if (linkTag.nodeStartTag.coordinate == null)
132 {
133 nodeTags.add(linkTag.nodeStartTag);
134 }
135 if (linkTag.nodeEndTag.coordinate == null)
136 {
137 nodeTags.add(linkTag.nodeEndTag);
138 }
139 }
140
141 while (nodeTags.size() > 0)
142 {
143 boolean found = false;
144 for (LinkTag linkTag : parser.linkTags.values())
145 {
146 if (linkTag.straightTag != null || linkTag.arcTag != null)
147 {
148 if (nodeTags.contains(linkTag.nodeStartTag) == nodeTags.contains(linkTag.nodeEndTag))
149 {
150 continue;
151 }
152
153 if (linkTag.straightTag != null)
154 {
155 double lengthSI = linkTag.straightTag.length.getSI();
156 if (linkTag.nodeEndTag.node == null)
157 {
158 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeStartTag.node.getLocation().getX(),
159 linkTag.nodeStartTag.node.getLocation().getY(),
160 linkTag.nodeStartTag.node.getLocation().getZ());
161 double angle = linkTag.nodeStartTag.node.getDirection().getSI();
162 double slope = linkTag.nodeStartTag.node.getSlope().getSI();
163 coordinate.x += lengthSI * Math.cos(angle);
164 coordinate.y += lengthSI * Math.sin(angle);
165 coordinate.z += lengthSI * Math.sin(slope);
166 NodeTag nodeTag = linkTag.nodeEndTag;
167 nodeTag.angle = new Direction(angle, AngleUnit.SI);
168 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
169 nodeTag.slope = new Direction(slope, AngleUnit.SI);
170 linkTag.nodeEndTag.node = NodeTag.makeOTSNode(nodeTag, parser);
171 nodeTags.remove(linkTag.nodeEndTag);
172 }
173 else if (linkTag.nodeStartTag.node == null)
174 {
175 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeEndTag.node.getLocation().getX(),
176 linkTag.nodeEndTag.node.getLocation().getY(), linkTag.nodeEndTag.node.getLocation().getZ());
177 double angle = linkTag.nodeEndTag.node.getDirection().getSI();
178 double slope = linkTag.nodeEndTag.node.getSlope().getSI();
179 coordinate.x -= lengthSI * Math.cos(angle);
180 coordinate.y -= lengthSI * Math.sin(angle);
181 coordinate.z -= lengthSI * Math.sin(slope);
182 NodeTag nodeTag = linkTag.nodeStartTag;
183 nodeTag.angle = new Direction(angle, AngleUnit.SI);
184 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
185 nodeTag.slope = new Direction(slope, AngleUnit.SI);
186 linkTag.nodeStartTag.node = NodeTag.makeOTSNode(nodeTag, parser);
187 nodeTags.remove(linkTag.nodeStartTag);
188 }
189 }
190 else if (linkTag.arcTag != null)
191 {
192 double radiusSI = linkTag.arcTag.radius.getSI();
193 double angle = linkTag.arcTag.angle.getSI();
194 ArcDirection direction = linkTag.arcTag.direction;
195
196 if (linkTag.nodeEndTag.node == null)
197 {
198 CartesianPoint coordinate = new CartesianPoint(0.0, 0.0, 0.0);
199 double startAngle = linkTag.nodeStartTag.node.getDirection().getSI();
200 double slope = linkTag.nodeStartTag.node.getSlope().getSI();
201 double lengthSI = radiusSI * angle;
202 NodeTag nodeTag = linkTag.nodeEndTag;
203 if (direction.equals(ArcDirection.LEFT))
204 {
205 linkTag.arcTag.center = new OTSPoint3D(
206 linkTag.nodeStartTag.node.getLocation().getX()
207 + radiusSI * Math.cos(startAngle + Math.PI / 2.0),
208 linkTag.nodeStartTag.node.getLocation().getY()
209 + radiusSI * Math.sin(startAngle + Math.PI / 2.0),
210 0.0);
211 linkTag.arcTag.startAngle = startAngle - Math.PI / 2.0;
212 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle + angle);
213 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle + angle);
214 nodeTag.angle = new Direction(AngleUtil.normalize(startAngle + angle), AngleUnit.SI);
215 }
216 else
217 {
218 linkTag.arcTag.center = new OTSPoint3D(
219 linkTag.nodeStartTag.node.getLocation().getX()
220 - radiusSI * Math.cos(startAngle + Math.PI / 2.0),
221 linkTag.nodeStartTag.node.getLocation().getY()
222 - radiusSI * Math.sin(startAngle + Math.PI / 2.0),
223 0.0);
224 linkTag.arcTag.startAngle = startAngle + Math.PI / 2.0;
225 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle - angle);
226 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle - angle);
227 nodeTag.angle = new Direction(AngleUtil.normalize(startAngle - angle), AngleUnit.SI);
228 }
229 coordinate.z = linkTag.nodeStartTag.node.getLocation().getZ() + lengthSI * Math.sin(slope);
230 nodeTag.slope = new Direction(slope, AngleUnit.SI);
231 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
232 linkTag.nodeEndTag.node = NodeTag.makeOTSNode(nodeTag, parser);
233 nodeTags.remove(linkTag.nodeEndTag);
234 }
235
236 else if (linkTag.nodeStartTag.node == null)
237 {
238 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeEndTag.node.getLocation().getX(),
239 linkTag.nodeEndTag.node.getLocation().getY(), linkTag.nodeEndTag.node.getLocation().getZ());
240 double endAngle = linkTag.nodeEndTag.node.getDirection().getSI();
241 double slope = linkTag.nodeEndTag.node.getSlope().getSI();
242 double lengthSI = radiusSI * angle;
243 NodeTag nodeTag = linkTag.nodeStartTag;
244 if (direction.equals(ArcDirection.LEFT))
245 {
246 linkTag.arcTag.center =
247 new OTSPoint3D(coordinate.x + radiusSI * Math.cos(endAngle + Math.PI / 2.0),
248 coordinate.y + radiusSI * Math.sin(endAngle + Math.PI / 2.0), 0.0);
249 linkTag.arcTag.startAngle = endAngle - Math.PI / 2.0 - angle;
250 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
251 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
252 nodeTag.angle = new Direction(AngleUtil.normalize(linkTag.arcTag.startAngle + Math.PI / 2.0),
253 AngleUnit.SI);
254 }
255 else
256 {
257 linkTag.arcTag.center =
258 new OTSPoint3D(coordinate.x + radiusSI * Math.cos(endAngle - Math.PI / 2.0),
259 coordinate.y + radiusSI * Math.sin(endAngle - Math.PI / 2.0), 0.0);
260 linkTag.arcTag.startAngle = endAngle + Math.PI / 2.0 + angle;
261 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
262 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
263 nodeTag.angle = new Direction(AngleUtil.normalize(linkTag.arcTag.startAngle - Math.PI / 2.0),
264 AngleUnit.SI);
265 }
266 coordinate.z -= lengthSI * Math.sin(slope);
267 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
268 nodeTag.slope = new Direction(slope, AngleUnit.SI);
269 linkTag.nodeStartTag.node = NodeTag.makeOTSNode(nodeTag, parser);
270 nodeTags.remove(linkTag.nodeStartTag);
271 }
272 }
273 }
274 }
275 if (!found)
276 {
277 throw new NetworkException("Cannot find coordinates of one or more nodes");
278 }
279 }
280
281
282 for (LinkTag linkTag : parser.linkTags.values())
283 {
284 if (linkTag.straightTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
285 {
286 if (linkTag.nodeStartTag.angle == null)
287 {
288 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
289 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
290 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), AngleUnit.RADIAN);
291 }
292 if (linkTag.nodeEndTag.angle == null)
293 {
294 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
295 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
296 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), AngleUnit.RADIAN);
297 }
298 }
299 }
300
301
302 for (NodeTag nodeTag : parser.nodeTags.values())
303 {
304 if (nodeTag.coordinate != null && nodeTag.node == null)
305 {
306 if (nodeTag.angle == null)
307 {
308 nodeTag.angle = Direction.ZERO;
309 }
310 if (nodeTag.slope == null)
311 {
312 nodeTag.slope = Direction.ZERO;
313 }
314 nodeTag.node = NodeTag.makeOTSNode(nodeTag, parser);
315 }
316 }
317
318 }
319
320
321
322
323
324
325
326
327
328
329 static void buildLink(final LinkTag linkTag, final XmlNetworkLaneParser parser, final OTSDEVSSimulatorInterface simulator)
330 throws OTSGeometryException, NamingException, NetworkException
331 {
332 NodeTag from = linkTag.nodeStartTag;
333 OTSPoint3D startPoint = new OTSPoint3D(from.coordinate);
334 double startAngle = from.angle.si;
335 if (linkTag.offsetStart != null && linkTag.offsetStart.si != 0.0)
336 {
337
338 double offset = linkTag.offsetStart.si;
339 startPoint = new OTSPoint3D(startPoint.x + offset * Math.cos(startAngle + Math.PI / 2.0),
340 startPoint.y + offset * Math.sin(startAngle + Math.PI / 2.0), startPoint.z);
341 System.out
342 .println("fc = " + from.coordinate + ", sa = " + startAngle + ", so = " + offset + ", sp = " + startPoint);
343 }
344
345 NodeTag to = linkTag.nodeEndTag;
346 OTSPoint3D endPoint = new OTSPoint3D(to.coordinate);
347 double endAngle = to.angle.si;
348 if (linkTag.offsetEnd != null && linkTag.offsetEnd.si != 0.0)
349 {
350
351 double offset = linkTag.offsetEnd.si;
352 endPoint = new OTSPoint3D(endPoint.x + offset * Math.cos(endAngle + Math.PI / 2.0),
353 endPoint.y + offset * Math.sin(endAngle + Math.PI / 2.0), endPoint.z);
354 System.out.println("tc = " + to.coordinate + ", ea = " + endAngle + ", eo = " + offset + ", ep = " + endPoint);
355 }
356
357 OTSPoint3D[] coordinates = null;
358
359 if (linkTag.straightTag != null)
360 {
361 coordinates = new OTSPoint3D[2];
362 coordinates[0] = startPoint;
363 coordinates[1] = endPoint;
364 }
365
366 else if (linkTag.polyLineTag != null)
367 {
368 int intermediatePoints = linkTag.polyLineTag.coordinates.length;
369 coordinates = new OTSPoint3D[intermediatePoints + 2];
370 coordinates[0] = startPoint;
371 coordinates[intermediatePoints + 1] = endPoint;
372 for (int p = 0; p < intermediatePoints; p++)
373 {
374 coordinates[p + 1] = linkTag.polyLineTag.coordinates[p];
375 }
376
377 }
378 else if (linkTag.arcTag != null)
379 {
380
381 double radiusSI = linkTag.arcTag.radius.getSI();
382 double offsetStart = 0.0;
383 if (linkTag.offsetStart != null)
384 {
385 offsetStart = linkTag.offsetStart.si;
386 }
387 double offsetEnd = 0.0;
388 if (linkTag.offsetEnd != null)
389 {
390 offsetEnd = linkTag.offsetEnd.si;
391 }
392 List<OTSPoint3D> center = OTSPoint3D.circleIntersections(from.coordinate, radiusSI + offsetStart, to.coordinate,
393 radiusSI + offsetEnd);
394 OTSPoint3D c = linkTag.arcTag.center =
395 (linkTag.arcTag.direction.equals(ArcTag.ArcDirection.RIGHT)) ? center.get(0) : center.get(1);
396
397
398 double sa = linkTag.arcTag.startAngle = Math.atan2(from.coordinate.y - c.y, from.coordinate.x - c.x);
399 double ea = Math.atan2(to.coordinate.y - c.y, to.coordinate.x - c.x);
400 if (linkTag.arcTag.direction.equals(ArcDirection.RIGHT))
401 {
402
403 ea = (sa < ea) ? ea + Math.PI * 2.0 : ea;
404 }
405 else
406 {
407
408 ea = (ea < sa) ? ea + Math.PI * 2.0 : ea;
409 }
410
411 int points = (Angle.normalize2Pi(ea - sa) <= Math.PI / 2.0) ? 64 : 128;
412 coordinates = new OTSPoint3D[points];
413 coordinates[0] = new OTSPoint3D(from.coordinate.x + Math.cos(sa) * offsetStart,
414 from.coordinate.y + Math.sin(sa) * offsetStart, from.coordinate.z);
415 coordinates[coordinates.length - 1] = new OTSPoint3D(to.coordinate.x + Math.cos(ea) * offsetEnd,
416 to.coordinate.y + Math.sin(ea) * offsetEnd, to.coordinate.z);
417 double angleStep = linkTag.arcTag.angle.getSI() / points;
418 double slopeStep = (to.coordinate.z - from.coordinate.z) / points;
419
420 if (linkTag.arcTag.direction.equals(ArcDirection.RIGHT))
421 {
422 for (int p = 1; p < points - 1; p++)
423 {
424 double dRad = offsetStart + (offsetEnd - offsetStart) * p / points;
425 coordinates[p] = new OTSPoint3D(
426 linkTag.arcTag.center.x + (radiusSI + dRad) * Math.cos(linkTag.arcTag.startAngle - angleStep * p),
427 linkTag.arcTag.center.y + (radiusSI + dRad) * Math.sin(linkTag.arcTag.startAngle - angleStep * p),
428 from.coordinate.z + slopeStep * p);
429 }
430 }
431 else
432 {
433 for (int p = 1; p < points - 1; p++)
434 {
435 double dRad = offsetStart + (offsetEnd - offsetStart) * p / points;
436 coordinates[p] = new OTSPoint3D(
437 linkTag.arcTag.center.x + (radiusSI + dRad) * Math.cos(linkTag.arcTag.startAngle + angleStep * p),
438 linkTag.arcTag.center.y + (radiusSI + dRad) * Math.sin(linkTag.arcTag.startAngle + angleStep * p),
439 from.coordinate.z + slopeStep * p);
440 }
441 }
442 }
443
444 else if (linkTag.bezierTag != null)
445 {
446 coordinates = Bezier
447 .cubic(128, new DirectedPoint(startPoint.x, startPoint.y, startPoint.z, 0, 0, startAngle),
448 new DirectedPoint(endPoint.x, endPoint.y, endPoint.z, 0, 0, endAngle), linkTag.bezierTag.shape)
449 .getPoints();
450 }
451
452 else
453 {
454 throw new NetworkException(
455 "Making link, but link " + linkTag.name + " has no filled straight, arc, or bezier curve");
456 }
457
458 OTSLine3D designLine = OTSLine3D.createAndCleanOTSLine3D(coordinates);
459
460
461 CrossSectionLink link = new CrossSectionLink(parser.network, linkTag.name, linkTag.nodeStartTag.node,
462 linkTag.nodeEndTag.node, LinkType.ALL, designLine, simulator,
463 new HashMap<GTUType, LongitudinalDirectionality>(), linkTag.laneKeepingPolicy);
464 try
465 {
466 new LinkAnimation(link, simulator, 0.5f);
467 }
468 catch (RemoteException exception)
469 {
470 exception.printStackTrace();
471 }
472 linkTag.link = link;
473 }
474
475
476
477
478
479
480
481
482
483
484
485
486 @SuppressWarnings({ "checkstyle:needbraces", "checkstyle:methodlength" })
487 static void applyRoadTypeToLink(final LinkTag linkTag, final XmlNetworkLaneParser parser,
488 final OTSDEVSSimulatorInterface simulator)
489 throws NetworkException, NamingException, SAXException, GTUException, OTSGeometryException, SimRuntimeException
490 {
491 CrossSectionLink csl = linkTag.link;
492 List<CrossSectionElement> cseList = new ArrayList<>();
493 List<Lane> lanes = new ArrayList<>();
494
495 LongitudinalDirectionality linkDirection = LongitudinalDirectionality.DIR_NONE;
496 for (CrossSectionElementTag cseTag : linkTag.roadLayoutTag.cseTags.values())
497 {
498 LaneOverrideTag laneOverrideTag = null;
499 if (linkTag.laneOverrideTags.containsKey(cseTag.name))
500 laneOverrideTag = linkTag.laneOverrideTags.get(cseTag.name);
501
502 switch (cseTag.elementType)
503 {
504 case STRIPE:
505 switch (cseTag.stripeType)
506 {
507 case BLOCKED:
508 case DASHED:
509 Stripe dashedLine = new Stripe(csl, cseTag.offset, cseTag.width);
510 dashedLine.addPermeability(GTUType.ALL, Permeable.BOTH);
511 if (simulator != null && simulator instanceof AnimatorInterface)
512 {
513 try
514 {
515 new StripeAnimation(dashedLine, simulator, StripeAnimation.TYPE.DASHED);
516 }
517 catch (RemoteException exception)
518 {
519 exception.printStackTrace();
520 }
521 }
522 cseList.add(dashedLine);
523 break;
524
525 case DOUBLE:
526 Stripe doubleLine = new Stripe(csl, cseTag.offset, cseTag.width);
527 if (simulator != null && simulator instanceof AnimatorInterface)
528 {
529 try
530 {
531 new StripeAnimation(doubleLine, simulator, StripeAnimation.TYPE.DOUBLE);
532 }
533 catch (RemoteException exception)
534 {
535 exception.printStackTrace();
536 }
537 }
538 cseList.add(doubleLine);
539 break;
540
541 case LEFTONLY:
542 Stripe leftOnlyLine = new Stripe(csl, cseTag.offset, cseTag.width);
543 leftOnlyLine.addPermeability(GTUType.ALL, Permeable.LEFT);
544 if (simulator != null && simulator instanceof AnimatorInterface)
545 {
546 try
547 {
548 new StripeAnimation(leftOnlyLine, simulator, StripeAnimation.TYPE.LEFTONLY);
549 }
550 catch (RemoteException exception)
551 {
552 exception.printStackTrace();
553 }
554 }
555 cseList.add(leftOnlyLine);
556 break;
557
558 case RIGHTONLY:
559 Stripe rightOnlyLine = new Stripe(csl, cseTag.offset, cseTag.width);
560 rightOnlyLine.addPermeability(GTUType.ALL, Permeable.RIGHT);
561 if (simulator != null && simulator instanceof AnimatorInterface)
562 {
563 try
564 {
565 new StripeAnimation(rightOnlyLine, simulator, StripeAnimation.TYPE.RIGHTONLY);
566 }
567 catch (RemoteException exception)
568 {
569 exception.printStackTrace();
570 }
571 }
572 cseList.add(rightOnlyLine);
573 break;
574
575 case SOLID:
576 Stripe solidLine = new Stripe(csl, cseTag.offset, cseTag.width);
577 if (simulator != null && simulator instanceof AnimatorInterface)
578 {
579 try
580 {
581 new StripeAnimation(solidLine, simulator, StripeAnimation.TYPE.SOLID);
582 }
583 catch (RemoteException exception)
584 {
585 exception.printStackTrace();
586 }
587 }
588 cseList.add(solidLine);
589 break;
590
591 default:
592 throw new SAXException("Unknown Stripe type: " + cseTag.stripeType.toString());
593 }
594 break;
595
596 case LANE:
597 {
598 LongitudinalDirectionality direction = cseTag.direction;
599 Color color = cseTag.color;
600 OvertakingConditions overtakingConditions = cseTag.overtakingConditions;
601 if (laneOverrideTag != null)
602 {
603 if (laneOverrideTag.overtakingConditions != null)
604 overtakingConditions = laneOverrideTag.overtakingConditions;
605 if (laneOverrideTag.color != null)
606 color = laneOverrideTag.color;
607 if (laneOverrideTag.direction != null)
608 direction = laneOverrideTag.direction;
609 }
610 Map<GTUType, LongitudinalDirectionality> directionality = new LinkedHashMap<>();
611 directionality.put(GTUType.ALL, direction);
612 if (linkDirection.equals(LongitudinalDirectionality.DIR_NONE))
613 {
614 linkDirection = direction;
615 }
616 else if (linkDirection.isForward())
617 {
618 if (direction.isBackwardOrBoth())
619 {
620 linkDirection = LongitudinalDirectionality.DIR_BOTH;
621 }
622 }
623 else if (linkDirection.isBackward())
624 {
625 if (direction.isForwardOrBoth())
626 {
627 linkDirection = LongitudinalDirectionality.DIR_BOTH;
628 }
629 }
630
631
632 csl.addDirectionality(GTUType.ALL, linkDirection);
633
634
635 Lane lane = new Lane(csl, cseTag.name, cseTag.offset, cseTag.offset, cseTag.width, cseTag.width,
636 LaneType.ALL, directionality, cseTag.legalSpeedLimits, overtakingConditions);
637
638
639
640
641
642
643 cseList.add(lane);
644 lanes.add(lane);
645 linkTag.lanes.put(cseTag.name, lane);
646 if (simulator != null && simulator instanceof AnimatorInterface)
647 {
648 try
649 {
650 new LaneAnimation(lane, simulator, color, false);
651 }
652 catch (RemoteException exception)
653 {
654 exception.printStackTrace();
655 }
656 }
657
658
659 if (linkTag.sinkTags.keySet().contains(cseTag.name))
660 {
661 SinkTag sinkTag = linkTag.sinkTags.get(cseTag.name);
662 Length position = LinkTag.parseBeginEndPosition(sinkTag.positionStr, lane);
663 new SinkSensor(lane, position, simulator);
664 }
665
666
667 if (linkTag.blockTags.containsKey(cseTag.name))
668 {
669 BlockTag blockTag = linkTag.blockTags.get(cseTag.name);
670 Length position = LinkTag.parseBeginEndPosition(blockTag.positionStr, lane);
671 new LaneBlock(UUID.randomUUID().toString(), lane, position, Length.ZERO);
672 }
673
674
675 if (linkTag.trafficLightTags.containsKey(cseTag.name))
676 {
677 for (TrafficLightTag trafficLightTag : linkTag.trafficLightTags.get(cseTag.name))
678 {
679 try
680 {
681 Class<?> clazz = Class.forName(trafficLightTag.className);
682 Constructor<?> trafficLightConstructor = ClassUtil.resolveConstructor(clazz, new Class[] {
683 String.class, Lane.class, Length.class, OTSDEVSSimulatorInterface.class });
684 Length position = LinkTag.parseBeginEndPosition(trafficLightTag.positionStr, lane);
685 SimpleTrafficLight trafficLight = (SimpleTrafficLight) trafficLightConstructor
686 .newInstance(new Object[] { trafficLightTag.name, lane, position, simulator });
687 }
688 catch (ClassNotFoundException | NoSuchMethodException | InstantiationException
689 | IllegalAccessException | IllegalArgumentException | InvocationTargetException
690 | NetworkException exception)
691 {
692 throw new NetworkException("TRAFFICLIGHT: CLASS NAME " + trafficLightTag.className
693 + " for traffic light " + trafficLightTag.name + " on lane " + lane.toString()
694 + " -- class not found or constructor not right", exception);
695 }
696 }
697 }
698
699
700 if (linkTag.generatorTags.containsKey(cseTag.name))
701 {
702 GeneratorTag generatorTag = linkTag.generatorTags.get(cseTag.name);
703 GeneratorTag.makeGenerator(generatorTag, parser, linkTag, simulator);
704 }
705
706
707
708
709 if (linkTag.sensorTags.containsKey(cseTag.name))
710 {
711 for (SensorTag sensorTag : linkTag.sensorTags.get(cseTag.name))
712 {
713 try
714 {
715 Class<?> clazz = Class.forName(sensorTag.className);
716 Constructor<?> sensorConstructor =
717 ClassUtil.resolveConstructor(clazz, new Class[] { String.class, Lane.class,
718 Length.class, RelativePosition.TYPE.class, OTSDEVSSimulatorInterface.class });
719 Length position = LinkTag.parseBeginEndPosition(sensorTag.positionStr, lane);
720
721
722 sensorConstructor.newInstance(
723 new Object[] { sensorTag.name, lane, position, sensorTag.triggerPosition, simulator });
724 }
725 catch (ClassNotFoundException | NoSuchMethodException | InstantiationException
726 | IllegalAccessException | IllegalArgumentException | InvocationTargetException
727 | NetworkException exception)
728 {
729 throw new NetworkException("SENSOR: CLASS NAME " + sensorTag.className + " for sensor "
730 + sensorTag.name + " on lane " + lane.toString()
731 + " -- class not found or constructor not right", exception);
732 }
733 }
734 }
735
736
737 if (linkTag.fillTags.containsKey(cseTag.name))
738 {
739 FillTag fillTag = linkTag.fillTags.get(cseTag.name);
740 FillTag.makeFill(fillTag, parser, linkTag, simulator);
741 }
742 break;
743 }
744
745 case NOTRAFFICLANE:
746 {
747 Lane lane = new NoTrafficLane(csl, cseTag.name, cseTag.offset, cseTag.offset, cseTag.width, cseTag.width);
748 cseList.add(lane);
749 if (simulator != null && simulator instanceof AnimatorInterface)
750 {
751 try
752 {
753 Color color = cseTag.color;
754 if (laneOverrideTag != null)
755 {
756 if (laneOverrideTag.color != null)
757 color = laneOverrideTag.color;
758 }
759 new LaneAnimation(lane, simulator, color, false);
760 }
761 catch (RemoteException exception)
762 {
763 exception.printStackTrace();
764 }
765 }
766 break;
767 }
768
769 case SHOULDER:
770 {
771 Shoulder shoulder = new Shoulder(csl, cseTag.name, cseTag.offset, cseTag.width);
772 cseList.add(shoulder);
773 if (simulator != null && simulator instanceof AnimatorInterface)
774 {
775 try
776 {
777 Color color = cseTag.color;
778 if (laneOverrideTag != null)
779 {
780 if (laneOverrideTag.color != null)
781 color = laneOverrideTag.color;
782 }
783 new ShoulderAnimation(shoulder, simulator, color);
784 }
785 catch (RemoteException exception)
786 {
787 exception.printStackTrace();
788 }
789 }
790 break;
791 }
792
793 default:
794 throw new SAXException("Unknown Element type: " + cseTag.elementType.toString());
795 }
796
797 }
798
799
800 csl.addDirectionality(GTUType.ALL, linkDirection);
801 }
802 }