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