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