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