View Javadoc
1   package org.opentrafficsim.core.network.factory;
2   
3   import java.awt.Color;
4   import java.rmi.RemoteException;
5   
6   import javax.naming.NamingException;
7   
8   import org.opentrafficsim.core.dsol.OTSAnimatorInterface;
9   import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
10  import org.opentrafficsim.core.network.LateralDirectionality;
11  import org.opentrafficsim.core.network.LongitudinalDirectionality;
12  import org.opentrafficsim.core.network.NetworkException;
13  import org.opentrafficsim.core.network.animation.LaneAnimation;
14  import org.opentrafficsim.core.network.geotools.LinearGeometry;
15  import org.opentrafficsim.core.network.geotools.NodeGeotools;
16  import org.opentrafficsim.core.network.lane.CrossSectionLink;
17  import org.opentrafficsim.core.network.lane.Lane;
18  import org.opentrafficsim.core.network.lane.LaneType;
19  import org.opentrafficsim.core.unit.FrequencyUnit;
20  import org.opentrafficsim.core.unit.LengthUnit;
21  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar;
22  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar.Rel;
23  
24  import com.vividsolutions.jts.geom.Coordinate;
25  import com.vividsolutions.jts.geom.GeometryFactory;
26  import com.vividsolutions.jts.geom.LineString;
27  
28  /**
29   * <p>
30   * Copyright (c) 2013-2014 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights
31   * reserved. <br>
32   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
33   * <p>
34   * @version 30 okt. 2014 <br>
35   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
36   */
37  public final class LaneFactory
38  {
39      /** Do not instantiate this class. */
40      private LaneFactory()
41      {
42          // Cannot be instantiated.
43      }
44  
45      /**
46       * Create a Link along intermediate coordinates from one Node to another.
47       * @param name String; name of the new Link
48       * @param from Node; start Node of the new Link
49       * @param to Node; end Node of the new Link
50       * @param intermediateCoordinates Coordinate[]; array of intermediate coordinates (may be null)
51       * @return Link; the newly constructed Link
52       */
53      public static CrossSectionLink<?, ?> makeLink(final String name, final NodeGeotools.STR from,
54              final NodeGeotools.STR to, final Coordinate[] intermediateCoordinates)
55      {
56          int coordinateCount = 2 + (null == intermediateCoordinates ? 0 : intermediateCoordinates.length);
57          Coordinate[] coordinates = new Coordinate[coordinateCount];
58          coordinates[0] = new Coordinate(from.getPoint().x, from.getPoint().y, 0);
59          coordinates[coordinates.length - 1] = new Coordinate(to.getPoint().x, to.getPoint().y, 0);
60          if (null != intermediateCoordinates)
61          {
62              for (int i = 0; i < intermediateCoordinates.length; i++)
63              {
64                  coordinates[i + 1] = new Coordinate(intermediateCoordinates[i]);
65              }
66          }
67          GeometryFactory factory = new GeometryFactory();
68          LineString lineString = factory.createLineString(coordinates);
69          @SuppressWarnings({"unchecked", "rawtypes"})
70          CrossSectionLink<?, ?> link =
71                  new CrossSectionLink(name, from, to, new DoubleScalar.Rel<LengthUnit>(lineString.getLength(),
72                          LengthUnit.METER));
73          try
74          {
75              new LinearGeometry(link, lineString, null);
76          }
77          catch (NetworkException exception)
78          {
79              throw new Error("Network exception in LinearGeometry");
80          }
81          return link;
82      }
83  
84      /**
85       * Create one Lane.
86       * @param link Link; the link that owns the new Lane
87       * @param laneType LaneType&lt;String&gt;; the type of the new Lane
88       * @param latPosAtStart DoubleScalar.Rel&lt;LengthUnit&gt;; the lateral position of the new Lane with respect to the
89       *            design line of the link at the start of the link
90       * @param latPosAtEnd DoubleScalar.Rel&lt;LengthUnit&gt;; the lateral position of the new Lane with respect to the
91       *            design line of the link at the end of the link
92       * @param width DoubleScalar.Rel&lt;LengthUnit&gt;; the width of the new Lane
93       * @param simulator OTSDEVSSimulatorInterface; the simulator
94       * @return Lane
95       * @throws NamingException when names cannot be registered for animation
96       * @throws RemoteException on communications failure
97       * @throws NetworkException on network inconsistency
98       */
99      private static Lane makeLane(final CrossSectionLink<?, ?> link, final LaneType<String> laneType,
100             final DoubleScalar.Rel<LengthUnit> latPosAtStart, Rel<LengthUnit> latPosAtEnd,
101             final DoubleScalar.Rel<LengthUnit> width, final OTSDEVSSimulatorInterface simulator)
102             throws RemoteException, NamingException, NetworkException
103     {
104         DoubleScalar.Abs<FrequencyUnit> f2000 = new DoubleScalar.Abs<FrequencyUnit>(2000.0, FrequencyUnit.PER_HOUR);
105         Lane result =
106                 new Lane(link, latPosAtStart, latPosAtEnd, width, width, laneType, LongitudinalDirectionality.FORWARD,
107                         f2000);
108         if (simulator instanceof OTSAnimatorInterface)
109         {
110             new LaneAnimation(result, simulator, Color.LIGHT_GRAY);
111         }
112         return result;
113     }
114 
115     /**
116      * Create a simple Lane.
117      * @param name String; name of the Lane (and also of the Link that owns it)
118      * @param from Node; starting node of the new Lane
119      * @param to Node; ending node of the new Lane
120      * @param intermediateCoordinates Coordinate[]; intermediate coordinates or null to create a straight road
121      * @param laneType LaneType; type of the new Lane
122      * @param simulator OTSDEVSSimulatorInterface; the simulator
123      * @return Lane; the new Lane
124      * @throws NamingException when names cannot be registered for animation
125      * @throws RemoteException on communications failure
126      * @throws NetworkException on network inconsistency
127      */
128     public static Lane makeLane(final String name, final NodeGeotools.STR from, final NodeGeotools.STR to,
129             final Coordinate[] intermediateCoordinates, final LaneType<String> laneType,
130             final OTSDEVSSimulatorInterface simulator) throws RemoteException, NamingException, NetworkException
131     {
132         DoubleScalar.Rel<LengthUnit> width = new DoubleScalar.Rel<LengthUnit>(4.0, LengthUnit.METER);
133         final CrossSectionLink<?, ?> link = makeLink(name, from, to, intermediateCoordinates);
134         DoubleScalar.Rel<LengthUnit> latPos = new DoubleScalar.Rel<LengthUnit>(0.0, LengthUnit.METER);
135         return makeLane(link, laneType, latPos, latPos, width, simulator);
136     }
137 
138     /**
139      * Create a simple road with the specified number of Lanes.<br/>
140      * This method returns an array of Lane. These lanes are embedded in a Link that can be accessed through the
141      * getParentLink method of the Lane.
142      * @param name String; name of the Link
143      * @param from Node; starting node of the new Lane
144      * @param to Node; ending node of the new Lane
145      * @param intermediateCoordinates Coordinate[]; intermediate coordinates or null to create a straight road
146      * @param laneCount int; number of lanes in the road
147      * @param laneOffsetAtStart int; extra offset from design line in lane widths at start of link
148      * @param laneOffsetAtEnd int; extra offset from design line in lane widths at end of link
149      * @param laneType LaneType; type of the new Lanes
150      * @param simulator OTSDEVSSimulatorInterface; the simulator
151      * @return Lane[]; array containing the new Lanes
152      * @throws NamingException when names cannot be registered for animation
153      * @throws RemoteException on communications failure
154      * @throws NetworkException on topological problems
155      */
156     public static Lane[] makeMultiLane(final String name, final NodeGeotools.STR from, final NodeGeotools.STR to,
157             final Coordinate[] intermediateCoordinates, final int laneCount, int laneOffsetAtStart,
158             int laneOffsetAtEnd, final LaneType<String> laneType, final OTSDEVSSimulatorInterface simulator)
159             throws RemoteException, NamingException, NetworkException
160     {
161         DoubleScalar.Rel<LengthUnit> width = new DoubleScalar.Rel<LengthUnit>(laneCount * 4.0, LengthUnit.METER);
162         final CrossSectionLink<?, ?> link = makeLink(name, from, to, intermediateCoordinates);
163         Lane[] result = new Lane[laneCount];
164         width = new DoubleScalar.Rel<LengthUnit>(4.0, LengthUnit.METER);
165         for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
166         {
167             // Be ware! LEFT is lateral positive, RIGHT is lateral negative.
168             DoubleScalar.Rel<LengthUnit> latPosAtStart =
169                     new DoubleScalar.Rel<LengthUnit>((-0.5 - laneIndex - laneOffsetAtStart) * width.getSI(), LengthUnit.METER);
170             DoubleScalar.Rel<LengthUnit> latPosAtEnd =
171                     new DoubleScalar.Rel<LengthUnit>((-0.5 - laneIndex - laneOffsetAtEnd) * width.getSI(), LengthUnit.METER);
172             result[laneIndex] = makeLane(link, laneType, latPosAtStart, latPosAtEnd, width, simulator);
173         }
174         // Make lanes adjacent in their natural order
175         for (int laneIndex = 1; laneIndex < laneCount; laneIndex++)
176         {
177             result[laneIndex - 1].addAccessibleAdjacentLane(result[laneIndex], LateralDirectionality.RIGHT);
178             result[laneIndex].addAccessibleAdjacentLane(result[laneIndex - 1], LateralDirectionality.LEFT);
179         }
180         return result;
181     }
182 
183     /**
184      * Create a simple road with the specified number of Lanes.<br/>
185      * This method returns an array of Lane. These lanes are embedded in a Link that can be accessed through the
186      * getParentLink method of the Lane.
187      * @param name String; name of the Link
188      * @param from Node; starting node of the new Lane
189      * @param to Node; ending node of the new Lane
190      * @param intermediateCoordinates Coordinate[]; intermediate coordinates or null to create a straight road
191      * @param laneCount int; number of lanes in the road
192      * @param laneType LaneType; type of the new Lanes
193      * @param simulator OTSDEVSSimulatorInterface; the simulator
194      * @return Lane[]; array containing the new Lanes
195      * @throws NamingException when names cannot be registered for animation
196      * @throws RemoteException on communications failure
197      * @throws NetworkException on topological problems
198      */
199     public static Lane[] makeMultiLane(final String name, final NodeGeotools.STR from, final NodeGeotools.STR to,
200             final Coordinate[] intermediateCoordinates, final int laneCount, final LaneType<String> laneType,
201             final OTSDEVSSimulatorInterface simulator) throws RemoteException, NamingException, NetworkException
202     {
203         return makeMultiLane(name, from, to, intermediateCoordinates, laneCount, 0, 0, laneType, simulator);
204     }
205 
206 }