View Javadoc
1   package org.opentrafficsim.demo.carFollowing;
2   
3   import java.awt.Dimension;
4   import java.awt.FileDialog;
5   import java.awt.geom.Rectangle2D;
6   import java.io.File;
7   import java.io.IOException;
8   import java.net.MalformedURLException;
9   import java.net.URISyntaxException;
10  import java.rmi.RemoteException;
11  import java.util.ArrayList;
12  import java.util.Iterator;
13  import java.util.List;
14  
15  import javax.naming.NamingException;
16  import javax.swing.JFrame;
17  
18  import org.djunits.unit.UNITS;
19  import org.djunits.value.vdouble.scalar.Duration;
20  import org.djunits.value.vdouble.scalar.Time;
21  import org.opentrafficsim.core.dsol.AbstractOTSModel;
22  import org.opentrafficsim.core.dsol.OTSAnimator;
23  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
24  import org.opentrafficsim.core.geometry.OTSGeometryException;
25  import org.opentrafficsim.core.network.Link;
26  import org.opentrafficsim.core.network.NetworkException;
27  import org.opentrafficsim.core.network.Node;
28  import org.opentrafficsim.draw.core.OTSDrawingException;
29  import org.opentrafficsim.road.network.OTSRoadNetwork;
30  import org.opentrafficsim.road.network.factory.osm.OSMLink;
31  import org.opentrafficsim.road.network.factory.osm.OSMNetwork;
32  import org.opentrafficsim.road.network.factory.osm.OSMNode;
33  import org.opentrafficsim.road.network.factory.osm.OSMTag;
34  import org.opentrafficsim.road.network.factory.osm.events.ProgressEvent;
35  import org.opentrafficsim.road.network.factory.osm.events.ProgressListener;
36  import org.opentrafficsim.road.network.factory.osm.events.ProgressListenerImpl;
37  import org.opentrafficsim.road.network.factory.osm.events.WarningListener;
38  import org.opentrafficsim.road.network.factory.osm.events.WarningListenerImpl;
39  import org.opentrafficsim.road.network.factory.osm.input.ReadOSMFile;
40  import org.opentrafficsim.road.network.factory.osm.output.Convert;
41  import org.opentrafficsim.road.network.lane.Lane;
42  import org.opentrafficsim.swing.gui.AnimationToggles;
43  import org.opentrafficsim.swing.gui.OTSAnimationPanel;
44  import org.opentrafficsim.swing.gui.OTSSimulationApplication;
45  
46  import nl.tudelft.simulation.dsol.SimRuntimeException;
47  
48  /**
49   * <p>
50   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
51   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
52   * <p>
53   * $LastChangedDate: 2019-03-17 22:16:44 +0100 (Sun, 17 Mar 2019) $, @version $Revision: 5158 $, by $Author: averbraeck $,
54   * initial version Feb 10, 2015 <br>
55   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
56   * @author Moritz Bergmann
57   */
58  public class OpenStreetMap extends OTSSimulationApplication<OSMModel> implements UNITS
59  {
60      /** */
61      private static final long serialVersionUID = 1L;
62  
63      /**
64       * Construct the OpenStreetMap demo.
65       * @param model OSMModel; the model
66       * @param panel OTSAnimationPanel; the Swing panel
67       * @throws OTSDrawingException on animation error
68       */
69      public OpenStreetMap(final OSMModel model, final OTSAnimationPanel panel) throws OTSDrawingException
70      {
71          super(model, panel);
72      }
73  
74      /** {@inheritDoc} */
75      @Override
76      protected void setAnimationToggles()
77      {
78          AnimationToggles.setTextAnimationTogglesFull(getAnimationPanel());
79      }
80  
81      /**
82       * Main program.
83       * @param args String[]; the command line arguments (not used)
84       */
85      public static void main(final String[] args)
86      {
87          demo(true);
88      }
89  
90      /**
91       * Start the demo.
92       * @param exitOnClose boolean; when running stand-alone: true; when running as part of a demo: false
93       */
94      public static void demo(final boolean exitOnClose)
95      {
96          try
97          {
98              String filepath = chooseFile();
99              if (filepath != null)
100             {
101                 OTSAnimator simulator = new OTSAnimator();
102                 final OSMModel osmModel = new OSMModel(simulator, filepath);
103                 simulator.initialize(Time.ZERO, Duration.ZERO, Duration.createSI(3600.0), osmModel);
104                 OTSAnimationPanel animationPanel = new OTSAnimationPanel(osmModel.getNetwork().getExtent(),
105                         new Dimension(800, 600), simulator, osmModel, DEFAULT_COLORER, osmModel.getNetwork());
106                 OpenStreetMap app = new OpenStreetMap(osmModel, animationPanel);
107                 app.setExitOnClose(exitOnClose);
108             }
109             else
110             {
111                 if (exitOnClose)
112                 {
113                     System.exit(0);
114                 }
115             }
116         }
117         catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException exception)
118         {
119             exception.printStackTrace();
120         }
121     }
122 
123     /**
124      * choose a file and construct the model.
125      * @return a model based on a given file
126      */
127     protected static final String chooseFile()
128     {
129         JFrame frame = new JFrame();
130         FileDialog fd = new FileDialog(frame, "Choose a file", FileDialog.LOAD);
131         fd.setFile("*.osm");
132         fd.setVisible(true);
133         File[] file = fd.getFiles();
134         if (file.length == 0)
135         {
136             return null;
137         }
138         String filename = fd.getFile();
139         String filepath = null;
140         try
141         {
142             filepath = file[0].toURI().toURL().toString();
143         }
144         catch (MalformedURLException e)
145         {
146             e.printStackTrace();
147         }
148         if (filename == null)
149         {
150             System.out.println("You cancelled the choice");
151             return null;
152         }
153         return filepath;
154     }
155 }
156 
157 /**
158  * <p>
159  * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
160  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
161  * <p>
162  * $LastChangedDate: 2019-03-17 22:16:44 +0100 (Sun, 17 Mar 2019) $, @version $Revision: 5158 $, by $Author: averbraeck $,
163  * initial version Feb 10, 2015 <br>
164  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
165  * @author Moritz Bergmann
166  */
167 class OSMModel extends AbstractOTSModel
168 {
169     /** */
170     private static final long serialVersionUID = 20150227L;
171 
172     /** Provided Network. */
173     private OSMNetwork osmNetwork;
174 
175     /** Provided lanes. */
176     private List<Lane> lanes = new ArrayList<>();
177 
178     /** The OTS network. */
179     private OTSRoadNetwork otsNetwork = new OTSRoadNetwork("network", true);
180 
181     /** The ProgressListener. */
182     private ProgressListener progressListener;
183 
184     /** The WarningListener. */
185     private WarningListener warningListener;
186 
187     /** The coordinate converter. */
188     private Convert converter;
189 
190     /** Bounding rectangle of the loaded map. */
191     private Rectangle2D rectangle = null;
192 
193     /** the file path. */
194     private String filepath;
195 
196     /**
197      * @param simulator OTSSimulatorInterface; the simulator
198      * @param filepath String; the path to the OSM file
199      */
200     OSMModel(final OTSSimulatorInterface simulator, final String filepath)
201     {
202         super(simulator);
203         this.filepath = filepath;
204     }
205 
206     /** {@inheritDoc} */
207     @Override
208     public void constructModel() throws SimRuntimeException
209     {
210         this.converter = new Convert();
211         System.out.println("Opening file " + this.filepath);
212         ArrayList<OSMTag> wantedTags = new ArrayList<>();
213         wantedTags.add(new OSMTag("highway", "primary"));
214         wantedTags.add(new OSMTag("highway", "secondary"));
215         wantedTags.add(new OSMTag("highway", "tertiary"));
216         wantedTags.add(new OSMTag("highway", "cycleway"));
217         wantedTags.add(new OSMTag("highway", "trunk"));
218         wantedTags.add(new OSMTag("highway", "path"));
219         wantedTags.add(new OSMTag("cycleway", "lane"));
220         wantedTags.add(new OSMTag("highway", "residential"));
221         wantedTags.add(new OSMTag("highway", "service"));
222         wantedTags.add(new OSMTag("highway", "motorway"));
223         wantedTags.add(new OSMTag("highway", "bus_stop"));
224         wantedTags.add(new OSMTag("highway", "motorway_link"));
225         wantedTags.add(new OSMTag("highway", "unclassified"));
226         wantedTags.add(new OSMTag("highway", "footway"));
227         wantedTags.add(new OSMTag("cycleway", "track"));
228         wantedTags.add(new OSMTag("highway", "road"));
229         wantedTags.add(new OSMTag("highway", "pedestrian"));
230         wantedTags.add(new OSMTag("highway", "track"));
231         wantedTags.add(new OSMTag("highway", "living_street"));
232         wantedTags.add(new OSMTag("highway", "tertiary_link"));
233         wantedTags.add(new OSMTag("highway", "secondary_link"));
234         wantedTags.add(new OSMTag("highway", "primary_link"));
235         wantedTags.add(new OSMTag("highway", "trunk_link"));
236         ArrayList<String> ft = new ArrayList<>();
237         try
238         {
239             System.out.println(this.filepath);
240             this.progressListener = new ProgressListenerImpl();
241             this.warningListener = new WarningListenerImpl();
242             ReadOSMFile osmf = new ReadOSMFile(this.filepath, wantedTags, ft, this.progressListener);
243             OSMNetwork net = osmf.getNetwork();
244             // net.removeRedundancy(); // Defective; do not call removeRedundancy
245             this.osmNetwork = net; // new OSMNetwork(net); // Why would you make a copy?
246             this.otsNetwork = new OTSRoadNetwork(this.osmNetwork.getName(), true);
247             for (OSMNode osmNode : this.osmNetwork.getNodes().values())
248             {
249                 try
250                 {
251                     this.converter.convertNode(this.otsNetwork, osmNode);
252                 }
253                 catch (NetworkException ne)
254                 {
255                     System.out.println(ne.getMessage());
256                 }
257             }
258             for (OSMLink osmLink : this.osmNetwork.getLinks())
259             {
260                 // TODO OTS-256
261                 Link link = this.converter.convertLink(this.otsNetwork, osmLink, null);
262                 this.otsNetwork.addLink(link);
263             }
264             this.osmNetwork.makeLinks(this.warningListener, this.progressListener);
265         }
266         catch (URISyntaxException | IOException | NetworkException | OTSGeometryException exception)
267         {
268             exception.printStackTrace();
269             return;
270         }
271 
272         Iterator<Node> count = this.otsNetwork.getNodeMap().values().iterator();
273         Rectangle2D area = null;
274         while (count.hasNext())
275         {
276             Node node = count.next();
277             if (null == area)
278             {
279                 area = new Rectangle2D.Double(node.getPoint().x, node.getPoint().y, 0, 0);
280             }
281             else
282             {
283                 area = area.createUnion(new Rectangle2D.Double(node.getPoint().x, node.getPoint().y, 0, 0));
284             }
285         }
286         this.rectangle = area;
287 
288         this.otsNetwork = new OTSRoadNetwork(this.osmNetwork.getName(), true);
289         for (OSMNode osmNode : this.osmNetwork.getNodes().values())
290         {
291             try
292             {
293                 this.converter.convertNode(this.otsNetwork, osmNode);
294             }
295             catch (Exception e)
296             {
297                 System.err.println(e.getMessage());
298             }
299         }
300         for (OSMLink osmLink : this.osmNetwork.getLinks())
301         {
302             try
303             {
304                 this.converter.convertLink(this.otsNetwork, osmLink, this.simulator);
305             }
306             catch (Exception e)
307             {
308                 System.err.println(e.getMessage());
309             }
310         }
311         Convert.findSinksandSources(this.osmNetwork, this.progressListener);
312         this.progressListener.progress(
313                 new ProgressEvent(this.osmNetwork, "Creation the lanes on " + this.osmNetwork.getLinks().size() + " links"));
314         double total = this.osmNetwork.getLinks().size();
315         double counter = 0;
316         double nextPercentage = 5.0;
317         for (OSMLink link : this.osmNetwork.getLinks())
318         {
319             try
320             {
321                 this.lanes.addAll(this.converter.makeLanes(this.otsNetwork, link, this.simulator, this.warningListener));
322             }
323             catch (Exception e)
324             {
325                 e.printStackTrace();
326                 System.err.println(e.getMessage());
327             }
328             counter++;
329             double currentPercentage = counter / total * 100;
330             if (currentPercentage >= nextPercentage)
331             {
332                 this.progressListener.progress(new ProgressEvent(this, nextPercentage + "% Progress"));
333                 nextPercentage += 5.0D;
334             }
335         }
336         System.out.println("Number of Links: " + this.otsNetwork.getLinkMap().size());
337         System.out.println("Number of Nodes: " + this.otsNetwork.getNodeMap().size());
338         System.out.println("Number of Lanes: " + this.lanes.size());
339     }
340 
341     /** {@inheritDoc} */
342     @Override
343     public OTSRoadNetwork getNetwork()
344     {
345         return this.otsNetwork;
346     }
347 
348     /**
349      * @return rectangle
350      */
351     public final Rectangle2D getRectangle()
352     {
353         return this.rectangle;
354     }
355 }