View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import java.rmi.RemoteException;
4   import java.util.List;
5   import java.util.Set;
6   
7   import javax.naming.NamingException;
8   
9   import org.djunits.value.vdouble.scalar.Length;
10  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
11  import org.opentrafficsim.core.geometry.OTSGeometryException;
12  import org.opentrafficsim.core.gtu.GTUType;
13  import org.opentrafficsim.core.network.LateralDirectionality;
14  import org.opentrafficsim.core.network.NetworkException;
15  import org.opentrafficsim.road.network.animation.StripeAnimation;
16  
17  /**
18   * Longitudinal road stripes; simple constructors.
19   * <p>
20   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
21   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
22   * <p>
23   * $LastChangedDate: 2015-09-03 13:38:01 +0200 (Thu, 03 Sep 2015) $, @version $Revision: 1378 $, by $Author: averbraeck $,
24   * initial version Oct 25, 2014 <br>
25   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
26   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
27   */
28  public class Stripe extends RoadMarkerAlong
29  {
30      /** */
31      private static final long serialVersionUID = 20151025L;
32  
33      /**
34       * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction, with the direction from
35       * the StartNode towards the EndNode as the longitudinal direction.
36       * @param parentLink Cross Section Link to which the element belongs
37       * @param lateralCenterPosition the lateral start position compared to the linear geometry of the Cross Section Link
38       * @param width positioned <i>symmetrically around</i> the center line given by the lateralCenterPosition.
39       * @throws OTSGeometryException when creation of the center line or contour geometry fails
40       * @throws NetworkException when id equal to null or not unique
41       */
42      public Stripe(final CrossSectionLink parentLink, final Length lateralCenterPosition, final Length width)
43              throws OTSGeometryException, NetworkException
44      {
45          super(parentLink, lateralCenterPosition, width);
46      }
47  
48      /**
49       * Helper constructor that immediately provides permeability for a number of GTU classes.<br>
50       * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction, with the direction from
51       * the StartNode towards the EndNode as the longitudinal direction.
52       * @param parentLink Cross Section Link to which the element belongs
53       * @param lateralCenterPosition the lateral start position compared to the linear geometry of the Cross Section Link
54       * @param width positioned <i>symmetrically around</i> the center line given by the lateralCenterPosition
55       * @param gtuTypes the GTU types for which the permeability is defined
56       * @param permeable one of the enums of Stripe.Permeable to define the permeability
57       * @throws OTSGeometryException when creation of the center line or contour geometry fails
58       * @throws NetworkException when id equal to null or not unique
59       */
60      public Stripe(final CrossSectionLink parentLink, final Length lateralCenterPosition, final Length width,
61              final Set<GTUType> gtuTypes, final Permeable permeable) throws OTSGeometryException, NetworkException
62      {
63          super(parentLink, lateralCenterPosition, width);
64          for (GTUType gtuType : gtuTypes)
65          {
66              addPermeability(gtuType, permeable);
67          }
68      }
69  
70      /**
71       * Helper constructor that immediately provides permeability for all GTU classes.<br>
72       * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction, with the direction from
73       * the StartNode towards the EndNode as the longitudinal direction.
74       * @param parentLink Cross Section Link to which the element belongs
75       * @param crossSectionSlices The offsets and widths at positions along the line, relative to the design line of the parent
76       *            link. If there is just one with and offset, there should just be one element in the list with Length = 0. If
77       *            there are more slices, the last one should be at the length of the design line. If not, a NetworkException is
78       *            thrown.
79       * @param permeable one of the enums of Stripe.Permeable to define the permeability
80       * @throws OTSGeometryException when creation of the center line or contour geometry fails
81       * @throws NetworkException when id equal to null or not unique
82       */
83      public Stripe(final CrossSectionLink parentLink, final List<CrossSectionSlice> crossSectionSlices,
84              final Permeable permeable) throws OTSGeometryException, NetworkException
85      {
86          super(parentLink, crossSectionSlices);
87          addPermeability(GTUType.ALL, permeable);
88      }
89  
90      /**
91       * Clone a Stripe for a new network.
92       * @param newParentLink the new link to which the clone belongs
93       * @param newSimulator the new simulator for this network
94       * @param animation whether to (re)create animation or not
95       * @param cse the element to clone from
96       * @throws NetworkException if link already exists in the network, if name of the link is not unique, or if the start node
97       *             or the end node of the link are not registered in the network.
98       */
99      protected Stripe(final CrossSectionLink newParentLink, final OTSSimulatorInterface newSimulator,
100             final boolean animation, final Stripe cse) throws NetworkException
101     {
102         super(newParentLink, newSimulator, animation, cse);
103     }
104 
105     /**
106      * @param gtuType GTU type to add permeability for.
107      * @param permeable direction(s) to add compared to the direction of the design line.
108      */
109     public final void addPermeability(final GTUType gtuType, final Permeable permeable)
110     {
111         if (permeable.equals(Permeable.LEFT) || permeable.equals(Permeable.BOTH))
112         {
113             addPermeability(gtuType, LateralDirectionality.LEFT);
114         }
115         if (permeable.equals(Permeable.RIGHT) || permeable.equals(Permeable.BOTH))
116         {
117             addPermeability(gtuType, LateralDirectionality.RIGHT);
118         }
119     }
120 
121     /** The types of permeability of a stripe. */
122     public enum Permeable
123     {
124         /** Permeable in the positive lateral direction compared to the design line direction. */
125         LEFT,
126         /** Permeable in the negative lateral direction compared to the design line direction. */
127         RIGHT,
128         /** Permeable in both directions. */
129         BOTH;
130     }
131 
132     /** {@inheritDoc} */
133     @Override
134     @SuppressWarnings("checkstyle:designforextension")
135     public String toString()
136     {
137         return String.format("Stripe offset %.2fm..%.2fm, width %.2fm..%.2fm", getDesignLineOffsetAtBegin().getSI(),
138                 getDesignLineOffsetAtEnd().getSI(), getBeginWidth().getSI(), getEndWidth().getSI());
139     }
140 
141     /** {@inheritDoc} */
142     @Override
143     @SuppressWarnings("checkstyle:designforextension")
144     public Stripe clone(final CrossSectionLink newParentLink, final OTSSimulatorInterface newSimulator,
145             final boolean animation) throws NetworkException
146     {
147         try
148         {
149             Stripe newStripe = new Stripe(newParentLink, newSimulator, animation, this);
150 
151             if (animation)
152             {
153                 // estimate the animation...
154                 Permeable permeable = null;
155                 for (GTUType gtuType : newStripe.getPermeabilityMap().keySet())
156                 {
157                     for (LateralDirectionality dir : newStripe.getPermeabilityMap().get(gtuType))
158                     {
159                         if (dir.isLeft())
160                         {
161                             if (permeable == null)
162                             {
163                                 permeable = Permeable.LEFT;
164                             }
165                             if (permeable.equals(Permeable.RIGHT))
166                             {
167                                 permeable = Permeable.BOTH;
168                             }
169                         }
170                         if (dir.isRight())
171                         {
172                             if (permeable == null)
173                             {
174                                 permeable = Permeable.RIGHT;
175                             }
176                             if (permeable.equals(Permeable.LEFT))
177                             {
178                                 permeable = Permeable.BOTH;
179                             }
180                         }
181                     }
182                 }
183                 if (permeable == null)
184                 {
185                     new StripeAnimation(newStripe, newSimulator, StripeAnimation.TYPE.SOLID);
186                 }
187                 else
188                 {
189                     switch (permeable)
190                     {
191                         case BOTH:
192                             new StripeAnimation(newStripe, newSimulator, StripeAnimation.TYPE.DASHED);
193                             break;
194 
195                         case LEFT:
196                             new StripeAnimation(newStripe, newSimulator, StripeAnimation.TYPE.LEFTONLY);
197                             break;
198 
199                         case RIGHT:
200                             new StripeAnimation(newStripe, newSimulator, StripeAnimation.TYPE.RIGHTONLY);
201                             break;
202 
203                         default:
204                             break;
205                     }
206                 }
207             }
208 
209             return newStripe;
210         }
211         catch (NamingException | RemoteException | OTSGeometryException exception)
212         {
213             throw new NetworkException(exception);
214         }
215     }
216 
217 }