View Javadoc
1   package org.opentrafficsim.road.network.factory.vissim;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.Serializable;
6   import java.net.URL;
7   import java.util.HashMap;
8   import java.util.Map;
9   import java.util.Map.Entry;
10  
11  import javax.naming.NamingException;
12  import javax.xml.parsers.DocumentBuilder;
13  import javax.xml.parsers.DocumentBuilderFactory;
14  import javax.xml.parsers.ParserConfigurationException;
15  
16  import org.locationtech.jts.geom.LineString;
17  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
18  import org.opentrafficsim.core.geometry.OTSGeometryException;
19  import org.opentrafficsim.core.geometry.OTSLine3D;
20  import org.opentrafficsim.core.gtu.GTUException;
21  import org.opentrafficsim.core.gtu.GTUType;
22  import org.opentrafficsim.core.network.NetworkException;
23  import org.opentrafficsim.road.network.OTSRoadNetwork;
24  import org.opentrafficsim.road.network.lane.LaneType;
25  import org.w3c.dom.Document;
26  import org.w3c.dom.NodeList;
27  import org.xml.sax.SAXException;
28  
29  import nl.tudelft.simulation.dsol.SimRuntimeException;
30  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
31  
32  /**
33   * <p>
34   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
35   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
36   * <p>
37   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
38   * initial version Jul 23, 2015 <br>
39   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
40   */
41  public class VissimNetworkLaneParser implements Serializable
42  {
43      /** */
44      private static final long serialVersionUID = 20150723L;
45  
46      /** Global values from the GLOBAL tag. */
47      private GlobalTag globalTag;
48  
49      /** The UNprocessed links for further reference. */
50      private Map<String, NodeTag> nodeTags = new HashMap<>();
51  
52      /** The UNprocessed links for further reference. */
53      private Map<String, LinkTag> linkTags = new HashMap<>();
54  
55      /** The UNprocessed links for further reference. */
56      private Map<String, LinkTag> connectorTags = new HashMap<>();
57  
58      /** The UNprocessed links for further reference. */
59      private Map<String, LinkTag> realLinkTags = new HashMap<>();
60  
61      /** The UNprocessed links for further reference. */
62      private Map<String, SignalHeadTag> signalHeadTags = new HashMap<>();
63  
64      /** The UNprocessed links for further reference. */
65      private Map<String, SensorTag> sensorTags = new HashMap<>();
66  
67      /** The gtu tags for further reference. */
68      private Map<String, GTUTag> gtuTags = new HashMap<>();
69  
70      /** The gtumix tags for further reference. */
71      private Map<String, GTUMixTag> gtuMixTags = new HashMap<>();
72  
73      /** The road type tags for further reference. */
74      private Map<String, RoadTypeTag> roadTypeTags = new HashMap<>();
75  
76      /** The GTUTypes that have been created. public to make it accessible from LaneAttributes. */
77      private Map<String, GTUType> gtuTypes = new HashMap<>();
78  
79      /** The LaneType tags that have been created. */
80      private Map<String, LaneTypeTag> laneTypeTags = new HashMap<>();
81  
82      /** The LaneType tags that have been created. */
83      private Map<String, RoadLayoutTag> roadLayoutTags = new HashMap<>();
84  
85      /** The RouteMix tags that have been created. */
86      private Map<String, RouteMixTag> routeMixTags = new HashMap<>();
87  
88      /** The RouteMix tags that have been created. */
89      private Map<String, ShortestRouteMixTag> shortestRouteMixTags = new HashMap<>();
90  
91      /** The RouteMix tags that have been created. */
92      private Map<String, ShortestRouteTag> shortestRouteTags = new HashMap<>();
93  
94      /** The RouteMix tags that have been created. */
95      private Map<String, RouteTag> routeTags = new HashMap<>();
96  
97      /** The LaneTypes that have been created. */
98      private Map<String, LaneType> laneTypes = new HashMap<>();
99  
100     /** The simulator for creating the animation. Null if no animation needed. */
101     private OTSSimulatorInterface simulator;
102 
103     /** The network to register the GTUs in. */
104     @SuppressWarnings("visibilitymodifier")
105     protected OTSRoadNetwork network;
106 
107     /*****
108      * Variables, typically for Vissim network import
109      */
110 
111     /** the node number is automatically generated and increases with every additional node. */
112     private int upperNodeNr = 1;
113 
114     /** the node number is automatically generated and increases with every additional node. */
115     private int upperLinkNr = 1;
116 
117     /**
118      * @param simulator OTSSimulatorInterface; the simulator for creating the animation. Null if no animation needed.
119      */
120     public VissimNetworkLaneParser(final OTSSimulatorInterface simulator)
121     {
122         this.simulator = simulator;
123     }
124 
125     /**
126      * @param inputUrl URL; input
127      * @param outputFile File; output file
128      * @param network OTSRoadNetwork; network
129      * @param sinkKillClassName String; name of the sink-sensor class
130      * @param sensorClassName String; name of the sensor class
131      * @param trafficLightName String; name of the trafficLight class
132      * @return the network with Nodes, Links, and Lanes.
133      * @throws NetworkException in case of parsing problems.
134      * @throws SAXException in case of parsing problems.
135      * @throws ParserConfigurationException in case of parsing problems.
136      * @throws IOException in case of file reading problems.
137      * @throws NamingException in case the animation context cannot be found
138      * @throws GTUException in case of a problem with creating the LaneBlock (which is a GTU right now)
139      * @throws OTSGeometryException when construction of a lane contour or offset design line fails
140      * @throws SimRuntimeException when simulator cannot be used to schedule GTU generation
141      */
142     @SuppressWarnings("checkstyle:needbraces")
143     public OTSRoadNetwork build(final URL inputUrl, final File outputFile, final OTSRoadNetwork network,
144             final String sinkKillClassName, final String sensorClassName, final String trafficLightName)
145             throws NetworkException, ParserConfigurationException, SAXException, IOException, NamingException, GTUException,
146             OTSGeometryException, SimRuntimeException
147     {
148         if (inputUrl.getFile().length() > 0 && !(new File(inputUrl.getFile()).exists()))
149         {
150             throw new SAXException("XmlNetworkLaneParser.build: File url.getFile() does not exist");
151         }
152 
153         // starts with the creation of an empty network
154         this.network = network;
155 
156         // prepare for reading the XML document
157         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
158         factory.setNamespaceAware(true);
159         factory.setXIncludeAware(true);
160         DocumentBuilder builder = factory.newDocumentBuilder();
161         Document document = builder.parse(inputUrl.openStream());
162         NodeList networkXMLNodeList = document.getDocumentElement().getChildNodes();
163 
164         // Is it a Vissim network?
165         if (!document.getDocumentElement().getNodeName().equals("network"))
166         {
167             throw new SAXException("XmlNetworkLaneParser.build: XML document does not start with an NETWORK tag, found "
168                     + document.getDocumentElement().getNodeName() + " instead");
169         }
170 
171         // make the GTUTypes ALL and NONE to get started
172         this.gtuTypes.put("ALL", network.getGtuType(GTUType.DEFAULTS.VEHICLE));
173         // this.gtuTypes.put("NONE", GTUType.NONE);
174 
175         // Read the link (and connector) tags and ...
176         // Construct the nodes as Vissim does not use Nodes!!
177         LinkTag.parseLinks(networkXMLNodeList, this);
178 
179         // the signal heads are stored separately. Read them first, connect to links later on
180         SignalHeadTag.parseSignalHead(networkXMLNodeList, this);
181 
182         // the sensor are defined separate also. Read them first, connect to links later on
183         SensorTag.parseSensor(networkXMLNodeList, this);
184 
185         // add the signalHeads to the links
186         LinkTag.addSignalHeads(this);
187 
188         // add the detectors to the links
189         LinkTag.addDetectors(this);
190 
191         // create a subset of connector links
192         for (LinkTag linkTag : this.linkTags.values())
193         {
194             if (linkTag.connector)
195             {
196                 this.connectorTags.put(linkTag.name, linkTag);
197             }
198             else
199             {
200                 this.realLinkTags.put(linkTag.name, linkTag);
201             }
202         }
203 
204         // removes all duplicate nodes, both in Link and Node lists
205         NodeTag.removeDuplicateNodes(this);
206         // Split links where appropriate
207         // Step 1: split links, where a connector intersects a link
208         // loops through all connectors
209         // a link gets split if the connector is more than a "margin" number of meters from the start or end of a link
210         Double margin = 5.0;
211         splitLinksIntersectedByConnector(margin);
212 
213         // create space between connectors and links, in order to make bezier curved links between connectors and links
214         // action: the connectors become shorter than they were
215         // LinkTag.shortenConnectors(this);
216 
217         // Create links to connect the shortened connectors and links by means of bezier curved links
218         createLinkBetweenConnectorAndLink(this);
219 
220         // Step 2: split links directly behind a signal head, assuming such a link enters a signalized junction
221         //
222         Double splitMetersAfterSignalHead = 1.5;
223         margin = 4.0;
224         splitLinkAtSignalAndDetector(this.linkTags, margin, splitMetersAfterSignalHead);
225 
226         // remove double links with the same start and end node
227         HashMap<String, LinkTag> removeConnectorTags = new HashMap<>();
228         removeDoubleConnectors(removeConnectorTags);
229 
230         // build links
231         for (LinkTag linkTag : this.linkTags.values())
232         {
233             Links.buildLink(linkTag, this, this.simulator);
234         }
235 
236         // Generate the real links
237         for (LinkTag realLinkTag : this.linkTags.values())
238         {
239             Links.applyRoadTypeToLink(realLinkTag, this, this.simulator);
240         }
241 
242         // Generate sink/kill sensors at the links that have no further connections (dead-walking)
243         for (LinkTag realLinkTag : this.linkTags.values())
244         {
245             Links.createSinkSensor(realLinkTag, this, this.simulator);
246         }
247 
248         // generate the connector links
249         for (LinkTag connectorTag : this.linkTags.values())
250         {
251             Links.applyRoadTypeToConnector(connectorTag, this, this.simulator);
252         }
253 
254         NodeTag.removeRedundantNodeTags(this);
255 
256         // process the routes
257         // for (RouteTag routeTag : this.routeTags.values())
258         // routeTag.makeRoute();
259         // TODO shortestRoute, routeMix, ShortestRouteMix
260 
261         // store the structure information in the network
262         XMLNetworkWriter.writeToXML(outputFile, linkTags, nodeTags, sinkKillClassName, sensorClassName, trafficLightName);
263 
264         return makeNetwork();
265     }
266 
267     private void removeDoubleConnectors(HashMap<String, LinkTag> removeConnectorTags)
268     {
269         for (LinkTag linkTag : this.connectorTags.values())
270         {
271             for (LinkTag linkTag2 : this.connectorTags.values())
272             {
273                 if (linkTag.nodeStartTag.name.equals(linkTag2.nodeStartTag.name)
274                         && linkTag.nodeEndTag.name.equals(linkTag2.nodeEndTag.name) && !linkTag.equals(linkTag2))
275                 {
276                     removeConnectorTags.put(linkTag.nodeStartTag.name + linkTag.nodeEndTag.name, linkTag);
277                 }
278             }
279         }
280         for (Entry<String, LinkTag> entry : removeConnectorTags.entrySet())
281         {
282             connectorTags.remove(entry.getValue().name);
283             linkTags.remove(entry.getValue().name);
284         }
285     }
286 
287     /**
288      * @param parser VissimNetworkLaneParser;
289      * @throws OTSGeometryException
290      */
291     private void createLinkBetweenConnectorAndLink(final VissimNetworkLaneParser parser) throws OTSGeometryException
292     {
293         // loop through all connector links
294         for (LinkTag connectorLinkTag : this.connectorTags.values())
295         {
296 
297             OTSLine3D designLineOTS = LinkTag.createLineString(connectorLinkTag);
298             LineString designLine = designLineOTS.getLineString();
299             Double length = designLine.getLength();
300             // default: we replace the connector link by a bezier curved link
301             if (length < 999995)
302             {
303                 connectorLinkTag.nodeStartTag = parser.nodeTags.get(connectorLinkTag.connectorTag.fromNodeName);
304                 connectorLinkTag.nodeEndTag = parser.nodeTags.get(connectorLinkTag.connectorTag.toNodeName);
305                 connectorLinkTag.bezierTag = new BezierTag();
306                 if (connectorLinkTag.nodeStartTag.name.equals(connectorLinkTag.nodeEndTag.name))
307                 {
308                     this.linkTags.remove(connectorLinkTag.name);
309                     // this.connectorTags.remove(connectorLinkTag.name);
310                 }
311                 if (connectorLinkTag.polyLineTag != null)
312                 {
313                     connectorLinkTag.polyLineTag = null;
314                 }
315                 if (connectorLinkTag.straightTag != null)
316                 {
317                     connectorLinkTag.straightTag = null;
318                 }
319             }
320             // if the link is quite long....we could split it but we don't do this now
321             // so the next block is inactive!!!
322             else
323             {
324                 // get the from link
325                 LinkTag pasteLinkFromTag = new LinkTag(connectorLinkTag);
326                 // add a unique name
327                 String linkName = "" + parser.upperLinkNr;
328                 parser.upperLinkNr++;
329                 pasteLinkFromTag.name = linkName;
330                 pasteLinkFromTag.nodeStartTag = parser.nodeTags.get(connectorLinkTag.connectorTag.fromNodeName);
331                 pasteLinkFromTag.nodeEndTag = connectorLinkTag.nodeStartTag;
332                 pasteLinkFromTag.bezierTag = new BezierTag();
333                 if (pasteLinkFromTag.polyLineTag != null)
334                 {
335                     pasteLinkFromTag.polyLineTag = null;
336                 }
337                 if (pasteLinkFromTag.straightTag != null)
338                 {
339                     pasteLinkFromTag.straightTag = null;
340                 }
341                 // this.linkTags.put(pasteLinkFromTag.name, pasteLinkFromTag);
342 
343                 // get the To link
344                 LinkTag pasteLinkToTag = new LinkTag(connectorLinkTag);
345                 linkName = "" + parser.upperLinkNr;
346                 parser.upperLinkNr++;
347                 pasteLinkToTag.name = linkName;
348                 pasteLinkToTag.nodeStartTag = connectorLinkTag.nodeEndTag;
349                 pasteLinkToTag.nodeEndTag = parser.nodeTags.get(connectorLinkTag.connectorTag.toNodeName);
350 
351                 pasteLinkToTag.bezierTag = new BezierTag();
352                 if (pasteLinkToTag.polyLineTag != null)
353                 {
354                     pasteLinkToTag.polyLineTag = null;
355                 }
356                 if (pasteLinkToTag.straightTag != null)
357                 {
358                     pasteLinkToTag.straightTag = null;
359                 }
360                 // this.linkTags.put(pasteLinkToTag.name, pasteLinkToTag);
361 
362             }
363             // }
364         }
365     }
366 
367     private void splitLinkAtSignalAndDetector(Map<String, LinkTag> inputLinkTags, Double margin,
368             Double splitMetersAfterSignalHead) throws OTSGeometryException, NetworkException
369     {
370 
371         Map<String, LinkTag> newLinkTags = new HashMap<>();
372         // Loops through all links
373         splitLinksAtSignal(margin, splitMetersAfterSignalHead, inputLinkTags, newLinkTags);
374 
375     }
376 
377     private void splitLinksAtSignal(Double margin, Double splitMetersAfterSignalHead, Map<String, LinkTag> inputLinkTags,
378             Map<String, LinkTag> newLinkTags) throws OTSGeometryException, NetworkException
379     {
380         for (LinkTag linkTag : inputLinkTags.values())
381         {
382             for (SignalHeadTag signalHeadTag : linkTag.signalHeads)
383             {
384                 Double position = Double.parseDouble(signalHeadTag.positionStr);
385                 Double splitPosition = position + splitMetersAfterSignalHead;
386                 // A new node has to be created
387                 NodeTag newNodeTag = NodeTag.createNewNodeAtLinkPosition(linkTag, this, splitPosition);
388                 // split the link and connect the new node after the position of the signalhead\
389                 Map<String, LinkTag> newLinks = LinkTag.splitLink(newNodeTag, linkTag, this, splitPosition, margin, false);
390                 if (newLinks != null)
391                 {
392                     newLinkTags.putAll(newLinks);
393                 }
394             }
395             linkTag.signalHeads.removeAll(linkTag.signalHeadsToRemove);
396             linkTag.sensors.removeAll(linkTag.sensorTagsToRemove);
397             // relocate the signalHeads and detectors afterwards!
398         }
399         if (!newLinkTags.isEmpty())
400         {
401             this.linkTags.putAll(newLinkTags);
402         }
403 
404         // run again for the newly created linkTags
405         Map<String, LinkTag> new2LinkTags = new HashMap<>();
406         if (newLinkTags.size() > 0)
407         {
408             splitLinksAtSignal(margin, splitMetersAfterSignalHead, newLinkTags, new2LinkTags);
409         }
410     }
411 
412     private void splitLinksIntersectedByConnector(Double margin) throws OTSGeometryException, NetworkException
413     {
414         // loop through all connector links
415         for (LinkTag connectorLinkTag : this.connectorTags.values())
416         {
417             // ***********************
418             // 1: connector meets link:
419             // get the position where this connector intersects the Link. Here the link will be split
420             Double position = Double.parseDouble(connectorLinkTag.connectorTag.toPositionStr);
421 
422             // get the meeting link
423             LinkTag linkToTag = this.realLinkTags.get(connectorLinkTag.connectorTag.toLinkNo);
424             boolean isConnectorToLink = true;
425 
426             // create a new node at the split position of the "meeting" Link
427             NodeTag newSplitNodeTag = NodeTag.createNewNodeAtLinkPosition(linkToTag, this, position);
428 
429             // split the link
430             Map<String, LinkTag> newLinkToTags =
431                     LinkTag.splitLink(newSplitNodeTag, linkToTag, this, position, margin, isConnectorToLink);
432             linkToTag.signalHeads.removeAll(linkToTag.signalHeadsToRemove);
433             linkToTag.sensors.removeAll(linkToTag.sensorTagsToRemove);
434 
435             if (newLinkToTags != null)
436             {
437                 // only add if a link is split
438                 connectorLinkTag.connectorTag.toNodeName = newSplitNodeTag.name;
439                 this.nodeTags.put(newSplitNodeTag.name, newSplitNodeTag);
440                 // adjust the connection of other Connector links
441                 for (LinkTag connectorLinkTag2 : this.connectorTags.values())
442                 {
443 
444                     if (connectorLinkTag2 != connectorLinkTag
445                             && connectorLinkTag2.connectorTag.toLinkNo.equals(connectorLinkTag.connectorTag.toLinkNo))
446                     {
447 
448                         Double position2 = Double.parseDouble(connectorLinkTag2.connectorTag.toPositionStr);
449                         if (position2 > position)
450                         {
451                             connectorLinkTag2.connectorTag.toLinkNo = newLinkToTags.values().iterator().next().name;
452                             Double newPosition = position2 - position;
453                             connectorLinkTag2.connectorTag.toPositionStr = newPosition.toString();
454                         }
455                     }
456                     if (connectorLinkTag2 != connectorLinkTag
457                             && connectorLinkTag2.connectorTag.fromLinkNo.equals(connectorLinkTag.connectorTag.toLinkNo))
458                     {
459 
460                         Double position2 = Double.parseDouble(connectorLinkTag2.connectorTag.fromPositionStr);
461                         if (position2 > position)
462                         {
463                             connectorLinkTag2.connectorTag.fromLinkNo = newLinkToTags.values().iterator().next().name;
464                             Double newPosition = position2 - position;
465                             connectorLinkTag2.connectorTag.fromPositionStr = newPosition.toString();
466                         }
467                     }
468                 }
469                 // connectorTag.connectorTag.toLinkNo = newLinkToTags.values().iterator().next().name;
470                 this.linkTags.putAll(newLinkToTags);
471                 this.realLinkTags.putAll(newLinkToTags);
472             }
473             else
474             {
475 
476                 // from connector to next link
477                 if (position < margin)
478                 {
479                     this.nodeTags.remove(connectorLinkTag.connectorTag.toNodeName);
480                     connectorLinkTag.connectorTag.toNodeName = linkToTag.nodeStartTag.name;
481                 }
482                 // from link to connector
483                 else
484                 {
485                     this.nodeTags.remove(connectorLinkTag.connectorTag.toNodeName);
486                     connectorLinkTag.connectorTag.toNodeName = linkToTag.nodeEndTag.name;
487                 }
488             }
489 
490             // ******************************
491             // 2: connector exits from a link:
492             position = Double.parseDouble(connectorLinkTag.connectorTag.fromPositionStr);
493             LinkTag linkFromTag = this.realLinkTags.get(connectorLinkTag.connectorTag.fromLinkNo);
494             isConnectorToLink = false;
495             NodeTag newSplitNodeTag2 = NodeTag.createNewNodeAtLinkPosition(linkFromTag, this, position);
496 
497             Map<String, LinkTag> newLinkFromTags =
498                     LinkTag.splitLink(newSplitNodeTag2, linkFromTag, this, position, margin, isConnectorToLink);
499             linkFromTag.signalHeads.removeAll(linkFromTag.signalHeadsToRemove);
500             linkFromTag.sensors.removeAll(linkFromTag.sensorTagsToRemove);
501 
502             if (newLinkFromTags != null)
503             {
504                 // only add if a link is split
505                 connectorLinkTag.connectorTag.fromNodeName = newSplitNodeTag2.name;
506                 this.nodeTags.put(newSplitNodeTag2.name, newSplitNodeTag2);
507                 // adjust the connection of other Connector links
508                 for (LinkTag connectorLinkTag2 : this.connectorTags.values())
509                 {
510                     if (connectorLinkTag2 != connectorLinkTag
511                             && connectorLinkTag2.connectorTag.fromLinkNo.equals(connectorLinkTag.connectorTag.fromLinkNo))
512                     {
513 
514                         Double position2 = Double.parseDouble(connectorLinkTag2.connectorTag.fromPositionStr);
515                         if (position2 > position)
516                         {
517                             connectorLinkTag2.connectorTag.fromLinkNo = newLinkFromTags.values().iterator().next().name;
518                             Double newPosition = position2 - position;
519                             connectorLinkTag2.connectorTag.fromPositionStr = newPosition.toString();
520                         }
521                     }
522                     if (connectorLinkTag2 != connectorLinkTag
523                             && connectorLinkTag2.connectorTag.toLinkNo.equals(connectorLinkTag.connectorTag.fromLinkNo))
524                     {
525 
526                         Double position2 = Double.parseDouble(connectorLinkTag2.connectorTag.toPositionStr);
527                         if (position2 > position)
528                         {
529                             connectorLinkTag2.connectorTag.toLinkNo = newLinkFromTags.values().iterator().next().name;
530                             Double newPosition = position2 - position;
531                             connectorLinkTag2.connectorTag.toPositionStr = newPosition.toString();
532                         }
533                     }
534                 }
535                 // connectorTag.connectorTag.fromLinkNo = newLinkFromTags.values().iterator().next().name;
536                 this.linkTags.putAll(newLinkFromTags);
537                 this.realLinkTags.putAll(newLinkFromTags);
538             }
539             else
540             {
541                 // from connector to next link
542                 if (position < margin)
543                 {
544                     this.nodeTags.remove(connectorLinkTag.connectorTag.fromNodeName);
545                     connectorLinkTag.connectorTag.fromNodeName = linkFromTag.nodeStartTag.name;
546                 }
547                 // from link to connector
548                 else
549                 {
550                     this.nodeTags.remove(connectorLinkTag.connectorTag.fromNodeName);
551                     connectorLinkTag.connectorTag.fromNodeName = linkFromTag.nodeEndTag.name;
552                 }
553             }
554         }
555     }
556 
557     /**
558      * @return the OTSRoadNetwork with the static information about the network
559      * @throws NetworkException if items cannot be added to the Network
560      */
561     private OTSRoadNetwork makeNetwork() throws NetworkException
562     {
563         // for (RouteTag routeTag : this.routeTags.values()) {
564         // // TODO Make routes GTU specific. See what to do with GTUType.ALL for routes
565         // // TODO Automate addition of Routes to network
566         // this.network.addRoute(GTUType.ALL, routeTag.route);
567         // }
568         return this.network;
569     }
570 
571     /** {@inheritDoc} */
572     @Override
573     public final String toString()
574     {
575         return "VissimANMNetworkLaneParser [gtuTypes=" + this.gtuTypes + ", laneTypes=" + this.laneTypes + "]";
576     }
577 
578     public GlobalTag getGlobalTag()
579     {
580         return globalTag;
581     }
582 
583     public void setGlobalTag(GlobalTag globalTag)
584     {
585         this.globalTag = globalTag;
586     }
587 
588     public Map<String, NodeTag> getNodeTags()
589     {
590         return nodeTags;
591     }
592 
593     public void setNodeTags(Map<String, NodeTag> nodeTags)
594     {
595         this.nodeTags = nodeTags;
596     }
597 
598     public Map<String, LinkTag> getLinkTags()
599     {
600         return linkTags;
601     }
602 
603     public void setLinkTags(Map<String, LinkTag> linkTags)
604     {
605         this.linkTags = linkTags;
606     }
607 
608     public Map<String, LinkTag> getConnectorTags()
609     {
610         return connectorTags;
611     }
612 
613     public void setConnectorTags(Map<String, LinkTag> connectorTags)
614     {
615         this.connectorTags = connectorTags;
616     }
617 
618     public Map<String, LinkTag> getRealLinkTags()
619     {
620         return realLinkTags;
621     }
622 
623     public void setRealLinkTags(Map<String, LinkTag> realLinkTags)
624     {
625         this.realLinkTags = realLinkTags;
626     }
627 
628     public Map<String, SignalHeadTag> getSignalHeadTags()
629     {
630         return signalHeadTags;
631     }
632 
633     public void setSignalHeadTags(Map<String, SignalHeadTag> signalHeadTags)
634     {
635         this.signalHeadTags = signalHeadTags;
636     }
637 
638     public Map<String, SensorTag> getSensorTags()
639     {
640         return sensorTags;
641     }
642 
643     public void setSensorTags(Map<String, SensorTag> sensorTags)
644     {
645         this.sensorTags = sensorTags;
646     }
647 
648     public Map<String, GTUTag> getGtuTags()
649     {
650         return gtuTags;
651     }
652 
653     public void setGtuTags(Map<String, GTUTag> gtuTags)
654     {
655         this.gtuTags = gtuTags;
656     }
657 
658     public Map<String, GTUMixTag> getGtuMixTags()
659     {
660         return gtuMixTags;
661     }
662 
663     public void setGtuMixTags(Map<String, GTUMixTag> gtuMixTags)
664     {
665         this.gtuMixTags = gtuMixTags;
666     }
667 
668     public Map<String, RoadTypeTag> getRoadTypeTags()
669     {
670         return roadTypeTags;
671     }
672 
673     public void setRoadTypeTags(Map<String, RoadTypeTag> roadTypeTags)
674     {
675         this.roadTypeTags = roadTypeTags;
676     }
677 
678     public Map<String, GTUType> getGtuTypes()
679     {
680         return gtuTypes;
681     }
682 
683     public void setGtuTypes(Map<String, GTUType> gtuTypes)
684     {
685         this.gtuTypes = gtuTypes;
686     }
687 
688     public Map<String, LaneTypeTag> getLaneTypeTags()
689     {
690         return laneTypeTags;
691     }
692 
693     public void setLaneTypeTags(Map<String, LaneTypeTag> laneTypeTags)
694     {
695         this.laneTypeTags = laneTypeTags;
696     }
697 
698     public Map<String, RoadLayoutTag> getRoadLayoutTags()
699     {
700         return roadLayoutTags;
701     }
702 
703     public void setRoadLayoutTags(Map<String, RoadLayoutTag> roadLayoutTags)
704     {
705         this.roadLayoutTags = roadLayoutTags;
706     }
707 
708     public Map<String, RouteMixTag> getRouteMixTags()
709     {
710         return routeMixTags;
711     }
712 
713     public void setRouteMixTags(Map<String, RouteMixTag> routeMixTags)
714     {
715         this.routeMixTags = routeMixTags;
716     }
717 
718     public Map<String, ShortestRouteMixTag> getShortestRouteMixTags()
719     {
720         return shortestRouteMixTags;
721     }
722 
723     public void setShortestRouteMixTags(Map<String, ShortestRouteMixTag> shortestRouteMixTags)
724     {
725         this.shortestRouteMixTags = shortestRouteMixTags;
726     }
727 
728     public Map<String, ShortestRouteTag> getShortestRouteTags()
729     {
730         return shortestRouteTags;
731     }
732 
733     public void setShortestRouteTags(Map<String, ShortestRouteTag> shortestRouteTags)
734     {
735         this.shortestRouteTags = shortestRouteTags;
736     }
737 
738     public Map<String, RouteTag> getRouteTags()
739     {
740         return routeTags;
741     }
742 
743     public void setRouteTags(Map<String, RouteTag> routeTags)
744     {
745         this.routeTags = routeTags;
746     }
747 
748     public Map<String, LaneType> getLaneTypes()
749     {
750         return laneTypes;
751     }
752 
753     public void setLaneTypes(Map<String, LaneType> laneTypes)
754     {
755         this.laneTypes = laneTypes;
756     }
757 
758     public DEVSSimulatorInterface.TimeDoubleUnit getSimulator()
759     {
760         return simulator;
761     }
762 
763     public void setSimulator(OTSSimulatorInterface simulator)
764     {
765         this.simulator = simulator;
766     }
767 
768     public OTSRoadNetwork getNetwork()
769     {
770         return network;
771     }
772 
773     public void setNetwork(OTSRoadNetwork network)
774     {
775         this.network = network;
776     }
777 
778     public int getUpperNodeNr()
779     {
780         return upperNodeNr;
781     }
782 
783     public void setUpperNodeNr(int upperNodeNr)
784     {
785         this.upperNodeNr = upperNodeNr;
786     }
787 
788     public int getUpperLinkNr()
789     {
790         return upperLinkNr;
791     }
792 
793     public void setUpperLinkNr(int upperLinkNr)
794     {
795         this.upperLinkNr = upperLinkNr;
796     }
797 }