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 new SimpleReportingSensor(sensorTag.name, lane, pos, RelativePosition.FRONT, simulator);
544 }
545 }
546 }
547 }
548
549 if (!linkTag.signalHeads.isEmpty())
550 {
551 for (SignalHeadTag signalHeadTag : linkTag.signalHeads)
552 {
553 if (signalHeadTag.laneName.equals(laneTag.laneNo))
554 {
555 Length pos = new Length(Double.parseDouble(signalHeadTag.positionStr), LengthUnit.METER);
556 if (pos.lt(lane.getLength()))
557 {
558 new SimpleTrafficLight(signalHeadTag.no, lane, pos, simulator);
559 }
560 }
561 }
562 }
563
564 cseList.add(lane);
565
566 lanes.add(lane);
567 linkTag.lanes.put(name, lane);
568
569 totalLaneWidth += Double.parseDouble(laneTag.width);
570 if (simulator != null && simulator instanceof AnimatorInterface)
571 {
572 try
573 {
574 new LaneAnimation(lane, simulator, color, true);
575 }
576 catch (RemoteException exception)
577 {
578 exception.printStackTrace();
579 }
580 }
581
582 }
583 }
584
585 }
586
587
588
589
590
591
592
593
594
595
596
597
598 @SuppressWarnings({ "checkstyle:needbraces", "checkstyle:methodlength" })
599 static void applyRoadTypeToConnector(final LinkTag linkTag, final VissimNetworkLaneParser parser,
600 final OTSDEVSSimulatorInterface simulator)
601 throws NetworkException, NamingException, SAXException, GTUException, OTSGeometryException, SimRuntimeException
602 {
603 CrossSectionLink csl = linkTag.link;
604
605 List<CrossSectionElement> cseList = new ArrayList<>();
606 List<Lane> lanes = new ArrayList<>();
607
608 LongitudinalDirectionality linkDirection = LongitudinalDirectionality.DIR_NONE;
609
610
611
612
613 Double roadWidth = 0.0;
614 for (LaneTag laneTag : linkTag.laneTags.values())
615 {
616 roadWidth += Double.parseDouble(laneTag.width);
617 }
618
619 Color color;
620 if (linkTag.connector)
621 {
622 color = Color.LIGHT_GRAY;
623 }
624 else
625 {
626 color = Color.DARK_GRAY;
627
628 }
629
630
631 LaneType laneType = LaneType.ALL;
632 linkDirection = LongitudinalDirectionality.DIR_PLUS;
633 csl.addDirectionality(GTUType.ALL, linkDirection);
634 Speed speedLimit = new Speed(Double.parseDouble(linkTag.legalSpeed), SpeedUnit.KM_PER_HOUR);
635
636
637
638 if (linkTag.connector)
639 {
640 Double totalFromLaneWidth = -1.75;
641 Double totalToLaneWidth = -1.75;
642
643 LinkTag linkToTag = parser.getRealLinkTags().get(linkTag.connectorTag.toLinkNo);
644 Lane laneTo = linkToTag.lanes.get(linkTag.connectorTag.toLaneNo);
645
646
647 LinkTag linkFromTag = parser.getRealLinkTags().get(linkTag.connectorTag.fromLinkNo);
648 Lane laneFrom = linkFromTag.lanes.get(linkTag.connectorTag.fromLaneNo);
649
650
651 for (LaneTag connectLaneTag : linkTag.laneTags.values())
652 {
653
654 String name = connectLaneTag.laneNo;
655
656 Length thisLaneWidth = new Length(Double.parseDouble(connectLaneTag.width), LengthUnit.METER);
657
658 Length totfromLaneWidth = new Length(totalFromLaneWidth, LengthUnit.METER);
659 Length totToLaneWidth = new Length(totalToLaneWidth, LengthUnit.METER);
660
661 Length lateralOffsetStart;
662 Length lateralOffsetEnd =
663 laneTo.getLateralBoundaryPosition(LateralDirectionality.RIGHT, 0).plus(totToLaneWidth);
664
665 if (laneFrom != null)
666 {
667 lateralOffsetStart =
668 laneFrom.getLateralBoundaryPosition(LateralDirectionality.RIGHT, 0).plus(totfromLaneWidth);
669 }
670 else
671 {
672 lateralOffsetStart = lateralOffsetEnd;
673 }
674
675
676
677 Lane lane = new Lane(csl, name, lateralOffsetStart, lateralOffsetEnd, thisLaneWidth, thisLaneWidth, laneType,
678 linkDirection, speedLimit, null);
679 cseList.add(lane);
680 lanes.add(lane);
681 linkTag.lanes.put(name, lane);
682
683
684 totalFromLaneWidth += Double.parseDouble(connectLaneTag.width);
685 totalToLaneWidth += Double.parseDouble(connectLaneTag.width);
686 if (simulator != null && simulator instanceof AnimatorInterface)
687 {
688 try
689 {
690 new LaneAnimation(lane, simulator, color, true);
691 }
692 catch (RemoteException exception)
693 {
694 exception.printStackTrace();
695 }
696 }
697
698 }
699 }
700
701 }
702
703
704
705
706
707
708
709 public static void createSinkSensor(LinkTag realLinkTag, VissimNetworkLaneParser vissimNetworkLaneParser,
710 OTSDEVSSimulatorInterface simulator) throws NetworkException
711 {
712 if (!realLinkTag.connector)
713 {
714 boolean deadLink = true;
715 for (LinkTag linkTag : vissimNetworkLaneParser.getLinkTags().values())
716 {
717 if (realLinkTag.nodeEndTag.name.equals(linkTag.nodeStartTag.name) && !realLinkTag.equals(linkTag))
718 {
719 deadLink = false;
720 }
721 }
722
723 if (deadLink)
724 {
725 for (Lane lane : realLinkTag.lanes.values())
726 {
727 Double smallest = Math.min(10, lane.getLength().getInUnit(LengthUnit.METER) - 1);
728 Length beforeEnd = new Length(smallest, LengthUnit.METER);
729 Length pos = lane.getLength().minus(beforeEnd);
730 SinkSensor sensor = new SinkSensor(lane, pos, simulator);
731 lane.getSensors().add(sensor);
732 }
733 }
734 }
735
736 }
737
738 }