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