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