View Javadoc
1   package org.opentrafficsim.demo.loadfromxml;
2   
3   import java.io.ByteArrayInputStream;
4   import java.io.File;
5   import java.io.IOException;
6   import java.net.URISyntaxException;
7   import java.nio.charset.StandardCharsets;
8   import java.nio.file.Files;
9   import java.nio.file.Paths;
10  import java.util.LinkedHashMap;
11  import java.util.Map;
12  
13  import javax.naming.NamingException;
14  import javax.swing.JFileChooser;
15  import javax.swing.JOptionPane;
16  import javax.swing.filechooser.FileFilter;
17  import javax.xml.parsers.ParserConfigurationException;
18  
19  import org.djunits.value.vdouble.scalar.Duration;
20  import org.djunits.value.vdouble.scalar.Time;
21  import org.opentrafficsim.base.logger.Logger;
22  import org.opentrafficsim.core.dsol.AbstractOtsModel;
23  import org.opentrafficsim.core.dsol.OtsAnimator;
24  import org.opentrafficsim.core.dsol.OtsModelInterface;
25  import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
26  import org.opentrafficsim.core.gtu.GtuException;
27  import org.opentrafficsim.core.network.NetworkException;
28  import org.opentrafficsim.core.perception.HistoryManagerDevs;
29  import org.opentrafficsim.demo.DefaultsFactory;
30  import org.opentrafficsim.road.network.RoadNetwork;
31  import org.opentrafficsim.road.network.factory.xml.XmlParserException;
32  import org.opentrafficsim.road.network.factory.xml.parser.XmlParser;
33  import org.opentrafficsim.swing.gui.OtsAnimationPanel;
34  import org.opentrafficsim.swing.gui.OtsSimulationApplication;
35  import org.opentrafficsim.trafficcontrol.TrafficControlException;
36  import org.xml.sax.SAXException;
37  
38  import jakarta.xml.bind.JAXBException;
39  import nl.tudelft.simulation.dsol.SimRuntimeException;
40  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
41  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
42  import nl.tudelft.simulation.jstats.streams.StreamInterface;
43  import nl.tudelft.simulation.language.DsolException;
44  
45  /**
46   * Select a OTS-network XML file, load it and run it.
47   * <p>
48   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
49   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
50   * </p>
51   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
52   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
53   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
54   */
55  public class LoadXml extends OtsSimulationApplication<OtsModelInterface>
56  {
57      /** */
58      private static final long serialVersionUID = 20170421L;
59  
60      /**
61       * Constructor.
62       * @param model the model
63       * @param animationPanel the animation panel
64       */
65      public LoadXml(final OtsModelInterface model, final OtsAnimationPanel animationPanel)
66      {
67          // TODO: colorer and markers based on XML
68          super(model, animationPanel, DefaultsFactory.GTU_TYPE_MARKERS.toMap());
69      }
70  
71      /**
72       * Load a network from an XML file; program entry point.
73       * @param args the command line arguments; optional name of file to load
74       * @throws IOException when the file could not be read
75       * @throws InputParameterException should never happen
76       * @throws NamingException when a name collision is detected
77       * @throws SimRuntimeException should never happen
78       * @throws DsolException when simulator does not implement AnimatorInterface
79       */
80      public static void main(final String[] args)
81              throws IOException, SimRuntimeException, NamingException, InputParameterException, DsolException
82      {
83          String fileName;
84          String xml;
85          if (0 == args.length)
86          {
87              JFileChooser fileChooser = new JFileChooser();
88              fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
89              fileChooser.addChoosableFileFilter(new FileFilter()
90              {
91  
92                  @Override
93                  public boolean accept(final File f)
94                  {
95                      if (f.isDirectory())
96                      {
97                          return true;
98                      }
99                      String name = f.getName();
100                     int length = name.length();
101                     if (length < 5)
102                     {
103                         return false;
104                     }
105                     String type = name.substring(length - 4);
106                     return type.equalsIgnoreCase(".xml");
107                 }
108 
109                 @Override
110                 public String getDescription()
111                 {
112                     return "XML files";
113                 }
114             });
115             fileChooser.removeChoosableFileFilter(fileChooser.getAcceptAllFileFilter());
116             if (JFileChooser.APPROVE_OPTION != fileChooser.showOpenDialog(null))
117             {
118                 Logger.ots().warn("No file chosen; exiting");
119                 System.exit(0);
120             }
121             fileName = fileChooser.getSelectedFile().getAbsolutePath();
122         }
123         else
124         {
125             fileName = args[0];
126         }
127         xml = new String(Files.readAllBytes(Paths.get(fileName)));
128         try
129         {
130             OtsAnimator simulator = new OtsAnimator("LoadXML");
131             XmlModel xmlModel = new XmlModel(simulator, "XML model", "Model built from XML file " + fileName, xml);
132             Map<String, StreamInterface> map = new LinkedHashMap<>();
133             // TODO: This seed is Aimsun specific.
134             map.put("generation", new MersenneTwister(6L));
135             xmlModel.getStreams().putAll(map);
136             simulator.initialize(Time.ZERO, Duration.ZERO, Duration.ofSI(3600.0), xmlModel,
137                     new HistoryManagerDevs(simulator, Duration.ofSI(5.0), Duration.ofSI(10.0)));
138             OtsAnimationPanel animationPanel = new OtsAnimationPanel(xmlModel.getNetwork().getExtent(), simulator, xmlModel,
139                     DEFAULT_GTU_COLORERS, xmlModel.getNetwork());
140             animationPanel.enableSimulationControlButtons();
141             LoadXml loadXml = new LoadXml(xmlModel, animationPanel);
142             // TODO: permabilityType (CAR above) can probably not be null, but we will move stripe type to stripe later
143             // (now StripeAnimation.TYPE is figured out from permebability)
144         }
145         catch (SimRuntimeException sre)
146         {
147             JOptionPane.showMessageDialog(null, sre.getMessage(), "Exception occured", JOptionPane.ERROR_MESSAGE);
148             System.exit(1);
149         }
150     }
151 
152     /**
153      * The Model.
154      */
155     static class XmlModel extends AbstractOtsModel
156     {
157         /** The network. */
158         private RoadNetwork network;
159 
160         /** The XML. */
161         private final String xml;
162 
163         /**
164          * Constructor.
165          * @param simulator the simulator
166          * @param shortName name of the model
167          * @param description description of the model
168          * @param xml the XML string
169          */
170         XmlModel(final OtsSimulatorInterface simulator, final String shortName, final String description, final String xml)
171         {
172             super(simulator, shortName, description, AbstractOtsModel.defaultInitialStreams());
173             this.xml = xml;
174         }
175 
176         @Override
177         public void constructModel() throws SimRuntimeException
178         {
179             this.network = new RoadNetwork(getShortName(), getSimulator());
180             try
181             {
182                 XmlParser xmlParser = new XmlParser(this.network)
183                         .setStream(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)));
184                 xmlParser.build();
185             }
186             catch (NetworkException | JAXBException | URISyntaxException | XmlParserException | SAXException
187                     | ParserConfigurationException | GtuException | IOException | TrafficControlException exception)
188             {
189                 exception.printStackTrace();
190                 // Abusing the SimRuntimeException to propagate the message to the main method (the problem could actually be a
191                 // parsing problem)
192                 throw new SimRuntimeException(exception.getMessage());
193             }
194         }
195 
196         @Override
197         public RoadNetwork getNetwork()
198         {
199             return this.network;
200         }
201 
202     }
203 
204 }