1 package org.opentrafficsim.road.network.factory.vissim;
2
3 import java.awt.Color;
4 import java.rmi.RemoteException;
5 import java.util.ArrayList;
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Set;
9
10 import javax.naming.NamingException;
11
12 import org.djunits.unit.AngleUnit;
13 import org.djunits.unit.DirectionUnit;
14 import org.djunits.unit.LengthUnit;
15 import org.djunits.unit.SpeedUnit;
16 import org.djunits.value.AngleUtil;
17 import org.djunits.value.vdouble.scalar.Angle;
18 import org.djunits.value.vdouble.scalar.Direction;
19 import org.djunits.value.vdouble.scalar.Length;
20 import org.djunits.value.vdouble.scalar.Speed;
21 import org.opentrafficsim.core.compatibility.Compatible;
22 import org.opentrafficsim.core.geometry.Bezier;
23 import org.opentrafficsim.core.geometry.OTSGeometryException;
24 import org.opentrafficsim.core.geometry.OTSLine3D;
25 import org.opentrafficsim.core.geometry.OTSPoint3D;
26 import org.opentrafficsim.core.gtu.GTUException;
27 import org.opentrafficsim.core.gtu.RelativePosition;
28 import org.opentrafficsim.core.network.LateralDirectionality;
29 import org.opentrafficsim.core.network.LinkType;
30 import org.opentrafficsim.core.network.LongitudinalDirectionality;
31 import org.opentrafficsim.core.network.NetworkException;
32 import org.opentrafficsim.road.network.animation.LaneAnimation;
33 import org.opentrafficsim.road.network.factory.vissim.ArcTag.ArcDirection;
34 import org.opentrafficsim.road.network.lane.CrossSectionElement;
35 import org.opentrafficsim.road.network.lane.CrossSectionLink;
36 import org.opentrafficsim.road.network.lane.Lane;
37 import org.opentrafficsim.road.network.lane.LaneType;
38 import org.opentrafficsim.road.network.lane.object.sensor.SimpleReportingSensor;
39 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
40 import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
41 import org.xml.sax.SAXException;
42
43 import nl.tudelft.simulation.dsol.SimRuntimeException;
44 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
45 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
46 import nl.tudelft.simulation.language.d3.CartesianPoint;
47 import nl.tudelft.simulation.language.d3.DirectedPoint;
48
49
50
51
52
53
54
55
56
57
58 final class Links
59 {
60
61 private Links()
62 {
63
64 }
65
66
67
68
69
70
71
72 @SuppressWarnings("methodlength")
73 static void calculateNodeCoordinates(final VissimNetworkLaneParser parser) throws NetworkException, NamingException
74 {
75
76 for (LinkTag linkTag : parser.getLinkTags().values())
77 {
78 if (linkTag.straightTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
79 {
80 if (linkTag.nodeStartTag.angle == null)
81 {
82 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
83 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
84 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
85 }
86 if (linkTag.nodeEndTag.angle == null)
87 {
88 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
89 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
90 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
91 }
92 }
93 }
94
95
96 Set<NodeTag> nodeTags = new HashSet<>();
97 for (LinkTag linkTag : parser.getLinkTags().values())
98 {
99
100 if (linkTag.nodeStartTag.coordinate == null)
101 {
102 nodeTags.add(linkTag.nodeStartTag);
103 }
104 if (linkTag.nodeEndTag.coordinate == null)
105 {
106 nodeTags.add(linkTag.nodeEndTag);
107 }
108 }
109
110 while (nodeTags.size() > 0)
111 {
112 boolean found = false;
113 for (LinkTag linkTag : parser.getLinkTags().values())
114 {
115 if (linkTag.straightTag != null || linkTag.polyLineTag != null || linkTag.arcTag != null)
116 {
117 if (nodeTags.contains(linkTag.nodeStartTag) == nodeTags.contains(linkTag.nodeEndTag))
118 {
119 continue;
120 }
121
122 if (linkTag.straightTag != null)
123 {
124 double lengthSI = linkTag.straightTag.length.getSI();
125 if (linkTag.nodeEndTag.node == null)
126 {
127 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeStartTag.node.getLocation().getX(),
128 linkTag.nodeStartTag.node.getLocation().getY(),
129 linkTag.nodeStartTag.node.getLocation().getZ());
130 double angle = linkTag.nodeStartTag.node.getDirection().getInUnit();
131 double slope = linkTag.nodeStartTag.node.getSlope().getSI();
132 coordinate.x += lengthSI * Math.cos(angle);
133 coordinate.y += lengthSI * Math.sin(angle);
134 coordinate.z += lengthSI * Math.sin(slope);
135 NodeTag nodeTag = linkTag.nodeEndTag;
136 nodeTag.angle = new Direction(angle, DirectionUnit.EAST_RADIAN);
137 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
138 nodeTag.slope = new Angle(slope, AngleUnit.SI);
139 linkTag.nodeEndTag.node = NodeTag.makeOTSNode(nodeTag, parser);
140 nodeTags.remove(linkTag.nodeEndTag);
141 }
142 else if (linkTag.nodeStartTag.node == null)
143 {
144 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeEndTag.node.getLocation().getX(),
145 linkTag.nodeEndTag.node.getLocation().getY(), linkTag.nodeEndTag.node.getLocation().getZ());
146 double angle = linkTag.nodeEndTag.node.getDirection().getInUnit();
147 double slope = linkTag.nodeEndTag.node.getSlope().getSI();
148 coordinate.x -= lengthSI * Math.cos(angle);
149 coordinate.y -= lengthSI * Math.sin(angle);
150 coordinate.z -= lengthSI * Math.sin(slope);
151 NodeTag nodeTag = linkTag.nodeStartTag;
152 nodeTag.angle = new Direction(angle, DirectionUnit.EAST_RADIAN);
153 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
154 nodeTag.slope = new Angle(slope, AngleUnit.SI);
155 linkTag.nodeStartTag.node = NodeTag.makeOTSNode(nodeTag, parser);
156 nodeTags.remove(linkTag.nodeStartTag);
157 }
158 }
159 else if (linkTag.polyLineTag != null)
160 {
161 double lengthSI = linkTag.polyLineTag.length.getSI();
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 }
194 else if (linkTag.arcTag != null)
195 {
196 double radiusSI = linkTag.arcTag.radius.getSI();
197 double angle = linkTag.arcTag.angle.getInUnit();
198 ArcDirection direction = linkTag.arcTag.direction;
199
200 if (linkTag.nodeEndTag.node == null)
201 {
202 CartesianPoint coordinate = new CartesianPoint(0.0, 0.0, 0.0);
203 double startAngle = linkTag.nodeStartTag.node.getDirection().getInUnit();
204 double slope = linkTag.nodeStartTag.node.getSlope().getSI();
205 double lengthSI = radiusSI * angle;
206 NodeTag nodeTag = linkTag.nodeEndTag;
207 if (direction.equals(ArcDirection.LEFT))
208 {
209 linkTag.arcTag.center = new OTSPoint3D(
210 linkTag.nodeStartTag.node.getLocation().getX()
211 + radiusSI * Math.cos(startAngle + Math.PI / 2.0),
212 linkTag.nodeStartTag.node.getLocation().getY()
213 + radiusSI * Math.sin(startAngle + Math.PI / 2.0),
214 0.0);
215 linkTag.arcTag.startAngle = startAngle - Math.PI / 2.0;
216 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle + angle);
217 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle + angle);
218 nodeTag.angle =
219 new Direction(AngleUtil.normalize(startAngle + angle), DirectionUnit.EAST_RADIAN);
220 }
221 else
222 {
223 linkTag.arcTag.center = new OTSPoint3D(
224 linkTag.nodeStartTag.node.getLocation().getX()
225 - radiusSI * Math.cos(startAngle + Math.PI / 2.0),
226 linkTag.nodeStartTag.node.getLocation().getY()
227 - radiusSI * Math.sin(startAngle + Math.PI / 2.0),
228 0.0);
229 linkTag.arcTag.startAngle = startAngle + Math.PI / 2.0;
230 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle - angle);
231 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle - angle);
232 nodeTag.angle =
233 new Direction(AngleUtil.normalize(startAngle - angle), DirectionUnit.EAST_RADIAN);
234 }
235 coordinate.z = linkTag.nodeStartTag.node.getLocation().getZ() + lengthSI * Math.sin(slope);
236 nodeTag.slope = new Angle(slope, AngleUnit.SI);
237 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
238 linkTag.nodeEndTag.node = NodeTag.makeOTSNode(nodeTag, parser);
239 nodeTags.remove(linkTag.nodeEndTag);
240 }
241
242 else if (linkTag.nodeStartTag.node == null)
243 {
244 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeEndTag.node.getLocation().getX(),
245 linkTag.nodeEndTag.node.getLocation().getY(), linkTag.nodeEndTag.node.getLocation().getZ());
246 double endAngle = linkTag.nodeEndTag.node.getDirection().getInUnit();
247 double slope = linkTag.nodeEndTag.node.getSlope().getSI();
248 double lengthSI = radiusSI * angle;
249 NodeTag nodeTag = linkTag.nodeStartTag;
250 if (direction.equals(ArcDirection.LEFT))
251 {
252 linkTag.arcTag.center =
253 new OTSPoint3D(coordinate.x + radiusSI * Math.cos(endAngle + Math.PI / 2.0),
254 coordinate.y + radiusSI * Math.sin(endAngle + Math.PI / 2.0), 0.0);
255 linkTag.arcTag.startAngle = endAngle - Math.PI / 2.0 - angle;
256 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
257 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
258 nodeTag.angle = new Direction(AngleUtil.normalize(linkTag.arcTag.startAngle + Math.PI / 2.0),
259 DirectionUnit.EAST_RADIAN);
260 }
261 else
262 {
263 linkTag.arcTag.center =
264 new OTSPoint3D(coordinate.x + radiusSI * Math.cos(endAngle - Math.PI / 2.0),
265 coordinate.y + radiusSI * Math.sin(endAngle - Math.PI / 2.0), 0.0);
266 linkTag.arcTag.startAngle = endAngle + Math.PI / 2.0 + angle;
267 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
268 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
269 nodeTag.angle = new Direction(AngleUtil.normalize(linkTag.arcTag.startAngle - Math.PI / 2.0),
270 DirectionUnit.EAST_RADIAN);
271 }
272 coordinate.z -= lengthSI * Math.sin(slope);
273 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
274 nodeTag.slope = new Angle(slope, AngleUnit.SI);
275 linkTag.nodeStartTag.node = NodeTag.makeOTSNode(nodeTag, parser);
276 nodeTags.remove(linkTag.nodeStartTag);
277 }
278 }
279 }
280 }
281 if (!found)
282 {
283 throw new NetworkException("Cannot find coordinates of one or more nodes");
284 }
285 }
286
287
288 for (LinkTag linkTag : parser.getLinkTags().values())
289 {
290 if (linkTag.straightTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
291 {
292 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
293 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
294 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
295 dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
296 dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
297 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
298 }
299 }
300
301
302
303 for (LinkTag linkTag : parser.getLinkTags().values())
304 {
305 if (linkTag.polyLineTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
306 {
307 double dx = linkTag.polyLineTag.vertices[0].x - linkTag.nodeStartTag.coordinate.x;
308 double dy = linkTag.polyLineTag.vertices[0].y - linkTag.nodeStartTag.coordinate.y;
309 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
310 int arrayLength = linkTag.polyLineTag.vertices.length;
311 dx = linkTag.nodeEndTag.coordinate.x - linkTag.polyLineTag.vertices[arrayLength - 1].x;
312 dy = linkTag.nodeEndTag.coordinate.y - linkTag.polyLineTag.vertices[arrayLength - 1].y;
313 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
314 }
315 }
316
317
318 for (NodeTag nodeTag : parser.getNodeTags().values())
319 {
320 if (nodeTag.coordinate != null && nodeTag.node == null)
321 {
322 if (nodeTag.angle == null)
323 {
324 nodeTag.angle = Direction.ZERO;
325 }
326 if (nodeTag.slope == null)
327 {
328 nodeTag.slope = Angle.ZERO;
329 }
330 nodeTag.node = NodeTag.makeOTSNode(nodeTag, parser);
331 }
332 }
333
334 }
335
336
337
338
339
340
341
342
343
344
345 static void buildLink(final LinkTag linkTag, final VissimNetworkLaneParser parser,
346 final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws OTSGeometryException, NamingException, NetworkException
347 {
348 NodeTag from = linkTag.nodeStartTag;
349 OTSPoint3D startPoint = new OTSPoint3D(from.coordinate);
350 double startAngle = 0.0;
351 if (from.angle != null)
352 {
353 startAngle = from.angle.getInUnit();
354 }
355 if (linkTag.offsetStart != null && linkTag.offsetStart.si != 0.0)
356 {
357
358 double offset = linkTag.offsetStart.si;
359 startPoint = new OTSPoint3D(startPoint.x + offset * Math.cos(startAngle + Math.PI / 2.0),
360 startPoint.y + offset * Math.sin(startAngle + Math.PI / 2.0), startPoint.z);
361 System.out
362 .println("fc = " + from.coordinate + ", sa = " + startAngle + ", so = " + offset + ", sp = " + startPoint);
363 }
364
365 NodeTag to = linkTag.nodeEndTag;
366 OTSPoint3D endPoint = new OTSPoint3D(to.coordinate);
367 double endAngle = to.angle.getInUnit();
368 if (linkTag.offsetEnd != null && linkTag.offsetEnd.si != 0.0)
369 {
370
371 double offset = linkTag.offsetEnd.si;
372 endPoint = new OTSPoint3D(endPoint.x + offset * Math.cos(endAngle + Math.PI / 2.0),
373 endPoint.y + offset * Math.sin(endAngle + Math.PI / 2.0), endPoint.z);
374 System.out.println("tc = " + to.coordinate + ", ea = " + endAngle + ", eo = " + offset + ", ep = " + endPoint);
375 }
376
377 OTSPoint3D[] coordinates = null;
378
379 if (linkTag.straightTag != null)
380 {
381 coordinates = new OTSPoint3D[2];
382 coordinates[0] = startPoint;
383 coordinates[1] = endPoint;
384 }
385
386 else if (linkTag.polyLineTag != null)
387 {
388 int intermediatePoints = linkTag.polyLineTag.vertices.length;
389 coordinates = new OTSPoint3D[intermediatePoints + 2];
390 coordinates[0] = startPoint;
391 coordinates[intermediatePoints + 1] = endPoint;
392 for (int p = 0; p < intermediatePoints; p++)
393 {
394 coordinates[p + 1] = linkTag.polyLineTag.vertices[p];
395 }
396
397 }
398 else if (linkTag.arcTag != null)
399 {
400
401 int points = (Math.abs(linkTag.arcTag.angle.getInUnit()) <= Math.PI / 2.0) ? 64 : 128;
402 coordinates = new OTSPoint3D[points];
403 coordinates[0] = new OTSPoint3D(from.coordinate.x, from.coordinate.y, from.coordinate.z);
404 coordinates[coordinates.length - 1] = new OTSPoint3D(to.coordinate.x, to.coordinate.y, to.coordinate.z);
405 double angleStep = linkTag.arcTag.angle.getInUnit() / points;
406 double slopeStep = (to.coordinate.z - from.coordinate.z) / points;
407 double radiusSI = linkTag.arcTag.radius.getSI();
408 if (linkTag.arcTag.direction.equals(ArcDirection.RIGHT))
409 {
410 for (int p = 1; p < points - 1; p++)
411 {
412 coordinates[p] = new OTSPoint3D(
413 linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle - angleStep * p),
414 linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle - angleStep * p),
415 from.coordinate.z + slopeStep * p);
416 }
417 }
418 else
419 {
420 for (int p = 1; p < points - 1; p++)
421 {
422 try
423 {
424 System.err.println("linkTag.arcTag.center = " + linkTag.arcTag.center);
425 System.err.println("linkTag.arcTag.startAngle = " + linkTag.arcTag.startAngle);
426 coordinates[p] = new OTSPoint3D(
427 linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle + angleStep * p),
428 linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle + angleStep * p),
429 from.coordinate.z + slopeStep * p);
430 }
431 catch (NullPointerException npe)
432 {
433 npe.printStackTrace();
434 System.err.println(npe.getMessage());
435 }
436 }
437 }
438 }
439
440 else if (linkTag.bezierTag != null)
441 {
442 if (new DirectedPoint(startPoint.x, startPoint.y, startPoint.z, 0, 0, startAngle)
443 .equals(new DirectedPoint(endPoint.x, endPoint.y, endPoint.z, 0, 0, endAngle)))
444 {
445 System.out.println(" ");
446 }
447
448 coordinates = Bezier.cubic(128, new DirectedPoint(startPoint.x, startPoint.y, startPoint.z, 0, 0, startAngle),
449 new DirectedPoint(endPoint.x, endPoint.y, endPoint.z, 0, 0, endAngle)).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 if (coordinates.length < 2)
458 {
459 throw new OTSGeometryException(
460 "Degenerate OTSLine3D; has " + coordinates.length + " point" + (coordinates.length != 1 ? "s" : ""));
461 }
462 OTSLine3D designLine = OTSLine3D.createAndCleanOTSLine3D(coordinates);
463
464
465 CrossSectionLink link = new CrossSectionLink(parser.getNetwork(), linkTag.name, linkTag.nodeStartTag.node,
466 linkTag.nodeEndTag.node, LinkType.ROAD, designLine, simulator, linkTag.laneKeepingPolicy);
467 linkTag.link = link;
468 }
469
470
471
472
473
474
475
476
477
478
479
480
481 @SuppressWarnings({ "checkstyle:needbraces", "checkstyle:methodlength" })
482 static void applyRoadTypeToLink(final LinkTag linkTag, final VissimNetworkLaneParser parser,
483 final DEVSSimulatorInterface.TimeDoubleUnit simulator)
484 throws NetworkException, NamingException, SAXException, GTUException, OTSGeometryException, SimRuntimeException
485 {
486 CrossSectionLink csl = linkTag.link;
487
488 List<CrossSectionElement> cseList = new ArrayList<>();
489 List<Lane> lanes = new ArrayList<>();
490
491 LongitudinalDirectionality linkDirection = LongitudinalDirectionality.DIR_NONE;
492
493
494
495
496 Double roadWidth = 0.0;
497 for (LaneTag laneTag : linkTag.laneTags.values())
498 {
499 roadWidth += Double.parseDouble(laneTag.width);
500 }
501
502 Color color;
503 if (linkTag.connector)
504 {
505 color = Color.LIGHT_GRAY;
506 }
507 else
508 {
509 color = Color.DARK_GRAY;
510
511 }
512
513
514 Double totalLaneWidth = 0.0;
515
516 if (!linkTag.connector)
517 {
518 for (LaneTag laneTag : linkTag.laneTags.values())
519 {
520 String name = laneTag.laneNo;
521 Double laneWidth = Double.parseDouble(laneTag.width);
522 Length thisLaneWidth = new Length(laneWidth, LengthUnit.METER);
523
524
525
526
527 Double negativeOffset = -(0.5 * roadWidth - totalLaneWidth - laneWidth / 2);
528 Length lateralOffset = new Length(negativeOffset, LengthUnit.METER);
529
530 LaneType laneType = LaneType.FREEWAY;
531 Speed speedLimit = new Speed(Double.parseDouble(linkTag.legalSpeed), SpeedUnit.KM_PER_HOUR);
532
533 Lane lane = new Lane(csl, name, lateralOffset, thisLaneWidth, laneType, speedLimit, null);
534 if (!linkTag.sensors.isEmpty())
535 {
536 for (SensorTag sensorTag : linkTag.sensors)
537 {
538 if (sensorTag.laneName.equals(laneTag.laneNo))
539 {
540 Length pos = new Length(Double.parseDouble(sensorTag.positionStr), LengthUnit.METER);
541 if (pos.lt(lane.getLength()))
542 {
543 new SimpleReportingSensor(sensorTag.name, lane, pos, RelativePosition.FRONT, simulator,
544 Compatible.EVERYTHING);
545 }
546 }
547 }
548 }
549
550 if (!linkTag.signalHeads.isEmpty())
551 {
552 for (SignalHeadTag signalHeadTag : linkTag.signalHeads)
553 {
554 if (signalHeadTag.laneName.equals(laneTag.laneNo))
555 {
556 Length pos = new Length(Double.parseDouble(signalHeadTag.positionStr), LengthUnit.METER);
557 if (pos.lt(lane.getLength()))
558 {
559 new SimpleTrafficLight(signalHeadTag.no, lane, pos, simulator);
560 }
561 }
562 }
563 }
564
565 cseList.add(lane);
566
567 lanes.add(lane);
568 linkTag.lanes.put(name, lane);
569
570 totalLaneWidth += Double.parseDouble(laneTag.width);
571 if (simulator != null && simulator instanceof AnimatorInterface)
572 {
573 try
574 {
575 new LaneAnimation(lane, simulator, color, true);
576 }
577 catch (RemoteException exception)
578 {
579 exception.printStackTrace();
580 }
581 }
582
583 }
584 }
585
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599 @SuppressWarnings({ "checkstyle:needbraces", "checkstyle:methodlength" })
600 static void applyRoadTypeToConnector(final LinkTag linkTag, final VissimNetworkLaneParser parser,
601 final DEVSSimulatorInterface.TimeDoubleUnit simulator)
602 throws NetworkException, NamingException, SAXException, GTUException, OTSGeometryException, SimRuntimeException
603 {
604 CrossSectionLink csl = linkTag.link;
605
606 List<CrossSectionElement> cseList = new ArrayList<>();
607 List<Lane> lanes = new ArrayList<>();
608
609
610
611
612 Double roadWidth = 0.0;
613 for (LaneTag laneTag : linkTag.laneTags.values())
614 {
615 roadWidth += Double.parseDouble(laneTag.width);
616 }
617
618 Color color;
619 if (linkTag.connector)
620 {
621 color = Color.LIGHT_GRAY;
622 }
623 else
624 {
625 color = Color.DARK_GRAY;
626
627 }
628
629
630 LaneType laneType = LaneType.FREEWAY;
631 Speed speedLimit = new Speed(Double.parseDouble(linkTag.legalSpeed), SpeedUnit.KM_PER_HOUR);
632
633
634
635 if (linkTag.connector)
636 {
637 Double totalFromLaneWidth = -1.75;
638 Double totalToLaneWidth = -1.75;
639
640 LinkTag linkToTag = parser.getRealLinkTags().get(linkTag.connectorTag.toLinkNo);
641 Lane laneTo = linkToTag.lanes.get(linkTag.connectorTag.toLaneNo);
642
643
644 LinkTag linkFromTag = parser.getRealLinkTags().get(linkTag.connectorTag.fromLinkNo);
645 Lane laneFrom = linkFromTag.lanes.get(linkTag.connectorTag.fromLaneNo);
646
647
648 for (LaneTag connectLaneTag : linkTag.laneTags.values())
649 {
650
651 String name = connectLaneTag.laneNo;
652
653 Length thisLaneWidth = new Length(Double.parseDouble(connectLaneTag.width), LengthUnit.METER);
654
655 Length totfromLaneWidth = new Length(totalFromLaneWidth, LengthUnit.METER);
656 Length totToLaneWidth = new Length(totalToLaneWidth, LengthUnit.METER);
657
658 Length lateralOffsetStart;
659 Length lateralOffsetEnd =
660 laneTo.getLateralBoundaryPosition(LateralDirectionality.RIGHT, 0).plus(totToLaneWidth);
661
662 if (laneFrom != null)
663 {
664 lateralOffsetStart =
665 laneFrom.getLateralBoundaryPosition(LateralDirectionality.RIGHT, 0).plus(totfromLaneWidth);
666 }
667 else
668 {
669 lateralOffsetStart = lateralOffsetEnd;
670 }
671
672
673
674 Lane lane = new Lane(csl, name, lateralOffsetStart, lateralOffsetEnd, thisLaneWidth, thisLaneWidth, laneType,
675 speedLimit, null);
676 cseList.add(lane);
677 lanes.add(lane);
678 linkTag.lanes.put(name, lane);
679
680
681 totalFromLaneWidth += Double.parseDouble(connectLaneTag.width);
682 totalToLaneWidth += Double.parseDouble(connectLaneTag.width);
683 if (simulator != null && simulator instanceof AnimatorInterface)
684 {
685 try
686 {
687 new LaneAnimation(lane, simulator, color, true);
688 }
689 catch (RemoteException exception)
690 {
691 exception.printStackTrace();
692 }
693 }
694
695 }
696 }
697
698 }
699
700
701
702
703
704
705
706 public static void createSinkSensor(LinkTag realLinkTag, VissimNetworkLaneParser vissimNetworkLaneParser,
707 DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NetworkException
708 {
709 if (!realLinkTag.connector)
710 {
711 boolean deadLink = true;
712 for (LinkTag linkTag : vissimNetworkLaneParser.getLinkTags().values())
713 {
714 if (realLinkTag.nodeEndTag.name.equals(linkTag.nodeStartTag.name) && !realLinkTag.equals(linkTag))
715 {
716 deadLink = false;
717 }
718 }
719
720 if (deadLink)
721 {
722 for (Lane lane : realLinkTag.lanes.values())
723 {
724 Double smallest = Math.min(10, lane.getLength().getInUnit(LengthUnit.METER) - 1);
725 Length beforeEnd = new Length(smallest, LengthUnit.METER);
726 Length pos = lane.getLength().minus(beforeEnd);
727 SinkSensor sensor = new SinkSensor(lane, pos, simulator);
728 lane.getSensors().add(sensor);
729 }
730 }
731 }
732
733 }
734
735 }