1 package org.opentrafficsim.road.network.factory;
2
3 import java.awt.Color;
4 import java.rmi.RemoteException;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.LinkedHashMap;
8 import java.util.List;
9 import java.util.Map;
10
11 import javax.naming.NamingException;
12
13 import nl.tudelft.simulation.language.d3.DirectedPoint;
14
15 import org.djunits.unit.LengthUnit;
16 import org.djunits.value.vdouble.scalar.Length;
17 import org.djunits.value.vdouble.scalar.Speed;
18 import org.opentrafficsim.core.dsol.OTSAnimatorInterface;
19 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
20 import org.opentrafficsim.core.geometry.Bezier;
21 import org.opentrafficsim.core.geometry.OTSGeometryException;
22 import org.opentrafficsim.core.geometry.OTSLine3D;
23 import org.opentrafficsim.core.geometry.OTSPoint3D;
24 import org.opentrafficsim.core.gtu.GTUType;
25 import org.opentrafficsim.core.network.LinkType;
26 import org.opentrafficsim.core.network.LongitudinalDirectionality;
27 import org.opentrafficsim.core.network.NetworkException;
28 import org.opentrafficsim.core.network.OTSNode;
29 import org.opentrafficsim.road.network.animation.LaneAnimation;
30 import org.opentrafficsim.road.network.lane.CrossSectionLink;
31 import org.opentrafficsim.road.network.lane.Lane;
32 import org.opentrafficsim.road.network.lane.LaneType;
33 import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
34 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
35
36
37
38
39
40
41
42
43
44
45 public final class LaneFactory
46 {
47
48 private LaneFactory()
49 {
50
51 }
52
53
54
55
56
57
58
59
60
61
62
63
64 public static CrossSectionLink makeLink(final String name, final OTSNode from, final OTSNode to,
65 final OTSPoint3D[] intermediatePoints, final LongitudinalDirectionality direction) throws OTSGeometryException
66 {
67 List<OTSPoint3D> pointList =
68 intermediatePoints == null ? new ArrayList<OTSPoint3D>() : new ArrayList<OTSPoint3D>(
69 Arrays.asList(intermediatePoints));
70 if (pointList.size() == 0 || !from.getPoint().equals(pointList.get(0)))
71 {
72 pointList.add(0, from.getPoint());
73 }
74 if (pointList.size() == 0 || !to.getPoint().equals(pointList.get(pointList.size() - 1)))
75 {
76 pointList.add(to.getPoint());
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 OTSLine3D designLine = new OTSLine3D(pointList);
108 CrossSectionLink link =
109 new CrossSectionLink(name, from, to, LinkType.ALL, designLine, direction, LaneKeepingPolicy.KEEP_RIGHT);
110 return link;
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 @SuppressWarnings("checkstyle:parameternumber")
132 private static Lane makeLane(final CrossSectionLink link, final String id, final LaneType laneType,
133 final Length.Rel latPosAtStart, final Length.Rel latPosAtEnd, final Length.Rel width, final Speed speedLimit,
134 final OTSDEVSSimulatorInterface simulator, final LongitudinalDirectionality direction) throws NamingException,
135 NetworkException, OTSGeometryException
136 {
137 Map<GTUType, LongitudinalDirectionality> directionalityMap = new LinkedHashMap<>();
138 directionalityMap.put(GTUType.ALL, direction);
139 Map<GTUType, Speed> speedMap = new LinkedHashMap<>();
140 speedMap.put(GTUType.ALL, speedLimit);
141 Lane result =
142 new Lane(link, id, latPosAtStart, latPosAtEnd, width, width, laneType, directionalityMap, speedMap,
143 new OvertakingConditions.LeftAndRight());
144 if (simulator instanceof OTSAnimatorInterface)
145 {
146 try
147 {
148 new LaneAnimation(result, simulator, Color.LIGHT_GRAY, false);
149 }
150 catch (RemoteException exception)
151 {
152 exception.printStackTrace();
153 }
154 }
155 return result;
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 public static Lane makeLane(final String name, final OTSNode from, final OTSNode to,
175 final OTSPoint3D[] intermediatePoints, final LaneType laneType, final Speed speedLimit,
176 final OTSDEVSSimulatorInterface simulator, final LongitudinalDirectionality direction) throws NamingException,
177 NetworkException, OTSGeometryException
178 {
179 Length.Rel width = new Length.Rel(4.0, LengthUnit.METER);
180 final CrossSectionLink link = makeLink(name, from, to, intermediatePoints, direction);
181 Length.Rel latPos = new Length.Rel(0.0, LengthUnit.METER);
182 return makeLane(link, "lane", laneType, latPos, latPos, width, speedLimit, simulator, direction);
183 }
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 @SuppressWarnings("checkstyle:parameternumber")
207 public static Lane[] makeMultiLane(final String name, final OTSNode from, final OTSNode to,
208 final OTSPoint3D[] intermediatePoints, final int laneCount, final int laneOffsetAtStart,
209 final int laneOffsetAtEnd, final LaneType laneType, final Speed speedLimit,
210 final OTSDEVSSimulatorInterface simulator, final LongitudinalDirectionality direction) throws NamingException,
211 NetworkException, OTSGeometryException
212 {
213 final CrossSectionLink link = makeLink(name, from, to, intermediatePoints, direction);
214 Lane[] result = new Lane[laneCount];
215 Length.Rel width = new Length.Rel(4.0, LengthUnit.METER);
216 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
217 {
218
219 Length.Rel latPosAtStart =
220 new Length.Rel((-0.5 - laneIndex - laneOffsetAtStart) * width.getSI(), LengthUnit.SI);
221 Length.Rel latPosAtEnd =
222 new Length.Rel((-0.5 - laneIndex - laneOffsetAtEnd) * width.getSI(), LengthUnit.SI);
223 result[laneIndex] =
224 makeLane(link, "lane." + laneIndex, laneType, latPosAtStart, latPosAtEnd, width, speedLimit, simulator,
225 direction);
226 }
227 return result;
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 @SuppressWarnings("checkstyle:parameternumber")
250 public static Lane[] makeMultiLane(final String name, final OTSNode from, final OTSNode to,
251 final OTSPoint3D[] intermediatePoints, final int laneCount, final LaneType laneType, final Speed speedLimit,
252 final OTSDEVSSimulatorInterface simulator, final LongitudinalDirectionality direction) throws NamingException,
253 NetworkException, OTSGeometryException
254 {
255 return makeMultiLane(name, from, to, intermediatePoints, laneCount, 0, 0, laneType, speedLimit, simulator,
256 direction);
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280 @SuppressWarnings("checkstyle:parameternumber")
281 public static Lane[] makeMultiLaneBezier(final String name, final OTSNode n1, final OTSNode n2, final OTSNode n3,
282 final OTSNode n4, final int laneCount, final int laneOffsetAtStart, final int laneOffsetAtEnd,
283 final LaneType laneType, final Speed speedLimit, final OTSDEVSSimulatorInterface simulator,
284 final LongitudinalDirectionality direction) throws NamingException, NetworkException, OTSGeometryException
285 {
286 OTSLine3D bezier = makeBezier(n1, n2, n3, n4);
287 final CrossSectionLink link = makeLink(name, n2, n3, bezier.getPoints(), direction);
288 Lane[] result = new Lane[laneCount];
289 Length.Rel width = new Length.Rel(4.0, LengthUnit.METER);
290 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
291 {
292
293 Length.Rel latPosAtStart =
294 new Length.Rel((-0.5 - laneIndex - laneOffsetAtStart) * width.getSI(), LengthUnit.SI);
295 Length.Rel latPosAtEnd =
296 new Length.Rel((-0.5 - laneIndex - laneOffsetAtEnd) * width.getSI(), LengthUnit.SI);
297 result[laneIndex] =
298 makeLane(link, "lane." + laneIndex, laneType, latPosAtStart, latPosAtEnd, width, speedLimit, simulator,
299 direction);
300 }
301 return result;
302 }
303
304
305
306
307
308
309
310
311
312 public static OTSLine3D makeBezier(final OTSNode n1, final OTSNode n2, final OTSNode n3, final OTSNode n4)
313 throws OTSGeometryException
314 {
315 OTSPoint3D p1 = n1.getPoint();
316 OTSPoint3D p2 = n2.getPoint();
317 OTSPoint3D p3 = n3.getPoint();
318 OTSPoint3D p4 = n4.getPoint();
319 DirectedPoint dp1 = new DirectedPoint(p2.x, p2.y, p2.z, 0.0, 0.0, Math.atan2(p2.y - p1.y, p2.x - p1.x));
320 DirectedPoint dp2 = new DirectedPoint(p3.x, p3.y, p3.z, 0.0, 0.0, Math.atan2(p4.y - p3.y, p4.x - p3.x));
321 return Bezier.cubic(dp1, dp2);
322 }
323
324 }