View Javadoc
1   /**
2    * 
3    */
4   package org.opentrafficsim.water.demand;
5   
6   import java.io.Serializable;
7   
8   import org.djunits.value.vdouble.scalar.Time;
9   import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
10  import org.opentrafficsim.water.role.Company;
11  import org.opentrafficsim.water.role.ShippingLine;
12  import org.opentrafficsim.water.statistics.ContainerTransportCO2BreakdownEnum;
13  import org.opentrafficsim.water.statistics.ContainerTransportCostBreakdownEnum;
14  import org.opentrafficsim.water.statistics.ContainerTransportFeeBreakdownEnum;
15  import org.opentrafficsim.water.statistics.ContainerTransportTimeBreakdownEnum;
16  import org.opentrafficsim.water.statistics.FullEmptyEnum;
17  import org.opentrafficsim.water.transfer.Terminal;
18  
19  /**
20   * A container is exactly 1 TEU. It collects statistics along the way, which are reported to the statistics objects just before
21   * the container disappears from the model at the inland client or deep sea terminal / empty depot.
22   * <p>
23   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
24   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
25   * </p>
26   * <p>
27   * Based on software from the IDVV project, which is Copyright (c) 2013 Rijkswaterstaat - Dienst Water, Verkeer en Leefomgeving
28   * and licensed without restrictions to Delft University of Technology, including the right to sub-license sources and derived
29   * products to third parties.
30   * </p>
31   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
32   * initial version Nov 6, 2016 <br>
33   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
34   */
35  public class Container implements Serializable
36  {
37      /** */
38      private static final long serialVersionUID = 1L;
39  
40      /** the simulator. */
41      private final OTSDEVSSimulatorInterface simulator;
42  
43      /** origin terminal. */
44      private Terminal terminalFrom;
45  
46      /** destination terminal. */
47      private Terminal terminalTo;
48  
49      /** terminal where the container was stacked last. */
50      private Terminal terminalLastStacked;
51  
52      /** empty? */
53      private boolean empty;
54  
55      /** shipping line. */
56      private ShippingLine shippingLine;
57  
58      /** creation time of container. */
59      private Time creationTime;
60  
61      /** time of arrival at last terminal in the stack (for statistics about terminal staying time). */
62      private Time stackArrivalTime;
63  
64      /** time when container loaded on ship. */
65      private Time onShipTime;
66  
67      /** cost breakdown (based on actual costs) of ALL handling of the container (could be multiple services). */
68      private float[] transportCosts = new float[ContainerTransportCostBreakdownEnum.values().length];
69  
70      /** fee breakdown (based on fixed costs for actions) of ALL handling of the container. */
71      private float[] transportFee = new float[ContainerTransportFeeBreakdownEnum.values().length];
72  
73      /** co2 breakdown (in si unit) for ALL handling of the container (could be multiple services). */
74      private float[] transportKgCO2 = new float[ContainerTransportCO2BreakdownEnum.values().length];
75  
76      /** time breakdown (in si unit) for ALL handling of the container (could be multiple services). */
77      private float[] transportTime = new float[ContainerTransportTimeBreakdownEnum.values().length];
78  
79      /**
80       * @param simulator the simulator
81       * @param terminalFrom origin terminal
82       * @param terminalTo destination terminal
83       * @param empty empty or full
84       * @param shippingLine shipping line of the container
85       */
86      public Container(final OTSDEVSSimulatorInterface simulator, final Terminal terminalFrom, final Terminal terminalTo,
87              final boolean empty, final ShippingLine shippingLine)
88      {
89          super();
90          this.simulator = simulator;
91          this.terminalFrom = terminalFrom;
92          this.terminalLastStacked = terminalFrom;
93          this.terminalTo = terminalTo;
94          this.empty = empty;
95          this.shippingLine = shippingLine;
96          this.creationTime = this.simulator.getSimulatorTime().getTime();
97          for (int i = 0; i < ContainerTransportCostBreakdownEnum.values().length; i++)
98          {
99              this.transportCosts[i] = 0.0f;
100         }
101         for (int i = 0; i < ContainerTransportFeeBreakdownEnum.values().length; i++)
102         {
103             this.transportFee[i] = 0.0f;
104         }
105         for (int i = 0; i < ContainerTransportCO2BreakdownEnum.values().length; i++)
106         {
107             this.transportKgCO2[i] = 0.0f;
108         }
109         for (int i = 0; i < ContainerTransportTimeBreakdownEnum.values().length; i++)
110         {
111             this.transportTime[i] = 0.0f;
112         }
113     }
114 
115     /**
116      * @param costEnum cost category
117      * @param cost cost to add
118      */
119     public final void addTransportCost(final ContainerTransportCostBreakdownEnum costEnum, final double cost)
120     {
121         this.transportCosts[costEnum.ordinal()] += cost;
122     }
123 
124     /**
125      * @param feeEnum cost category
126      * @param fee the fee to add
127      */
128     public final void addTransportFee(final ContainerTransportFeeBreakdownEnum feeEnum, final double fee)
129     {
130         this.transportFee[feeEnum.ordinal()] += fee;
131     }
132 
133     /**
134      * @param co2Enum CO2 category
135      * @param kgCO2 the amount of CO2 to add
136      */
137     public final void addTransportKgCO2(final ContainerTransportCO2BreakdownEnum co2Enum, final double kgCO2)
138     {
139         this.transportKgCO2[co2Enum.ordinal()] += kgCO2;
140     }
141 
142     /**
143      * @param timeEnum time category
144      * @param time the time in hours to add
145      */
146     public final void addTransportTime(final ContainerTransportTimeBreakdownEnum timeEnum, final double time)
147     {
148         this.transportTime[timeEnum.ordinal()] += time;
149     }
150 
151     /**
152      * @param costEnum cost category
153      * @return costs of this cost breakdown category until now
154      */
155     public final double getTransportCost(final ContainerTransportCostBreakdownEnum costEnum)
156     {
157         return this.transportCosts[costEnum.ordinal()];
158     }
159 
160     /**
161      * @param feeEnum cost category
162      * @return fee until now of this cost breakdown category until now
163      */
164     public final double getTransportFee(final ContainerTransportFeeBreakdownEnum feeEnum)
165     {
166         return this.transportFee[feeEnum.ordinal()];
167     }
168 
169     /**
170      * @param co2Enum CO2 category
171      * @return kg CO2 of this CO2 breakdown category until now
172      */
173     public final double getTransportKgCO2(final ContainerTransportCO2BreakdownEnum co2Enum)
174     {
175         return this.transportKgCO2[co2Enum.ordinal()];
176     }
177 
178     /**
179      * @param timeEnum time category
180      * @return the time in hours
181      */
182     public final double getTransportTime(final ContainerTransportTimeBreakdownEnum timeEnum)
183     {
184         return this.transportTime[timeEnum.ordinal()];
185     }
186 
187     /**
188      * @return summed total costs
189      */
190     public final double getSumTransportCost()
191     {
192         double sum = 0.0;
193         for (int i = 0; i < ContainerTransportCostBreakdownEnum.values().length; i++)
194         {
195             sum += this.transportCosts[i];
196         }
197         return sum;
198     }
199 
200     /**
201      * @return summed total fee
202      */
203     public final double getSumTransportFee()
204     {
205         double sum = 0.0;
206         for (int i = 0; i < ContainerTransportFeeBreakdownEnum.values().length; i++)
207         {
208             sum += this.transportFee[i];
209         }
210         return sum;
211     }
212 
213     /**
214      * @return summed total kg CO2
215      */
216     public final double getSumTransportKgCO2()
217     {
218         double sum = 0.0;
219         for (int i = 0; i < ContainerTransportCO2BreakdownEnum.values().length; i++)
220         {
221             sum += this.transportKgCO2[i];
222         }
223         return sum;
224     }
225 
226     /**
227      * @return summed total time
228      */
229     public final double getSumTransportTime()
230     {
231         double sum = 0.0;
232         for (int i = 0; i < ContainerTransportTimeBreakdownEnum.values().length; i++)
233         {
234             sum += this.transportTime[i];
235         }
236         return sum;
237     }
238 
239     /**
240      * Collect the final statistics when the container arrived at its destination.
241      */
242     @SuppressWarnings("checkstyle:needbraces")
243     public final void collectTerminalStatisticsAtContainerDestination()
244     {
245         // Terminal terminal = this.terminalTo.isRtmTerminal() ? this.terminalFrom : this.terminalTo;
246         // TODO: add at terminal: totalCosts += terminal.getAnnualFixedCostsTerminalPerTEU();
247         // TerminalStatistics stats = terminal.getTerminalStatistics();
248         //
249         // stats.costPerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportCost());
250         // stats.feePerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportFee());
251         // stats.kgCO2PerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportKgCO2());
252         // stats.transportTime.get(DirectionEnum.TOTAL).tally(getSumTransportTime());
253         // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
254         // stats.addBreakdownCost(DirectionEnum.TOTAL, ctcb, this.getTransportCost(ctcb));
255         // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
256         // stats.addBreakdownFee(DirectionEnum.TOTAL, ctfb, this.getTransportFee(ctfb));
257         // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
258         // stats.addBreakdownCO2(DirectionEnum.TOTAL, ctcb, this.getTransportKgCO2(ctcb));
259         // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
260         // stats.addBreakdownTime(DirectionEnum.TOTAL, cttb, this.getTransportTime(cttb));
261         //
262         // if (this.terminalTo.isRtmTerminal())
263         // {
264         // stats.costPerTEU.get(DirectionEnum.TORTM).tally(getSumTransportCost());
265         // stats.feePerTEU.get(DirectionEnum.TORTM).tally(getSumTransportFee());
266         // stats.kgCO2PerTEU.get(DirectionEnum.TORTM).tally(getSumTransportKgCO2());
267         // stats.transportTime.get(DirectionEnum.TORTM).tally(getSumTransportTime());
268         // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
269         // stats.addBreakdownCost(DirectionEnum.TORTM, ctcb, this.getTransportCost(ctcb));
270         // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
271         // stats.addBreakdownFee(DirectionEnum.TORTM, ctfb, this.getTransportFee(ctfb));
272         // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
273         // stats.addBreakdownCO2(DirectionEnum.TORTM, ctcb, this.getTransportKgCO2(ctcb));
274         // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
275         // stats.addBreakdownTime(DirectionEnum.TORTM, cttb, this.getTransportTime(cttb));
276         // }
277         //
278         // else
279         //
280         // {
281         // stats.costPerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportCost());
282         // stats.feePerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportFee());
283         // stats.kgCO2PerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportKgCO2());
284         // stats.transportTime.get(DirectionEnum.FROMRTM).tally(getSumTransportTime());
285         // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
286         // stats.addBreakdownCost(DirectionEnum.FROMRTM, ctcb, this.getTransportCost(ctcb));
287         // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
288         // stats.addBreakdownFee(DirectionEnum.FROMRTM, ctfb, this.getTransportFee(ctfb));
289         // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
290         // stats.addBreakdownCO2(DirectionEnum.FROMRTM, ctcb, this.getTransportKgCO2(ctcb));
291         // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
292         // stats.addBreakdownTime(DirectionEnum.FROMRTM, cttb, this.getTransportTime(cttb));
293         // }
294     }
295 
296     /**
297      * @return the terminalFrom
298      */
299     public final Terminal getTerminalFrom()
300     {
301         return this.terminalFrom;
302     }
303 
304     /**
305      * @return the terminalTo
306      */
307     public final Terminal getTerminalTo()
308     {
309         return this.terminalTo;
310     }
311 
312     /**
313      * @return the terminalCurrent
314      */
315     public final Terminal getTerminalLastStacked()
316     {
317         return this.terminalLastStacked;
318     }
319 
320     /**
321      * @param terminalFrom the terminalFrom to set
322      */
323     public final void setTerminalFrom(final Terminal terminalFrom)
324     {
325         this.terminalFrom = terminalFrom;
326     }
327 
328     /**
329      * @param terminalTo the terminalTo to set
330      */
331     public final void setTerminalTo(final Terminal terminalTo)
332     {
333         this.terminalTo = terminalTo;
334     }
335 
336     /**
337      * @param terminalLastStacked the terminalCurrent to set
338      */
339     public final void setTerminalLastStacked(final Terminal terminalLastStacked)
340     {
341         this.terminalLastStacked = terminalLastStacked;
342     }
343 
344     /**
345      * @return the empty
346      */
347     public final boolean isEmpty()
348     {
349         return this.empty;
350     }
351 
352     /**
353      * @return full or empty
354      */
355     public final FullEmptyEnum fullEmpty()
356     {
357         if (this.empty)
358         {
359             return FullEmptyEnum.EMPTY;
360         }
361         return FullEmptyEnum.FULL;
362     }
363 
364     /**
365      * @return the owner
366      */
367     public final Company getOwner()
368     {
369         return this.shippingLine;
370     }
371 
372     /**
373      * @return the shippingLine
374      */
375     public final ShippingLine getShippingLine()
376     {
377         return this.shippingLine;
378     }
379 
380     /** {@inheritDoc} */
381     @Override
382     public final String toString()
383     {
384         String full = this.empty ? "[EMPTY]" : "[FULL]";
385         return "Container from " + this.terminalFrom.getName() + " to " + this.terminalTo.getName() + " at "
386                 + this.terminalLastStacked.getName() + " (owner " + this.shippingLine.getCode() + ") " + full;
387     }
388 
389     /**
390      * @return short info
391      */
392     public final String toShortString()
393     {
394         String full = this.empty ? "[E]" : "[F]";
395         return this.terminalFrom.getName() + "->" + this.terminalTo.getName() + "@" + this.terminalLastStacked.getName() + full;
396     }
397 
398     /**
399      * @return the arrivalTime
400      */
401     public final Time getStackArrivalTime()
402     {
403         return this.stackArrivalTime;
404     }
405 
406     /**
407      * set the arrivalTime.
408      */
409     public final void setStackArrivalTime()
410     {
411         this.stackArrivalTime = this.simulator.getSimulatorTime().getTime();
412     }
413 
414     /**
415      * @return the creationTime
416      */
417     public final Time getCreationTime()
418     {
419         return this.creationTime;
420     }
421 
422     /**
423      * @return the onShipTime
424      */
425     public final Time getOnShipTime()
426     {
427         return this.onShipTime;
428     }
429 
430     /**
431      * set onShipTime.
432      */
433     public final void setOnShipTime()
434     {
435         this.onShipTime = this.simulator.getSimulatorTime().getTime()   ;
436     }
437 
438 }