1 package org.opentrafficsim.road.network.lane;
2
3 import java.util.LinkedHashMap;
4 import java.util.LinkedHashSet;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Set;
8 import java.util.UUID;
9
10 import org.djunits.unit.LengthUnit;
11 import org.djunits.value.vdouble.scalar.Length;
12 import org.djutils.draw.line.Polygon2d;
13 import org.djutils.exceptions.Throw;
14 import org.opentrafficsim.core.geometry.OtsLine2d;
15 import org.opentrafficsim.core.gtu.GtuType;
16 import org.opentrafficsim.core.network.LateralDirectionality;
17 import org.opentrafficsim.core.network.NetworkException;
18
19
20
21
22
23
24
25
26
27
28 public class Stripe extends CrossSectionElement
29 {
30
31 private static final long serialVersionUID = 20141025L;
32
33
34 private final Type type;
35
36
37 private Type overruleType;
38
39
40 private final Map<GtuType, Set<LateralDirectionality>> permeabilityMap = new LinkedHashMap<>();
41
42
43
44
45
46
47
48
49
50
51 public Stripe(final Type type, final CrossSectionLink link, final OtsLine2d centerLine, final Polygon2d contour,
52 final List<CrossSectionSlice> crossSectionSlices) throws NetworkException
53 {
54 super(link, UUID.randomUUID().toString(), centerLine, contour, crossSectionSlices);
55 Throw.whenNull(type, "Type may not be null.");
56 this.type = type;
57 }
58
59
60
61
62
63 public Type getType()
64 {
65 return this.type;
66 }
67
68
69
70
71
72
73 public void setOverruleType(final Type overruleType)
74 {
75 this.overruleType = overruleType;
76 }
77
78
79
80
81 public void clearOverruleType()
82 {
83 this.overruleType = null;
84 }
85
86
87
88
89
90 private Type activeType()
91 {
92 return this.overruleType == null ? this.type : this.overruleType;
93 }
94
95
96
97
98
99
100
101
102 public void addPermeability(final GtuType gtuType, final LateralDirectionality lateralDirection)
103 {
104 if (!this.permeabilityMap.containsKey(gtuType))
105 {
106 this.permeabilityMap.put(gtuType, new LinkedHashSet<LateralDirectionality>(2));
107 }
108 this.permeabilityMap.get(gtuType).add(lateralDirection);
109 }
110
111
112
113
114
115
116
117
118 public final boolean isPermeable(final GtuType gtuType, final LateralDirectionality lateralDirection)
119 {
120 Throw.when(lateralDirection.isNone(), RuntimeException.class,
121 "May not request NONE lateral direction for permeability.");
122 for (GtuType testGtuType = gtuType; null != testGtuType; testGtuType = testGtuType.getParent())
123 {
124 Set<LateralDirectionality> set = this.permeabilityMap.get(testGtuType);
125 if (null != set)
126 {
127 return set.contains(lateralDirection);
128 }
129 }
130 return lateralDirection.isLeft() ? activeType().left() : activeType().right;
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144 public enum Type
145 {
146
147 SOLID(false, false),
148
149
150 LEFT(true, false, new Length(60.0, LengthUnit.CENTIMETER)),
151
152
153 RIGHT(false, true, new Length(60.0, LengthUnit.CENTIMETER)),
154
155
156 DASHED(true, true),
157
158
159 DOUBLE(false, false, new Length(60.0, LengthUnit.CENTIMETER)),
160
161
162 BLOCK(true, true, new Length(40.0, LengthUnit.CENTIMETER));
163
164
165 private final boolean left;
166
167
168 private final boolean right;
169
170
171 private final Length defaultWidth;
172
173
174
175
176
177
178 Type(final boolean left, final boolean right)
179 {
180 this(left, right, new Length(20.0, LengthUnit.CENTIMETER));
181 }
182
183
184
185
186
187
188
189 Type(final boolean left, final boolean right, final Length defaultWidth)
190 {
191 this.left = left;
192 this.right = right;
193 this.defaultWidth = defaultWidth;
194 }
195
196
197
198
199
200 public boolean left()
201 {
202 return this.left;
203 }
204
205
206
207
208
209 public boolean right()
210 {
211 return this.right;
212 }
213
214
215
216
217
218 public Length defaultWidth()
219 {
220 return this.defaultWidth;
221 }
222 }
223
224 }