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