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