View Javadoc
1   package org.opentrafficsim.road.network.factory.opendrive;
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.List;
9   import java.util.Map;
10  import java.util.Set;
11  
12  import javax.naming.NamingException;
13  import javax.xml.parsers.DocumentBuilder;
14  import javax.xml.parsers.DocumentBuilderFactory;
15  import javax.xml.parsers.ParserConfigurationException;
16  
17  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
18  import org.opentrafficsim.core.geometry.OTSGeometryException;
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.OTSRoadNetwork;
24  import org.opentrafficsim.road.network.lane.LaneType;
25  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
26  import org.w3c.dom.Document;
27  import org.w3c.dom.Node;
28  import org.w3c.dom.NodeList;
29  import org.xml.sax.SAXException;
30  
31  import nl.tudelft.simulation.dsol.SimRuntimeException;
32  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
33  
34  /**
35   * <p>
36   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
37   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
38   * <p>
39   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
40   * initial version Jul 23, 2015 <br>
41   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
42   */
43  public class OpenDriveNetworkLaneParser implements Serializable
44  {
45      /** */
46      private static final long serialVersionUID = 20150723L;
47  
48      /** Header tag. */
49      @SuppressWarnings("visibilitymodifier")
50      protected HeaderTag headerTag = null;
51  
52      /** Junction tags. */
53      @SuppressWarnings("visibilitymodifier")
54      protected Map<String, ControllerTag> controllerTags = new HashMap<>();
55  
56      /** Controller tags. */
57      @SuppressWarnings("visibilitymodifier")
58      protected Map<String, JunctionTag> junctionTags = new HashMap<>();
59  
60      /** Road tags. */
61      @SuppressWarnings("visibilitymodifier")
62      protected Map<String, RoadTag> roadTags = new HashMap<>();
63  
64      /** The GTUTypes that have been created. */
65      @SuppressWarnings("visibilitymodifier")
66      protected Map<String, GTUType> gtuTypes = new HashMap<>();
67  
68      /** The LaneTypes that have been created. */
69      @SuppressWarnings("visibilitymodifier")
70      protected Map<String, LaneType> laneTypes = new HashMap<>();
71  
72      /** The simulator for creating the animation. Null if no animation needed. */
73      @SuppressWarnings("visibilitymodifier")
74      protected OTSSimulatorInterface simulator;
75  
76      /** OTS network */
77      @SuppressWarnings("visibilitymodifier")
78      protected OTSRoadNetwork network = null;
79  
80      /** The signalTags that have been created. */
81      @SuppressWarnings("visibilitymodifier")
82      protected Map<String, SignalTag> signalTags = new HashMap<>();
83  
84      /** The trafficLights that have been created, organized by signals */
85      @SuppressWarnings("visibilitymodifier")
86      protected Map<String, Set<SimpleTrafficLight>> trafficLightsBySignals = new HashMap<>();
87  
88      /** The trafficLights that have been created, organized by lanes */
89      @SuppressWarnings("visibilitymodifier")
90      protected Map<String, Set<SimpleTrafficLight>> trafficLightsByLanes = new HashMap<>();
91  
92      /** The generated animation per object. */
93      @SuppressWarnings("checkstyle:visibilitymodifier")
94      public Map<Object, Renderable2D<?>> animationMap = new HashMap<>();
95  
96      /**
97       * @param simulator OTSSimulatorInterface; the simulator for creating the animation. Null if no animation needed.
98       */
99      public OpenDriveNetworkLaneParser(final OTSSimulatorInterface simulator)
100     {
101         this.simulator = simulator;
102     }
103 
104     /**
105      * @param url URL; the file with the network in the agreed xml-grammar.
106      * @return the network with Nodes, Links, and Lanes.
107      * @throws NetworkException in case of parsing problems.
108      * @throws SAXException in case of parsing problems.
109      * @throws ParserConfigurationException in case of parsing problems.
110      * @throws IOException in case of file reading problems.
111      * @throws NamingException in case the animation context cannot be found
112      * @throws GTUException in case of a problem with creating the LaneBlock (which is a GTU right now)
113      * @throws OTSGeometryException when construction of a lane contour or offset design line fails
114      * @throws SimRuntimeException when simulator cannot be used to schedule GTU generation
115      */
116     @SuppressWarnings("checkstyle:needbraces")
117     public final OTSRoadNetwork build(final URL url) throws NetworkException, ParserConfigurationException, SAXException,
118             IOException, NamingException, GTUException, OTSGeometryException, SimRuntimeException
119     {
120         if (url.getFile().length() > 0 && !(new File(url.getFile()).exists()))
121             throw new SAXException("OpenDriveNetworkLaneParser.build: File url.getFile() does not exist");
122 
123         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
124         factory.setNamespaceAware(true);
125         factory.setXIncludeAware(true);
126         DocumentBuilder builder = factory.newDocumentBuilder();
127         Document document = builder.parse(url.openStream());
128         NodeList networkNodeList = document.getDocumentElement().getChildNodes();
129 
130         if (!document.getDocumentElement().getNodeName().equals("OpenDRIVE"))
131             throw new SAXException("OpenDriveNetworkLaneParser.build: XML document does not start with an OpenDRIVE tag, found "
132                     + document.getDocumentElement().getNodeName() + " instead");
133 
134         this.network = new OTSRoadNetwork(url.toString(), true);
135 
136         // there should be a header tag
137         List<Node> headerNodes = XMLParser.getNodes(networkNodeList, "header");
138         if (headerNodes.size() != 1)
139             throw new SAXException("OpenDriveNetworkLaneParser.build: XML document does not have a header tag");
140         else
141             HeaderTag.parseHeader(headerNodes.get(0), this);
142 
143         // parse the junction tags
144         List<Node> junctionNodes = XMLParser.getNodes(networkNodeList, "junction");
145         for (Node junctionNode : junctionNodes)
146             JunctionTag.parseJunction(junctionNode, this);
147 
148         // parse the controller tags
149         List<Node> controllerNodes = XMLParser.getNodes(networkNodeList, "controller");
150         for (Node controllerNode : controllerNodes)
151         {
152             ControllerTag controllerTag = ControllerTag.parseController(controllerNode, this);
153             this.controllerTags.put(controllerTag.id, controllerTag);
154         }
155 
156         // parse the road tags
157         List<Node> roadNodes = XMLParser.getNodes(networkNodeList, "road");
158         if (roadNodes.size() == 0)
159             throw new SAXException("OpenDriveNetworkLaneParser.build: XML document does not have a road tag");
160         for (Node roadNode : roadNodes)
161         {
162             RoadTag roadTag = RoadTag.parseRoad(roadNode, this);
163             LinkTag.parseLink(roadNode.getChildNodes(), this, roadTag);
164             TypeTag.parseType(roadNode.getChildNodes(), this, roadTag);
165 
166             ElevationProfileTag.parseElevationProfile(roadNode.getChildNodes(), this, roadTag);
167 
168             PlanViewTag.parsePlanView(roadNode.getChildNodes(), this, roadTag);
169 
170             LateralProfileTag.parseElevationProfile(roadNode.getChildNodes(), this, roadTag);
171             LanesTag.parseLanes(roadNode.getChildNodes(), this, roadTag);
172             // ObjectsTag.parseObjects(roadNode.getChildNodes(), this, roadTag);
173             SignalsTag.parseSignals(roadNode.getChildNodes(), this, roadTag);
174             /*-SurfaceTag.parseSurface(roadNode.getChildNodes(), this, roadTag);
175             RailroadTag.parseRailroad(roadNode.getChildNodes(), this, roadTag);
176              */
177         }
178 
179         for (RoadTag roadTag : this.roadTags.values())
180         {
181             RoadTag.buildLink(roadTag, this);
182         }
183 
184         for (RoadTag roadTag : this.roadTags.values())
185         {
186             RoadTag.buildSubLinks(roadTag, this.simulator, this);
187         }
188 
189         for (RoadTag roadTag : this.roadTags.values())
190         {
191             // System.err.println("RoadTag " + roadTag.id);
192             RoadTag.generateRegularRoads(roadTag, this.simulator, this);
193         }
194 
195         for (RoadTag roadTag : this.roadTags.values())
196         {
197             RoadTag.generateTrafficLightsbySignal(roadTag, this.simulator, this);
198         }
199 
200         for (RoadTag roadTag : this.roadTags.values())
201         {
202             RoadTag.generateTrafficLightsbySignalReference(roadTag, this.simulator, this);
203         }
204 
205         for (JunctionTag juncTag : this.junctionTags.values())
206             JunctionTag.createController(juncTag, this.simulator, this);
207 
208         // store the structure information in the network
209         return this.network;
210     }
211 
212     /**
213      * @param name String; the name of the network
214      * @return the OTSNetwork with the static information about the network
215      * @throws NetworkException if items cannot be added to the Network
216      */
217     @SuppressWarnings({"unused"})
218     private OTSNetwork makeNetwork(final String name) throws NetworkException
219     {
220         this.network = new OTSRoadNetwork(name, true);
221         return this.network;
222     }
223 
224     /**
225      * @return headerTag
226      */
227     public HeaderTag getHeaderTag()
228     {
229         return this.headerTag;
230     }
231 
232     /** {@inheritDoc} */
233     @Override
234     public final String toString()
235     {
236         return "OpenDriveNetworkLaneParser [headerTag=" + this.headerTag + ", controllerTags.size=" + this.controllerTags.size()
237                 + ", junctionTags.size=" + this.junctionTags.size() + ", roadTags.size=" + this.roadTags.size()
238                 + ", gtuTypes.size=" + this.gtuTypes.size() + ", laneTypes.size=" + this.laneTypes.size() + ", simulator="
239                 + this.simulator + ", network=" + this.network + ", signalTags.size=" + this.signalTags.size()
240                 + ", trafficLightsBySignals.size=" + this.trafficLightsBySignals.size() + ", trafficLightsByLanes.size="
241                 + this.trafficLightsByLanes.size() + ", animationMap.size=" + this.animationMap.size() + "]";
242     }
243 
244 }