View Javadoc
1   package org.opentrafficsim.draw.egtf;
2   
3   import java.util.LinkedHashMap;
4   import java.util.Map;
5   
6   /**
7    * Data source for the EGTF. These are obtained using {@code EGTF.getDataSource()}.
8    * <p>
9    * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
10   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
11   * </p>
12   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
13   */
14  public final class DataSource
15  {
16      /** Unique name. */
17      private final String name;
18  
19      /** Data stream of this data source. */
20      private final Map<String, DataStream<?>> streams = new LinkedHashMap<>();
21  
22      /**
23       * Constructor.
24       * @param name unique name
25       */
26      DataSource(final String name)
27      {
28          this.name = name;
29      }
30  
31      /**
32       * Returns the name.
33       * @return name
34       */
35      public String getName()
36      {
37          return this.name;
38      }
39  
40      /**
41       * Add a non-speed stream for the quantity to this data source.
42       * @param quantity quantity
43       * @param thetaCong standard deviation of this quantity of measurements in congestion by this data source
44       * @param thetaFree standard deviation of this quantity of measurements in free flow by this data source
45       * @param <T> implicit data type
46       * @return the created data stream
47       * @throws IllegalArgumentException if the quantity is speed
48       */
49      public <T extends Number> DataStream<T> addStream(final Quantity<T, ?> quantity, final T thetaCong, final T thetaFree)
50      {
51          return addStreamSI(quantity, thetaCong.doubleValue(), thetaFree.doubleValue());
52      }
53  
54      /**
55       * Add a stream for the quantity to this data source.
56       * @param quantity quantity
57       * @param thetaCong standard deviation of this quantity of measurements in congestion by this data source in SI
58       * @param thetaFree standard deviation of this quantity of measurements in free flow by this data source in SI
59       * @param <T> implicit data type
60       * @return the created data stream
61       */
62      public <T extends Number> DataStream<T> addStreamSI(final Quantity<T, ?> quantity, final double thetaCong,
63              final double thetaFree)
64      {
65          if (this.streams.containsKey(quantity.getName()))
66          {
67              throw new IllegalStateException(
68                      String.format("Data source %s already has a stream for quantity %s.", this.name, quantity.getName()));
69          }
70          if (thetaCong <= 0.0 || thetaFree <= 0.0)
71          {
72              throw new IllegalArgumentException("Standard deviation must be positive and above 0.");
73          }
74          DataStream<T> dataStream = new DataStream<>(this, quantity, thetaCong, thetaFree);
75          this.streams.put(quantity.getName(), dataStream);
76          return dataStream;
77      }
78  
79      /**
80       * Get a stream for the quantity of this data source. If no stream has been created, one will be created with 1.0 standard
81       * deviation.
82       * @param quantity quantity
83       * @return stream for the quantity of this data source
84       * @param <T> implicit data type
85       */
86      @SuppressWarnings({"unchecked"})
87      public <T extends Number> DataStream<T> getStream(final Quantity<T, ?> quantity)
88      {
89          if (!this.streams.containsKey(quantity.getName()))
90          {
91              addStreamSI(quantity, 1.0, 1.0);
92          }
93          return (DataStream<T>) this.streams.get(quantity.getName());
94      }
95  
96      @Override
97      public int hashCode()
98      {
99          final int prime = 31;
100         int result = 1;
101         result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
102         return result;
103     }
104 
105     @Override
106     public boolean equals(final Object obj)
107     {
108         if (this == obj)
109         {
110             return true;
111         }
112         if (obj == null)
113         {
114             return false;
115         }
116         if (getClass() != obj.getClass())
117         {
118             return false;
119         }
120         DataSource other = (DataSource) obj;
121         if (this.name == null)
122         {
123             if (other.name != null)
124             {
125                 return false;
126             }
127         }
128         else if (!this.name.equals(other.name))
129         {
130             return false;
131         }
132         return true;
133     }
134 
135     @Override
136     public String toString()
137     {
138         return "DataSource [" + this.name + "]";
139     }
140 
141 }