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