View Javadoc
1   package org.opentrafficsim.animation.graphs;
2   
3   import java.awt.Color;
4   import java.util.List;
5   
6   import org.djunits.unit.AccelerationUnit;
7   import org.djunits.value.ValueRuntimeException;
8   import org.djunits.value.vdouble.matrix.AccelerationMatrix;
9   import org.djunits.value.vdouble.scalar.Acceleration;
10  import org.djunits.value.vdouble.scalar.Duration;
11  import org.djunits.value.vdouble.scalar.Length;
12  import org.djutils.math.means.ArithmeticMean;
13  import org.opentrafficsim.animation.BoundsPaintScale;
14  import org.opentrafficsim.animation.Colors;
15  import org.opentrafficsim.animation.egtf.Converter;
16  import org.opentrafficsim.animation.egtf.Quantity;
17  import org.opentrafficsim.animation.graphs.ContourDataSource.ContourAdditionalDataType;
18  import org.opentrafficsim.animation.graphs.ContourDataSource.ContourDataType;
19  import org.opentrafficsim.base.OtsRuntimeException;
20  import org.opentrafficsim.kpi.sampling.Trajectory;
21  import org.opentrafficsim.kpi.sampling.TrajectoryGroup;
22  
23  /**
24   * Contour plot for acceleration.
25   * <p>
26   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
27   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
28   * </p>
29   * @author Alexander Verbraeck
30   * @author Peter Knoppers
31   * @author Wouter Schakel
32   */
33  public class ContourPlotAcceleration extends AbstractContourPlot<Acceleration>
34  {
35  
36      /** Quantity for the EGTF. */
37      private static final Quantity<Acceleration, AccelerationMatrix> QUANTITY =
38              new Quantity<>("acceleration", new Converter<AccelerationMatrix>()
39              {
40                  @Override
41                  public AccelerationMatrix convert(final double[][] filteredData)
42                  {
43                      try
44                      {
45                          return new AccelerationMatrix(filteredData, AccelerationUnit.SI);
46                      }
47                      catch (ValueRuntimeException exception)
48                      {
49                          // should not happen as filtered data comes from the EGTF
50                          throw new OtsRuntimeException("Unexpected exception while converting acceleration to output format.",
51                                  exception);
52                      }
53                  }
54              });
55  
56      /** Contour data type. */
57      private static final ContourAdditionalDataType<Acceleration, ArithmeticMean<Double, Double>> CONTOUR_DATA_TYPE =
58              new ContourAdditionalDataType<Acceleration, ArithmeticMean<Double, Double>>()
59              {
60                  @Override
61                  public ArithmeticMean<Double, Double> identity()
62                  {
63                      return new ArithmeticMean<>();
64                  }
65  
66                  @Override
67                  public ArithmeticMean<Double, Double> processSeries(final ArithmeticMean<Double, Double> intermediate,
68                          final List<TrajectoryGroup<?>> trajectories, final List<Length> xFrom, final List<Length> xTo,
69                          final Duration tFrom, final Duration tTo)
70                  {
71                      for (int i = 0; i < trajectories.size(); i++)
72                      {
73                          TrajectoryGroup<?> trajectoryGroup = trajectories.get(i);
74                          for (Trajectory<?> trajectory : trajectoryGroup.getTrajectories())
75                          {
76                              if (GraphUtil.considerTrajectory(trajectory, tFrom, tTo))
77                              {
78                                  trajectory = trajectory.subSet(xFrom.get(i), xTo.get(i), tFrom, tTo);
79                                  ContourDataType.weighted(trajectory.getA(), trajectory.getX(), intermediate);
80                              }
81                          }
82                      }
83                      return intermediate;
84                  }
85  
86                  @Override
87                  public Acceleration finalize(final ArithmeticMean<Double, Double> intermediate)
88                  {
89                      return Acceleration.ofSI(intermediate.getMean());
90                  }
91  
92                  @Override
93                  public Quantity<Acceleration, ?> getQuantity()
94                  {
95                      return QUANTITY;
96                  }
97  
98                  @Override
99                  public boolean normalize()
100                 {
101                     return false;
102                 }
103 
104             };
105 
106     /**
107      * Constructor.
108      * @param caption caption
109      * @param source data source
110      */
111     public ContourPlotAcceleration(final String caption, final ContourDataSource source)
112     {
113         super(caption, source, CONTOUR_DATA_TYPE, createPaintScale(),
114                 new LabelData<>(Acceleration.ofSI(1.0), "%.1fm/s\u00B2", "acceleration %.2f m/s\u00B2"));
115     }
116 
117     /**
118      * Creates a paint scale from red, via yellow to green.
119      * @return paint scale
120      */
121     private static BoundsPaintScale createPaintScale()
122     {
123         double[] boundaries = {-3.0, -1.5, 0.0, 1.0, 2.0};
124         Color[] colorValues = Colors.reverse(Colors.GREEN_RED_DARK);
125         return new BoundsPaintScale(boundaries, colorValues);
126     }
127 
128     @Override
129     public GraphType getGraphType()
130     {
131         return GraphType.ACCELERATION_CONTOUR;
132     }
133 
134     @Override
135     protected double scale(final double si)
136     {
137         return si;
138     }
139 
140     @Override
141     public String toString()
142     {
143         return "ContourPlotAcceleration [" + getCaption() + "]";
144     }
145 
146 }