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