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