View Javadoc
1   package org.opentrafficsim.graphs;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.djunits.unit.LengthUnit;
7   import org.djunits.value.StorageType;
8   import org.djunits.value.ValueException;
9   import org.djunits.value.vdouble.scalar.DoubleScalar;
10  import org.djunits.value.vdouble.vector.MutableLengthVector;
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-2015 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, new Axis(INITIALLOWERTIMEBOUND, INITIALUPPERTIMEBOUND, STANDARDTIMEGRANULARITIES,
38              STANDARDTIMEGRANULARITIES[STANDARDINITIALTIMEGRANULARITYINDEX], "", "Time", "%.0fs"), path, 2500d, 1500d,
39              0d, "flow %.0f veh/h", "%.0f veh/h", 500d);
40      }
41  
42      /** Storage for the total length traveled in each cell. */
43      private ArrayList<MutableLengthVector.Abs> cumulativeLengths;
44  
45      /** {@inheritDoc} */
46      @Override
47      public final Comparable<String> getSeriesKey(final int series)
48      {
49          return "flow";
50      }
51  
52      /** {@inheritDoc} */
53      @Override
54      public final void extendXRange(final DoubleScalar<?> newUpperLimit)
55      {
56          if (null == this.cumulativeLengths)
57          {
58              this.cumulativeLengths = new ArrayList<MutableLengthVector.Abs>();
59          }
60          final int highestBinNeeded =
61              (int) Math.floor(this.getXAxis().getRelativeBin(newUpperLimit) * this.getXAxis().getCurrentGranularity()
62                  / this.getXAxis().getGranularities()[0]);
63          while (highestBinNeeded >= this.cumulativeLengths.size())
64          {
65              try
66              {
67                  this.cumulativeLengths.add(new MutableLengthVector.Abs(new double[this.getYAxis().getBinCount()],
68                      LengthUnit.METER, StorageType.DENSE));
69              }
70              catch (ValueException exception)
71              {
72                  exception.printStackTrace();
73              }
74          }
75      }
76  
77      /** {@inheritDoc} */
78      @Override
79      public final void incrementBinData(final int timeBin, final int distanceBin, final double duration,
80          final double distanceCovered, final double acceleration)
81      {
82          if (timeBin < 0 || distanceBin < 0 || 0 == duration || distanceBin >= this.getYAxis().getBinCount())
83          {
84              return;
85          }
86          while (timeBin >= this.cumulativeLengths.size())
87          {
88              try
89              {
90                  this.cumulativeLengths.add(new MutableLengthVector.Abs(new double[this.getYAxis().getBinCount()],
91                      LengthUnit.METER, StorageType.DENSE));
92              }
93              catch (ValueException exception)
94              {
95                  exception.printStackTrace();
96              }
97          }
98          MutableLengthVector.Abs values = this.cumulativeLengths.get(timeBin);
99          try
100         {
101             values.setSI(distanceBin, values.getSI(distanceBin) + distanceCovered);
102         }
103         catch (ValueException exception)
104         {
105             System.err.println("Error in incrementData:");
106             exception.printStackTrace();
107         }
108     }
109 
110     /** {@inheritDoc} */
111     @Override
112     public final double computeZValue(final int firstTimeBin, final int endTimeBin, final int firstDistanceBin,
113         final int endDistanceBin)
114     {
115         double cumulativeLengthInSI = 0;
116         if (firstTimeBin >= this.cumulativeLengths.size())
117         {
118             return Double.NaN;
119         }
120         try
121         {
122             for (int timeBinIndex = firstTimeBin; timeBinIndex < endTimeBin; timeBinIndex++)
123             {
124                 if (timeBinIndex >= this.cumulativeLengths.size())
125                 {
126                     break;
127                 }
128                 MutableLengthVector.Abs values = this.cumulativeLengths.get(timeBinIndex);
129                 for (int distanceBinIndex = firstDistanceBin; distanceBinIndex < endDistanceBin; distanceBinIndex++)
130                 {
131                     cumulativeLengthInSI += values.getSI(distanceBinIndex);
132                 }
133             }
134         }
135         catch (ValueException exception)
136         {
137             System.err.println(String.format("Error in getZValue(timeBinRange=[%d-%d], distanceBinRange=[%d-%d]",
138                 firstTimeBin, endTimeBin, firstDistanceBin, endDistanceBin));
139             exception.printStackTrace();
140         }
141         return 3600 * cumulativeLengthInSI / this.getXAxis().getCurrentGranularity()
142             / this.getYAxis().getCurrentGranularity();
143     }
144 
145 }