View Javadoc
1   package org.opentrafficsim.graphs;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.djunits.unit.PositionUnit;
7   import org.djunits.unit.TimeUnit;
8   import org.djunits.value.StorageType;
9   import org.djunits.value.ValueException;
10  import org.djunits.value.vdouble.scalar.DoubleScalarInterface;
11  import org.djunits.value.vdouble.vector.MutablePositionVector;
12  import org.djunits.value.vdouble.vector.MutableTimeVector;
13  import org.opentrafficsim.road.network.lane.Lane;
14  import org.opentrafficsim.simulationengine.OTSSimulationException;
15  
16  /**
17   * Speed contour plot.
18   * <p>
19   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
20   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
21   * <p>
22   * $LastChangedDate: 2015-09-03 13:38:01 +0200 (Thu, 03 Sep 2015) $, @version $Revision: 1378 $, by $Author: averbraeck $,
23   * initial version Jul 29, 2014 <br>
24   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
25   */
26  public class SpeedContourPlot extends ContourPlot
27  {
28      /** */
29      private static final long serialVersionUID = 20140729L;
30  
31      /**
32       * Create a new SpeedContourPlot.
33       * @param caption String; text to show above the SpeedContourPlot
34       * @param path List&lt;Lane&gt;; the series of Lanes that will provide the data for this TrajectoryPlot
35       * @throws OTSSimulationException in case of problems initializing the graph
36       */
37      public SpeedContourPlot(final String caption, final List<Lane> path) throws OTSSimulationException
38      {
39          super(caption,
40                  new Axis(INITIALLOWERTIMEBOUND, INITIALUPPERTIMEBOUND, STANDARDTIMEGRANULARITIES,
41                          STANDARDTIMEGRANULARITIES[STANDARDINITIALTIMEGRANULARITYINDEX], "", "Time", "%.0fs"),
42                  path, 0d, 40d, 150d, "speed %.1f km/h", "%.1f km/h", 20d);
43      }
44  
45      /** {@inheritDoc} */
46      @Override
47      public final GraphType getGraphType()
48      {
49          return GraphType.SPEED_CONTOUR;
50      }
51  
52      /** Storage for the total time spent in each cell. */
53      private ArrayList<MutableTimeVector> cumulativeTimes;
54  
55      /** Storage for the total length traveled in each cell. */
56      private ArrayList<MutablePositionVector> cumulativeLengths;
57  
58      /** {@inheritDoc} */
59      @Override
60      public final Comparable<String> getSeriesKey(final int series)
61      {
62          return "speed";
63      }
64  
65      /** {@inheritDoc} */
66      @Override
67      public final void extendXRange(final DoubleScalarInterface newUpperLimit)
68      {
69          if (null == this.cumulativeTimes)
70          {
71              this.cumulativeTimes = new ArrayList<MutableTimeVector>();
72              this.cumulativeLengths = new ArrayList<MutablePositionVector>();
73          }
74          int highestBinNeeded = (int) Math.floor(this.getXAxis().getRelativeBin(newUpperLimit)
75                  * this.getXAxis().getCurrentGranularity() / this.getXAxis().getGranularities()[0]);
76          while (highestBinNeeded >= this.cumulativeTimes.size())
77          {
78              try
79              {
80                  this.cumulativeTimes.add(
81                          new MutableTimeVector(new double[this.getYAxis().getBinCount()], TimeUnit.BASE, StorageType.DENSE));
82                  this.cumulativeLengths.add(new MutablePositionVector(new double[this.getYAxis().getBinCount()],
83                          PositionUnit.METER, StorageType.DENSE));
84              }
85              catch (ValueException exception)
86              {
87                  exception.printStackTrace();
88              }
89          }
90      }
91  
92      /** {@inheritDoc} */
93      @Override
94      public final void incrementBinData(final int timeBin, final int distanceBin, final double duration,
95              final double distanceCovered, final double acceleration)
96      {
97          if (timeBin < 0 || distanceBin < 0 || 0 == duration || distanceBin >= this.getYAxis().getBinCount())
98          {
99              return;
100         }
101         MutableTimeVector timeValues = this.cumulativeTimes.get(timeBin);
102         MutablePositionVector lengthValues = this.cumulativeLengths.get(timeBin);
103         try
104         {
105             timeValues.setSI(distanceBin, timeValues.getSI(distanceBin) + duration);
106             lengthValues.setSI(distanceBin, lengthValues.getSI(distanceBin) + distanceCovered);
107         }
108         catch (ValueException exception)
109         {
110             System.err.println("Error in incrementData:");
111             exception.printStackTrace();
112         }
113     }
114 
115     /** {@inheritDoc} */
116     @Override
117     public final double computeZValue(final int firstTimeBin, final int endTimeBin, final int firstDistanceBin,
118             final int endDistanceBin)
119     {
120         double cumulativeTimeInSI = 0;
121         double cumulativeLengthInSI = 0;
122         if (firstTimeBin >= this.cumulativeTimes.size())
123         {
124             return Double.NaN;
125         }
126         try
127         {
128             for (int timeBinIndex = firstTimeBin; timeBinIndex < endTimeBin; timeBinIndex++)
129             {
130                 if (timeBinIndex >= this.cumulativeTimes.size())
131                 {
132                     break;
133                 }
134                 MutableTimeVector timeValues = this.cumulativeTimes.get(timeBinIndex);
135                 MutablePositionVector lengthValues = this.cumulativeLengths.get(timeBinIndex);
136                 for (int distanceBinIndex = firstDistanceBin; distanceBinIndex < endDistanceBin; distanceBinIndex++)
137                 {
138                     cumulativeTimeInSI += timeValues.getSI(distanceBinIndex);
139                     cumulativeLengthInSI += lengthValues.getSI(distanceBinIndex);
140                 }
141             }
142         }
143         catch (ValueException exception)
144         {
145             System.err.println(String.format("Error in getZValue(timeBinRange=[%d-%d], distanceBinRange=[%d-%d]", firstTimeBin,
146                     endTimeBin, firstDistanceBin, endDistanceBin));
147             exception.printStackTrace();
148         }
149         if (0 == cumulativeTimeInSI)
150         {
151             return Double.NaN;
152         }
153         return 3600d / 1000 * cumulativeLengthInSI / cumulativeTimeInSI;
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public final String toString()
159     {
160         return "SpeedContourPlot [cumulativeTimes.size=" + this.cumulativeTimes.size() + ", cumulativeLengths.size="
161                 + this.cumulativeLengths.size() + "]";
162     }
163 
164 }