DensityContourPlot.java

  1. package org.opentrafficsim.graphs;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. import org.djunits.unit.TimeUnit;
  5. import org.djunits.value.StorageType;
  6. import org.djunits.value.ValueException;
  7. import org.djunits.value.vdouble.scalar.DoubleScalarInterface;
  8. import org.djunits.value.vdouble.vector.MutableTimeVector;
  9. import org.opentrafficsim.road.network.lane.Lane;
  10. import org.opentrafficsim.simulationengine.OTSSimulationException;

  11. /**
  12.  * Density contour plot.
  13.  * <p>
  14.  * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  15.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  16.  * <p>
  17.  * $LastChangedDate: 2015-09-03 13:38:01 +0200 (Thu, 03 Sep 2015) $, @version $Revision: 1378 $, by $Author: averbraeck $,
  18.  * initial version Jul 28, 2014 <br>
  19.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  20.  */
  21. public class DensityContourPlot extends ContourPlot
  22. {
  23.     /** */
  24.     private static final long serialVersionUID = 20140729L;

  25.     /**
  26.      * Create a new DensityContourPlot.
  27.      * @param caption String; text to show above the DensityContourPlot
  28.      * @param path List&lt;Lane&gt;; the series of Lanes that will provide the data for this TrajectoryPlot
  29.      * @throws OTSSimulationException in case of problems initializing the graph
  30.      */
  31.     public DensityContourPlot(final String caption, final List<Lane> path) throws OTSSimulationException
  32.     {
  33.         super(caption, new Axis(INITIALLOWERTIMEBOUND, INITIALUPPERTIMEBOUND, STANDARDTIMEGRANULARITIES,
  34.             STANDARDTIMEGRANULARITIES[STANDARDINITIALTIMEGRANULARITYINDEX], "", "Time", "%.0fs"), path, 120d, 10d, 0d,
  35.             "density %.1f veh/km", "%.1f veh/km", 20d);
  36.     }

  37.     /** {@inheritDoc} */
  38.     @Override
  39.     public final GraphType getGraphType()
  40.     {
  41.         return GraphType.DENSITY_CONTOUR;
  42.     }

  43.     /** Storage for the total time spent in each cell. */
  44.     private ArrayList<MutableTimeVector> cumulativeTimes;

  45.     /** {@inheritDoc} */
  46.     @Override
  47.     public final Comparable<String> getSeriesKey(final int series)
  48.     {
  49.         return "density";
  50.     }

  51.     /** {@inheritDoc} */
  52.     @Override
  53.     public final void extendXRange(final DoubleScalarInterface newUpperLimit)
  54.     {
  55.         if (null == this.cumulativeTimes)
  56.         {
  57.             this.cumulativeTimes = new ArrayList<MutableTimeVector>();
  58.         }
  59.         final int highestBinNeeded =
  60.             (int) Math.floor(this.getXAxis().getRelativeBin(newUpperLimit) * this.getXAxis().getCurrentGranularity()
  61.                 / this.getXAxis().getGranularities()[0]);
  62.         while (highestBinNeeded >= this.cumulativeTimes.size())
  63.         {
  64.             try
  65.             {
  66.                 this.cumulativeTimes.add(new MutableTimeVector(new double[this.getYAxis().getBinCount()],
  67.                     TimeUnit.SECOND, StorageType.DENSE));
  68.             }
  69.             catch (ValueException exception)
  70.             {
  71.                 exception.printStackTrace();
  72.             }
  73.         }
  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public final void incrementBinData(final int timeBin, final int distanceBin, final double duration,
  78.         final double distanceCovered, final double acceleration)
  79.     {
  80.         if (timeBin < 0 || distanceBin < 0 || 0 == duration || distanceBin >= this.getYAxis().getBinCount())
  81.         {
  82.             return;
  83.         }
  84.         MutableTimeVector values = this.cumulativeTimes.get(timeBin);
  85.         try
  86.         {
  87.             values.setSI(distanceBin, values.getSI(distanceBin) + duration);
  88.         }
  89.         catch (ValueException exception)
  90.         {
  91.             System.err.println("Error in incrementData:");
  92.             exception.printStackTrace();
  93.         }
  94.     }

  95.     /** {@inheritDoc} */
  96.     @Override
  97.     public final double computeZValue(final int firstTimeBin, final int endTimeBin, final int firstDistanceBin,
  98.         final int endDistanceBin)
  99.     {
  100.         double cumulativeTimeInSI = 0;
  101.         if (null == this.cumulativeTimes)
  102.         {
  103.             return Double.NaN;
  104.         }
  105.         try
  106.         {
  107.             for (int timeBinIndex = firstTimeBin; timeBinIndex < endTimeBin; timeBinIndex++)
  108.             {
  109.                 MutableTimeVector values = this.cumulativeTimes.get(timeBinIndex);
  110.                 for (int distanceBinIndex = firstDistanceBin; distanceBinIndex < endDistanceBin; distanceBinIndex++)
  111.                 {
  112.                     cumulativeTimeInSI += values.getSI(distanceBinIndex);
  113.                 }
  114.             }
  115.         }
  116.         catch (ValueException exception)
  117.         {
  118.             System.err.println(String.format("Error in getZValue(timeBinRange=[%d-%d], distanceBinRange=[%d-%d]",
  119.                 firstTimeBin, endTimeBin, firstDistanceBin, endDistanceBin));
  120.             exception.printStackTrace();
  121.         }
  122.         return 1000 * cumulativeTimeInSI / this.getXAxis().getCurrentGranularity()
  123.             / this.getYAxis().getCurrentGranularity();
  124.     }

  125.     /** {@inheritDoc} */
  126.     @Override
  127.     public final String toString()
  128.     {
  129.         return "DensityContourPlot [cumulativeTimes.size=" + this.cumulativeTimes.size() + "]";
  130.     }

  131. }