View Javadoc
1   package org.opentrafficsim.road.network.factory.xml;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
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  
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.gtu.GTUException;
19  import org.opentrafficsim.core.gtu.GTUType;
20  import org.opentrafficsim.core.network.NetworkException;
21  import org.opentrafficsim.core.network.OTSNetwork;
22  import org.opentrafficsim.road.network.lane.LaneType;
23  import org.w3c.dom.Document;
24  import org.w3c.dom.Node;
25  import org.w3c.dom.NodeList;
26  import org.xml.sax.SAXException;
27  
28  import nl.tudelft.simulation.dsol.SimRuntimeException;
29  
30  /**
31   * <p>
32   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
33   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
34   * <p>
35   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
36   * initial version Jul 23, 2015 <br>
37   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
38   */
39  public class XmlNetworkLaneParser implements Serializable
40  {
41      /** */
42      private static final long serialVersionUID = 20150723L;
43  
44      /** Global values from the GLOBAL tag. */
45      @SuppressWarnings("visibilitymodifier")
46      protected GlobalTag globalTag;
47  
48      /** The UNprocessed nodes for further reference. */
49      @SuppressWarnings("visibilitymodifier")
50      protected Map<String, NodeTag> nodeTags = new HashMap<>();
51  
52      /** The UNprocessed links for further reference. */
53      @SuppressWarnings("visibilitymodifier")
54      protected Map<String, LinkTag> linkTags = new HashMap<>();
55  
56      /** The GTU tags for further reference. */
57      @SuppressWarnings("visibilitymodifier")
58      protected Map<String, GTUTag> gtuTags = new HashMap<>();
59  
60      /** The GTUmix tags for further reference. */
61      @SuppressWarnings("visibilitymodifier")
62      protected Map<String, GTUMixTag> gtuMixTags = new HashMap<>();
63  
64      /** The route tags for further reference. */
65      @SuppressWarnings("visibilitymodifier")
66      protected Map<String, RouteTag> routeTags = new HashMap<>();
67  
68      /** The route mix tags for further reference. */
69      @SuppressWarnings("visibilitymodifier")
70      protected Map<String, RouteMixTag> routeMixTags = new HashMap<>();
71  
72      /** The shortest route tags for further reference. */
73      @SuppressWarnings("visibilitymodifier")
74      protected Map<String, ShortestRouteTag> shortestRouteTags = new HashMap<>();
75  
76      /** The shortest route mix tags for further reference. */
77      @SuppressWarnings("visibilitymodifier")
78      protected Map<String, ShortestRouteMixTag> shortestRouteMixTags = new HashMap<>();
79  
80      /** The road type tags for further reference. */
81      @SuppressWarnings("visibilitymodifier")
82      protected Map<String, RoadTypeTag> roadTypeTags = new HashMap<>();
83  
84      /** The road layout tags for further reference. */
85      @SuppressWarnings("visibilitymodifier")
86      protected Map<String, RoadLayoutTag> roadLayoutTags = new HashMap<>();
87  
88      /** The GTUTypes that have been created. public to make it accessible from LaneAttributes. */
89      @SuppressWarnings("visibilitymodifier")
90      public Map<String, GTUType> gtuTypes = new HashMap<>();
91  
92      /** The LaneType tags that have been created. */
93      @SuppressWarnings("visibilitymodifier")
94      protected Map<String, LaneTypeTag> laneTypeTags = new HashMap<>();
95  
96      /** The LaneTypes that have been created. */
97      @SuppressWarnings("visibilitymodifier")
98      protected Map<String, LaneType> laneTypes = new HashMap<>();
99  
100     /** The simulator for creating the animation. Null if no animation needed. */
101     @SuppressWarnings("visibilitymodifier")
102     protected OTSDEVSSimulatorInterface simulator;
103 
104     /** The network to register the GTUs in. */
105     @SuppressWarnings("visibilitymodifier")
106     protected OTSNetwork network;
107 
108     /**
109      * @param simulator the simulator for creating the animation. Null if no animation needed.
110      */
111     public XmlNetworkLaneParser(final OTSDEVSSimulatorInterface simulator)
112     {
113         this.simulator = simulator;
114         LaneTypeTag laneTypeTagNoTraffic = new LaneTypeTag();
115         laneTypeTagNoTraffic.name = "NOTRAFFIC";
116         this.laneTypeTags.put(laneTypeTagNoTraffic.name, laneTypeTagNoTraffic);
117     }
118 
119     /**
120      * @param url the file with the network in the agreed xml-grammar.
121      * @return the network with Nodes, Links, and Lanes.
122      * @throws NetworkException in case of parsing problems.
123      * @throws SAXException in case of parsing problems.
124      * @throws ParserConfigurationException in case of parsing problems.
125      * @throws IOException in case of file reading problems.
126      * @throws NamingException in case the animation context cannot be found
127      * @throws GTUException in case of a problem with creating the LaneBlock (which is a GTU right now)
128      * @throws OTSGeometryException when construction of a lane contour or offset design line fails
129      * @throws SimRuntimeException when simulator cannot be used to schedule GTU generation
130      */
131     @SuppressWarnings("checkstyle:needbraces")
132     public final OTSNetwork build(final URL url) throws NetworkException, ParserConfigurationException, SAXException,
133             IOException, NamingException, GTUException, OTSGeometryException, SimRuntimeException
134     {
135         return build(url, new OTSNetwork(url.toString()));
136     }
137 
138     /**
139      * @param stream the input stream with the network in the agreed xml-grammar.
140      * @return the network with Nodes, Links, and Lanes.
141      * @throws NetworkException in case of parsing problems.
142      * @throws SAXException in case of parsing problems.
143      * @throws ParserConfigurationException in case of parsing problems.
144      * @throws IOException in case of file reading problems.
145      * @throws NamingException in case the animation context cannot be found
146      * @throws GTUException in case of a problem with creating the LaneBlock (which is a GTU right now)
147      * @throws OTSGeometryException when construction of a lane contour or offset design line fails
148      * @throws SimRuntimeException when simulator cannot be used to schedule GTU generation
149      */
150     @SuppressWarnings("checkstyle:needbraces")
151     public final OTSNetwork build(final InputStream stream) throws NetworkException, ParserConfigurationException, SAXException,
152             IOException, NamingException, GTUException, OTSGeometryException, SimRuntimeException
153     {
154         return build(stream, new OTSNetwork(stream.toString()));
155     }
156 
157     /**
158      * @param url the file with the network in the agreed xml-grammar.
159      * @param network OTSNetwork; the network
160      * @return the network with Nodes, Links, and Lanes.
161      * @throws NetworkException in case of parsing problems.
162      * @throws SAXException in case of parsing problems.
163      * @throws ParserConfigurationException in case of parsing problems.
164      * @throws IOException in case of file reading problems.
165      * @throws NamingException in case the animation context cannot be found
166      * @throws GTUException in case of a problem with creating the LaneBlock (which is a GTU right now)
167      * @throws OTSGeometryException when construction of a lane contour or offset design line fails
168      * @throws SimRuntimeException when simulator cannot be used to schedule GTU generation
169      */
170     @SuppressWarnings("checkstyle:needbraces")
171     public final OTSNetwork build(final URL url, final OTSNetwork network)
172             throws NetworkException, ParserConfigurationException, SAXException, IOException, NamingException, GTUException,
173             OTSGeometryException, SimRuntimeException
174     {
175         return build(url.openStream(), network);
176     }
177 
178     /**
179      * @param stream the input stream with the network in the agreed xml-grammar.
180      * @param network OTSNetwork; the network
181      * @return the network with Nodes, Links, and Lanes.
182      * @throws NetworkException in case of parsing problems.
183      * @throws SAXException in case of parsing problems.
184      * @throws ParserConfigurationException in case of parsing problems.
185      * @throws IOException in case of file reading problems.
186      * @throws NamingException in case the animation context cannot be found
187      * @throws GTUException in case of a problem with creating the LaneBlock (which is a GTU right now)
188      * @throws OTSGeometryException when construction of a lane contour or offset design line fails
189      * @throws SimRuntimeException when simulator cannot be used to schedule GTU generation
190      */
191     @SuppressWarnings("checkstyle:needbraces")
192     public final OTSNetwork build(final InputStream stream, final OTSNetwork network)
193             throws NetworkException, ParserConfigurationException, SAXException, IOException, NamingException, GTUException,
194             OTSGeometryException, SimRuntimeException
195     {
196         // try
197         // {
198         // if (url.getFile().length() > 0 && !(new File(url.toURI()).exists()))
199         // throw new SAXException("XmlNetworkLaneParser.build: File " + url.getFile() + " does not exist");
200         // }
201         // catch (URISyntaxException exception)
202         // {
203         // throw new SAXException("XmlNetworkLaneParser.build: File " + url.getFile() + " is not properly formatted",
204         // exception);
205         // }
206         this.network = network;
207 
208         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
209         factory.setNamespaceAware(true);
210         factory.setXIncludeAware(true);
211         DocumentBuilder builder = factory.newDocumentBuilder();
212         Document document = builder.parse(stream);
213         NodeList networkNodeList = document.getDocumentElement().getChildNodes();
214 
215         if (!document.getDocumentElement().getNodeName().equals("NETWORK"))
216             throw new SAXException("XmlNetworkLaneParser.build: XML document does not start with an NETWORK tag, found "
217                     + document.getDocumentElement().getNodeName() + " instead");
218 
219         // there should be some definitions using DEFINITIONS tags (could be more than one due to include files)
220         List<Node> definitionNodes = XMLParser.getNodes(networkNodeList, "DEFINITIONS");
221 
222         if (definitionNodes.size() == 0)
223             throw new SAXException("XmlNetworkLaneParser.build: XML document does not have a DEFINITIONS tag");
224 
225         // make the GTUTypes ALL and NONE to get started
226         this.gtuTypes.put("ALL", GTUType.ALL);
227         this.gtuTypes.put("NONE", GTUType.NONE);
228 
229         // parse the DEFINITIONS tags
230         for (Node definitionNode : definitionNodes)
231             GlobalTag.parseGlobal(definitionNode.getChildNodes(), this);
232         for (Node definitionNode : definitionNodes)
233             GTUTypeTag.parseGTUTypes(definitionNode.getChildNodes(), this);
234         for (Node definitionNode : definitionNodes)
235             GTUTag.parseGTUs(definitionNode.getChildNodes(), this);
236         for (Node definitionNode : definitionNodes)
237             GTUMixTag.parseGTUMix(definitionNode.getChildNodes(), this);
238         for (Node definitionNode : definitionNodes)
239             RoadTypeTag.parseRoadTypes(definitionNode.getChildNodes(), this);
240         for (Node definitionNode : definitionNodes)
241             LaneTypeTag.parseLaneTypes(definitionNode.getChildNodes(), this);
242         for (Node definitionNode : definitionNodes)
243             RoadLayoutTag.parseRoadTypes(definitionNode.getChildNodes(), this);
244 
245         // parse the NETWORK tag
246         NodeTag.parseNodes(networkNodeList, this);
247         RouteTag.parseRoutes(networkNodeList, this);
248         ShortestRouteTag.parseShortestRoutes(networkNodeList, this);
249         RouteMixTag.parseRouteMix(networkNodeList, this);
250         ShortestRouteMixTag.parseShortestRouteMix(networkNodeList, this);
251         LinkTag.parseLinks(networkNodeList, this);
252 
253         // process nodes and links to calculate coordinates and positions
254         Links.calculateNodeCoordinates(this);
255         for (LinkTag linkTag : this.linkTags.values())
256             Links.buildLink(linkTag, this, this.simulator);
257         for (LinkTag linkTag : this.linkTags.values())
258             Links.applyRoadTypeToLink(linkTag, this, this.simulator);
259 
260         // process the routes
261         for (RouteTag routeTag : this.routeTags.values())
262             routeTag.makeRoute();
263         // TODO shortestRoute, routeMix, ShortestRouteMix
264 
265         // store the structure information in the network
266         return makeNetwork();
267     }
268 
269     /**
270      * @return the OTSNetwork with the static information about the network
271      * @throws NetworkException if items cannot be added to the Network
272      */
273     private OTSNetwork makeNetwork() throws NetworkException
274     {
275         for (RouteTag routeTag : this.routeTags.values())
276         {
277             // TODO Make routes GTU specific. See what to do with GTUType.ALL for routes
278             // TODO Automate addition of Routes to network
279             this.network.addRoute(GTUType.ALL, routeTag.route);
280         }
281         return this.network;
282     }
283 
284     /** {@inheritDoc} */
285     @Override
286     public String toString()
287     {
288         return "XmlNetworkLaneParser [globalTag=" + this.globalTag + ", nodeTags.size=" + this.nodeTags.size()
289                 + ", linkTags.size=" + this.linkTags.size() + ", gtuTags.size=" + this.gtuTags.size() + ", gtuMixTags.size="
290                 + this.gtuMixTags.size() + ", routeTags.size=" + this.routeTags.size() + ", routeMixTags.size="
291                 + this.routeMixTags.size() + ", shortestRouteTagssize.=" + this.shortestRouteTags.size()
292                 + ", shortestRouteMixTags.size=" + this.shortestRouteMixTags.size() + ", roadTypeTags.size="
293                 + this.roadTypeTags.size() + ", gtuTypes.size=" + this.gtuTypes.size() + ", laneTypes.size="
294                 + this.laneTypeTags.size() + "]";
295     }
296 
297 }