View Javadoc
1   package org.opentrafficsim.road.network.factory.xml.parser;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileNotFoundException;
6   import java.io.InputStream;
7   import java.io.Serializable;
8   import java.net.URISyntaxException;
9   import java.rmi.RemoteException;
10  import java.util.HashMap;
11  import java.util.HashSet;
12  import java.util.LinkedHashMap;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.Set;
16  
17  import javax.xml.bind.JAXBContext;
18  import javax.xml.bind.JAXBException;
19  import javax.xml.bind.Unmarshaller;
20  import javax.xml.parsers.ParserConfigurationException;
21  import javax.xml.parsers.SAXParserFactory;
22  import javax.xml.transform.sax.SAXSource;
23  
24  import org.djunits.value.vdouble.scalar.Direction;
25  import org.djunits.value.vdouble.scalar.Speed;
26  import org.djutils.io.URLResource;
27  import org.djutils.logger.CategoryLogger;
28  import org.opentrafficsim.base.logger.Cat;
29  import org.opentrafficsim.base.parameters.ParameterException;
30  import org.opentrafficsim.base.parameters.ParameterType;
31  import org.opentrafficsim.core.dsol.OTSSimulator;
32  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
33  import org.opentrafficsim.core.geometry.OTSGeometryException;
34  import org.opentrafficsim.core.gtu.GTUException;
35  import org.opentrafficsim.core.gtu.GTUType;
36  import org.opentrafficsim.core.network.LinkType;
37  import org.opentrafficsim.core.network.NetworkException;
38  import org.opentrafficsim.core.parameters.InputParameters;
39  import org.opentrafficsim.core.parameters.ParameterFactory;
40  import org.opentrafficsim.draw.lane.LaneStructureAnimation;
41  import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
42  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
43  import org.opentrafficsim.road.gtu.lane.perception.RollingLaneStructure;
44  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
45  import org.opentrafficsim.road.network.OTSRoadNetwork;
46  import org.opentrafficsim.road.network.factory.xml.XmlParserException;
47  import org.opentrafficsim.road.network.factory.xml.utils.StreamInformation;
48  import org.opentrafficsim.xml.generated.ANIMATION;
49  import org.opentrafficsim.xml.generated.CONTROL;
50  import org.opentrafficsim.xml.generated.GTUTEMPLATE;
51  import org.opentrafficsim.xml.generated.MODELTYPE;
52  import org.opentrafficsim.xml.generated.NETWORK;
53  import org.opentrafficsim.xml.generated.NETWORKDEMAND;
54  import org.opentrafficsim.xml.generated.OTS;
55  import org.opentrafficsim.xml.generated.ROADLAYOUT;
56  import org.opentrafficsim.xml.generated.SCENARIO;
57  import org.pmw.tinylog.Level;
58  import org.xml.sax.InputSource;
59  import org.xml.sax.SAXException;
60  import org.xml.sax.XMLReader;
61  
62  import nl.tudelft.simulation.dsol.SimRuntimeException;
63  import nl.tudelft.simulation.dsol.experiment.Experiment;
64  import nl.tudelft.simulation.dsol.logger.SimLogger;
65  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameter;
66  import nl.tudelft.simulation.event.EventInterface;
67  import nl.tudelft.simulation.event.EventListenerInterface;
68  
69  /**
70   * Parse an XML file for an OTS network, based on the ots-network.xsd definition.
71   * <p>
72   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
73   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
74   * <p>
75   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
76   * initial version Jul 23, 2015 <br>
77   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
78   */
79  public final class XmlNetworkLaneParser implements Serializable
80  {
81      /** */
82      private static final long serialVersionUID = 2019022L;
83  
84      /** */
85      private XmlNetworkLaneParser()
86      {
87          // utility class
88      }
89  
90      /**
91       * Parse the XML file and build the network.
92       * @param filename String; the name of the file to parse
93       * @param otsNetwork OTSRoadNetwork; the network to insert the parsed objects in
94       * @param simulator OTSSimulatorInterface; the simulator
95       * @return the network that contains the parsed objects
96       * @throws JAXBException when the parsing fails
97       * @throws URISyntaxException when the filename is not valid
98       * @throws NetworkException when the objects cannot be inserted into the network due to inconsistencies
99       * @throws OTSGeometryException when the design line of a link is invalid
100      * @throws XmlParserException when the stripe type cannot be recognized
101      * @throws ParserConfigurationException on error with parser configuration
102      * @throws SAXException on error creating SAX parser
103      * @throws SimRuntimeException in case of simulation problems building the car generator
104      * @throws GTUException when construction of the Strategical Planner failed
105      */
106     public static OTSRoadNetwork build(final String filename, final OTSRoadNetwork otsNetwork,
107             final OTSSimulatorInterface simulator)
108             throws JAXBException, URISyntaxException, NetworkException, OTSGeometryException, XmlParserException, SAXException,
109             ParserConfigurationException, SimRuntimeException, GTUException
110     {
111         File xml = new File(URLResource.getResource(filename).toURI().getPath());
112         try
113         {
114             build(new FileInputStream(xml), otsNetwork, simulator);
115         }
116         catch (FileNotFoundException exception)
117         {
118             throw new XmlParserException("File could not be found.", exception);
119         }
120 
121         return otsNetwork;
122     }
123 
124     /**
125      * Parse the XML file and build the network.
126      * @param xmlStream InputStream; the xml input stream
127      * @param otsNetwork OTSRoadNetwork; the network to insert the parsed objects in
128      * @param simulator OTSSimulatorInterface; the simulator
129      * @return the experiment based on the information in the RUN tag
130      * @throws JAXBException when the parsing fails
131      * @throws URISyntaxException when the filename is not valid
132      * @throws NetworkException when the objects cannot be inserted into the network due to inconsistencies
133      * @throws OTSGeometryException when the design line of a link is invalid
134      * @throws XmlParserException when the stripe type cannot be recognized
135      * @throws ParserConfigurationException on error with parser configuration
136      * @throws SAXException on error creating SAX parser
137      * @throws SimRuntimeException in case of simulation problems building the car generator
138      * @throws GTUException when construction of the Strategical Planner failed
139      */
140     public static Experiment.TimeDoubleUnit<OTSSimulatorInterface> build(final InputStream xmlStream,
141             final OTSRoadNetwork otsNetwork, final OTSSimulatorInterface simulator)
142             throws JAXBException, URISyntaxException, NetworkException, OTSGeometryException, XmlParserException, SAXException,
143             ParserConfigurationException, SimRuntimeException, GTUException
144     {
145         JAXBContext jc = JAXBContext.newInstance(OTS.class);
146         Unmarshaller unmarshaller = jc.createUnmarshaller();
147         SAXParserFactory spf = SAXParserFactory.newInstance();
148         spf.setXIncludeAware(true);
149         spf.setNamespaceAware(true);
150         spf.setValidating(false);
151         XMLReader xmlReader = spf.newSAXParser().getXMLReader();
152         SAXSource saxSource = new SAXSource(xmlReader, new InputSource(xmlStream));
153         OTS ots = (OTS) unmarshaller.unmarshal(saxSource);
154 
155         CategoryLogger.setLogCategories(Cat.PARSER);
156         CategoryLogger.setAllLogLevel(Level.TRACE);
157 
158         Map<String, StreamInformation> streamMap = new HashMap<>();
159         Experiment.TimeDoubleUnit<OTSSimulatorInterface> experiment =
160                 RunParser.parseRun(otsNetwork, ots.getRUN(), streamMap, simulator);
161 
162         Map<String, ROADLAYOUT> roadLayoutMap = new HashMap<>();
163         Map<String, GTUTEMPLATE> gtuTemplates = new HashMap<>();
164         Map<LinkType, Map<GTUType, Speed>> linkTypeSpeedLimitMap = new HashMap<>();
165         DefinitionsParser.parseDefinitions(otsNetwork, ots.getDEFINITIONS(), true, roadLayoutMap, gtuTemplates, streamMap,
166                 linkTypeSpeedLimitMap);
167 
168         NETWORK network = ots.getNETWORK();
169         NetworkParser.parseNodes(otsNetwork, network);
170         Map<String, Direction> nodeDirections = NetworkParser.calculateNodeAngles(otsNetwork, network);
171         NetworkParser.parseLinks(otsNetwork, network, nodeDirections, simulator);
172         NetworkParser.applyRoadLayout(otsNetwork, network, simulator, roadLayoutMap, linkTypeSpeedLimitMap);
173         NetworkParser.parseRoutes(otsNetwork, network);
174         NetworkParser.parseShortestRoutes(otsNetwork, network);
175 
176         List<NETWORKDEMAND> demands = ots.getNETWORKDEMAND();
177         for (NETWORKDEMAND demand : demands)
178         {
179             List<LaneBasedGTUGenerator> generators =
180                     GeneratorSinkParser.parseGenerators(otsNetwork, demand, gtuTemplates, simulator, streamMap);
181             // The code below can be used to visualize the LaneStructure of a particular GTU
182             /*-for (LaneBasedGTUGenerator generator : generators)
183             {
184                 EventListenerInterface listener = new EventListenerInterface()
185                 {
186                     @Override
187                     public void notify(final EventInterface event) throws RemoteException
188                     {
189                         LaneBasedGTU gtu = (LaneBasedGTU) event.getContent();
190                         if (gtu.getId().equals("25"))
191                         {
192                             try
193                             {
194                                 LaneStructureAnimation.visualize(
195                                         (RollingLaneStructure) gtu.getTacticalPlanner().getPerception().getLaneStructure(), gtu);
196                             }
197                             catch (ParameterException | ClassCastException exception)
198                             {
199                                 SimLogger.always().warn("Could not draw lane structure of GTU.");
200                             }
201                         }
202                     }
203                 };
204                 generator.addListener(listener, LaneBasedGTUGenerator.GTU_GENERATED_EVENT);
205             }*/
206             GeneratorSinkParser.parseSinks(otsNetwork, demand, simulator);
207         }
208         List<MODELTYPE> models = ots.getMODEL();
209         // TODO: parse input parameters
210         InputParameters inputParameters = new InputParameters()
211         {
212             /** {@inheritDoc} */
213             @Override
214             public <T> Set<T> getObjects(final Class<T> clazz)
215             {
216                 return new HashSet<>();
217             }
218 
219             /** {@inheritDoc} */
220             @Override
221             public Map<String, InputParameter<?, ?>> getInputParameters(final Object object)
222             {
223                 throw new UnsupportedOperationException("No input parameters.");
224             }
225 
226             /** {@inheritDoc} */
227             @Override
228             public InputParameter<?, ?> getInputParameter(final Object object, final String id)
229             {
230                 throw new UnsupportedOperationException("No input parameters.");
231             }
232         };
233         Map<String, ParameterType<?>> parameterTypes = new LinkedHashMap<>();
234         Map<String, ParameterFactory> parameterFactories =
235                 ModelParser.parseParameters(otsNetwork, models, inputParameters, parameterTypes, streamMap);
236         DefinitionsParser.parseParameterTypes(ots.getDEFINITIONS(), otsNetwork, parameterTypes);
237         Map<String, LaneBasedStrategicalPlannerFactory<?>> factories =
238                 ModelParser.parseModel(otsNetwork, models, inputParameters, parameterTypes, streamMap, parameterFactories);
239         Map<String, String> modelIdReferrals = ScenarioParser.parseModelIdReferral(ots.getSCENARIO(), ots.getNETWORKDEMAND());
240         List<LaneBasedGTUGenerator> generators =
241                 DemandParser.parseDemand(otsNetwork, simulator, demands, gtuTemplates, factories, modelIdReferrals, streamMap);
242         // The code below can be used to visualize the LaneStructure of a particular GTU
243         /*-EventListenerInterface listener = new EventListenerInterface()
244         {
245             @Override
246             public void notify(final EventInterface event) throws RemoteException
247             {
248                 LaneBasedGTU gtu = (LaneBasedGTU) event.getContent();
249                 if (gtu.getId().equals("27"))
250                 {
251                     try
252                     {
253                         LaneStructureAnimation.visualize(
254                                 (RollingLaneStructure) gtu.getTacticalPlanner().getPerception().getLaneStructure(), gtu);
255                     }
256                     catch (ParameterException | ClassCastException exception)
257                     {
258                         SimLogger.always().warn("Could not draw lane structure of GTU.");
259                     }
260                 }
261             }
262         };
263         for (LaneBasedGTUGenerator generator : generators)
264         {
265             generator.addListener(listener, LaneBasedGTUGenerator.GTU_GENERATED_EVENT);
266         }*/
267 
268         List<CONTROL> controls = ots.getCONTROL();
269         List<MODELTYPE> modelParameters = ots.getMODEL();
270         List<SCENARIO> scenario = ots.getSCENARIO();
271         ANIMATION animation = ots.getANIMATION();
272 
273         ControlParser.parseControl(otsNetwork, simulator, controls);
274 
275         return experiment;
276     }
277 
278     /**
279      * @param args String[]; not used
280      * @throws Exception on parsing error
281      */
282     public static void main(final String[] args) throws Exception
283     {
284         OTSSimulatorInterface simulator = new OTSSimulator();
285         build("/example.xml", new OTSRoadNetwork("", true), simulator);
286         System.exit(0);
287     }
288 }