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