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