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