View Javadoc
1   package org.opentrafficsim.road.gtu.generator.od;
2   
3   import java.util.HashMap;
4   import java.util.Map;
5   
6   import org.djunits.value.vdouble.scalar.Frequency;
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djutils.exceptions.Throw;
9   import org.opentrafficsim.core.gtu.GTUType;
10  import org.opentrafficsim.core.idgenerator.IdGenerator;
11  import org.opentrafficsim.core.network.LinkType;
12  import org.opentrafficsim.core.network.Node;
13  import org.opentrafficsim.road.gtu.generator.CFBARoomChecker;
14  import org.opentrafficsim.road.gtu.generator.GeneratorPositions.LaneBias;
15  import org.opentrafficsim.road.gtu.generator.GeneratorPositions.LaneBiases;
16  import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
17  import org.opentrafficsim.road.gtu.generator.MarkovCorrelation;
18  import org.opentrafficsim.road.gtu.generator.headway.ArrivalsHeadwayGenerator.HeadwayDistribution;
19  import org.opentrafficsim.road.network.lane.Lane;
20  
21  /**
22   * Options for vehicle generation based on an OD matrix.
23   * <p>
24   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
25   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
26   * <p>
27   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 dec. 2017 <br>
28   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
29   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
30   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
31   */
32  public class ODOptions
33  {
34  
35      /** Headway randomization option. */
36      public static final Option<HeadwayDistribution> HEADWAY_DIST =
37              new Option<>("headway distribution", HeadwayDistribution.EXPONENTIAL);
38  
39      /** ID generator option. */
40      public static final Option<IdGenerator> GTU_ID = new Option<>("gtu id", new IdGenerator(""));
41  
42      /** GTU characteristics generator option. */
43      public static final Option<GTUCharacteristicsGeneratorOD> GTU_TYPE =
44              new Option<>("gtu type", new DefaultGTUCharacteristicsGeneratorOD());
45  
46      /** Room checker option. */
47      public static final Option<RoomChecker> ROOM_CHECKER = new Option<>("room checker", new CFBARoomChecker());
48  
49      /** Markov chain for GTU type option. */
50      public static final Option<MarkovCorrelation<GTUType, Frequency>> MARKOV = new Option<>("markov", null);
51  
52      /** Lane bias. Default is Truck: truck right (strong right, max 2 lanes), Vehicle (other): weak left. */
53      public static final Option<LaneBiases> LANE_BIAS = new Option<>("lane bias",
54              new LaneBiases().addBias(GTUType.TRUCK, LaneBias.TRUCK_RIGHT).addBias(GTUType.VEHICLE, LaneBias.WEAK_LEFT));
55  
56      /** Initial distance over which lane changes shouldn't be performed option. */
57      public static final Option<Length> NO_LC_DIST = new Option<>("no lc distance", null);
58  
59      /** Options overall. */
60      private OptionSet<Void> options = new OptionSet<>();
61  
62      /** Options per lane. */
63      private OptionSet<Lane> laneOptions = new OptionSet<>();
64  
65      /** Options per node. */
66      private OptionSet<Node> nodeOptions = new OptionSet<>();
67  
68      /** Options per road type. */
69      private OptionSet<LinkType> linkTypeOptions = new OptionSet<>();
70  
71      /**
72       * Set option value.
73       * @param option Option&lt;K&gt;; option
74       * @param value K; option value
75       * @param <K> value type
76       * @return this option set
77       */
78      public final <K> ODOptions set(final Option<K> option, final K value)
79      {
80          this.options.set(null, option, value);
81          return this;
82      }
83  
84      /**
85       * Set option value for lane.
86       * @param lane Lane; lane
87       * @param option Option&lt;K&gt;; option
88       * @param value K; option value
89       * @param <K> value type
90       * @return this option set
91       */
92      public final <K> ODOptions set(final Lane lane, final Option<K> option, final K value)
93      {
94          this.laneOptions.set(lane, option, value);
95          return this;
96      }
97  
98      /**
99       * Set option value for node.
100      * @param node Node; node
101      * @param option Option&lt;K&gt;; option
102      * @param value K; option value
103      * @param <K> value type
104      * @return this option set
105      */
106     public final <K> ODOptions set(final Node node, final Option<K> option, final K value)
107     {
108         this.nodeOptions.set(node, option, value);
109         return this;
110     }
111 
112     /**
113      * Set option value for link type.
114      * @param linkType LinkType; link type
115      * @param option Option&lt;K&gt;; option
116      * @param value K; option value
117      * @param <K> value type
118      * @return this option set
119      */
120     public final <K> ODOptions set(final LinkType linkType, final Option<K> option, final K value)
121     {
122         this.linkTypeOptions.set(linkType, option, value);
123         return this;
124     }
125 
126     /**
127      * Get option value. If a value is specified for a specific category, it is returned. The following order is used:
128      * <ul>
129      * <li>{@code Lane}</li>
130      * <li>{@code Node} (origin)</li>
131      * <li>{@code LinkType}</li>
132      * <li>None (global option value)</li>
133      * <li>Default option value</li>
134      * </ul>
135      * @param option Option&lt;K&gt;; option
136      * @param lane Lane; lane to obtain specific option value, may be null
137      * @param node Node; node to obtain specific option value, may be null
138      * @param linkType LinkType; link type to obtain specific option value, may be null
139      * @param <K> value type
140      * @return K; option value
141      */
142     public final <K> K get(final Option<K> option, final Lane lane, final Node node, final LinkType linkType)
143     {
144         Throw.whenNull(option, "Option may not be null.");
145         K value = this.laneOptions.get(lane, option);
146         if (value != null)
147         {
148             return value;
149         }
150         value = this.nodeOptions.get(node, option);
151         if (value != null)
152         {
153             return value;
154         }
155         value = this.linkTypeOptions.get(linkType, option);
156         if (value != null)
157         {
158             return value;
159         }
160         value = this.options.get(null, option);
161         if (value != null)
162         {
163             return value;
164         }
165         return option.getDefaultValue();
166     }
167 
168     /**
169      * Utility class to store options.
170      * <p>
171      * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
172      * <br>
173      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
174      * <p>
175      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 dec. 2017 <br>
176      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
177      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
178      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
179      * @param <K> option value type
180      */
181     private static final class Option<K>
182     {
183 
184         /** Id. */
185         private final String id;
186 
187         /** Default value. */
188         private final K defaultValue;
189 
190         /**
191          * Constructor.
192          * @param id String; id
193          * @param defaultValue K; default value
194          */
195         Option(final String id, final K defaultValue)
196         {
197             this.id = id;
198             this.defaultValue = defaultValue;
199         }
200 
201         /**
202          * Returns the default value.
203          * @return default value
204          */
205         public K getDefaultValue()
206         {
207             return this.defaultValue;
208         }
209 
210         /** {@inheritDoc} */
211         @Override
212         public int hashCode()
213         {
214             final int prime = 31;
215             int result = 1;
216             result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
217             return result;
218         }
219 
220         /** {@inheritDoc} */
221         @Override
222         public boolean equals(final Object obj)
223         {
224             if (this == obj)
225             {
226                 return true;
227             }
228             if (obj == null)
229             {
230                 return false;
231             }
232             if (getClass() != obj.getClass())
233             {
234                 return false;
235             }
236             Option<?> other = (Option<?>) obj;
237             if (this.id == null)
238             {
239                 if (other.id != null)
240                 {
241                     return false;
242                 }
243             }
244             else if (!this.id.equals(other.id))
245             {
246                 return false;
247             }
248             return true;
249         }
250 
251         /** {@inheritDoc} */
252         @Override
253         public String toString()
254         {
255             return "Option [id=" + this.id + "]";
256         }
257 
258     }
259 
260     /**
261      * Single set of options for a certain category, i.e. lane, node, link type or null (i.e. global).
262      * <p>
263      * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
264      * <br>
265      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
266      * <p>
267      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 jan. 2018 <br>
268      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
269      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
270      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
271      * @param <C> category type, i.e. {@code Lane}, {@code Node}, {@code LinkType} or {@code Void} (i.e. global).
272      */
273     private class OptionSet<C>
274     {
275 
276         /** Options. */
277         private Map<C, Map<Option<?>, Object>> optionsSet = new HashMap<>();
278 
279         /**
280          * Constructor.
281          */
282         OptionSet()
283         {
284             //
285         }
286 
287         /**
288          * Set value in option set.
289          * @param category C; category
290          * @param option Option&lt;K&gt;; option
291          * @param value K; value
292          * @param <K> option value type
293          */
294         public <K> void set(final C category, final Option<K> option, final K value)
295         {
296             Map<Option<?>, Object> map = this.optionsSet.get(category);
297             if (map == null)
298             {
299                 map = new HashMap<>();
300                 this.optionsSet.put(category, map);
301             }
302             map.put(option, value);
303         }
304 
305         /**
306          * Returns the option value for the category.
307          * @param category C; category
308          * @param option Option&lt;K&gt;; option
309          * @return option value for the category
310          * @param <K> value type
311          */
312         @SuppressWarnings("unchecked")
313         public <K> K get(final C category, final Option<K> option)
314         {
315             if (!this.optionsSet.containsKey(category))
316             {
317                 return null;
318             }
319             return (K) this.optionsSet.get(category).get(option);
320         }
321 
322     }
323 
324 }