package loadfromxml; import java.awt.Dimension; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.LinkedHashMap; import java.util.Map; import javax.naming.NamingException; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import javax.xml.bind.JAXBException; import javax.xml.parsers.ParserConfigurationException; import org.djunits.value.vdouble.scalar.Duration; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Time; import org.opentrafficsim.core.dsol.AbstractOTSModel; import org.opentrafficsim.core.dsol.OTSAnimator; import org.opentrafficsim.core.dsol.OTSModelInterface; import org.opentrafficsim.core.dsol.OTSSimulationException; import org.opentrafficsim.core.dsol.OTSSimulatorInterface; import org.opentrafficsim.core.geometry.OTSGeometryException; import org.opentrafficsim.core.gtu.GTUException; import org.opentrafficsim.core.gtu.GTUType; import org.opentrafficsim.core.network.NetworkException; import org.opentrafficsim.draw.core.OTSDrawingException; import org.opentrafficsim.road.network.OTSRoadNetwork; import org.opentrafficsim.road.network.factory.xml.XmlParserException; import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser; import org.opentrafficsim.road.network.lane.CrossSectionLink; import org.opentrafficsim.road.network.lane.conflict.ConflictBuilder; import org.opentrafficsim.road.network.lane.conflict.LaneCombinationList; import org.opentrafficsim.swing.gui.OTSAnimationPanel; import org.opentrafficsim.swing.gui.OTSSimulationApplication; import org.opentrafficsim.trafficcontrol.TrafficControlException; import org.xml.sax.SAXException; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException; import nl.tudelft.simulation.jstats.streams.MersenneTwister; import nl.tudelft.simulation.jstats.streams.StreamInterface; import nl.tudelft.simulation.language.DSOLException; /** * Select a OTS-network XML file, load it and run it. *

* Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 21, 2017
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ public class LoadXML extends OTSSimulationApplication { /** */ private static final long serialVersionUID = 20170421L; /** * @param model OTSModelInterface; the model * @param animationPanel OTSAnimationPanel; the animation panel * @throws OTSDrawingException on drawing error */ public LoadXML(final OTSModelInterface model, final OTSAnimationPanel animationPanel) throws OTSDrawingException { super(model, animationPanel); } /** * Load a network from an XML file; program entry point. * @param args String[]; the command line arguments; optional name of file to load * @throws IOException when the file could not be read * @throws InputParameterException should never happen * @throws OTSSimulationException when an error occurs during simulation * @throws NamingException when a name collision is detected * @throws SimRuntimeException should never happen * @throws DSOLException when simulator does not implement AnimatorInterface */ public static void main(final String[] args) throws IOException, SimRuntimeException, NamingException, OTSSimulationException, InputParameterException, DSOLException { String fileName; String xml; if (0 == args.length) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); fileChooser.addChoosableFileFilter(new FileFilter() { @Override public boolean accept(final File f) { if (f.isDirectory()) { return true; } String name = f.getName(); int length = name.length(); if (length < 5) { return false; } String type = name.substring(length - 4); return type.equalsIgnoreCase(".xml"); } @Override public String getDescription() { return "XML files"; } }); fileChooser.removeChoosableFileFilter(fileChooser.getAcceptAllFileFilter()); if (JFileChooser.APPROVE_OPTION != fileChooser.showOpenDialog(null)) { System.out.println("No file chosen; exiting"); System.exit(0); } fileName = fileChooser.getSelectedFile().getAbsolutePath(); } else { fileName = args[0]; } xml = new String(Files.readAllBytes(Paths.get(fileName))); try { OTSAnimator simulator = new OTSAnimator("LoadXML"); XMLModel xmlModel = new XMLModel(simulator, "XML model", "Model built from XML file " + fileName, xml); Map map = new LinkedHashMap<>(); // TODO: This seed is Aimsun specific. map.put("generation", new MersenneTwister(6L)); simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), xmlModel, map); OTSAnimationPanel animationPanel = new OTSAnimationPanel(xmlModel.getNetwork().getExtent(), new Dimension(800, 600), simulator, xmlModel, DEFAULT_COLORER, xmlModel.getNetwork()); new LoadXML(xmlModel, animationPanel); } catch (SimRuntimeException | OTSDrawingException sre) { JOptionPane.showMessageDialog(null, sre.getMessage(), "Exception occured", JOptionPane.ERROR_MESSAGE); System.exit(1); } } /** * The Model. */ static class XMLModel extends AbstractOTSModel { /** */ private static final long serialVersionUID = 20170421L; /** The network. */ private OTSRoadNetwork network; /** The XML. */ private final String xml; /** * @param simulator OTSSimulatorInterface; the simulator * @param shortName String; name of the model * @param description String; description of the model * @param xml String; the XML string */ XMLModel(final OTSSimulatorInterface simulator, final String shortName, final String description, final String xml) { super(simulator, shortName, description); this.xml = xml; } /** {@inheritDoc} */ @Override public void constructModel() throws SimRuntimeException { this.network = new OTSRoadNetwork(getShortName(), true, getSimulator()); try { XmlNetworkLaneParser.build(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)), this.network, false); LaneCombinationList ignoreList = new LaneCombinationList(); try { // TODO: These links are Aimsun Barcelona network specific. ignoreList.addLinkCombination((CrossSectionLink) this.network.getLink("928_J5"), (CrossSectionLink) this.network.getLink("928_J6")); ignoreList.addLinkCombination((CrossSectionLink) this.network.getLink("925_J1"), (CrossSectionLink) this.network.getLink("925_J2")); } catch (NullPointerException npe) { // Ignore exception that is expected to happen when the network is NOT the Barcelona test network } LaneCombinationList permittedList = new LaneCombinationList(); ConflictBuilder.buildConflicts(this.network, this.network.getGtuType(GTUType.DEFAULTS.VEHICLE), getSimulator(), new ConflictBuilder.FixedWidthGenerator(Length.instantiateSI(2.0)), ignoreList, permittedList); } catch (NetworkException | OTSGeometryException | JAXBException | URISyntaxException | XmlParserException | SAXException | ParserConfigurationException | GTUException | IOException | TrafficControlException exception) { exception.printStackTrace(); // Abusing the SimRuntimeException to propagate the message to the main method (the problem could actually be a // parsing problem) throw new SimRuntimeException(exception.getMessage()); } } /** {@inheritDoc} */ @Override public OTSRoadNetwork getNetwork() { return this.network; } /** {@inheritDoc} */ @Override public Serializable getSourceId() { return "LoadXML.Model"; } } }