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