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