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