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.unit.TimeUnit;
8 import org.djunits.value.StorageType;
9 import org.djunits.value.ValueException;
10 import org.djunits.value.vdouble.scalar.DoubleScalar;
11 import org.djunits.value.vdouble.vector.MutableDoubleVector;
12 import org.djunits.value.vdouble.vector.MutableLengthVector;
13 import org.djunits.value.vdouble.vector.MutableTimeVector;
14 import org.opentrafficsim.road.network.lane.Lane;
15 import org.opentrafficsim.simulationengine.OTSSimulationException;
16
17
18
19
20
21
22
23
24
25
26
27 public class SpeedContourPlot extends ContourPlot
28 {
29
30 private static final long serialVersionUID = 20140729L;
31
32
33
34
35
36
37
38 public SpeedContourPlot(final String caption, final List<Lane> path) throws OTSSimulationException
39 {
40 super(caption, new Axis(INITIALLOWERTIMEBOUND, INITIALUPPERTIMEBOUND, STANDARDTIMEGRANULARITIES,
41 STANDARDTIMEGRANULARITIES[STANDARDINITIALTIMEGRANULARITYINDEX], "", "Time", "%.0fs"), path, 0d, 40d, 150d,
42 "speed %.1f km/h", "%.1f km/h", 20d);
43 }
44
45
46 private ArrayList<MutableDoubleVector.Abs<TimeUnit>> cumulativeTimes;
47
48
49 private ArrayList<MutableDoubleVector.Abs<LengthUnit>> cumulativeLengths;
50
51
52 @Override
53 public final Comparable<String> getSeriesKey(final int series)
54 {
55 return "speed";
56 }
57
58
59 @Override
60 public final void extendXRange(final DoubleScalar<?> newUpperLimit)
61 {
62 if (null == this.cumulativeTimes)
63 {
64 this.cumulativeTimes = new ArrayList<MutableDoubleVector.Abs<TimeUnit>>();
65 this.cumulativeLengths = new ArrayList<MutableDoubleVector.Abs<LengthUnit>>();
66 }
67 int highestBinNeeded =
68 (int) Math.floor(this.getXAxis().getRelativeBin(newUpperLimit) * this.getXAxis().getCurrentGranularity()
69 / this.getXAxis().getGranularities()[0]);
70 while (highestBinNeeded >= this.cumulativeTimes.size())
71 {
72 try
73 {
74 this.cumulativeTimes.add(new MutableTimeVector.Abs(new double[this.getYAxis().getBinCount()],
75 TimeUnit.SECOND, StorageType.DENSE));
76 this.cumulativeLengths.add(new MutableLengthVector.Abs(new double[this.getYAxis().getBinCount()],
77 LengthUnit.METER, StorageType.DENSE));
78 }
79 catch (ValueException exception)
80 {
81 exception.printStackTrace();
82 }
83 }
84 }
85
86
87 @Override
88 public final void incrementBinData(final int timeBin, final int distanceBin, final double duration,
89 final double distanceCovered, final double acceleration)
90 {
91 if (timeBin < 0 || distanceBin < 0 || 0 == duration || distanceBin >= this.getYAxis().getBinCount())
92 {
93 return;
94 }
95 MutableDoubleVector.Abs<TimeUnit> timeValues = this.cumulativeTimes.get(timeBin);
96 MutableDoubleVector.Abs<LengthUnit> lengthValues = this.cumulativeLengths.get(timeBin);
97 try
98 {
99 timeValues.setSI(distanceBin, timeValues.getSI(distanceBin) + duration);
100 lengthValues.setSI(distanceBin, lengthValues.getSI(distanceBin) + distanceCovered);
101 }
102 catch (ValueException exception)
103 {
104 System.err.println("Error in incrementData:");
105 exception.printStackTrace();
106 }
107 }
108
109
110 @Override
111 public final double computeZValue(final int firstTimeBin, final int endTimeBin, final int firstDistanceBin,
112 final int endDistanceBin)
113 {
114 double cumulativeTimeInSI = 0;
115 double cumulativeLengthInSI = 0;
116 if (firstTimeBin >= this.cumulativeTimes.size())
117 {
118 return Double.NaN;
119 }
120 try
121 {
122 for (int timeBinIndex = firstTimeBin; timeBinIndex < endTimeBin; timeBinIndex++)
123 {
124 if (timeBinIndex >= this.cumulativeTimes.size())
125 {
126 break;
127 }
128 MutableDoubleVector.Abs<TimeUnit> timeValues = this.cumulativeTimes.get(timeBinIndex);
129 MutableDoubleVector.Abs<LengthUnit> lengthValues = this.cumulativeLengths.get(timeBinIndex);
130 for (int distanceBinIndex = firstDistanceBin; distanceBinIndex < endDistanceBin; distanceBinIndex++)
131 {
132 cumulativeTimeInSI += timeValues.getSI(distanceBinIndex);
133 cumulativeLengthInSI += lengthValues.getSI(distanceBinIndex);
134 }
135 }
136 }
137 catch (ValueException exception)
138 {
139 System.err.println(String.format("Error in getZValue(timeBinRange=[%d-%d], distanceBinRange=[%d-%d]",
140 firstTimeBin, endTimeBin, firstDistanceBin, endDistanceBin));
141 exception.printStackTrace();
142 }
143 if (0 == cumulativeTimeInSI)
144 {
145 return Double.NaN;
146 }
147 return 3600d / 1000 * cumulativeLengthInSI / cumulativeTimeInSI;
148 }
149
150 }