1 package org.opentrafficsim.road.network.lane;
2
3 import java.util.HashMap;
4 import java.util.HashSet;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Set;
8 import java.util.UUID;
9
10 import org.djunits.value.vdouble.scalar.Length;
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
16 /**
17 * <p>
18 * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
19 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
20 * <p>
21 * $LastChangedDate: 2015-09-03 13:38:01 +0200 (Thu, 03 Sep 2015) $, @version $Revision: 1378 $, by $Author: averbraeck $,
22 * initial version Oct 25, 2014 <br>
23 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
24 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
25 */
26 public abstract class RoadMarkerAlong extends CrossSectionElement
27 {
28 /** */
29 private static final long serialVersionUID = 20141025L;
30
31 /** Lateral permeability per GTU type and direction. */
32 private final Map<GTUType, Set<LateralDirectionality>> permeabilityMap = new HashMap<>();
33
34 /**
35 * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction, with the direction from
36 * the StartNode towards the EndNode as the longitudinal direction.
37 * @param parentLink Cross Section Link to which the element belongs.
38 * @param startCenterPosition the lateral start position compared to the linear geometry of the Cross Section Link at the
39 * start of the road marker.
40 * @param endCenterPosition the lateral end position compared to the linear geometry of the Cross Section Link at the end of
41 * the road marker.
42 * @param beginWidth start width, positioned <i>symmetrically around</i> the lateral start position.
43 * @param endWidth end width, positioned <i>symmetrically around</i> the lateral end position.
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 RoadMarkerAlong(final CrossSectionLink parentLink, final Length startCenterPosition,
48 final Length endCenterPosition, final Length beginWidth, final Length endWidth)
49 throws OTSGeometryException, NetworkException
50 {
51 super(parentLink, UUID.randomUUID().toString(), startCenterPosition, endCenterPosition, beginWidth, endWidth);
52 }
53
54 /**
55 * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction, with the direction from
56 * the StartNode towards the EndNode as the longitudinal direction.
57 * @param parentLink Cross Section Link to which the element belongs.
58 * @param lateralCenterPosition the lateral start position compared to the linear geometry of the Cross Section Link.
59 * @param width start width, positioned <i>symmetrically around</i> the lateral start position.
60 * @throws OTSGeometryException when creation of the center line or contour geometry fails
61 * @throws NetworkException when id equal to null or not unique
62 */
63 public RoadMarkerAlong(final CrossSectionLink parentLink, final Length lateralCenterPosition,
64 final Length width) throws OTSGeometryException, NetworkException
65 {
66 super(parentLink, UUID.randomUUID().toString(), lateralCenterPosition, width);
67 }
68
69 /**
70 * <b>Note:</b> LEFT is seen as a positive lateral direction, RIGHT as a negative lateral direction, with the direction from
71 * the StartNode towards the EndNode as the longitudinal direction.
72 * @param parentLink Cross Section Link to which the element belongs.
73 * @param crossSectionSlices The offsets and widths at positions along the line, relative to the design line of the parent
74 * link. If there is just one with and offset, there should just be one element in the list with Length = 0.
75 * If there are more slices, the last one should be at the length of the design line. If not, a NetworkException
76 * is thrown.
77 * @throws OTSGeometryException when creation of the center line or contour geometry fails
78 * @throws NetworkException when id equal to null or not unique
79 */
80 public RoadMarkerAlong(final CrossSectionLink parentLink, final List<CrossSectionSlice> crossSectionSlices)
81 throws OTSGeometryException, NetworkException
82 {
83 super(parentLink, UUID.randomUUID().toString(), crossSectionSlices);
84 }
85
86 /** {@inheritDoc} */
87 @Override
88 protected final double getZ()
89 {
90 return 0.0001;
91 }
92
93 /**
94 * Add lateral permeability for a GTU type in the direction of the design line of the overarching CrossSectionLink.
95 * Therefore, the lateral directionality of one-sided permeability has to be switched for left lanes. This is done because
96 * the CrossSectionLink has no idea in which direction vehicles will be moving. On a 1+1 lane road with overtaking
97 * possibilities, the longitudinal directionality of both lanes will be BOTH. Example:
98 *
99 * <pre>
100 * Suppose the design line runs from left to right.
101 *
102 * =========================
103 *
104 * LANE 1L (BACKWARD) GTUs are allowed to move to lane 2L
105 * Permeability RIGHT is true, although vehicles will go to the LEFT...
106 * -------------------------
107 * =========================
108 *
109 * LANE 2L (BACKWARD) GTUs are NOT allowed to move to lane 1L nor to lane 2R
110 * No permeability defined (empty set)
111 * =========================
112 * =========================
113 *
114 * LANE 2R (FORWARD) GTUs are NOT allowed to move to lane 1R nor to lane 2L
115 * No permeability defined (empty set)
116 * =========================
117 * -------------------------
118 *
119 * LANE 1R (FORWARD) GTUs are allowed to move to lane 2R
120 * Permeability LEFT is true
121 * =========================
122 * </pre>
123 *
124 * <b>Note:</b> GTUType.ALL can be used to set permeability for all types of GTU at once.
125 * <p>
126 * @param gtuType GTU type to add permeability for.
127 * @param lateralDirection direction to add (LEFT or RIGHT) compared to the direction of the design line.
128 */
129 public final void addPermeability(final GTUType gtuType, final LateralDirectionality lateralDirection)
130 {
131 if (!this.permeabilityMap.containsKey(gtuType))
132 {
133 this.permeabilityMap.put(gtuType, new HashSet<LateralDirectionality>(2));
134 }
135 this.permeabilityMap.get(gtuType).add(lateralDirection);
136 }
137
138 /**
139 * @param gtuType GTU type to look for.
140 * @param lateralDirection direction to look for (LEFT or RIGHT) compared to the direction of the design line.
141 * @return whether the road marker is permeable for the GTU type.
142 */
143 public final boolean isPermeable(final GTUType gtuType, final LateralDirectionality lateralDirection)
144 {
145 if (this.permeabilityMap.containsKey(GTUType.ALL))
146 {
147 return this.permeabilityMap.get(GTUType.ALL).contains(lateralDirection);
148 }
149 if (!this.permeabilityMap.containsKey(gtuType))
150 {
151 return false;
152 }
153 return this.permeabilityMap.get(gtuType).contains(lateralDirection);
154 }
155
156 }