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.DirectionUnit;
15 import org.djunits.unit.LengthUnit;
16 import org.djunits.unit.SpeedUnit;
17 import org.djunits.value.AngleUtil;
18 import org.djunits.value.vdouble.scalar.Angle;
19 import org.djunits.value.vdouble.scalar.Direction;
20 import org.djunits.value.vdouble.scalar.Length;
21 import org.djunits.value.vdouble.scalar.Speed;
22 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
23 import org.opentrafficsim.core.geometry.Bezier;
24 import org.opentrafficsim.core.geometry.OTSGeometryException;
25 import org.opentrafficsim.core.geometry.OTSLine3D;
26 import org.opentrafficsim.core.geometry.OTSPoint3D;
27 import org.opentrafficsim.core.gtu.GTUException;
28 import org.opentrafficsim.core.gtu.GTUType;
29 import org.opentrafficsim.core.gtu.RelativePosition;
30 import org.opentrafficsim.core.network.LateralDirectionality;
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.road.network.animation.LaneAnimation;
35 import org.opentrafficsim.road.network.factory.vissim.ArcTag.ArcDirection;
36 import org.opentrafficsim.road.network.lane.CrossSectionElement;
37 import org.opentrafficsim.road.network.lane.CrossSectionLink;
38 import org.opentrafficsim.road.network.lane.Lane;
39 import org.opentrafficsim.road.network.lane.LaneType;
40 import org.opentrafficsim.road.network.lane.object.sensor.SimpleReportingSensor;
41 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
42 import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
43 import org.xml.sax.SAXException;
44
45 import nl.tudelft.simulation.dsol.SimRuntimeException;
46 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
47 import nl.tudelft.simulation.language.d3.CartesianPoint;
48 import nl.tudelft.simulation.language.d3.DirectedPoint;
49
50
51
52
53
54
55
56
57
58
59 final class Links
60 {
61
62 private Links()
63 {
64
65 }
66
67
68
69
70
71
72
73 @SuppressWarnings("methodlength")
74 static void calculateNodeCoordinates(final VissimNetworkLaneParser parser) throws NetworkException, NamingException
75 {
76
77 for (LinkTag linkTag : parser.getLinkTags().values())
78 {
79 if (linkTag.straightTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
80 {
81 if (linkTag.nodeStartTag.angle == null)
82 {
83 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
84 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
85 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
86 }
87 if (linkTag.nodeEndTag.angle == null)
88 {
89 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
90 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
91 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
92 }
93 }
94 }
95
96
97 Set<NodeTag> nodeTags = new HashSet<>();
98 for (LinkTag linkTag : parser.getLinkTags().values())
99 {
100
101 if (linkTag.nodeStartTag.coordinate == null)
102 {
103 nodeTags.add(linkTag.nodeStartTag);
104 }
105 if (linkTag.nodeEndTag.coordinate == null)
106 {
107 nodeTags.add(linkTag.nodeEndTag);
108 }
109 }
110
111 while (nodeTags.size() > 0)
112 {
113 boolean found = false;
114 for (LinkTag linkTag : parser.getLinkTags().values())
115 {
116 if (linkTag.straightTag != null || linkTag.polyLineTag != null || linkTag.arcTag != null)
117 {
118 if (nodeTags.contains(linkTag.nodeStartTag) == nodeTags.contains(linkTag.nodeEndTag))
119 {
120 continue;
121 }
122
123 if (linkTag.straightTag != null)
124 {
125 double lengthSI = linkTag.straightTag.length.getSI();
126 if (linkTag.nodeEndTag.node == null)
127 {
128 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeStartTag.node.getLocation().getX(),
129 linkTag.nodeStartTag.node.getLocation().getY(),
130 linkTag.nodeStartTag.node.getLocation().getZ());
131 double angle = linkTag.nodeStartTag.node.getDirection().getInUnit();
132 double slope = linkTag.nodeStartTag.node.getSlope().getSI();
133 coordinate.x += lengthSI * Math.cos(angle);
134 coordinate.y += lengthSI * Math.sin(angle);
135 coordinate.z += lengthSI * Math.sin(slope);
136 NodeTag nodeTag = linkTag.nodeEndTag;
137 nodeTag.angle = new Direction(angle, DirectionUnit.EAST_RADIAN);
138 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
139 nodeTag.slope = new Angle(slope, AngleUnit.SI);
140 linkTag.nodeEndTag.node = NodeTag.makeOTSNode(nodeTag, parser);
141 nodeTags.remove(linkTag.nodeEndTag);
142 }
143 else if (linkTag.nodeStartTag.node == null)
144 {
145 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeEndTag.node.getLocation().getX(),
146 linkTag.nodeEndTag.node.getLocation().getY(), linkTag.nodeEndTag.node.getLocation().getZ());
147 double angle = linkTag.nodeEndTag.node.getDirection().getInUnit();
148 double slope = linkTag.nodeEndTag.node.getSlope().getSI();
149 coordinate.x -= lengthSI * Math.cos(angle);
150 coordinate.y -= lengthSI * Math.sin(angle);
151 coordinate.z -= lengthSI * Math.sin(slope);
152 NodeTag nodeTag = linkTag.nodeStartTag;
153 nodeTag.angle = new Direction(angle, DirectionUnit.EAST_RADIAN);
154 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
155 nodeTag.slope = new Angle(slope, AngleUnit.SI);
156 linkTag.nodeStartTag.node = NodeTag.makeOTSNode(nodeTag, parser);
157 nodeTags.remove(linkTag.nodeStartTag);
158 }
159 }
160 else if (linkTag.polyLineTag != null)
161 {
162 double lengthSI = linkTag.polyLineTag.length.getSI();
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 }
195 else if (linkTag.arcTag != null)
196 {
197 double radiusSI = linkTag.arcTag.radius.getSI();
198 double angle = linkTag.arcTag.angle.getInUnit();
199 ArcDirection direction = linkTag.arcTag.direction;
200
201 if (linkTag.nodeEndTag.node == null)
202 {
203 CartesianPoint coordinate = new CartesianPoint(0.0, 0.0, 0.0);
204 double startAngle = linkTag.nodeStartTag.node.getDirection().getInUnit();
205 double slope = linkTag.nodeStartTag.node.getSlope().getSI();
206 double lengthSI = radiusSI * angle;
207 NodeTag nodeTag = linkTag.nodeEndTag;
208 if (direction.equals(ArcDirection.LEFT))
209 {
210 linkTag.arcTag.center = new OTSPoint3D(
211 linkTag.nodeStartTag.node.getLocation().getX()
212 + radiusSI * Math.cos(startAngle + Math.PI / 2.0),
213 linkTag.nodeStartTag.node.getLocation().getY()
214 + radiusSI * Math.sin(startAngle + Math.PI / 2.0),
215 0.0);
216 linkTag.arcTag.startAngle = startAngle - Math.PI / 2.0;
217 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle + angle);
218 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle + angle);
219 nodeTag.angle =
220 new Direction(AngleUtil.normalize(startAngle + angle), DirectionUnit.EAST_RADIAN);
221 }
222 else
223 {
224 linkTag.arcTag.center = new OTSPoint3D(
225 linkTag.nodeStartTag.node.getLocation().getX()
226 - radiusSI * Math.cos(startAngle + Math.PI / 2.0),
227 linkTag.nodeStartTag.node.getLocation().getY()
228 - radiusSI * Math.sin(startAngle + Math.PI / 2.0),
229 0.0);
230 linkTag.arcTag.startAngle = startAngle + Math.PI / 2.0;
231 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle - angle);
232 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle - angle);
233 nodeTag.angle =
234 new Direction(AngleUtil.normalize(startAngle - angle), DirectionUnit.EAST_RADIAN);
235 }
236 coordinate.z = linkTag.nodeStartTag.node.getLocation().getZ() + lengthSI * Math.sin(slope);
237 nodeTag.slope = new Angle(slope, AngleUnit.SI);
238 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
239 linkTag.nodeEndTag.node = NodeTag.makeOTSNode(nodeTag, parser);
240 nodeTags.remove(linkTag.nodeEndTag);
241 }
242
243 else if (linkTag.nodeStartTag.node == null)
244 {
245 CartesianPoint coordinate = new CartesianPoint(linkTag.nodeEndTag.node.getLocation().getX(),
246 linkTag.nodeEndTag.node.getLocation().getY(), linkTag.nodeEndTag.node.getLocation().getZ());
247 double endAngle = linkTag.nodeEndTag.node.getDirection().getInUnit();
248 double slope = linkTag.nodeEndTag.node.getSlope().getSI();
249 double lengthSI = radiusSI * angle;
250 NodeTag nodeTag = linkTag.nodeStartTag;
251 if (direction.equals(ArcDirection.LEFT))
252 {
253 linkTag.arcTag.center =
254 new OTSPoint3D(coordinate.x + radiusSI * Math.cos(endAngle + Math.PI / 2.0),
255 coordinate.y + radiusSI * Math.sin(endAngle + Math.PI / 2.0), 0.0);
256 linkTag.arcTag.startAngle = endAngle - Math.PI / 2.0 - angle;
257 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
258 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
259 nodeTag.angle = new Direction(AngleUtil.normalize(linkTag.arcTag.startAngle + Math.PI / 2.0),
260 DirectionUnit.EAST_RADIAN);
261 }
262 else
263 {
264 linkTag.arcTag.center =
265 new OTSPoint3D(coordinate.x + radiusSI * Math.cos(endAngle - Math.PI / 2.0),
266 coordinate.y + radiusSI * Math.sin(endAngle - Math.PI / 2.0), 0.0);
267 linkTag.arcTag.startAngle = endAngle + Math.PI / 2.0 + angle;
268 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
269 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
270 nodeTag.angle = new Direction(AngleUtil.normalize(linkTag.arcTag.startAngle - Math.PI / 2.0),
271 DirectionUnit.EAST_RADIAN);
272 }
273 coordinate.z -= lengthSI * Math.sin(slope);
274 nodeTag.coordinate = new OTSPoint3D(coordinate.x, coordinate.y, coordinate.z);
275 nodeTag.slope = new Angle(slope, AngleUnit.SI);
276 linkTag.nodeStartTag.node = NodeTag.makeOTSNode(nodeTag, parser);
277 nodeTags.remove(linkTag.nodeStartTag);
278 }
279 }
280 }
281 }
282 if (!found)
283 {
284 throw new NetworkException("Cannot find coordinates of one or more nodes");
285 }
286 }
287
288
289 for (LinkTag linkTag : parser.getLinkTags().values())
290 {
291 if (linkTag.straightTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
292 {
293 double dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
294 double dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
295 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
296 dx = linkTag.nodeEndTag.coordinate.x - linkTag.nodeStartTag.coordinate.x;
297 dy = linkTag.nodeEndTag.coordinate.y - linkTag.nodeStartTag.coordinate.y;
298 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
299 }
300 }
301
302
303
304 for (LinkTag linkTag : parser.getLinkTags().values())
305 {
306 if (linkTag.polyLineTag != null && linkTag.nodeStartTag.coordinate != null && linkTag.nodeEndTag.coordinate != null)
307 {
308 double dx = linkTag.polyLineTag.vertices[0].x - linkTag.nodeStartTag.coordinate.x;
309 double dy = linkTag.polyLineTag.vertices[0].y - linkTag.nodeStartTag.coordinate.y;
310 linkTag.nodeStartTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
311 int arrayLength = linkTag.polyLineTag.vertices.length;
312 dx = linkTag.nodeEndTag.coordinate.x - linkTag.polyLineTag.vertices[arrayLength - 1].x;
313 dy = linkTag.nodeEndTag.coordinate.y - linkTag.polyLineTag.vertices[arrayLength - 1].y;
314 linkTag.nodeEndTag.angle = new Direction(Math.atan2(dy, dx), DirectionUnit.EAST_RADIAN);
315 }
316 }
317
318
319 for (NodeTag nodeTag : parser.getNodeTags().values())
320 {
321 if (nodeTag.coordinate != null && nodeTag.node == null)
322 {
323 if (nodeTag.angle == null)
324 {
325 nodeTag.angle = Direction.ZERO;
326 }
327 if (nodeTag.slope == null)
328 {
329 nodeTag.slope = Angle.ZERO;
330 }
331 nodeTag.node = NodeTag.makeOTSNode(nodeTag, parser);
332 }
333 }
334
335 }
336
337
338
339
340
341
342
343
344
345
346 static void buildLink(final LinkTag linkTag, final VissimNetworkLaneParser parser,
347 final OTSDEVSSimulatorInterface simulator) throws OTSGeometryException, NamingException, NetworkException
348 {
349 NodeTag from = linkTag.nodeStartTag;
350 OTSPoint3D startPoint = new OTSPoint3D(from.coordinate);
351 double startAngle = 0.0;
352 if (from.angle != null)
353 {
354 startAngle = from.angle.getInUnit();
355 }
356 if (linkTag.offsetStart != null && linkTag.offsetStart.si != 0.0)
357 {
358
359 double offset = linkTag.offsetStart.si;
360 startPoint = new OTSPoint3D(startPoint.x + offset * Math.cos(startAngle + Math.PI / 2.0),
361 startPoint.y + offset * Math.sin(startAngle + Math.PI / 2.0), startPoint.z);
362 System.out
363 .println("fc = " + from.coordinate + ", sa = " + startAngle + ", so = " + offset + ", sp = " + startPoint);
364 }
365
366 NodeTag to = linkTag.nodeEndTag;
367 OTSPoint3D endPoint = new OTSPoint3D(to.coordinate);
368 double endAngle = to.angle.getInUnit();
369 if (linkTag.offsetEnd != null && linkTag.offsetEnd.si != 0.0)
370 {
371
372 double offset = linkTag.offsetEnd.si;
373 endPoint = new OTSPoint3D(endPoint.x + offset * Math.cos(endAngle + Math.PI / 2.0),
374 endPoint.y + offset * Math.sin(endAngle + Math.PI / 2.0), endPoint.z);
375 System.out.println("tc = " + to.coordinate + ", ea = " + endAngle + ", eo = " + offset + ", ep = " + endPoint);
376 }
377
378 OTSPoint3D[] coordinates = null;
379
380 if (linkTag.straightTag != null)
381 {
382 coordinates = new OTSPoint3D[2];
383 coordinates[0] = startPoint;
384 coordinates[1] = endPoint;
385 }
386
387 else if (linkTag.polyLineTag != null)
388 {
389 int intermediatePoints = linkTag.polyLineTag.vertices.length;
390 coordinates = new OTSPoint3D[intermediatePoints + 2];
391 coordinates[0] = startPoint;
392 coordinates[intermediatePoints + 1] = endPoint;
393 for (int p = 0; p < intermediatePoints; p++)
394 {
395 coordinates[p + 1] = linkTag.polyLineTag.vertices[p];
396 }
397
398 }
399 else if (linkTag.arcTag != null)
400 {
401
402 int points = (Math.abs(linkTag.arcTag.angle.getInUnit()) <= Math.PI / 2.0) ? 64 : 128;
403 coordinates = new OTSPoint3D[points];
404 coordinates[0] = new OTSPoint3D(from.coordinate.x, from.coordinate.y, from.coordinate.z);
405 coordinates[coordinates.length - 1] = new OTSPoint3D(to.coordinate.x, to.coordinate.y, to.coordinate.z);
406 double angleStep = linkTag.arcTag.angle.getInUnit() / points;
407 double slopeStep = (to.coordinate.z - from.coordinate.z) / points;
408 double radiusSI = linkTag.arcTag.radius.getSI();
409 if (linkTag.arcTag.direction.equals(ArcDirection.RIGHT))
410 {
411 for (int p = 1; p < points - 1; p++)
412 {
413 coordinates[p] = new OTSPoint3D(
414 linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle - angleStep * p),
415 linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle - angleStep * p),
416 from.coordinate.z + slopeStep * p);
417 }
418 }
419 else
420 {
421 for (int p = 1; p < points - 1; p++)
422 {
423 try
424 {
425 System.err.println("linkTag.arcTag.center = " + linkTag.arcTag.center);
426 System.err.println("linkTag.arcTag.startAngle = " + linkTag.arcTag.startAngle);
427 coordinates[p] = new OTSPoint3D(
428 linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle + angleStep * p),
429 linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle + angleStep * p),
430 from.coordinate.z + slopeStep * p);
431 }
432 catch (NullPointerException npe)
433 {
434 npe.printStackTrace();
435 System.err.println(npe.getMessage());
436 }
437 }
438 }
439 }
440
441 else if (linkTag.bezierTag != null)
442 {
443 if (new DirectedPoint(startPoint.x, startPoint.y, startPoint.z, 0, 0, startAngle)
444 .equals(new DirectedPoint(endPoint.x, endPoint.y, endPoint.z, 0, 0, endAngle)))
445 {
446 System.out.println(" ");
447 }
448
449 coordinates = Bezier.cubic(128, new DirectedPoint(startPoint.x, startPoint.y, startPoint.z, 0, 0, startAngle),
450 new DirectedPoint(endPoint.x, endPoint.y, endPoint.z, 0, 0, endAngle)).getPoints();
451 }
452
453 else
454 {
455 throw new NetworkException(
456 "Making link, but link " + linkTag.name + " has no filled straight, arc, or bezier curve");
457 }
458 if (coordinates.length < 2)
459 {
460 throw new OTSGeometryException(
461 "Degenerate OTSLine3D; has " + coordinates.length + " point" + (coordinates.length != 1 ? "s" : ""));
462 }
463 OTSLine3D designLine = OTSLine3D.createAndCleanOTSLine3D(coordinates);
464
465
466 CrossSectionLink link = new CrossSectionLink(parser.getNetwork(), linkTag.name, linkTag.nodeStartTag.node,
467 linkTag.nodeEndTag.node, LinkType.ALL, designLine, simulator,
468 new HashMap<GTUType, LongitudinalDirectionality>(), linkTag.laneKeepingPolicy);
469 linkTag.link = link;
470 }
471
472
473
474
475
476
477
478
479
480
481
482
483 @SuppressWarnings({ "checkstyle:needbraces", "checkstyle:methodlength" })
484 static void applyRoadTypeToLink(final LinkTag linkTag, final VissimNetworkLaneParser parser,
485 final OTSDEVSSimulatorInterface simulator)
486 throws NetworkException, NamingException, SAXException, GTUException, OTSGeometryException, SimRuntimeException
487 {
488 CrossSectionLink csl = linkTag.link;
489
490 List<CrossSectionElement> cseList = new ArrayList<>();
491 List<Lane> lanes = new ArrayList<>();
492
493 LongitudinalDirectionality linkDirection = LongitudinalDirectionality.DIR_NONE;
494
495
496
497
498 Double roadWidth = 0.0;
499 for (LaneTag laneTag : linkTag.laneTags.values())
500 {
501 roadWidth += Double.parseDouble(laneTag.width);
502 }
503
504 Color color;
505 if (linkTag.connector)
506 {
507 color = Color.LIGHT_GRAY;
508 }
509 else
510 {
511 color = Color.DARK_GRAY;
512
513 }
514
515
516 Double totalLaneWidth = 0.0;
517
518 if (!linkTag.connector)
519 {
520 for (LaneTag laneTag : linkTag.laneTags.values())
521 {
522 String name = laneTag.laneNo;
523 Double laneWidth = Double.parseDouble(laneTag.width);
524 Length thisLaneWidth = new Length(laneWidth, LengthUnit.METER);
525
526
527
528
529 Double negativeOffset = -(0.5 * roadWidth - totalLaneWidth - laneWidth / 2);
530 Length lateralOffset = new Length(negativeOffset, LengthUnit.METER);
531
532 LaneType laneType = LaneType.ALL;
533 linkDirection = LongitudinalDirectionality.DIR_PLUS;
534 csl.addDirectionality(GTUType.ALL, linkDirection);
535 Speed speedLimit = new Speed(Double.parseDouble(linkTag.legalSpeed), SpeedUnit.KM_PER_HOUR);
536
537 Lane lane = new Lane(csl, name, lateralOffset, thisLaneWidth, laneType, linkDirection, speedLimit, null);
538 if (!linkTag.sensors.isEmpty())
539 {
540 for (SensorTag sensorTag : linkTag.sensors)
541 {
542 if (sensorTag.laneName.equals(laneTag.laneNo))
543 {
544 Length pos = new Length(Double.parseDouble(sensorTag.positionStr), LengthUnit.METER);
545 if (pos.lt(lane.getLength()))
546 {
547 new SimpleReportingSensor(sensorTag.name, lane, pos, RelativePosition.FRONT, simulator);
548 }
549 }
550 }
551 }
552
553 if (!linkTag.signalHeads.isEmpty())
554 {
555 for (SignalHeadTag signalHeadTag : linkTag.signalHeads)
556 {
557 if (signalHeadTag.laneName.equals(laneTag.laneNo))
558 {
559 Length pos = new Length(Double.parseDouble(signalHeadTag.positionStr), LengthUnit.METER);
560 if (pos.lt(lane.getLength()))
561 {
562 new SimpleTrafficLight(signalHeadTag.no, lane, pos, simulator);
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 }