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