1   package org.opentrafficsim.road.gtu.generator.od;
2   
3   import java.util.HashSet;
4   import java.util.LinkedHashMap;
5   import java.util.LinkedHashSet;
6   import java.util.Map;
7   import java.util.Set;
8   
9   import org.djutils.exceptions.Throw;
10  import org.djutils.exceptions.Try;
11  import org.opentrafficsim.core.distributions.Generator;
12  import org.opentrafficsim.core.gtu.GTUCharacteristics;
13  import org.opentrafficsim.core.gtu.GTUException;
14  import org.opentrafficsim.core.gtu.GTUType;
15  import org.opentrafficsim.core.gtu.TemplateGTUType;
16  import org.opentrafficsim.core.network.Node;
17  import org.opentrafficsim.core.network.route.Route;
18  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGTUCharacteristics;
19  import org.opentrafficsim.road.gtu.lane.VehicleModel;
20  import org.opentrafficsim.road.gtu.lane.VehicleModelFactory;
21  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
22  import org.opentrafficsim.road.gtu.strategical.od.Categorization;
23  import org.opentrafficsim.road.gtu.strategical.od.Category;
24  import org.opentrafficsim.road.gtu.strategical.route.RouteGeneratorOD;
25  
26  import nl.tudelft.simulation.jstats.streams.StreamInterface;
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  public final class DefaultGTUCharacteristicsGeneratorOD implements GTUCharacteristicsGeneratorOD
40  {
41      
42      private Generator<GTUType> gtuTypeGenerator = null;
43  
44      
45      private final Map<GTUType, TemplateGTUType> templates = new LinkedHashMap<>();
46  
47      
48      private final RouteGeneratorOD routeGenerator;
49  
50      
51      private final StrategicalPlannerFactorySupplierOD factorySupplier;
52  
53      
54      private VehicleModelFactory vehicleModelFactory = VehicleModelFactory.MINMAX;
55  
56      
57  
58  
59      public DefaultGTUCharacteristicsGeneratorOD()
60      {
61          this(null, RouteGeneratorOD.NULL, new HashSet<>(), StrategicalPlannerFactorySupplierOD.lmrs());
62      }
63  
64      
65  
66  
67  
68      public DefaultGTUCharacteristicsGeneratorOD(final RouteGeneratorOD routeGenerator)
69      {
70          this(null, routeGenerator, new HashSet<>(), StrategicalPlannerFactorySupplierOD.lmrs());
71      }
72  
73      
74  
75  
76  
77  
78      public DefaultGTUCharacteristicsGeneratorOD(final RouteGeneratorOD routeSupplier, final Set<TemplateGTUType> templates)
79      {
80          this(null, routeSupplier, templates, StrategicalPlannerFactorySupplierOD.lmrs());
81      }
82  
83      
84  
85  
86  
87  
88      public DefaultGTUCharacteristicsGeneratorOD(final RouteGeneratorOD routeGenerator,
89              final StrategicalPlannerFactorySupplierOD factorySupplier)
90      {
91          this(null, routeGenerator, new HashSet<>(), factorySupplier);
92      }
93  
94      
95  
96  
97  
98  
99  
100 
101     public DefaultGTUCharacteristicsGeneratorOD(final Generator<GTUType> gtuTypeGenerator,
102             final RouteGeneratorOD routeGenerator, final Set<TemplateGTUType> templates,
103             final StrategicalPlannerFactorySupplierOD factorySupplier)
104     {
105         Throw.whenNull(factorySupplier, "Strategical factory supplier may not be null.");
106         this.gtuTypeGenerator = gtuTypeGenerator;
107         if (routeGenerator == null)
108         {
109             this.routeGenerator = RouteGeneratorOD.NULL;
110         }
111         else
112         {
113             this.routeGenerator = routeGenerator;
114         }
115         if (templates != null)
116         {
117             for (TemplateGTUType template : templates)
118             {
119                 this.templates.put(template.getGTUType(), template);
120             }
121         }
122         this.factorySupplier = factorySupplier;
123     }
124 
125     
126 
127 
128 
129     public DefaultGTUCharacteristicsGeneratorOD(final Set<TemplateGTUType> templates)
130     {
131         this(null, RouteGeneratorOD.NULL, templates, StrategicalPlannerFactorySupplierOD.lmrs());
132     }
133 
134     
135 
136 
137 
138 
139     public DefaultGTUCharacteristicsGeneratorOD(final Set<TemplateGTUType> templates,
140             final StrategicalPlannerFactorySupplierOD factorySupplier)
141     {
142         this(null, RouteGeneratorOD.NULL, templates, factorySupplier);
143     }
144 
145     
146 
147 
148 
149 
150     public DefaultGTUCharacteristicsGeneratorOD(final StrategicalPlannerFactorySupplierOD factorySupplier)
151     {
152         this(null, RouteGeneratorOD.NULL, new HashSet<>(), factorySupplier);
153     }
154 
155     
156 
157     
158 
159 
160 
161 
162 
163 
164 
165     private DefaultGTUCharacteristicsGeneratorOD(final Generator<GTUType> gtuTypeGenerator,
166             final RouteGeneratorOD routeSupplier, final Set<TemplateGTUType> templates,
167             final StrategicalPlannerFactorySupplierOD factorySupplier, final VehicleModelFactory vehicleModelFactory)
168     {
169         Throw.whenNull(factorySupplier, "Strategical factory supplier may not be null.");
170         this.gtuTypeGenerator = gtuTypeGenerator;
171         if (routeSupplier == null)
172         {
173             this.routeGenerator = RouteGeneratorOD.NULL;
174         }
175         else
176         {
177             this.routeGenerator = routeSupplier;
178         }
179         if (templates != null)
180         {
181             for (TemplateGTUType template : templates)
182             {
183                 this.templates.put(template.getGTUType(), template);
184             }
185         }
186         this.factorySupplier = factorySupplier;
187         if (vehicleModelFactory == null)
188         {
189             this.vehicleModelFactory = VehicleModelFactory.MINMAX;
190         }
191         else
192         {
193             this.vehicleModelFactory = vehicleModelFactory;
194         }
195     }
196 
197     
198     @Override
199     public LaneBasedGTUCharacteristics draw(final Node origin, final Node destination, final Category category,
200             final StreamInterface randomStream) throws GTUException
201     {
202         Categorization categorization = category.getCategorization();
203         
204         GTUType gtuType;
205         if (categorization.entails(GTUType.class))
206         {
207             gtuType = category.get(GTUType.class);
208         }
209         else if (this.gtuTypeGenerator != null)
210         {
211             gtuType = Try.assign(() -> this.gtuTypeGenerator.draw(), GTUException.class, "Parameter while drawing GTU type.");
212         }
213         else
214         {
215             gtuType = GTUType.CAR;
216         }
217         GTUCharacteristics gtuCharacteristics;
218         if (this.templates.containsKey(gtuType))
219         {
220             gtuCharacteristics =
221                     Try.assign(() -> this.templates.get(gtuType).draw(), "Exception while drawing GTU characteristics.");
222         }
223         else
224         {
225             gtuCharacteristics = Try.assign(() -> GTUType.defaultCharacteristics(gtuType, randomStream),
226                     "Exception while applying default GTU characteristics.");
227         }
228         
229         LaneBasedStrategicalPlannerFactory<?> laneBasedStrategicalPlannerFactory =
230                 this.factorySupplier.getFactory(origin, destination, category, randomStream);
231         
232         Route route;
233         if (categorization.entails(Route.class))
234         {
235             route = category.get(Route.class);
236         }
237         else
238         {
239             
240             route = this.routeGenerator.getRoute(origin, destination, gtuType);
241         }
242         
243         VehicleModel vehicleModel = this.vehicleModelFactory.create(gtuType);
244 
245         return new LaneBasedGTUCharacteristics(gtuCharacteristics, laneBasedStrategicalPlannerFactory, route, origin,
246                 destination, vehicleModel);
247     }
248 
249     
250 
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261     @SuppressWarnings("hiddenfield")
262     public static class Factory
263     {
264         
265         private Generator<GTUType> gtuTypeGenerator = null;
266 
267         
268         private Set<TemplateGTUType> templates = new LinkedHashSet<>();
269 
270         
271         private RouteGeneratorOD routeGenerator = RouteGeneratorOD.NULL;
272 
273         
274         private StrategicalPlannerFactorySupplierOD factorySupplier = StrategicalPlannerFactorySupplierOD.lmrs();
275 
276         
277         private VehicleModelFactory vehicleModelFactory = VehicleModelFactory.MINMAX;
278 
279         
280 
281 
282 
283         public Factory setGtuTypeGenerator(final Generator<GTUType> gtuTypeGenerator)
284         {
285             this.gtuTypeGenerator = gtuTypeGenerator;
286             return this;
287         }
288 
289         
290 
291 
292 
293         public Factory setTemplates(final Set<TemplateGTUType> templates)
294         {
295             this.templates = templates;
296             return this;
297         }
298 
299         
300 
301 
302 
303         public Factory setRouteSupplier(final RouteGeneratorOD routeSupplier)
304         {
305             this.routeGenerator = routeSupplier;
306             return this;
307         }
308 
309         
310 
311 
312 
313         public Factory setFactorySupplier(final StrategicalPlannerFactorySupplierOD factorySupplier)
314         {
315             this.factorySupplier = factorySupplier;
316             return this;
317         }
318 
319         
320 
321 
322 
323         public Factory setVehicleModelGenerator(final VehicleModelFactory vehicleModelFactory)
324         {
325             this.vehicleModelFactory = vehicleModelFactory;
326             return this;
327         }
328 
329         
330 
331 
332 
333         @SuppressWarnings("synthetic-access")
334         public DefaultGTUCharacteristicsGeneratorOD create()
335         {
336             return new DefaultGTUCharacteristicsGeneratorOD(this.gtuTypeGenerator, this.routeGenerator, this.templates,
337                     this.factorySupplier, this.vehicleModelFactory);
338         }
339     }
340 
341 }