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