View Javadoc
1   package org.opentrafficsim.road.test;
2   
3   import java.awt.geom.Rectangle2D;
4   import java.awt.geom.Rectangle2D.Double;
5   import java.io.IOException;
6   import java.io.Serializable;
7   import java.net.URL;
8   import java.util.ArrayList;
9   
10  import javax.naming.NamingException;
11  import javax.swing.JPanel;
12  import javax.swing.SwingUtilities;
13  import javax.xml.parsers.ParserConfigurationException;
14  
15  import nl.javel.gisbeans.io.esri.CoordinateTransform;
16  import nl.tudelft.simulation.dsol.SimRuntimeException;
17  import nl.tudelft.simulation.dsol.animation.D2.GisRenderable2D;
18  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
19  import nl.tudelft.simulation.jstats.distributions.DistConstant;
20  import nl.tudelft.simulation.jstats.distributions.DistExponential;
21  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
22  import nl.tudelft.simulation.jstats.streams.StreamInterface;
23  import nl.tudelft.simulation.language.io.URLResource;
24  
25  import org.djunits.unit.AccelerationUnit;
26  import org.djunits.unit.LengthUnit;
27  import org.djunits.unit.SpeedUnit;
28  import org.djunits.unit.TimeUnit;
29  import org.djunits.value.vdouble.scalar.Acceleration;
30  import org.djunits.value.vdouble.scalar.DoubleScalar;
31  import org.djunits.value.vdouble.scalar.Duration;
32  import org.djunits.value.vdouble.scalar.Length;
33  import org.djunits.value.vdouble.scalar.Speed;
34  import org.djunits.value.vdouble.scalar.Time;
35  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
36  import org.opentrafficsim.core.dsol.OTSModelInterface;
37  import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
38  import org.opentrafficsim.core.geometry.OTSGeometryException;
39  import org.opentrafficsim.core.gtu.GTUDirectionality;
40  import org.opentrafficsim.core.gtu.GTUException;
41  import org.opentrafficsim.core.gtu.GTUType;
42  import org.opentrafficsim.core.gtu.animation.AccelerationGTUColorer;
43  import org.opentrafficsim.core.gtu.animation.GTUColorer;
44  import org.opentrafficsim.core.gtu.animation.IDGTUColorer;
45  import org.opentrafficsim.core.gtu.animation.SpeedGTUColorer;
46  import org.opentrafficsim.core.gtu.animation.SwitchableGTUColorer;
47  import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
48  import org.opentrafficsim.core.gtu.plan.tactical.TacticalPlanner;
49  import org.opentrafficsim.core.network.NetworkException;
50  import org.opentrafficsim.core.network.OTSNetwork;
51  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
52  import org.opentrafficsim.road.gtu.generator.GTUGeneratorIndividual;
53  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
54  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlanner;
55  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlannerFactory;
56  import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
57  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
58  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
59  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
60  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
61  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
62  import org.opentrafficsim.road.network.factory.xml.XmlNetworkLaneParser;
63  import org.opentrafficsim.road.network.lane.CrossSectionLink;
64  import org.opentrafficsim.road.network.lane.Lane;
65  import org.opentrafficsim.road.test.TestGMParser.WGS84ToRDNewTransform.Coords;
66  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
67  import org.opentrafficsim.simulationengine.OTSSimulationException;
68  import org.opentrafficsim.simulationengine.properties.AbstractProperty;
69  import org.opentrafficsim.simulationengine.properties.PropertyException;
70  import org.xml.sax.SAXException;
71  
72  /**
73   * <p>
74   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
75   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
76   * <p>
77   * $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $,
78   * initial version Oct 17, 2014 <br>
79   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
80   */
81  public class TestGMParser extends AbstractWrappableAnimation
82  {
83      /** */
84      private static final long serialVersionUID = 1L;
85  
86      /**
87       * Main program.
88       * @param args String[]; the command line arguments (not used)
89       * @throws SimRuntimeException should never happen
90       */
91      public static void main(final String[] args) throws SimRuntimeException
92      {
93          SwingUtilities.invokeLater(new Runnable()
94          {
95              @Override
96              public void run()
97              {
98                  try
99                  {
100                     TestGMParser xmlModel = new TestGMParser();
101                     // 1 hour simulation run for testing
102                     xmlModel.buildAnimator(new Time(0.0, TimeUnit.SECOND), new Duration(0.0, TimeUnit.SECOND), new Duration(
103                             60.0, TimeUnit.MINUTE), new ArrayList<AbstractProperty<?>>(), null, true);
104                 }
105                 catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
106                 {
107                     exception.printStackTrace();
108                 }
109             }
110         });
111     }
112 
113     /** {@inheritDoc} */
114     @Override
115     public final String shortName()
116     {
117         return "TestGMModel";
118     }
119 
120     /** {@inheritDoc} */
121     @Override
122     public final String description()
123     {
124         return "TestGMModel";
125     }
126 
127     /** {@inheritDoc} */
128     @Override
129     public final void stopTimersThreads()
130     {
131         super.stopTimersThreads();
132     }
133 
134     /** {@inheritDoc} */
135     @Override
136     protected final JPanel makeCharts()
137     {
138         return null;
139     }
140 
141     /** {@inheritDoc} */
142     @Override
143     protected final OTSModelInterface makeModel(final GTUColorer colorer)
144     {
145         return new TestGMModel();
146     }
147 
148     /** {@inheritDoc} */
149     @Override
150     protected final Double makeAnimationRectangle()
151     {
152         return new Rectangle2D.Double(0, 2900, 1400, 1200);
153     }
154 
155     /** {@inheritDoc} */
156     @Override
157     public String toString()
158     {
159         return "TestGMParser []";
160     }
161 
162     /**
163      * Model to test the GM XML parser.
164      * <p>
165      * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. <br>
166      * All rights reserved. BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim
167      * License</a>.
168      * <p>
169      * $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $,
170      * initial version un 27, 2015 <br>
171      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
172      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
173      */
174     class TestGMModel implements OTSModelInterface, Serializable
175     {
176         /** */
177         private static final long serialVersionUID = 20141121L;
178 
179         /** The simulator. */
180         private OTSDEVSSimulatorInterface simulator;
181 
182         /** {@inheritDoc} */
183         @Override
184         public final void constructModel(
185                 final SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> pSimulator)
186                 throws SimRuntimeException
187         {
188             this.simulator = (OTSDEVSSimulatorInterface) pSimulator;
189             URL url = URLResource.getResource("/networkv2_90km_V5i2.xml");
190             XmlNetworkLaneParser nlp = new XmlNetworkLaneParser(this.simulator);
191             OTSNetwork network = null;
192             try
193             {
194                 network = nlp.build(url);
195             }
196             catch (NetworkException | ParserConfigurationException | SAXException | IOException | NamingException
197                     | GTUException | OTSGeometryException exception)
198             {
199                 exception.printStackTrace();
200             }
201 
202             URL gisURL = URLResource.getResource("/N201/map.xml");
203             System.err.println("GIS-map file: " + gisURL.toString());
204             CoordinateTransform rdto0 = new CoordinateTransformRD(104450, 478845);
205             new GisRenderable2D(this.simulator, gisURL, rdto0);
206 
207             // make the GTU generators.
208             GTUType carType = new GTUType("CAR");
209             StreamInterface stream = new MersenneTwister(1);
210             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> initialSpeedDist =
211                     new ContinuousDistDoubleScalar.Rel<>(new DistConstant(stream, 0.0), SpeedUnit.METER_PER_SECOND);
212             ContinuousDistDoubleScalar.Rel<Duration, TimeUnit> interarrivelTimeDist =
213                     new ContinuousDistDoubleScalar.Rel<>(new DistExponential(stream, 7.0), TimeUnit.SECOND);
214             ContinuousDistDoubleScalar.Rel<Length, LengthUnit> lengthDist =
215                     new ContinuousDistDoubleScalar.Rel<>(new DistConstant(stream, 4.5), LengthUnit.METER);
216             ContinuousDistDoubleScalar.Rel<Length, LengthUnit> widthDist =
217                     new ContinuousDistDoubleScalar.Rel<>(new DistConstant(stream, 2.0), LengthUnit.METER);
218             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> maximumSpeedDist =
219                     new ContinuousDistDoubleScalar.Rel<>(new DistConstant(stream, 140.0), SpeedUnit.KM_PER_HOUR);
220             int maxGTUs = Integer.MAX_VALUE;
221             Time startTime = Time.ZERO;
222             Time endTime = new Time(1E24, TimeUnit.HOUR);
223             GTUColorer gtuColorer =
224                     new SwitchableGTUColorer(0, new IDGTUColorer(),
225                             new SpeedGTUColorer(new Speed(100.0, SpeedUnit.KM_PER_HOUR)), new AccelerationGTUColorer(
226                                     new Acceleration(-1.0, AccelerationUnit.METER_PER_SECOND_2), new Acceleration(1.0,
227                                             AccelerationUnit.METER_PER_SECOND_2)));
228             
229             LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFactory =
230                     new LaneBasedStrategicalRoutePlannerFactory(
231                         new LaneBasedGTUFollowingTacticalPlannerFactory(new IDMPlusOld()));
232 
233             CrossSectionLink L2a = (CrossSectionLink) network.getLink("L2a");
234             Lane L2a_A2 = (Lane) L2a.getCrossSectionElement("A2");
235             Lane L2a_A3 = (Lane) L2a.getCrossSectionElement("A3");
236             new GTUGeneratorIndividual("L2a_A2", this.simulator, carType, LaneBasedIndividualGTU.class,
237                 initialSpeedDist, interarrivelTimeDist, lengthDist, widthDist, maximumSpeedDist, maxGTUs, startTime,
238                 endTime, L2a_A2, new Length(10.0, LengthUnit.METER), GTUDirectionality.DIR_PLUS, gtuColorer,
239                 strategicalPlannerFactory, network);
240             new GTUGeneratorIndividual("L2a_A3", this.simulator, carType, LaneBasedIndividualGTU.class,
241                 initialSpeedDist, interarrivelTimeDist, lengthDist, widthDist, maximumSpeedDist, maxGTUs, startTime,
242                 endTime, L2a_A3, new Length(10.0, LengthUnit.METER), GTUDirectionality.DIR_PLUS, gtuColorer,
243                 strategicalPlannerFactory, network);
244 
245             CrossSectionLink L49b = (CrossSectionLink) network.getLink("L49b");
246             Lane L49b_A1 = (Lane) L49b.getCrossSectionElement("A1");
247             Lane L49b_A2 = (Lane) L49b.getCrossSectionElement("A2");
248             new GTUGeneratorIndividual("L49b_A1", this.simulator, carType, LaneBasedIndividualGTU.class,
249                 initialSpeedDist, interarrivelTimeDist, lengthDist, widthDist, maximumSpeedDist, maxGTUs, startTime,
250                 endTime, L49b_A1, new Length(10.0, LengthUnit.METER), GTUDirectionality.DIR_PLUS, gtuColorer,
251                 strategicalPlannerFactory, network);
252             new GTUGeneratorIndividual("L49b_A2", this.simulator, carType, LaneBasedIndividualGTU.class,
253                 initialSpeedDist, interarrivelTimeDist, lengthDist, widthDist, maximumSpeedDist, maxGTUs, startTime,
254                 endTime, L49b_A2, new Length(10.0, LengthUnit.METER), GTUDirectionality.DIR_PLUS, gtuColorer,
255                 strategicalPlannerFactory, network);
256         }
257 
258         /** {@inheritDoc} */
259         @Override
260         public SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getSimulator()
261 
262         {
263             return this.simulator;
264         }
265 
266         /** {@inheritDoc} */
267         @Override
268         public final String toString()
269         {
270             return "TestGMModel [simulator=" + this.simulator + "]";
271         }
272 
273     }
274 
275     /**
276      * Convert coordinates to/from the Dutch RD system.
277      */
278     class CoordinateTransformRD implements CoordinateTransform, Serializable
279     {
280         /** */
281         private static final long serialVersionUID = 20141017L;
282 
283         /** */
284         final double dx;
285 
286         /** */
287         final double dy;
288 
289         /**
290          * @param dx x transform
291          * @param dy y transform
292          */
293         public CoordinateTransformRD(final double dx, final double dy)
294         {
295             this.dx = dx;
296             this.dy = dy;
297         }
298 
299         /** {@inheritDoc} */
300         @Override
301         public float[] floatTransform(double x, double y)
302         {
303             double[] d = doubleTransform(x, y);
304             return new float[] { (float) d[0], (float) d[1] };
305         }
306 
307         /** {@inheritDoc} */
308         @Override
309         public double[] doubleTransform(double x, double y)
310         {
311             try
312             {
313                 Coords c = WGS84ToRDNewTransform.ellipswgs842rd(x, y);
314                 return new double[] { c.x - this.dx, c.y - this.dy };
315             }
316             catch (Exception exception)
317             {
318                 exception.printStackTrace();
319                 return new double[] { 0, 0 };
320             }
321         }
322 
323         /** {@inheritDoc} */
324         @Override
325         public final String toString()
326         {
327             return "CoordinateTransformRD [dx=" + this.dx + ", dy=" + this.dy + "]";
328         }
329     }
330 
331     /**
332      * <p>
333      * Copyright (c) 2011 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. The
334      * source code and binary code of this software is proprietary information of Delft University of Technology. Specific
335      * MathTransform for WGS84 WGS84 (EPSG:4326) to RD_new (EPSG:28992) conversions. Code based on C code by Peter Knoppers as
336      * applied <a href="http://www.regiolab-delft.nl/?q=node/36">here</a>, which is based on <a
337      * href="http://www.dekoepel.nl/pdf/Transformatieformules.pdf">this</a> paper.
338      * @author Gert-Jan Stolk
339      **/
340     public static class WGS84ToRDNewTransform
341     {
342 
343         /** */
344         private static final long serialVersionUID = 20141017L;
345 
346         //@formatter:off
347         private static final double r[][] = { /* p down, q right */
348             {  155000.00, 190094.945,   -0.008, -32.391, 0.0   , },
349             {     -0.705, -11832.228,    0.0  ,   0.608, 0.0   , },
350             {      0.0  ,   -114.221,    0.0  ,   0.148, 0.0   , },
351             {      0.0  ,      2.340,    0.0  ,   0.0  , 0.0   , },
352             {      0.0  ,      0.0  ,    0.0  ,   0.0  , 0.0   , }};
353         private static final double s[][] = { /* p down, q right */
354             { 463000.00 ,      0.433, 3638.893,   0.0  ,  0.092, },
355             { 309056.544,     -0.032, -157.984,   0.0  , -0.054, },
356             {     73.077,      0.0  ,   -6.439,   0.0  ,  0.0  , },
357             {     59.788,      0.0  ,    0.0  ,   0.0  ,  0.0  , },
358             {      0.0  ,      0.0  ,    0.0  ,   0.0  ,  0.0  , }};
359         //@formatter:on
360 
361         public static void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws Exception
362         {
363             int offsetDelta = dstOff - srcOff;
364             for (int i = srcOff; i < srcOff + numPts && i + 1 < srcPts.length && i + offsetDelta + 1 < dstPts.length; i += 2)
365             {
366                 Coords transformedCoords = ellipswgs842rd(srcPts[i], srcPts[i + 1]);
367                 dstPts[i + offsetDelta] = transformedCoords.x;
368                 dstPts[i + offsetDelta + 1] = transformedCoords.y;
369             }
370         }
371 
372         private static Coords ellipswgs842rd(double EW, double NS)
373         {
374             Coords result = new Coords(0, 0);
375             int p;
376             double pown = 1;
377             double dn = 0.36 * (NS - 52.15517440);
378             double de = 0.36 * (EW - 5.38720621);
379             if (NS <= 50 || NS >= 54 || EW <= 3 || (EW >= 8))
380             {
381                 System.err.println("Error: ellipswgs842rd input out of range (" + EW + ", " + NS + ")");
382             }
383 
384             for (p = 0; p < 5; p++)
385             {
386                 double powe = 1;
387                 int q;
388 
389                 for (q = 0; q < 5; q++)
390                 {
391                     result.x += r[p][q] * powe * pown;
392                     result.y += s[p][q] * powe * pown;
393                     powe *= de;
394                 }
395                 pown *= dn;
396             }
397             return result;
398         }
399 
400         /**
401          * Coordinate pair.
402          */
403         static class Coords implements Serializable
404         {
405             /** */
406             private static final long serialVersionUID = 20141017L;
407 
408             public double x, y;
409 
410             public Coords(double x, double y)
411             {
412                 this.x = x;
413                 this.y = y;
414             }
415 
416             /** {@inheritDoc} */
417             @Override
418             public final String toString()
419             {
420                 return "Coords [x=" + this.x + ", y=" + this.y + "]";
421             }
422 
423         }
424 
425         /** {@inheritDoc} */
426         @Override
427         public final String toString()
428         {
429             return "WGS84ToRDNewTransform []";
430         }
431 
432     }
433 
434 }