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