View Javadoc
1   package org.opentrafficsim.core.network;
2   
3   import java.util.Arrays;
4   import java.util.LinkedHashSet;
5   
6   import org.djutils.immutablecollections.Immutable;
7   import org.djutils.immutablecollections.ImmutableHashSet;
8   import org.djutils.immutablecollections.ImmutableSet;
9   import org.opentrafficsim.core.gtu.GTUDirectionality;
10  
11  /**
12   * Permitted longitudinal driving directions.
13   * <p>
14   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
15   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
16   * <p>
17   * $LastChangedDate: 2020-02-24 11:14:29 +0100 (Mon, 24 Feb 2020) $, @version $Revision: 6393 $, by $Author: pknoppers $,
18   * initial version Oct 15, 2014 <br>
19   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
20   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
21   * @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a>
22   */
23  public enum LongitudinalDirectionality
24  {
25      /** Direction the same as the direction of the graph, increasing fractional position when driving in this direction. */
26      DIR_PLUS(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS }),
27      /** Direction opposite to the direction of the graph, decreasing fractional position when driving in this direction. */
28      DIR_MINUS(new GTUDirectionality[] { GTUDirectionality.DIR_MINUS }),
29      /** Bidirectional. */
30      DIR_BOTH(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS, GTUDirectionality.DIR_MINUS }),
31      /** No traffic possible. */
32      DIR_NONE(new GTUDirectionality[] {});
33  
34      /** Array of permitted driving directions. */
35      private final ImmutableSet<GTUDirectionality> directions;
36  
37      /**
38       * Construct a new LongitudinalDirectionality.
39       * @param directions GTUDirectionality[]; array containing the permitted driving directions
40       */
41      LongitudinalDirectionality(final GTUDirectionality[] directions)
42      {
43          this.directions = new ImmutableHashSet<>(new LinkedHashSet<>(Arrays.asList(directions)), Immutable.WRAP);
44      }
45  
46      /**
47       * Retrieve the permitted driving directions.
48       * @return ImmutableSet&lt;GTUDirectionality&gt;; immutable set containing the permitted driving directions
49       */
50      public final ImmutableSet<GTUDirectionality> getDirectionalities()
51      {
52          return this.directions;
53      }
54  
55      /**
56       * This method looks if this directionality "contains" the provided other directionality. The logic table looks as follows:
57       * <table border="1">
58       * <caption>&nbsp;</caption>
59       * <tr>
60       * <td><b>THIS &darr; &nbsp; OTHER &rarr;</b></td>
61       * <td><b>DIR_BOTH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></td>
62       * <td><b>DIR_PLUS&nbsp;&nbsp;&nbsp;</b></td>
63       * <td><b>DIR_MINUS</b></td>
64       * <td><b>DIR_NONE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b></td>
65       * </tr>
66       * <tr>
67       * <td><b>DIR_BOTH</b></td>
68       * <td>true</td>
69       * <td>true</td>
70       * <td>true</td>
71       * <td>true</td>
72       * </tr>
73       * <tr>
74       * <td><b>DIR_PLUS</b></td>
75       * <td>false</td>
76       * <td>true</td>
77       * <td>false</td>
78       * <td>true</td>
79       * </tr>
80       * <tr>
81       * <td><b>DIR_MINUS</b></td>
82       * <td>false</td>
83       * <td>false</td>
84       * <td>true</td>
85       * <td>true</td>
86       * </tr>
87       * <tr>
88       * <td><b>DIR_NONE</b></td>
89       * <td>false</td>
90       * <td>false</td>
91       * <td>false</td>
92       * <td>true</td>
93       * </tr>
94       * </table>
95       * @param directionality LongitudinalDirectionality; the directionality to compare with
96       * @return whether this directionality "contains" the provided other directionality
97       */
98      public final boolean contains(final LongitudinalDirectionality directionality)
99      {
100         return (this.equals(directionality) || this.equals(DIR_BOTH) || directionality.equals(DIR_NONE)) ? true : false;
101     }
102 
103     /**
104      * Easy access method to test if the directionality is FORWARD or BOTH.
105      * @return whether the directionality is FORWARD or BOTH
106      */
107     public final boolean isForwardOrBoth()
108     {
109         return this.equals(DIR_PLUS) || this.equals(DIR_BOTH);
110     }
111 
112     /**
113      * Easy access method to test if the directionality is BACKWARD or BOTH.
114      * @return whether the directionality is BACKWARD or BOTH
115      */
116     public final boolean isBackwardOrBoth()
117     {
118         return this.equals(DIR_MINUS) || this.equals(DIR_BOTH);
119     }
120 
121     /**
122      * Easy access method to test if the directionality is FORWARD.
123      * @return whether the directionality is FORWARD
124      */
125     public final boolean isForward()
126     {
127         return this.equals(DIR_PLUS);
128     }
129 
130     /**
131      * Easy access method to test if the directionality is BACKWARD.
132      * @return whether the directionality is BACKWARD
133      */
134     public final boolean isBackward()
135     {
136         return this.equals(DIR_MINUS);
137     }
138 
139     /**
140      * Easy access method to test if the directionality is BACKWARD or BOTH.
141      * @return whether the directionality is BACKWARD or BOTH
142      */
143     public final boolean isBoth()
144     {
145         return this.equals(DIR_BOTH);
146     }
147 
148     /**
149      * Easy access method to test if the directionality is NONE.
150      * @return whether the directionality is NONE
151      */
152     public final boolean isNone()
153     {
154         return this.equals(DIR_NONE);
155     }
156 
157     /**
158      * Compute the intersection of this LongitudinalDirectionality with another LongitudinalDirectionality.
159      * @param other LongitudinalDirectionality; the other LongitudinalDirectionality
160      * @return LongitudinalDirectionality; the intersection of <code>this</code> and <code>other</code>
161      */
162     public final LongitudinalDirectionalityonality.html#LongitudinalDirectionality">LongitudinalDirectionality intersect(final LongitudinalDirectionality other)
163     {
164         if (null == other)
165         {
166             System.err.println("other LongitudinalDirectionality should not be null; returning DIR_NONE");
167             return DIR_NONE;
168         }
169         switch (other)
170         {
171             case DIR_BOTH:
172                 return this;
173             case DIR_MINUS:
174                 if (this.equals(other))
175                 {
176                     return this;
177                 }
178                 if (this.equals(DIR_BOTH))
179                 {
180                     return other;
181                 }
182                 return DIR_NONE;
183             case DIR_NONE:
184                 return other;
185             case DIR_PLUS:
186                 if (this.equals(other))
187                 {
188                     return this;
189                 }
190                 if (this.equals(DIR_BOTH))
191                 {
192                     return other;
193                 }
194                 return DIR_NONE;
195             default:
196                 // Cannot happen (unless someone manages to change this enum).
197                 System.err.println("intersect with ???? (returns DIR_NONE)");
198                 return DIR_NONE;
199         }
200     }
201 
202     /**
203      * Check if a direction is permitted by this LongitudinalDirectionality.
204      * @param direction GTUDirectionality; the direction of motion in which a GTU moves, or wants to move
205      * @return boolean; true if the direction is permitted by this LongitudinalDirectionality; false if it is not permitted
206      */
207     public final boolean permits(final GTUDirectionality direction)
208     {
209         switch (direction)
210         {
211             case DIR_MINUS:
212                 return isBackwardOrBoth();
213             case DIR_PLUS:
214                 return isForwardOrBoth();
215             default:
216                 System.out.println("Bad direction: " + direction);
217                 return false;
218         }
219     }
220 
221     /**
222      * Return the inverse if this LongitudinalDirectionality.
223      * @return LongitudinalDirectionality; the directional inverse of this LongitudinalDirectionality
224      */
225     public LongitudinalDirectionality invert()
226     {
227         switch (this)
228         {
229             case DIR_BOTH:
230                 return this;
231             case DIR_MINUS:
232                 return DIR_PLUS;
233             case DIR_NONE:
234                 return this;
235             case DIR_PLUS:
236                 return DIR_MINUS;
237             default:
238                 return this; // cannot happen
239         }
240     }
241 
242 }