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