1   package org.opentrafficsim.road.gtu.lane.perception;
2   
3   import java.io.Serializable;
4   
5   import org.djutils.exceptions.Throw;
6   import org.opentrafficsim.core.network.LateralDirectionality;
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  public class RelativeLane implements Comparable<RelativeLane>, Serializable
18  {
19  
20      
21      private static final long serialVersionUID = 20160502L;
22  
23      
24      public static final RelativeLaneperception/RelativeLane.html#RelativeLane">RelativeLane SECOND_LEFT = new RelativeLane(LateralDirectionality.LEFT, 2);
25  
26      
27      public static final RelativeLaneu/lane/perception/RelativeLane.html#RelativeLane">RelativeLane LEFT = new RelativeLane(LateralDirectionality.LEFT, 1);
28  
29      
30      public static final RelativeLaneane/perception/RelativeLane.html#RelativeLane">RelativeLane CURRENT = new RelativeLane(LateralDirectionality.NONE, 0);
31  
32      
33      public static final RelativeLane/lane/perception/RelativeLane.html#RelativeLane">RelativeLane RIGHT = new RelativeLane(LateralDirectionality.RIGHT, 1);
34  
35      
36      public static final RelativeLaneerception/RelativeLane.html#RelativeLane">RelativeLane SECOND_RIGHT = new RelativeLane(LateralDirectionality.RIGHT, 2);
37  
38      
39      private final LateralDirectionality lat;
40  
41      
42      private final int numLanes;
43  
44      
45      private final int rank;
46  
47      
48  
49  
50  
51  
52  
53  
54      public RelativeLane(final LateralDirectionality lat, final int numLanes)
55      {
56          Throw.whenNull(lat, "Lateral directionality may not be null.");
57          Throw.when(lat.isNone() && numLanes != 0, IllegalArgumentException.class,
58                  "Number of lanes must be zero if the lateral directionality is NONE.");
59          Throw.when(numLanes < 0, IllegalArgumentException.class,
60                  "Relative lane with %d lanes in %s direction is not allowed, use values > 0.", numLanes, lat);
61          this.lat = lat;
62          this.numLanes = numLanes;
63          this.rank = lat.isLeft() ? -numLanes : numLanes;
64      }
65  
66      
67  
68  
69  
70      public final LateralDirectionality getLateralDirectionality()
71      {
72          return this.lat;
73      }
74  
75      
76  
77  
78  
79      public final int getNumLanes()
80      {
81          return this.numLanes;
82      }
83  
84      
85  
86  
87  
88      public final boolean isSecondLeft()
89      {
90          return this.equals(SECOND_LEFT);
91      }
92  
93      
94  
95  
96  
97      public final boolean isLeft()
98      {
99          return this.equals(LEFT);
100     }
101 
102     
103 
104 
105 
106     public final boolean isCurrent()
107     {
108         return this.equals(CURRENT);
109     }
110 
111     
112 
113 
114 
115     public final boolean isRight()
116     {
117         return this.equals(RIGHT);
118     }
119 
120     
121 
122 
123 
124     public final boolean isSecondRight()
125     {
126         return this.equals(SECOND_RIGHT);
127     }
128 
129     
130 
131 
132 
133     public final RelativeLane getLeft()
134     {
135         return this.add(LEFT);
136     }
137 
138     
139 
140 
141 
142     public final RelativeLane getRight()
143     {
144         return this.add(RIGHT);
145     }
146 
147     
148 
149 
150 
151 
152 
153     public final RelativeLanetu/lane/perception/RelativeLane.html#RelativeLane">RelativeLane add(final RelativeLane relativeLane)
154     {
155         int rankSum = this.rank + relativeLane.rank;
156         if (rankSum < 0)
157         {
158             return new RelativeLane(LateralDirectionality.LEFT, -rankSum);
159         }
160         if (rankSum > 0)
161         {
162             return new RelativeLane(LateralDirectionality.RIGHT, rankSum);
163         }
164         return CURRENT;
165     }
166 
167     
168     @Override
169     public int hashCode()
170     {
171         final int prime = 31;
172         int result = 1;
173         result = prime * result + this.rank;
174         return result;
175     }
176 
177     
178     @Override
179     public boolean equals(final Object obj)
180     {
181         if (this == obj)
182         {
183             return true;
184         }
185         if (obj == null)
186         {
187             return false;
188         }
189         if (getClass() != obj.getClass())
190         {
191             return false;
192         }
193         RelativeLane/../../../../org/opentrafficsim/road/gtu/lane/perception/RelativeLane.html#RelativeLane">RelativeLane other = (RelativeLane) obj;
194         if (this.rank != other.rank) 
195         {
196             return false;
197         }
198         return true;
199     }
200 
201     
202     @Override
203     public final String toString()
204     {
205         if (this.equals(CURRENT))
206         {
207             return "RelativeLane [CURRENT]";
208         }
209         return new StringBuilder("RelativeLane [").append(this.lat).append(", ").append(this.numLanes).append("]").toString();
210     }
211 
212     
213     @Override
214     public final int compareTo(final RelativeLane rel)
215     {
216         return this.rank - rel.rank;
217     }
218 
219 }