1 package org.opentrafficsim.core.network.factory;
2
3 import java.awt.Color;
4 import java.awt.geom.Point2D;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.net.URL;
8 import java.rmi.RemoteException;
9 import java.util.ArrayDeque;
10 import java.util.ArrayList;
11 import java.util.Deque;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
18 import javax.naming.NamingException;
19 import javax.vecmath.Point2d;
20 import javax.vecmath.Point3d;
21 import javax.xml.parsers.ParserConfigurationException;
22 import javax.xml.parsers.SAXParser;
23 import javax.xml.parsers.SAXParserFactory;
24
25 import nl.tudelft.simulation.jstats.distributions.DistBeta;
26 import nl.tudelft.simulation.jstats.distributions.DistConstant;
27 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
28 import nl.tudelft.simulation.jstats.distributions.DistErlang;
29 import nl.tudelft.simulation.jstats.distributions.DistExponential;
30 import nl.tudelft.simulation.jstats.distributions.DistGamma;
31 import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
32 import nl.tudelft.simulation.jstats.distributions.DistNormal;
33 import nl.tudelft.simulation.jstats.distributions.DistPearson5;
34 import nl.tudelft.simulation.jstats.distributions.DistPearson6;
35 import nl.tudelft.simulation.jstats.distributions.DistTriangular;
36 import nl.tudelft.simulation.jstats.distributions.DistUniform;
37 import nl.tudelft.simulation.jstats.distributions.DistWeibull;
38 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
39 import nl.tudelft.simulation.jstats.streams.StreamInterface;
40 import nl.tudelft.simulation.language.io.URLResource;
41
42 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
43 import org.opentrafficsim.core.gtu.GTUType;
44 import org.opentrafficsim.core.gtu.following.GTUFollowingModel;
45 import org.opentrafficsim.core.gtu.following.IDM;
46 import org.opentrafficsim.core.gtu.following.IDMPlus;
47 import org.opentrafficsim.core.gtu.lane.changing.Altruistic;
48 import org.opentrafficsim.core.gtu.lane.changing.Egoistic;
49 import org.opentrafficsim.core.gtu.lane.changing.LaneChangeModel;
50 import org.opentrafficsim.core.network.Link;
51 import org.opentrafficsim.core.network.LongitudinalDirectionality;
52 import org.opentrafficsim.core.network.Network;
53 import org.opentrafficsim.core.network.NetworkException;
54 import org.opentrafficsim.core.network.Node;
55 import org.opentrafficsim.core.network.animation.LaneAnimation;
56 import org.opentrafficsim.core.network.animation.ShoulderAnimation;
57 import org.opentrafficsim.core.network.geotools.LinearGeometry;
58 import org.opentrafficsim.core.network.geotools.LinkGeotools;
59 import org.opentrafficsim.core.network.geotools.NodeGeotools;
60 import org.opentrafficsim.core.network.lane.CrossSectionElement;
61 import org.opentrafficsim.core.network.lane.CrossSectionLink;
62 import org.opentrafficsim.core.network.lane.Lane;
63 import org.opentrafficsim.core.network.lane.LaneType;
64 import org.opentrafficsim.core.network.lane.NoTrafficLane;
65 import org.opentrafficsim.core.network.lane.RoadMarkerAlong;
66 import org.opentrafficsim.core.network.lane.Shoulder;
67 import org.opentrafficsim.core.network.point2d.NodePoint2D;
68 import org.opentrafficsim.core.unit.AnglePlaneUnit;
69 import org.opentrafficsim.core.unit.AngleSlopeUnit;
70 import org.opentrafficsim.core.unit.FrequencyUnit;
71 import org.opentrafficsim.core.unit.LengthUnit;
72 import org.opentrafficsim.core.unit.SpeedUnit;
73 import org.opentrafficsim.core.unit.TimeUnit;
74 import org.opentrafficsim.core.value.vdouble.scalar.DistContinuousDoubleScalar;
75 import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar;
76 import org.xml.sax.Attributes;
77 import org.xml.sax.SAXException;
78 import org.xml.sax.helpers.DefaultHandler;
79
80 import com.vividsolutions.jts.geom.Coordinate;
81 import com.vividsolutions.jts.geom.GeometryFactory;
82 import com.vividsolutions.jts.geom.LineString;
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 public class XmlNetworkLaneParser
150 {
151
152 @SuppressWarnings("visibilitymodifier")
153 protected final Class<?> networkIdClass;
154
155
156 @SuppressWarnings("visibilitymodifier")
157 protected final Class<?> nodeClass;
158
159
160 @SuppressWarnings("visibilitymodifier")
161 protected final Class<?> nodeIdClass;
162
163
164 @SuppressWarnings("visibilitymodifier")
165 protected final Class<?> nodePointClass;
166
167
168 @SuppressWarnings("visibilitymodifier")
169 protected final Class<?> linkClass;
170
171
172 @SuppressWarnings("visibilitymodifier")
173 protected final Class<?> linkIdClass;
174
175
176 private Network<?, ?> network;
177
178
179 private static final Map<String, SpeedUnit> SPEED_UNITS = new HashMap<>();
180
181
182 private static final Map<String, LengthUnit> LENGTH_UNITS = new HashMap<>();
183
184
185 private static final Map<String, TimeUnit> TIME_UNITS = new HashMap<>();
186
187
188 @SuppressWarnings({"rawtypes", "visibilitymodifier"})
189 protected Map<String, Node> nodes = new HashMap<>();
190
191
192 @SuppressWarnings("visibilitymodifier")
193 protected Map<String, NodeTag> nodeTags = new HashMap<>();
194
195
196 @SuppressWarnings({"rawtypes", "visibilitymodifier"})
197 protected Map<String, Link> links = new HashMap<>();
198
199
200 @SuppressWarnings("visibilitymodifier")
201 protected Map<String, GTUTag> gtuTags = new HashMap<>();
202
203
204 @SuppressWarnings("visibilitymodifier")
205 protected Map<String, GTUType<String>> gtuTypes = new HashMap<>();
206
207
208 private final LaneType<String> laneType = new LaneType<String>("CarLane");
209
210
211 private OTSSimulatorInterface simulator;
212
213 static
214 {
215 SPEED_UNITS.put("km/h", SpeedUnit.KM_PER_HOUR);
216 SPEED_UNITS.put("mi/h", SpeedUnit.MILE_PER_HOUR);
217 SPEED_UNITS.put("m/s", SpeedUnit.METER_PER_SECOND);
218 SPEED_UNITS.put("ft/s", SpeedUnit.FOOT_PER_SECOND);
219
220 LENGTH_UNITS.put("mm", LengthUnit.MILLIMETER);
221 LENGTH_UNITS.put("cm", LengthUnit.CENTIMETER);
222 LENGTH_UNITS.put("dm", LengthUnit.DECIMETER);
223 LENGTH_UNITS.put("dam", LengthUnit.DEKAMETER);
224 LENGTH_UNITS.put("hm", LengthUnit.HECTOMETER);
225 LENGTH_UNITS.put("m", LengthUnit.METER);
226 LENGTH_UNITS.put("km", LengthUnit.KILOMETER);
227 LENGTH_UNITS.put("mi", LengthUnit.MILE);
228 LENGTH_UNITS.put("y", LengthUnit.YARD);
229 LENGTH_UNITS.put("ft", LengthUnit.FOOT);
230
231 TIME_UNITS.put("ms", TimeUnit.MILLISECOND);
232 TIME_UNITS.put("s", TimeUnit.SECOND);
233 TIME_UNITS.put("m", TimeUnit.MINUTE);
234 TIME_UNITS.put("min", TimeUnit.MINUTE);
235 TIME_UNITS.put("h", TimeUnit.HOUR);
236 TIME_UNITS.put("hr", TimeUnit.HOUR);
237 TIME_UNITS.put("d", TimeUnit.DAY);
238 TIME_UNITS.put("day", TimeUnit.DAY);
239 TIME_UNITS.put("wk", TimeUnit.WEEK);
240 TIME_UNITS.put("week", TimeUnit.WEEK);
241 }
242
243
244
245
246
247
248
249
250
251
252 public XmlNetworkLaneParser(final Class<?> networkIdClass, final Class<?> nodeClass, final Class<?> nodeIdClass,
253 final Class<?> nodePointClass, final Class<?> linkClass, final Class<?> linkIdClass,
254 final OTSSimulatorInterface simulator)
255 {
256 this.networkIdClass = networkIdClass;
257 this.nodeClass = nodeClass;
258 this.nodeIdClass = nodeIdClass;
259 this.nodePointClass = nodePointClass;
260 this.linkClass = linkClass;
261 this.linkIdClass = linkIdClass;
262 this.simulator = simulator;
263 }
264
265
266
267
268
269
270
271
272
273 public final Network<?, ?> build(final InputStream is) throws NetworkException, ParserConfigurationException,
274 SAXException, IOException
275 {
276
277 this.nodes.clear();
278
279 SAXParserFactory parserFactor = SAXParserFactory.newInstance();
280 SAXParser parser = parserFactor.newSAXParser();
281 SAXHandler handler = new SAXHandler();
282 parser.parse(is, handler);
283
284
285 return this.network;
286 }
287
288
289
290
291 class SAXHandler extends DefaultHandler
292 {
293
294
295
296
297 private Deque<String> stack = new ArrayDeque<String>();
298
299
300 private GlobalTag globalTag;
301
302
303 private LinkTag linkTag;
304
305
306 private NodeTag nodeTag;
307
308 @Override
309 @SuppressWarnings("checkstyle:methodlength")
310 public void startElement(final String uri, final String localName, final String qName, final Attributes attributes)
311 throws SAXException
312 {
313 System.out.println("start: " + qName);
314 try
315 {
316 if (!qName.equals("NETWORK"))
317 {
318 switch (this.stack.getLast())
319 {
320 case "NETWORK":
321 switch (qName)
322 {
323 case "GLOBAL":
324 parseGlobalTag(attributes);
325 break;
326
327 case "NODE":
328 parseNodeTag(attributes);
329 break;
330
331 case "LINK":
332 parseLinkTag(attributes);
333 break;
334
335 case "GTU":
336 parseGTUTag(attributes);
337 break;
338
339 default:
340 throw new SAXException("NETWORK: Received start tag " + qName + ", but stack contains: "
341 + this.stack);
342 }
343 break;
344
345 case "LINK":
346 switch (qName)
347 {
348 case "STRAIGHT":
349 parseStraightTag(attributes);
350 break;
351
352 case "ARC":
353 parseArcTag(attributes);
354 break;
355
356 case "LANE":
357 parseLaneTag(attributes);
358 break;
359
360 case "GENERATOR":
361 parseGeneratorTag(attributes);
362 break;
363
364 case "FILL":
365 parseFillTag(attributes);
366 break;
367
368 default:
369 throw new SAXException("LINK: Received start tag " + qName + ", but stack contains: "
370 + this.stack);
371 }
372 break;
373
374 default:
375 throw new SAXException("startElement: Received start tag " + qName + ", but stack contains: "
376 + this.stack);
377 }
378 }
379 this.stack.addLast(qName);
380 }
381 catch (Exception e)
382 {
383 throw new SAXException(e);
384 }
385 }
386
387 @Override
388 public void endElement(final String uri, final String localName, final String qName) throws SAXException
389 {
390 System.out.println("end : " + qName);
391 if (!this.stack.getLast().equals(qName))
392 {
393 throw new SAXException("endElement: Received /" + qName + ", but stack contains: " + this.stack);
394 }
395 this.stack.removeLast();
396
397 try
398 {
399 if (!qName.equals("NETWORK"))
400 {
401 switch (this.stack.getLast())
402 {
403 case "NETWORK":
404 switch (qName)
405 {
406 case "GLOBAL":
407 break;
408
409 case "NODE":
410 XmlNetworkLaneParser.this.nodeTags.put(this.nodeTag.name, this.nodeTag);
411 if (this.nodeTag.coordinate != null)
412 {
413
414 @SuppressWarnings("rawtypes")
415 Node node = makeNode(XmlNetworkLaneParser.this.nodeClass, this.nodeTag);
416 XmlNetworkLaneParser.this.nodes.put(node.getId().toString(), node);
417 }
418 break;
419
420 case "LINK":
421 calculateNodeCoordinates(this.linkTag);
422 @SuppressWarnings("rawtypes")
423 CrossSectionLink link = makeLink(this.linkTag);
424 parseElements(this.linkTag.elements, link, this.linkTag, this.globalTag);
425 XmlNetworkLaneParser.this.links.put(link.getId().toString(), link);
426 break;
427
428 case "GTU":
429 break;
430
431 default:
432 throw new SAXException("NETWORK: Received end tag " + qName + ", but stack contains: "
433 + this.stack);
434 }
435 break;
436
437 case "LINK":
438 switch (qName)
439 {
440 case "STRAIGHT":
441 break;
442 case "ARC":
443 break;
444 case "LANE":
445 break;
446 case "GENERATOR":
447 break;
448 case "FILL":
449 break;
450 default:
451 throw new SAXException("LINK: Received end tag " + qName + ", but stack contains: "
452 + this.stack);
453 }
454 break;
455
456 default:
457 throw new SAXException("Received end tag " + qName + ", but stack contains: " + this.stack);
458 }
459 }
460 }
461 catch (Exception e)
462 {
463 throw new SAXException(e);
464 }
465 }
466
467
468
469
470
471
472 @SuppressWarnings("checkstyle:needbraces")
473 private void parseGlobalTag(final Attributes attributes) throws NetworkException
474 {
475 this.globalTag = new GlobalTag();
476 if (attributes.getValue("SPEED") != null)
477 this.globalTag.speed = parseSpeedAbs(attributes.getValue("SPEED"));
478 if (attributes.getValue("WIDTH") != null)
479 this.globalTag.width = parseLengthRel(attributes.getValue("WIDTH"));
480 }
481
482
483
484
485
486
487
488 @SuppressWarnings("checkstyle:needbraces")
489 private void parseNodeTag(final Attributes attributes) throws NetworkException, SAXException
490 {
491 this.nodeTag = new NodeTag();
492
493 String name = attributes.getValue("NAME");
494 if (name == null)
495 throw new SAXException("NODE: missing attribute NAME");
496 this.nodeTag.name = name;
497
498 if (attributes.getValue("COORDINATE") != null)
499 this.nodeTag.coordinate = parseCoordinate(attributes.getValue("COORDINATE"));
500
501 if (attributes.getValue("ANGLE") != null)
502 this.nodeTag.angle =
503 new DoubleScalar.Abs<AnglePlaneUnit>(Double.parseDouble(attributes.getValue("ANGLE")),
504 AnglePlaneUnit.DEGREE);
505 }
506
507
508
509
510
511
512
513 @SuppressWarnings("checkstyle:needbraces")
514 private void parseLinkTag(final Attributes attributes) throws NetworkException, SAXException
515 {
516 this.linkTag = new LinkTag();
517
518 String name = attributes.getValue("NAME");
519 if (name == null)
520 throw new SAXException("NODE: missing attribute NAME");
521 this.linkTag.name = name;
522
523 String elements = attributes.getValue("ELEMENTS");
524 if (elements == null)
525 throw new SAXException("NODE: missing attribute ELEMENTS");
526 this.linkTag.elements = attributes.getValue("ELEMENTS");
527 String[] nameStrings = elements.split("(\\-)|(\\|)|(\\:)|(\\<)|(\\>)|(\\#)");
528 for (String laneName : nameStrings)
529 {
530 if (laneName.length() > 0 && !laneName.equals("D"))
531 {
532 LaneTag laneTag = new LaneTag();
533 laneTag.name = laneName;
534 this.linkTag.laneTags.put(laneName, laneTag);
535 }
536 }
537
538 String fromNodeStr = attributes.getValue("FROM");
539 if (fromNodeStr == null)
540 throw new SAXException("NODE: missing attribute FROM for link " + name);
541 this.linkTag.nodeFromName = fromNodeStr;
542 @SuppressWarnings("rawtypes")
543 Node fromNode = XmlNetworkLaneParser.this.nodes.get(fromNodeStr);
544 this.linkTag.nodeFrom = fromNode;
545
546 String toNodeStr = attributes.getValue("TO");
547 if (toNodeStr == null)
548 throw new SAXException("NODE: missing attribute TO for link " + name);
549 this.linkTag.nodeToName = toNodeStr;
550 @SuppressWarnings("rawtypes")
551 Node toNode = XmlNetworkLaneParser.this.nodes.get(toNodeStr);
552 this.linkTag.nodeTo = toNode;
553
554 if (attributes.getValue("SPEED") != null)
555 this.linkTag.speed = parseSpeedAbs(attributes.getValue("SPEED"));
556
557 if (attributes.getValue("WIDTH") != null)
558 this.linkTag.width = parseLengthRel(attributes.getValue("WIDTH"));
559 }
560
561
562
563
564
565
566
567 @SuppressWarnings("checkstyle:needbraces")
568 private void parseGTUTag(final Attributes attributes) throws NetworkException, SAXException
569 {
570 GTUTag gtuTag = new GTUTag();
571
572 String name = attributes.getValue("NAME");
573 if (name == null)
574 throw new SAXException("GTU: missing attribute NAME");
575 gtuTag.name = name;
576
577 String gtuType = attributes.getValue("GTUTYPE");
578 if (gtuType == null)
579 throw new SAXException("GTU: missing attribute GTUTYPE");
580 gtuTag.gtuType = parseGTUType(attributes.getValue("GTUTYPE"));
581
582 String length = attributes.getValue("LENGTH");
583 if (length == null)
584 throw new SAXException("GTU: missing attribute LENGTH");
585 gtuTag.lengthDist = parseLengthDistRel(attributes.getValue("LENGTH"));
586
587 String width = attributes.getValue("WIDTH");
588 if (width == null)
589 throw new SAXException("GTU: missing attribute WIDTH");
590 gtuTag.widthDist = parseLengthDistRel(attributes.getValue("WIDTH"));
591
592 String following = attributes.getValue("FOLLOWING");
593 if (following == null)
594 throw new SAXException("GTU: missing attribute FOLLOWING");
595 gtuTag.followingModel = parseFollowingModel(attributes.getValue("FOLLOWING"));
596
597 String laneChange = attributes.getValue("LANECHANGE");
598 if (laneChange == null)
599 throw new SAXException("GTU: missing attribute LANECHANGE");
600 gtuTag.laneChangeModel = parseLaneChangeModel(attributes.getValue("LANECHANGE"));
601
602 String maxSpeed = attributes.getValue("MAXSPEED");
603 if (maxSpeed == null)
604 throw new SAXException("GTU: missing attribute LENGTH");
605 gtuTag.maxSpeedDist = parseSpeedDistAbs(attributes.getValue("MAXSPEED"));
606
607 XmlNetworkLaneParser.this.gtuTags.put(gtuTag.name, gtuTag);
608 }
609
610
611
612
613
614
615
616 @SuppressWarnings("checkstyle:needbraces")
617 private void parseStraightTag(final Attributes attributes) throws NetworkException, SAXException
618 {
619 this.linkTag.straightTag = new StraightTag();
620 String length = attributes.getValue("LENGTH");
621 if (length == null)
622 throw new SAXException("STRAIGHT: missing attribute LENGTH");
623 this.linkTag.straightTag.length = parseLengthRel(length);
624 }
625
626
627
628
629
630
631
632 @SuppressWarnings("checkstyle:needbraces")
633 private void parseArcTag(final Attributes attributes) throws NetworkException, SAXException
634 {
635 this.linkTag.arcTag = new ArcTag();
636
637 String radius = attributes.getValue("RADIUS");
638 if (radius == null)
639 throw new SAXException("ARC: missing attribute RADIUS");
640 this.linkTag.arcTag.radius = parseLengthRel(radius);
641
642 String angle = attributes.getValue("ANGLE");
643 if (angle == null)
644 throw new SAXException("ARC: missing attribute ANGLE");
645 this.linkTag.arcTag.angle =
646 new DoubleScalar.Abs<AnglePlaneUnit>(Double.parseDouble(angle), AnglePlaneUnit.DEGREE);
647
648 String dir = attributes.getValue("DIRECTION");
649 if (dir == null)
650 throw new SAXException("ARC: missing attribute ANGLE");
651 this.linkTag.arcTag.direction =
652 (dir.equals("L") || dir.equals("LEFT") || dir.equals("COUNTERCLOCKWISE")) ? ArcDirection.LEFT
653 : ArcDirection.RIGHT;
654 }
655
656
657
658
659
660
661
662 @SuppressWarnings("checkstyle:needbraces")
663 private void parseLaneTag(final Attributes attributes) throws NetworkException, SAXException
664 {
665 String name = attributes.getValue("NAME");
666 if (name == null)
667 throw new SAXException("LANE: missing attribute NAME");
668 LaneTag laneTag = this.linkTag.laneTags.get(name);
669 if (laneTag == null)
670 throw new NetworkException("LANE: Lane with NAME " + name + "not found in elements of link "
671 + this.linkTag.name);
672
673 if (attributes.getValue("SPEED") != null)
674 laneTag.speed = parseSpeedAbs(attributes.getValue("SPEED"));
675
676 if (attributes.getValue("WIDTH") != null)
677 laneTag.width = parseLengthRel(attributes.getValue("WIDTH"));
678 }
679
680
681
682
683
684
685
686 @SuppressWarnings("checkstyle:needbraces")
687 private void parseGeneratorTag(final Attributes attributes) throws NetworkException, SAXException
688 {
689 GeneratorTag generatorTag = new GeneratorTag();
690
691 String laneName = attributes.getValue("LANE");
692 if (laneName == null)
693 throw new SAXException("GENERATOR: missing attribute LANE");
694 LaneTag laneTag = this.linkTag.laneTags.get(laneName);
695 if (laneTag == null)
696 throw new NetworkException("LANE: Lane with NAME " + laneName + "not found in elements of link "
697 + this.linkTag.name);
698 generatorTag.laneTag = laneTag;
699
700 String gtuName = attributes.getValue("GTU");
701 if (gtuName == null)
702 throw new SAXException("GENERATOR: missing attribute GTU");
703 if (!XmlNetworkLaneParser.this.gtuTags.containsKey(gtuName))
704 throw new NetworkException("GENERATOR: LANE " + laneName + " GTU " + gtuName + " not defined in link "
705 + this.linkTag.name);
706 generatorTag.gtuTag = XmlNetworkLaneParser.this.gtuTags.get(gtuName);
707
708 String iat = attributes.getValue("IAT");
709 if (iat == null)
710 throw new SAXException("GENERATOR: missing attribute IAT");
711 generatorTag.iatDist = parseTimeDistRel(iat);
712
713 String initialSpeed = attributes.getValue("INITIALSPEED");
714 if (initialSpeed == null)
715 throw new SAXException("GENERATOR: missing attribute INITIALSPEED");
716 generatorTag.initialSpeedDist = parseSpeedDistAbs(initialSpeed);
717
718 String maxGTU = attributes.getValue("MAXGTU");
719 generatorTag.maxGTUs = maxGTU == null ? Integer.MAX_VALUE : Integer.parseInt(maxGTU);
720
721 if (attributes.getValue("STARTTIME") != null)
722 generatorTag.startTime = parseTimeAbs(attributes.getValue("STARTTIME"));
723
724 if (attributes.getValue("ENDTIME") != null)
725 generatorTag.endTime = parseTimeAbs(attributes.getValue("ENDTIME"));
726
727 generatorTag.laneTag.generatorTags.add(generatorTag);
728 }
729
730
731
732
733
734
735
736 @SuppressWarnings("checkstyle:needbraces")
737 private void parseFillTag(final Attributes attributes) throws NetworkException, SAXException
738 {
739 FillTag fillTag = new FillTag();
740
741 String laneName = attributes.getValue("LANE");
742 if (laneName == null)
743 throw new SAXException("FILL: missing attribute LANE");
744 if (!this.linkTag.laneTags.containsKey(laneName))
745 throw new NetworkException("FILL: LANE " + laneName + " not defined in link " + this.linkTag.name);
746 fillTag.laneTag = this.linkTag.laneTags.get(laneName);
747
748 String gtuName = attributes.getValue("GTU");
749 if (gtuName == null)
750 throw new SAXException("FILL: missing attribute GTU");
751 if (!XmlNetworkLaneParser.this.gtuTags.containsKey(gtuName))
752 throw new NetworkException("FILL: LANE " + laneName + " GTU " + gtuName + " not defined in link "
753 + this.linkTag.name);
754 fillTag.gtuTag = XmlNetworkLaneParser.this.gtuTags.get(gtuName);
755
756 String distance = attributes.getValue("DISTANCE");
757 if (distance == null)
758 throw new SAXException("FILL: missing attribute DISTANCE");
759 fillTag.distanceDist = parseLengthDistRel(distance);
760
761 String initialSpeed = attributes.getValue("INITIALSPEED");
762 if (initialSpeed == null)
763 throw new SAXException("FILL: missing attribute INITIALSPEED");
764 fillTag.initialSpeedDist = parseSpeedDistAbs(initialSpeed);
765
766 String maxGTU = attributes.getValue("MAXGTU");
767 fillTag.maxGTUs = maxGTU == null ? Integer.MAX_VALUE : Integer.parseInt(maxGTU);
768
769 fillTag.laneTag.fillTags.add(fillTag);
770 }
771
772 }
773
774
775
776
777
778
779
780
781
782
783
784
785 protected final Object makeId(final Class<?> clazz, final String ids) throws NetworkException
786 {
787 Object id = null;
788 try
789 {
790 if (String.class.isAssignableFrom(clazz))
791 {
792 id = new String(ids);
793 }
794 else if (int.class.isAssignableFrom(clazz))
795 {
796 id = Integer.valueOf(ids);
797 }
798 else if (long.class.isAssignableFrom(clazz))
799 {
800 id = Long.valueOf(ids);
801 }
802 else
803 {
804 throw new NetworkException("Parsing network. ID class " + clazz.getName() + ": cannot instantiate.");
805 }
806 }
807 catch (NumberFormatException nfe)
808 {
809 throw new NetworkException("Parsing network. ID class " + clazz.getName() + ": cannot instantiate number: "
810 + ids, nfe);
811 }
812 return id;
813 }
814
815
816
817
818
819
820
821
822 protected final Object makePoint(final Class<?> clazz, final Point3d p) throws NetworkException
823 {
824 Object point = null;
825 if (Point3d.class.isAssignableFrom(clazz))
826 {
827 point = p;
828 }
829 else if (Point2D.class.isAssignableFrom(clazz))
830 {
831 point = new Point2D.Double(p.x, p.y);
832 }
833 else if (Point2d.class.isAssignableFrom(clazz))
834 {
835 point = new Point2d(new double[] {p.x, p.y});
836 }
837 else if (Coordinate.class.isAssignableFrom(clazz))
838 {
839 point = new Coordinate(p.x, p.y, p.z);
840 }
841 else
842 {
843 throw new NetworkException("Parsing network. Point class " + clazz.getName() + ": cannot instantiate.");
844 }
845 return point;
846 }
847
848
849
850
851
852
853
854
855
856 @SuppressWarnings({"unchecked", "rawtypes"})
857 protected final Node makeNode(final Class<?> clazz, final NodeTag nodeTag) throws NetworkException, RemoteException,
858 NamingException
859 {
860 Object id = makeId(this.nodeIdClass, nodeTag.name);
861 Object point = makePoint(this.nodePointClass, nodeTag.coordinate);
862 DoubleScalar.Abs<AnglePlaneUnit> angle =
863 nodeTag.angle == null ? new DoubleScalar.Abs<AnglePlaneUnit>(0.0, AnglePlaneUnit.SI) : nodeTag.angle;
864 DoubleScalar.Abs<AngleSlopeUnit> slope =
865 nodeTag.slope == null ? new DoubleScalar.Abs<AngleSlopeUnit>(0.0, AngleSlopeUnit.SI) : nodeTag.slope;
866 if (NodeGeotools.class.isAssignableFrom(clazz))
867 {
868 if (point instanceof Coordinate)
869 {
870 Node node = new NodeGeotools(id, (Coordinate) point, angle, slope);
871 this.nodes.put(id.toString(), node);
872 return node;
873 }
874 throw new NetworkException("Parsing network. Node class " + clazz.getName()
875 + ": cannot instantiate. Wrong Coordinate type: " + point.getClass() + ", coordinate: " + point);
876 }
877 else if (NodePoint2D.class.isAssignableFrom(clazz))
878 {
879 if (point instanceof Point2D)
880 {
881 Node node = new NodePoint2D(id, (Point2D) point, angle, slope);
882 this.nodes.put(id.toString(), node);
883 return node;
884 }
885 throw new NetworkException("Parsing network. Node class " + clazz.getName()
886 + ": cannot instantiate. Wrong Point2D type: " + point.getClass() + ", coordinate: " + point);
887 }
888 else
889 {
890 throw new NetworkException("Parsing network. Node class " + clazz.getName() + ": cannot instantiate.");
891 }
892 }
893
894
895
896
897
898
899
900
901 @SuppressWarnings("methodlength")
902 protected final void calculateNodeCoordinates(final LinkTag linkTag) throws RemoteException, NetworkException,
903 NamingException
904 {
905
906 if (linkTag.nodeFrom != null && linkTag.nodeTo != null)
907 {
908 if (linkTag.arcTag != null)
909 {
910 double radiusSI = linkTag.arcTag.radius.getSI();
911 ArcDirection direction = linkTag.arcTag.direction;
912 Point3d coordinate =
913 new Point3d(linkTag.nodeFrom.getLocation().getX(), linkTag.nodeFrom.getLocation().getY(),
914 linkTag.nodeFrom.getLocation().getZ());
915 double startAngle = linkTag.nodeFrom.getDirection().getSI();
916 if (direction.equals(ArcDirection.LEFT))
917 {
918 linkTag.arcTag.center =
919 new Point3d(coordinate.x + radiusSI * Math.cos(startAngle + Math.PI / 2.0), coordinate.y + radiusSI
920 * Math.sin(startAngle + Math.PI / 2.0), 0.0);
921 linkTag.arcTag.startAngle = startAngle - Math.PI / 2.0;
922 }
923 else
924 {
925 linkTag.arcTag.center =
926 new Point3d(coordinate.x + radiusSI * Math.cos(startAngle - Math.PI / 2.0), coordinate.y + radiusSI
927 * Math.sin(startAngle - Math.PI / 2.0), 0.0);
928 linkTag.arcTag.startAngle = startAngle + Math.PI / 2.0;
929 }
930 }
931 return;
932 }
933
934 if (linkTag.nodeFrom == null && linkTag.nodeTo == null)
935 {
936 throw new NetworkException("Parsing network. Link: " + linkTag.name + ", both From-node and To-node are null");
937 }
938
939 if (linkTag.straightTag != null)
940 {
941 double lengthSI = linkTag.straightTag.length.getSI();
942 if (linkTag.nodeTo == null)
943 {
944 Point3d coordinate =
945 new Point3d(linkTag.nodeFrom.getLocation().getX(), linkTag.nodeFrom.getLocation().getY(),
946 linkTag.nodeFrom.getLocation().getZ());
947 double angle = linkTag.nodeFrom.getDirection().getSI();
948 double slope = linkTag.nodeFrom.getSlope().getSI();
949 coordinate.x += lengthSI * Math.cos(angle);
950 coordinate.y += lengthSI * Math.sin(angle);
951 coordinate.z += lengthSI * Math.sin(slope);
952 NodeTag nodeTag = this.nodeTags.get(linkTag.nodeToName);
953 nodeTag.angle = new DoubleScalar.Abs<AnglePlaneUnit>(angle, AnglePlaneUnit.SI);
954 nodeTag.coordinate = coordinate;
955 nodeTag.slope = new DoubleScalar.Abs<AngleSlopeUnit>(slope, AngleSlopeUnit.SI);
956 @SuppressWarnings("rawtypes")
957 Node node = makeNode(this.nodeClass, nodeTag);
958 linkTag.nodeTo = node;
959 }
960 else if (linkTag.nodeFrom == null)
961 {
962 Point3d coordinate =
963 new Point3d(linkTag.nodeTo.getLocation().getX(), linkTag.nodeTo.getLocation().getY(), linkTag.nodeTo
964 .getLocation().getZ());
965 double angle = linkTag.nodeTo.getDirection().getSI();
966 double slope = linkTag.nodeTo.getSlope().getSI();
967 coordinate.x -= lengthSI * Math.cos(angle);
968 coordinate.y -= lengthSI * Math.sin(angle);
969 coordinate.z -= lengthSI * Math.sin(slope);
970 NodeTag nodeTag = this.nodeTags.get(linkTag.nodeFromName);
971 nodeTag.angle = new DoubleScalar.Abs<AnglePlaneUnit>(angle, AnglePlaneUnit.SI);
972 nodeTag.coordinate = coordinate;
973 nodeTag.slope = new DoubleScalar.Abs<AngleSlopeUnit>(slope, AngleSlopeUnit.SI);
974 @SuppressWarnings("rawtypes")
975 Node node = makeNode(this.nodeClass, nodeTag);
976 linkTag.nodeFrom = node;
977 }
978 }
979 else if (linkTag.arcTag != null)
980 {
981 double radiusSI = linkTag.arcTag.radius.getSI();
982 double angle = linkTag.arcTag.angle.getSI();
983 ArcDirection direction = linkTag.arcTag.direction;
984 if (linkTag.nodeTo == null)
985 {
986 Point3d coordinate =
987 new Point3d(linkTag.nodeFrom.getLocation().getX(), linkTag.nodeFrom.getLocation().getY(),
988 linkTag.nodeFrom.getLocation().getZ());
989 double startAngle = linkTag.nodeFrom.getDirection().getSI();
990 double slope = linkTag.nodeFrom.getSlope().getSI();
991 double lengthSI = radiusSI * angle;
992 if (direction.equals(ArcDirection.LEFT))
993 {
994 linkTag.arcTag.center =
995 new Point3d(coordinate.x + radiusSI * Math.cos(startAngle + Math.PI / 2.0), coordinate.y + radiusSI
996 * Math.sin(startAngle + Math.PI / 2.0), 0.0);
997 linkTag.arcTag.startAngle = startAngle - Math.PI / 2.0;
998 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle + angle);
999 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle + angle);
1000 }
1001 else
1002 {
1003 linkTag.arcTag.center =
1004 new Point3d(coordinate.x + radiusSI * Math.cos(startAngle - Math.PI / 2.0), coordinate.y + radiusSI
1005 * Math.sin(startAngle - Math.PI / 2.0), 0.0);
1006 linkTag.arcTag.startAngle = startAngle + Math.PI / 2.0;
1007 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle - angle);
1008 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle - angle);
1009 }
1010 coordinate.z += lengthSI * Math.sin(slope);
1011 NodeTag nodeTag = this.nodeTags.get(linkTag.nodeToName);
1012 nodeTag.angle = new DoubleScalar.Abs<AnglePlaneUnit>(norm(startAngle - angle), AnglePlaneUnit.SI);
1013 nodeTag.coordinate = coordinate;
1014 nodeTag.slope = new DoubleScalar.Abs<AngleSlopeUnit>(slope, AngleSlopeUnit.SI);
1015 @SuppressWarnings("rawtypes")
1016 Node node = makeNode(this.nodeClass, nodeTag);
1017 linkTag.nodeTo = node;
1018 }
1019
1020 else if (linkTag.nodeFrom == null)
1021 {
1022 Point3d coordinate =
1023 new Point3d(linkTag.nodeTo.getLocation().getX(), linkTag.nodeTo.getLocation().getY(), linkTag.nodeTo
1024 .getLocation().getZ());
1025 double endAngle = linkTag.nodeTo.getDirection().getSI();
1026 double slope = linkTag.nodeTo.getSlope().getSI();
1027 double lengthSI = radiusSI * angle;
1028 NodeTag nodeTag = this.nodeTags.get(linkTag.nodeFromName);
1029 if (direction.equals(ArcDirection.LEFT))
1030 {
1031 linkTag.arcTag.center =
1032 new Point3d(coordinate.x + radiusSI + Math.cos(endAngle + Math.PI / 2.0), coordinate.y + radiusSI
1033 * Math.sin(endAngle + Math.PI / 2.0), 0.0);
1034 linkTag.arcTag.startAngle = endAngle - Math.PI / 2.0 - angle;
1035 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
1036 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
1037 nodeTag.angle =
1038 new DoubleScalar.Abs<AnglePlaneUnit>(norm(linkTag.arcTag.startAngle + Math.PI / 2.0),
1039 AnglePlaneUnit.SI);
1040 }
1041 else
1042 {
1043 linkTag.arcTag.center =
1044 new Point3d(coordinate.x + radiusSI * Math.cos(endAngle - Math.PI / 2.0), coordinate.y + radiusSI
1045 * Math.sin(endAngle - Math.PI / 2.0), 0.0);
1046 linkTag.arcTag.startAngle = endAngle + Math.PI / 2.0 + angle;
1047 coordinate.x = linkTag.arcTag.center.x + radiusSI * Math.cos(linkTag.arcTag.startAngle);
1048 coordinate.y = linkTag.arcTag.center.y + radiusSI * Math.sin(linkTag.arcTag.startAngle);
1049 nodeTag.angle =
1050 new DoubleScalar.Abs<AnglePlaneUnit>(norm(linkTag.arcTag.startAngle - Math.PI / 2.0),
1051 AnglePlaneUnit.SI);
1052 }
1053 coordinate.z -= lengthSI * Math.sin(slope);
1054 nodeTag.coordinate = coordinate;
1055 nodeTag.slope = new DoubleScalar.Abs<AngleSlopeUnit>(slope, AngleSlopeUnit.SI);
1056 @SuppressWarnings("rawtypes")
1057 Node node = makeNode(this.nodeClass, nodeTag);
1058 linkTag.nodeFrom = node;
1059 }
1060 }
1061
1062 }
1063
1064
1065
1066
1067
1068
1069
1070 private double norm(final double angle)
1071 {
1072 double normalized = angle % (2 * Math.PI);
1073 if (normalized < 0.0)
1074 {
1075 normalized += 2 * Math.PI;
1076 }
1077 return normalized;
1078 }
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088 @SuppressWarnings({"unchecked", "rawtypes"})
1089 protected final CrossSectionLink makeLink(final LinkTag linkTag) throws SAXException, RemoteException, NamingException
1090 {
1091 try
1092 {
1093 if (LinkGeotools.class.isAssignableFrom(this.linkClass))
1094 {
1095 Object id = makeId(this.linkIdClass, linkTag.name);
1096 DoubleScalar.Rel<LengthUnit> length = null;
1097 LinearGeometry geometry = null;
1098 int points = 2;
1099 if (linkTag.arcTag != null)
1100 {
1101 points = (Math.abs(linkTag.arcTag.angle.getSI()) <= Math.PI / 2.0) ? 32 : 64;
1102 }
1103 NodeTag from = this.nodeTags.get(linkTag.nodeFromName);
1104 NodeTag to = this.nodeTags.get(linkTag.nodeToName);
1105 Coordinate[] coordinates = new Coordinate[points];
1106 coordinates[0] = new Coordinate(from.coordinate.x, from.coordinate.y, from.coordinate.z);
1107 coordinates[coordinates.length - 1] = new Coordinate(to.coordinate.x, to.coordinate.y, to.coordinate.z);
1108 if (linkTag.straightTag != null)
1109 {
1110 length = linkTag.straightTag.length;
1111 }
1112 else if (linkTag.arcTag != null)
1113 {
1114 length =
1115 new DoubleScalar.Rel<LengthUnit>(linkTag.arcTag.radius.getInUnit() * linkTag.arcTag.angle.getSI(),
1116 linkTag.arcTag.radius.getUnit());
1117 double angleStep = linkTag.arcTag.angle.getSI() / points;
1118 double slopeStep = (to.coordinate.z - from.coordinate.z) / points;
1119 double radiusSI = linkTag.arcTag.radius.getSI();
1120 if (linkTag.arcTag.direction.equals(ArcDirection.RIGHT))
1121 {
1122 for (int p = 1; p < points - 1; p++)
1123 {
1124 coordinates[p] =
1125 new Coordinate(linkTag.arcTag.center.x + radiusSI
1126 * Math.cos(linkTag.arcTag.startAngle - angleStep * p), linkTag.arcTag.center.y
1127 + radiusSI * Math.sin(linkTag.arcTag.startAngle - angleStep * p), from.coordinate.z
1128 + slopeStep * p);
1129 }
1130 }
1131 else
1132 {
1133 for (int p = 1; p < points - 1; p++)
1134 {
1135 coordinates[p] =
1136 new Coordinate(linkTag.arcTag.center.x + radiusSI
1137 * Math.cos(linkTag.arcTag.startAngle + angleStep * p), linkTag.arcTag.center.y
1138 + radiusSI * Math.sin(linkTag.arcTag.startAngle + angleStep * p), from.coordinate.z
1139 + slopeStep * p);
1140 }
1141 }
1142 }
1143 CrossSectionLink link =
1144 new CrossSectionLink(id, (NodeGeotools) linkTag.nodeFrom, (NodeGeotools) linkTag.nodeTo, length);
1145 GeometryFactory factory = new GeometryFactory();
1146 LineString lineString = factory.createLineString(coordinates);
1147 geometry = new LinearGeometry(link, lineString, null);
1148 link.setGeometry(geometry);
1149 return link;
1150 }
1151 else
1152 {
1153 throw new SAXException("Parsing network. Link class " + this.linkClass.getName() + ": cannot instantiate.");
1154 }
1155 }
1156 catch (NetworkException ne)
1157 {
1158 throw new SAXException("Error building Link", ne);
1159 }
1160 }
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 @SuppressWarnings({"rawtypes", "checkstyle:methodlength"})
1173 protected final List<CrossSectionElement> parseElements(final String elements, final CrossSectionLink csl,
1174 final LinkTag linkTag, final GlobalTag globalTag) throws SAXException, RemoteException, NamingException
1175 {
1176 List<CrossSectionElement> cseList = new ArrayList<>();
1177 List<RoadMarkerAlong> roadMarkers = new ArrayList<>();
1178 String[] nameStrings = elements.split("(\\-)|(\\|)|(\\:)|(\\<)|(\\>)|(\\#)");
1179 List<String> names = new ArrayList<>();
1180 for (String s : nameStrings)
1181 {
1182 if (s.length() > 0)
1183 {
1184 names.add(s);
1185 }
1186 }
1187 List<Double> widthsSI = new ArrayList<>();
1188 int designIndex = -1;
1189 int i = -1;
1190 for (String name : names)
1191 {
1192 i++;
1193 if (name.equals("D"))
1194 {
1195 widthsSI.add(0.0);
1196 designIndex = i;
1197 }
1198 else
1199 {
1200 LaneTag laneTag = linkTag.laneTags.get(name);
1201 if (laneTag == null)
1202 {
1203 laneTag = new LaneTag();
1204 laneTag.name = name;
1205 linkTag.laneTags.put(laneTag.name, laneTag);
1206 }
1207 if (laneTag.width != null)
1208 {
1209 widthsSI.add(laneTag.width.getSI());
1210 }
1211 else if (linkTag.width != null)
1212 {
1213 widthsSI.add(linkTag.width.getSI());
1214 }
1215 else if (globalTag != null && globalTag.width != null)
1216 {
1217 widthsSI.add(globalTag.width.getSI());
1218 }
1219 else
1220 {
1221 throw new SAXException("width not set for lane type in " + elements + ": " + name.charAt(0));
1222 }
1223 }
1224 }
1225
1226
1227 double[] offsetSI = new double[widthsSI.size()];
1228 double cumSI = 0.0;
1229 for (int j = designIndex; j >= 0; j--)
1230 {
1231 offsetSI[j] = cumSI;
1232 cumSI = cumSI - widthsSI.get(j) / 2.0 - ((j > 0) ? widthsSI.get(j - 1) / 2.0 : 0.0);
1233 }
1234 cumSI = 0.0;
1235 for (int j = designIndex; j < widthsSI.size(); j++)
1236 {
1237 offsetSI[j] = cumSI;
1238 cumSI = cumSI + widthsSI.get(j) / 2.0 + ((j < widthsSI.size() - 1) ? widthsSI.get(j + 1) / 2.0 : 0.0);
1239 }
1240
1241 i = -1;
1242 for (String name : names)
1243 {
1244 if (name.length() > 0)
1245 {
1246 i++;
1247 LongitudinalDirectionality ld = null;
1248 if (name.startsWith("A"))
1249 {
1250 ld = LongitudinalDirectionality.FORWARD;
1251 }
1252 else if (name.startsWith("V"))
1253 {
1254 ld = LongitudinalDirectionality.BACKWARD;
1255 }
1256 else if (name.startsWith("B"))
1257 {
1258 ld = LongitudinalDirectionality.BOTH;
1259 }
1260 else if (name.startsWith("X"))
1261 {
1262 ld = LongitudinalDirectionality.NONE;
1263 }
1264 else if (name.startsWith("S"))
1265 {
1266 ld = LongitudinalDirectionality.NONE;
1267 }
1268 else if (name.equals("D"))
1269 {
1270 ld = LongitudinalDirectionality.NONE;
1271 }
1272 else
1273 {
1274 throw new SAXException("unknown lane type in " + elements + ": " + name.charAt(0));
1275 }
1276
1277 try
1278 {
1279 if (ld.equals(LongitudinalDirectionality.NONE))
1280 {
1281 if (name.startsWith("S"))
1282 {
1283 Shoulder shoulder =
1284 new Shoulder(csl, new DoubleScalar.Rel<LengthUnit>(offsetSI[i], LengthUnit.SI),
1285 new DoubleScalar.Rel<LengthUnit>(widthsSI.get(i), LengthUnit.SI),
1286 new DoubleScalar.Rel<LengthUnit>(widthsSI.get(i), LengthUnit.SI));
1287 linkTag.laneTags.get(name).cse = shoulder;
1288 cseList.add(shoulder);
1289 if (this.simulator != null)
1290 {
1291 new ShoulderAnimation(shoulder, this.simulator);
1292 }
1293 }
1294 else if (name.startsWith("X"))
1295 {
1296 Lane lane =
1297 new NoTrafficLane(csl, new DoubleScalar.Rel<LengthUnit>(offsetSI[i], LengthUnit.SI),
1298 new DoubleScalar.Rel<LengthUnit>(offsetSI[i], LengthUnit.SI),
1299 new DoubleScalar.Rel<LengthUnit>(widthsSI.get(i), LengthUnit.SI),
1300 new DoubleScalar.Rel<LengthUnit>(widthsSI.get(i), LengthUnit.SI), this.laneType, ld,
1301 new DoubleScalar.Abs<FrequencyUnit>(0.0, FrequencyUnit.PER_HOUR));
1302 linkTag.laneTags.get(name).cse = lane;
1303 cseList.add(lane);
1304 if (this.simulator != null)
1305 {
1306 new LaneAnimation(lane, this.simulator, Color.LIGHT_GRAY);
1307 }
1308 }
1309 }
1310 else
1311 {
1312 Lane lane =
1313 new Lane(csl, new DoubleScalar.Rel<LengthUnit>(offsetSI[i], LengthUnit.SI),
1314 new DoubleScalar.Rel<LengthUnit>(offsetSI[i], LengthUnit.SI),
1315 new DoubleScalar.Rel<LengthUnit>(widthsSI.get(i), LengthUnit.SI),
1316 new DoubleScalar.Rel<LengthUnit>(widthsSI.get(i), LengthUnit.SI), this.laneType, ld,
1317 new DoubleScalar.Abs<FrequencyUnit>(Double.MAX_VALUE, FrequencyUnit.PER_HOUR));
1318 linkTag.laneTags.get(name).cse = lane;
1319 cseList.add(lane);
1320 if (this.simulator != null)
1321 {
1322 new LaneAnimation(lane, this.simulator, Color.GRAY);
1323 }
1324 }
1325 }
1326 catch (NetworkException ne)
1327 {
1328 throw new SAXException(ne);
1329 }
1330 }
1331 }
1332 return cseList;
1333 }
1334
1335
1336
1337
1338
1339 protected final GTUType<String> parseGTUType(final String typeName)
1340 {
1341 if (!this.gtuTypes.containsKey(typeName))
1342 {
1343 GTUType<String> gtuType = new GTUType<>(typeName);
1344 this.gtuTypes.put(typeName, gtuType);
1345 }
1346 return this.gtuTypes.get(typeName);
1347 }
1348
1349
1350
1351
1352
1353
1354
1355 protected final GTUFollowingModel parseFollowingModel(final String modelName) throws NetworkException
1356 {
1357 if (modelName.equals("IDM"))
1358 {
1359 return new IDM();
1360 }
1361 else if (modelName.equals("IDM+"))
1362 {
1363 return new IDMPlus();
1364 }
1365 throw new NetworkException("Unknown GTU following model: " + modelName);
1366 }
1367
1368
1369
1370
1371
1372
1373
1374 protected final LaneChangeModel parseLaneChangeModel(final String modelName) throws NetworkException
1375 {
1376 if (modelName.equals("EGOISTIC"))
1377 {
1378 return new Egoistic();
1379 }
1380 else if (modelName.equals("ALTRUISTIC"))
1381 {
1382 return new Altruistic();
1383 }
1384 throw new NetworkException("Unknown lane change model: " + modelName);
1385 }
1386
1387
1388
1389
1390
1391
1392 protected final Point3d parseCoordinate(final String cs)
1393 {
1394 String c = cs.replace("(", "");
1395 c = c.replace(")", "");
1396 String[] cc = c.split(",");
1397 double x = Double.parseDouble(cc[0]);
1398 double y = Double.parseDouble(cc[1]);
1399 double z = cc.length > 2 ? Double.parseDouble(cc[1]) : 0.0;
1400 return new Point3d(x, y, z);
1401 }
1402
1403
1404
1405
1406
1407
1408 private String parseSpeedUnit(final String s) throws NetworkException
1409 {
1410 String u = null;
1411 for (String us : SPEED_UNITS.keySet())
1412 {
1413 if (s.toString().contains(us))
1414 {
1415 u = us;
1416 }
1417 }
1418 if (u == null)
1419 {
1420 throw new NetworkException("Parsing network: cannot instantiate speed unit in: " + s);
1421 }
1422 return u;
1423 }
1424
1425
1426
1427
1428
1429
1430 protected final DoubleScalar.Abs<SpeedUnit> parseSpeedAbs(final String s) throws NetworkException
1431 {
1432 String us = parseSpeedUnit(s);
1433 SpeedUnit u = SPEED_UNITS.get(us);
1434 String sv = s.substring(0, s.indexOf(us));
1435 try
1436 {
1437 double value = Double.parseDouble(sv);
1438 return new DoubleScalar.Abs<SpeedUnit>(value, u);
1439 }
1440 catch (NumberFormatException nfe)
1441 {
1442 throw new NetworkException("Parsing network: cannot instantiate scalar: " + s, nfe);
1443 }
1444 }
1445
1446
1447
1448
1449
1450
1451 protected final DoubleScalar.Rel<SpeedUnit> parseSpeedRel(final String s) throws NetworkException
1452 {
1453 String us = parseSpeedUnit(s);
1454 SpeedUnit u = SPEED_UNITS.get(us);
1455 String sv = s.substring(0, s.indexOf(us));
1456 try
1457 {
1458 double value = Double.parseDouble(sv);
1459 return new DoubleScalar.Rel<SpeedUnit>(value, u);
1460 }
1461 catch (NumberFormatException nfe)
1462 {
1463 throw new NetworkException("Parsing network: cannot instantiate scalar: " + s, nfe);
1464 }
1465 }
1466
1467
1468
1469
1470
1471
1472 private String parseLengthUnit(final String s) throws NetworkException
1473 {
1474 String u = null;
1475 for (String us : LENGTH_UNITS.keySet())
1476 {
1477 if (s.toString().contains(us))
1478 {
1479 u = us;
1480 }
1481 }
1482 if (u == null)
1483 {
1484 throw new NetworkException("Parsing network: cannot instantiate length unit in: " + s);
1485 }
1486 return u;
1487 }
1488
1489
1490
1491
1492
1493
1494 protected final DoubleScalar.Abs<LengthUnit> parseLengthAbs(final String s) throws NetworkException
1495 {
1496 String us = parseLengthUnit(s);
1497 LengthUnit u = LENGTH_UNITS.get(us);
1498 String sv = s.substring(0, s.indexOf(us));
1499 try
1500 {
1501 double value = Double.parseDouble(sv);
1502 return new DoubleScalar.Abs<LengthUnit>(value, u);
1503 }
1504 catch (NumberFormatException nfe)
1505 {
1506 throw new NetworkException("Parsing network: cannot instantiate scalar: " + s, nfe);
1507 }
1508 }
1509
1510
1511
1512
1513
1514
1515 protected final DoubleScalar.Rel<LengthUnit> parseLengthRel(final String s) throws NetworkException
1516 {
1517 String us = parseLengthUnit(s);
1518 LengthUnit u = LENGTH_UNITS.get(us);
1519 String sv = s.substring(0, s.indexOf(us));
1520 try
1521 {
1522 double value = Double.parseDouble(sv);
1523 return new DoubleScalar.Rel<LengthUnit>(value, u);
1524 }
1525 catch (NumberFormatException nfe)
1526 {
1527 throw new NetworkException("Parsing network: cannot instantiate scalar: " + s, nfe);
1528 }
1529 }
1530
1531
1532
1533
1534
1535
1536 private String parseTimeUnit(final String s) throws NetworkException
1537 {
1538 String u = null;
1539 for (String us : TIME_UNITS.keySet())
1540 {
1541 if (s.toString().contains(us))
1542 {
1543 u = us;
1544 }
1545 }
1546 if (u == null)
1547 {
1548 throw new NetworkException("Parsing network: cannot instantiate time unit in: " + s);
1549 }
1550 return u;
1551 }
1552
1553
1554
1555
1556
1557
1558 protected final DoubleScalar.Abs<TimeUnit> parseTimeAbs(final String s) throws NetworkException
1559 {
1560 String us = parseTimeUnit(s);
1561 TimeUnit u = TIME_UNITS.get(us);
1562 String sv = s.substring(0, s.indexOf(us));
1563 try
1564 {
1565 double value = Double.parseDouble(sv);
1566 return new DoubleScalar.Abs<TimeUnit>(value, u);
1567 }
1568 catch (NumberFormatException nfe)
1569 {
1570 throw new NetworkException("Parsing network: cannot instantiate scalar: " + s, nfe);
1571 }
1572 }
1573
1574
1575
1576
1577
1578
1579 protected final DoubleScalar.Rel<TimeUnit> parseTimeRel(final String s) throws NetworkException
1580 {
1581 String us = parseTimeUnit(s);
1582 TimeUnit u = TIME_UNITS.get(us);
1583 String sv = s.substring(0, s.indexOf(us));
1584 try
1585 {
1586 double value = Double.parseDouble(sv);
1587 return new DoubleScalar.Rel<TimeUnit>(value, u);
1588 }
1589 catch (NumberFormatException nfe)
1590 {
1591 throw new NetworkException("Parsing network: cannot instantiate scalar: " + s, nfe);
1592 }
1593 }
1594
1595
1596
1597
1598
1599
1600 private double[] parseDoubleArgs(final String s)
1601 {
1602 String[] ss = s.split(",");
1603 double[] d = new double[ss.length];
1604 for (int i = 0; i < ss.length; i++)
1605 {
1606 d[i] = Double.parseDouble(ss[i]);
1607 }
1608 return d;
1609 }
1610
1611
1612 private static final StreamInterface STREAM = new MersenneTwister();
1613
1614
1615
1616
1617
1618
1619
1620
1621 private DistContinuous makeDistContinuous(final String ds, final double[] args) throws NetworkException
1622 {
1623 try
1624 {
1625 switch (ds)
1626 {
1627 case "CONST":
1628 case "CONSTANT":
1629 return new DistConstant(STREAM, args[0]);
1630
1631 case "EXPO":
1632 case "EXPONENTIAL":
1633 return new DistExponential(STREAM, args[0]);
1634
1635 case "TRIA":
1636 case "TRIANGULAR":
1637 return new DistTriangular(STREAM, args[0], args[1], args[2]);
1638
1639 case "NORM":
1640 case "NORMAL":
1641 return new DistNormal(STREAM, args[0], args[1]);
1642
1643 case "BETA":
1644 return new DistBeta(STREAM, args[0], args[1]);
1645
1646 case "ERLANG":
1647 return new DistErlang(STREAM, (int) args[0], args[1]);
1648
1649 case "GAMMA":
1650 return new DistGamma(STREAM, args[0], args[1]);
1651
1652 case "LOGN":
1653 case "LOGNORMAL":
1654 return new DistLogNormal(STREAM, args[0], args[1]);
1655
1656 case "PEARSON5":
1657 return new DistPearson5(STREAM, args[0], args[1]);
1658
1659 case "PEARSON6":
1660 return new DistPearson6(STREAM, args[0], args[1], args[2]);
1661
1662 case "UNIF":
1663 case "UNIFORM":
1664 return new DistUniform(STREAM, args[0], args[1]);
1665
1666 case "WEIB":
1667 case "WEIBULL":
1668 return new DistWeibull(STREAM, args[0], args[1]);
1669
1670 default:
1671 throw new NetworkException("makeDistContinuous - unknown distribution function " + ds);
1672 }
1673 }
1674 catch (IndexOutOfBoundsException e)
1675 {
1676 throw new NetworkException("makeDistContinuous - wrong number of parameters for distribution function " + ds);
1677 }
1678 }
1679
1680
1681
1682
1683
1684
1685
1686 protected final DistContinuousDoubleScalar.Rel<LengthUnit> parseLengthDistRel(final String s) throws NetworkException
1687 {
1688 String[] s1 = s.split("\\(");
1689 String ds = s1[0];
1690 String[] s2 = s1[1].split("\\)");
1691 String unit = parseLengthUnit(s2[1]);
1692 double[] args = parseDoubleArgs(s2[0]);
1693 DistContinuous dist = makeDistContinuous(ds, args);
1694 return new DistContinuousDoubleScalar.Rel<LengthUnit>(dist, LENGTH_UNITS.get(unit));
1695 }
1696
1697
1698
1699
1700
1701
1702
1703 protected final DistContinuousDoubleScalar.Abs<LengthUnit> parseLengthDistAbs(final String s) throws NetworkException
1704 {
1705 String[] s1 = s.split("\\(");
1706 String ds = s1[0];
1707 String[] s2 = s1[1].split("\\)");
1708 String unit = parseLengthUnit(s2[1]);
1709 double[] args = parseDoubleArgs(s2[0]);
1710 DistContinuous dist = makeDistContinuous(ds, args);
1711 return new DistContinuousDoubleScalar.Abs<LengthUnit>(dist, LENGTH_UNITS.get(unit));
1712 }
1713
1714
1715
1716
1717
1718
1719
1720 protected final DistContinuousDoubleScalar.Rel<TimeUnit> parseTimeDistRel(final String s) throws NetworkException
1721 {
1722 String[] s1 = s.split("\\(");
1723 String ds = s1[0];
1724 String[] s2 = s1[1].split("\\)");
1725 String unit = parseTimeUnit(s2[1]);
1726 double[] args = parseDoubleArgs(s2[0]);
1727 DistContinuous dist = makeDistContinuous(ds, args);
1728 return new DistContinuousDoubleScalar.Rel<TimeUnit>(dist, TIME_UNITS.get(unit));
1729 }
1730
1731
1732
1733
1734
1735
1736
1737 protected final DistContinuousDoubleScalar.Abs<TimeUnit> parseTimeDistAbs(final String s) throws NetworkException
1738 {
1739 String[] s1 = s.split("\\(");
1740 String ds = s1[0];
1741 String[] s2 = s1[1].split("\\)");
1742 String unit = parseTimeUnit(s2[1]);
1743 double[] args = parseDoubleArgs(s2[0]);
1744 DistContinuous dist = makeDistContinuous(ds, args);
1745 return new DistContinuousDoubleScalar.Abs<TimeUnit>(dist, TIME_UNITS.get(unit));
1746 }
1747
1748
1749
1750
1751
1752
1753
1754 protected final DistContinuousDoubleScalar.Rel<SpeedUnit> parseSpeedDistRel(final String s) throws NetworkException
1755 {
1756 String[] s1 = s.split("\\(");
1757 String ds = s1[0];
1758 String[] s2 = s1[1].split("\\)");
1759 String unit = parseSpeedUnit(s2[1]);
1760 double[] args = parseDoubleArgs(s2[0]);
1761 DistContinuous dist = makeDistContinuous(ds, args);
1762 return new DistContinuousDoubleScalar.Rel<SpeedUnit>(dist, SPEED_UNITS.get(unit));
1763 }
1764
1765
1766
1767
1768
1769
1770
1771 protected final DistContinuousDoubleScalar.Abs<SpeedUnit> parseSpeedDistAbs(final String s) throws NetworkException
1772 {
1773 String[] s1 = s.split("\\(");
1774 String ds = s1[0];
1775 String[] s2 = s1[1].split("\\)");
1776 String unit = parseSpeedUnit(s2[1]);
1777 double[] args = parseDoubleArgs(s2[0]);
1778 DistContinuous dist = makeDistContinuous(ds, args);
1779 return new DistContinuousDoubleScalar.Abs<SpeedUnit>(dist, SPEED_UNITS.get(unit));
1780 }
1781
1782
1783
1784
1785
1786
1787 @SuppressWarnings("checkstyle:visibilitymodifier")
1788 protected class GlobalTag
1789 {
1790
1791 protected DoubleScalar.Abs<SpeedUnit> speed = null;
1792
1793
1794 protected DoubleScalar.Rel<LengthUnit> width = null;
1795 }
1796
1797
1798 @SuppressWarnings("checkstyle:visibilitymodifier")
1799 protected class LinkTag
1800 {
1801
1802 protected String name;
1803
1804
1805 protected DoubleScalar.Abs<SpeedUnit> speed = null;
1806
1807
1808 protected DoubleScalar.Rel<LengthUnit> width = null;
1809
1810
1811 @SuppressWarnings("rawtypes")
1812 protected Node nodeFrom = null;
1813
1814
1815 @SuppressWarnings("rawtypes")
1816 protected Node nodeTo = null;
1817
1818
1819 protected String nodeFromName = null;
1820
1821
1822 protected String nodeToName = null;
1823
1824
1825 protected String elements = null;
1826
1827
1828 protected Map<String, LaneTag> laneTags = new HashMap<>();
1829
1830
1831 protected StraightTag straightTag = null;
1832
1833
1834 protected ArcTag arcTag = null;
1835 }
1836
1837
1838 @SuppressWarnings("checkstyle:visibilitymodifier")
1839 protected class LaneTag
1840 {
1841
1842 protected String name;
1843
1844
1845 protected DoubleScalar.Abs<SpeedUnit> speed = null;
1846
1847
1848 protected DoubleScalar.Rel<LengthUnit> width = null;
1849
1850
1851 protected Set<GeneratorTag> generatorTags = new HashSet<>();
1852
1853
1854 protected Set<FillTag> fillTags = new HashSet<>();
1855
1856
1857 protected CrossSectionElement cse = null;
1858 }
1859
1860
1861 @SuppressWarnings("checkstyle:visibilitymodifier")
1862 protected class ArcTag
1863 {
1864
1865 protected DoubleScalar.Abs<AnglePlaneUnit> angle = null;
1866
1867
1868 protected DoubleScalar.Rel<LengthUnit> radius = null;
1869
1870
1871 protected ArcDirection direction = null;
1872
1873
1874 protected Point3d center;
1875
1876
1877 protected double startAngle;
1878 }
1879
1880
1881 @SuppressWarnings("checkstyle:visibilitymodifier")
1882 protected class StraightTag
1883 {
1884
1885 protected DoubleScalar.Rel<LengthUnit> length = null;
1886 }
1887
1888
1889 @SuppressWarnings("checkstyle:visibilitymodifier")
1890 protected class NodeTag
1891 {
1892
1893 String name = null;
1894
1895
1896 Point3d coordinate = null;
1897
1898
1899 DoubleScalar.Abs<AnglePlaneUnit> angle = null;
1900
1901
1902 DoubleScalar.Abs<AngleSlopeUnit> slope = null;
1903 }
1904
1905
1906 protected enum ArcDirection
1907 {
1908
1909 LEFT,
1910
1911 RIGHT;
1912 }
1913
1914
1915 @SuppressWarnings("checkstyle:visibilitymodifier")
1916 protected class GTUTag
1917 {
1918
1919 protected String name;
1920
1921
1922 protected GTUType<String> gtuType = null;
1923
1924
1925 protected DistContinuousDoubleScalar.Rel<LengthUnit> lengthDist = null;
1926
1927
1928 protected DistContinuousDoubleScalar.Rel<LengthUnit> widthDist = null;
1929
1930
1931 protected GTUFollowingModel followingModel = null;
1932
1933
1934 protected LaneChangeModel laneChangeModel = null;
1935
1936
1937 protected DistContinuousDoubleScalar.Abs<SpeedUnit> maxSpeedDist = null;
1938 }
1939
1940
1941 @SuppressWarnings("checkstyle:visibilitymodifier")
1942 protected class GeneratorTag
1943 {
1944
1945 protected LaneTag laneTag = null;
1946
1947
1948 protected GTUTag gtuTag = null;
1949
1950
1951 protected DistContinuousDoubleScalar.Rel<TimeUnit> iatDist = null;
1952
1953
1954 protected DistContinuousDoubleScalar.Abs<SpeedUnit> initialSpeedDist = null;
1955
1956
1957 protected int maxGTUs = Integer.MAX_VALUE;
1958
1959
1960 protected DoubleScalar.Abs<TimeUnit> startTime = null;
1961
1962
1963 protected DoubleScalar.Abs<TimeUnit> endTime = null;
1964 }
1965
1966
1967 @SuppressWarnings("checkstyle:visibilitymodifier")
1968 protected class FillTag
1969 {
1970
1971 protected LaneTag laneTag = null;
1972
1973
1974 protected GTUTag gtuTag = null;
1975
1976
1977 protected DistContinuousDoubleScalar.Rel<LengthUnit> distanceDist = null;
1978
1979
1980 protected DistContinuousDoubleScalar.Abs<SpeedUnit> initialSpeedDist = null;
1981
1982
1983 protected int maxGTUs = Integer.MAX_VALUE;
1984 }
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994 public static void main(final String[] args) throws NetworkException, ParserConfigurationException, SAXException,
1995 IOException
1996 {
1997 URL url = URLResource.getResource("/ots-infra-example.xml");
1998 XmlNetworkLaneParser nlp =
1999 new XmlNetworkLaneParser(String.class, NodeGeotools.class, String.class, Coordinate.class, LinkGeotools.class,
2000 String.class, null);
2001 Network n = nlp.build(url.openStream());
2002 }
2003 }