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.geometry.Bezier;
17 import org.opentrafficsim.core.geometry.OTSGeometryException;
18 import org.opentrafficsim.core.geometry.OTSLine3D;
19 import org.opentrafficsim.core.geometry.OTSPoint3D;
20 import org.opentrafficsim.core.gtu.GTUType;
21 import org.opentrafficsim.core.network.LinkType;
22 import org.opentrafficsim.core.network.Network;
23 import org.opentrafficsim.core.network.NetworkException;
24 import org.opentrafficsim.core.network.Node;
25 import org.opentrafficsim.core.network.OTSNode;
26 import org.opentrafficsim.core.network.animation.LinkAnimation;
27 import org.opentrafficsim.road.network.animation.LaneAnimation;
28 import org.opentrafficsim.road.network.lane.CrossSectionLink;
29 import org.opentrafficsim.road.network.lane.Lane;
30 import org.opentrafficsim.road.network.lane.LaneType;
31 import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
32 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
33
34 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
35 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
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 public static CrossSectionLink makeLink(final Network network, final String name, final Node from, final Node to,
70 final OTSPoint3D[] intermediatePoints, final DEVSSimulatorInterface.TimeDoubleUnit simulator)
71 throws OTSGeometryException, NetworkException
72 {
73 List<OTSPoint3D> pointList =
74 intermediatePoints == null ? new ArrayList<>() : new ArrayList<>(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.ROAD, designLine, simulator,
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 @SuppressWarnings("checkstyle:parameternumber")
136 private static Lane makeLane(final CrossSectionLink link, final String id, final LaneType laneType,
137 final Length latPosAtStart, final Length latPosAtEnd, final Length width, final Speed speedLimit,
138 final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NamingException, NetworkException, OTSGeometryException
139 {
140 Map<GTUType, Speed> speedMap = new LinkedHashMap<>();
141 speedMap.put(GTUType.VEHICLE, speedLimit);
142 Lane result = new Lane(link, id, latPosAtStart, latPosAtEnd, width, width, laneType, speedMap,
143 new OvertakingConditions.LeftAndRight());
144 if (simulator instanceof AnimatorInterface)
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 Network network, final String name, final OTSNode from, final OTSNode to,
175 final OTSPoint3D[] intermediatePoints, final LaneType laneType, final Speed speedLimit,
176 final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NamingException, NetworkException, OTSGeometryException
177 {
178 Length width = new Length(4.0, LengthUnit.METER);
179 final CrossSectionLink link = makeLink(network, name, from, to, intermediatePoints, simulator);
180 Length latPos = new Length(0.0, LengthUnit.METER);
181 return makeLane(link, "lane", laneType, latPos, latPos, width, speedLimit, simulator);
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 @SuppressWarnings("checkstyle:parameternumber")
206 public static Lane[] makeMultiLane(final Network network, final String name, final OTSNode from, final OTSNode to,
207 final OTSPoint3D[] intermediatePoints, final int laneCount, final int laneOffsetAtStart, final int laneOffsetAtEnd,
208 final LaneType laneType, final Speed speedLimit, final DEVSSimulatorInterface.TimeDoubleUnit simulator)
209 throws NamingException, NetworkException, OTSGeometryException
210 {
211 final CrossSectionLink link = makeLink(network, name, from, to, intermediatePoints, simulator);
212 Lane[] result = new Lane[laneCount];
213 Length width = new Length(4.0, LengthUnit.METER);
214 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
215 {
216
217 Length latPosAtStart = new Length((-0.5 - laneIndex - laneOffsetAtStart) * width.getSI(), LengthUnit.SI);
218 Length latPosAtEnd = new Length((-0.5 - laneIndex - laneOffsetAtEnd) * width.getSI(), LengthUnit.SI);
219 result[laneIndex] =
220 makeLane(link, "lane." + laneIndex, laneType, latPosAtStart, latPosAtEnd, width, speedLimit, simulator);
221 }
222 if (simulator instanceof AnimatorInterface)
223 {
224 try
225 {
226 new LinkAnimation(link, simulator, 3f);
227 }
228 catch (RemoteException exception)
229 {
230 exception.printStackTrace();
231 }
232 }
233 return result;
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 @SuppressWarnings("checkstyle:parameternumber")
256 public static Lane[] makeMultiLane(final Network network, final String name, final OTSNode from, final OTSNode to,
257 final OTSPoint3D[] intermediatePoints, final int laneCount, final LaneType laneType, final Speed speedLimit,
258 final DEVSSimulatorInterface.TimeDoubleUnit simulator) throws NamingException, NetworkException, OTSGeometryException
259 {
260 return makeMultiLane(network, name, from, to, intermediatePoints, laneCount, 0, 0, laneType, speedLimit, simulator);
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 DEVSSimulatorInterface.TimeDoubleUnit simulator)
288 throws NamingException, NetworkException, OTSGeometryException
289 {
290 OTSLine3D bezier = makeBezier(n1, n2, n3, n4);
291 final CrossSectionLink link = makeLink(network, name, n2, n3, bezier.getPoints(), simulator);
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] =
300 makeLane(link, "lane." + laneIndex, laneType, latPosAtStart, latPosAtEnd, width, speedLimit, simulator);
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 }