Stripe.java

  1. package org.opentrafficsim.road.network.lane;

  2. import java.util.LinkedHashMap;
  3. import java.util.LinkedHashSet;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.Set;
  7. import java.util.UUID;

  8. import org.djunits.value.vdouble.scalar.Length;
  9. import org.djutils.exceptions.Throw;
  10. import org.opentrafficsim.core.geometry.OtsGeometryException;
  11. import org.opentrafficsim.core.gtu.GtuType;
  12. import org.opentrafficsim.core.network.LateralDirectionality;
  13. import org.opentrafficsim.core.network.NetworkException;

  14. /**
  15.  * <p>
  16.  * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  17.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  18.  * </p>
  19.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  20.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  21.  * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  22.  */
  23. public class Stripe extends CrossSectionElement
  24. {
  25.     /** */
  26.     private static final long serialVersionUID = 20141025L;

  27.     /** Type of the stripe, defining default permeability. */
  28.     private final Type type;

  29.     /** Type to overrule the normal type, e.g. rush-hour lanes without changing the appearance of the stripe. */
  30.     private Type overruleType;

  31.     /** Lateral permeability per GTU type and direction. */
  32.     private final Map<GtuType, Set<LateralDirectionality>> permeabilityMap = new LinkedHashMap<>();

  33.     /**
  34.      * Constructor allowing difference at start at end.
  35.      * @param type Type; strip type defining appearance and default permeability.
  36.      * @param parentLink CrossSectionLink; Cross Section Link to which the element belongs.
  37.      * @param startCenterPosition Length; the lateral start position compared to the linear geometry of the Cross Section Link
  38.      *            at the start of the road marker.
  39.      * @param endCenterPosition Length; the lateral end position compared to the linear geometry of the Cross Section Link at
  40.      *            the end of the road marker.
  41.      * @param beginWidth Length; start width, positioned &lt;i&gt;symmetrically around&lt;/i&gt; the lateral start position.
  42.      * @param endWidth Length; end width, positioned &lt;i&gt;symmetrically around&lt;/i&gt; the lateral end position.
  43.      * @param fixGradualLateralOffset boolean; true if gradualLateralOffset needs to be fixed
  44.      * @throws OtsGeometryException when creation of the center line or contour geometry fails
  45.      * @throws NetworkException when id equal to null or not unique
  46.      */
  47.     public Stripe(final Type type, final CrossSectionLink parentLink, final Length startCenterPosition,
  48.             final Length endCenterPosition, final Length beginWidth, final Length endWidth,
  49.             final boolean fixGradualLateralOffset) throws OtsGeometryException, NetworkException
  50.     {
  51.         super(parentLink, UUID.randomUUID().toString(), startCenterPosition, endCenterPosition, beginWidth, endWidth,
  52.                 fixGradualLateralOffset);
  53.         Throw.whenNull(type, "Type may not be null.");
  54.         this.type = type;
  55.     }

  56.     /**
  57.      * Constructor for constant properties along the length.
  58.      * @param type Type; strip type defining appearance and default permeability.
  59.      * @param parentLink CrossSectionLink; Cross Section Link to which the element belongs.
  60.      * @param lateralCenterPosition Length; the lateral start position compared to the linear geometry of the Cross Section
  61.      *            Link.
  62.      * @param width Length; start width, positioned &lt;i&gt;symmetrically around&lt;/i&gt; the lateral start position.
  63.      * @throws OtsGeometryException when creation of the center line or contour geometry fails
  64.      * @throws NetworkException when id equal to null or not unique
  65.      */
  66.     public Stripe(final Type type, final CrossSectionLink parentLink, final Length lateralCenterPosition, final Length width)
  67.             throws OtsGeometryException, NetworkException
  68.     {
  69.         this(type, parentLink, lateralCenterPosition, lateralCenterPosition, width, width, false);
  70.     }

  71.     /**
  72.      * Constructor for elaborate longitudinal property changes.
  73.      * @param type Type; strip type defining appearance and default permeability.
  74.      * @param parentLink CrossSectionLink; Cross Section Link to which the element belongs.
  75.      * @param crossSectionSlices List&lt;CrossSectionSlice&gt;; The offsets and widths at positions along the line, relative to
  76.      *            the design line of the parent link. If there is just one with and offset, there should just be one element in
  77.      *            the list with Length = 0. If there are more slices, the last one should be at the length of the design line.
  78.      *            If not, a NetworkException is thrown.
  79.      * @throws OtsGeometryException when creation of the center line or contour geometry fails
  80.      * @throws NetworkException when id equal to null or not unique
  81.      */
  82.     public Stripe(final Type type, final CrossSectionLink parentLink, final List<CrossSectionSlice> crossSectionSlices)
  83.             throws OtsGeometryException, NetworkException
  84.     {
  85.         super(parentLink, UUID.randomUUID().toString(), crossSectionSlices);
  86.         Throw.whenNull(type, "Type may not be null.");
  87.         this.type = type;
  88.     }

  89.     /**
  90.      * Returns the stripe type.
  91.      * @return Type; stripe type.
  92.      */
  93.     public Type getType()
  94.     {
  95.         return this.type;
  96.     }

  97.     /**
  98.      * Sets an overruling stripe type. This can be used for e.g. rush-hour lanes, without changing the appearance of the stripe.
  99.      * Note that custom set permeabilities (addPermeability()) remain active.
  100.      * @param overruleType Type; overruling stripe type.
  101.      */
  102.     public void setOverruleType(final Type overruleType)
  103.     {
  104.         this.overruleType = overruleType;
  105.     }

  106.     /**
  107.      * Clears the overrule type, after which the normal type will hold.
  108.      */
  109.     public void clearOverruleType()
  110.     {
  111.         this.overruleType = null;
  112.     }

  113.     /**
  114.      * Returns the currently active stripe type.
  115.      * @return Type; the currently active stripe type.
  116.      */
  117.     private Type activeType()
  118.     {
  119.         return this.overruleType == null ? this.type : this.overruleType;
  120.     }

  121.     /** {@inheritDoc} */
  122.     @Override
  123.     public final double getZ()
  124.     {
  125.         return -0.0002;
  126.     }

  127.     /**
  128.      * Add lateral permeability for a GTU type in the direction of the design line of the overarching CrossSectionLink. Add NONE
  129.      * to prevent lane changes relative to the stripe type. Add LEFT or RIGHT, or both in two calls, to enable lane changes
  130.      * relative to the stripe type.
  131.      * @param gtuType GtuType; GTU type to add permeability for.
  132.      * @param lateralDirection LateralDirectionality; direction to add compared to the direction of the design line.
  133.      */
  134.     public void addPermeability(final GtuType gtuType, final LateralDirectionality lateralDirection)
  135.     {
  136.         if (!this.permeabilityMap.containsKey(gtuType))
  137.         {
  138.             this.permeabilityMap.put(gtuType, new LinkedHashSet<LateralDirectionality>(2));
  139.         }
  140.         this.permeabilityMap.get(gtuType).add(lateralDirection);
  141.     }

  142.     /**
  143.      * Returns whether the given GTU type is allowed to cross the line in the given lateral direction.
  144.      * @param gtuType GtuType; GTU type to look for.
  145.      * @param lateralDirection LateralDirectionality; direction to look for (LEFT or RIGHT) compared to the direction of the
  146.      *            design line.
  147.      * @return whether the road marker is permeable for the GTU type.
  148.      */
  149.     public final boolean isPermeable(final GtuType gtuType, final LateralDirectionality lateralDirection)
  150.     {
  151.         Throw.when(lateralDirection.isNone(), RuntimeException.class,
  152.                 "May not request NONE lateral direction for permeability.");
  153.         for (GtuType testGtuType = gtuType; null != testGtuType; testGtuType = testGtuType.getParent())
  154.         {
  155.             Set<LateralDirectionality> set = this.permeabilityMap.get(testGtuType);
  156.             if (null != set)
  157.             {
  158.                 return set.contains(lateralDirection);
  159.             }
  160.         }
  161.         return lateralDirection.isLeft() ? activeType().left() : activeType().right;
  162.     }

  163.     /**
  164.      * Defines the visible type of the stripe, and the standard permeability that pertains to it.
  165.      * <p>
  166.      * Copyright (c) 2022-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
  167.      * <br>
  168.      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  169.      * </p>
  170.      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  171.      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  172.      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
  173.      */
  174.     public enum Type
  175.     {
  176.         /** Single solid line. */
  177.         SOLID(false, false),

  178.         /** Line |¦ allow to go to left, but not to right. */
  179.         LEFT(true, false),

  180.         /** Line ¦| allow to go to right, but not to left. */
  181.         RIGHT(false, true),

  182.         /** Dashes ¦ allow to cross in both directions. */
  183.         DASHED(true, true),

  184.         /** Double solid line ||, don't cross. */
  185.         DOUBLE(false, false),

  186.         /** Block : allow to cross in both directions. */
  187.         BLOCK(true, true);

  188.         /** Left permeable. */
  189.         private final boolean left;

  190.         /** Right permeable. */
  191.         private final boolean right;

  192.         /**
  193.          * Constructor setting permeability.
  194.          * @param left boolean; left permeability.
  195.          * @param right boolean; right permeability.
  196.          */
  197.         Type(final boolean left, final boolean right)
  198.         {
  199.             this.left = left;
  200.             this.right = right;
  201.         }

  202.         /**
  203.          * Returns the left permeability.
  204.          * @return boolean; left permeability.
  205.          */
  206.         public boolean left()
  207.         {
  208.             return this.left;
  209.         }

  210.         /**
  211.          * Returns the right permeability.
  212.          * @return boolean; right permeability.
  213.          */
  214.         public boolean right()
  215.         {
  216.             return this.right;
  217.         }
  218.     }

  219. }