1 package org.opentrafficsim.road.network.lane;
2
3 import java.io.Serializable;
4
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djutils.exceptions.Throw;
7 import org.opentrafficsim.core.geometry.OTSLine3D;
8 import org.opentrafficsim.core.gtu.GTUDirectionality;
9 import org.opentrafficsim.core.gtu.GTUException;
10 import org.opentrafficsim.core.network.LinkDirection;
11
12 import nl.tudelft.simulation.language.d3.DirectedPoint;
13
14
15
16
17
18
19
20
21
22
23
24
25 public class DirectedLanePosition implements Serializable
26 {
27
28 private static final long serialVersionUID = 20151111L;
29
30
31 private final Lane lane;
32
33
34 private final Length position;
35
36
37 private final GTUDirectionality gtuDirection;
38
39
40 private LinkDirection linkDirection = null;
41
42
43
44
45
46
47
48
49
50 public DirectedLanePosition(final Lane lane, final Length position, final GTUDirectionality gtuDirection)
51 throws GTUException
52 {
53 super();
54 Throw.when(lane == null, GTUException.class, "lane is null");
55 Throw.when(position == null, GTUException.class, "position is null");
56 Throw.when(gtuDirection == null, GTUException.class, "gtuDirection is null");
57 this.lane = lane;
58 this.position = position;
59 this.gtuDirection = gtuDirection;
60 }
61
62
63
64
65
66 public final Lane getLane()
67 {
68 return this.lane;
69 }
70
71
72
73
74
75 public final Length getPosition()
76 {
77 return this.position;
78 }
79
80
81
82
83
84
85 public final GTUDirectionality getGtuDirection()
86 {
87 return this.gtuDirection;
88 }
89
90
91
92
93
94 public final DirectedPoint getLocation()
95 {
96
97 OTSLine3D centerLine = this.lane.getCenterLine();
98 double centerLineLength = centerLine.getLengthSI();
99 double fraction = this.position.si / centerLineLength;
100 DirectedPoint p = centerLine.getLocationFractionExtended(fraction);
101 if (this.gtuDirection.equals(GTUDirectionality.DIR_PLUS))
102 {
103 return p;
104 }
105 return new DirectedPoint(p.x, p.y, p.z, p.getRotX(), p.getRotY(), p.getRotZ() + Math.PI);
106 }
107
108
109
110
111
112 public final LaneDirection getLaneDirection()
113 {
114 return new LaneDirection(this.lane, this.gtuDirection);
115 }
116
117
118
119
120
121 public final LinkDirection getLinkDirection()
122 {
123 if (this.linkDirection == null)
124 {
125 this.linkDirection = new LinkDirection(this.lane.getParentLink(), this.gtuDirection);
126 }
127 return this.linkDirection;
128 }
129
130
131 @Override
132 public int hashCode()
133 {
134 final int prime = 31;
135 int result = 1;
136 result = prime * result + ((this.gtuDirection == null) ? 0 : this.gtuDirection.hashCode());
137 result = prime * result + ((this.lane == null) ? 0 : this.lane.hashCode());
138 result = prime * result + ((this.position == null) ? 0 : this.position.hashCode());
139 return result;
140 }
141
142
143 @SuppressWarnings("checkstyle:needbraces")
144 @Override
145 public boolean equals(final Object obj)
146 {
147 if (this == obj)
148 return true;
149 if (obj == null)
150 return false;
151 if (getClass() != obj.getClass())
152 return false;
153 DirectedLanePosition other = (DirectedLanePosition) obj;
154 if (this.gtuDirection != other.gtuDirection)
155 return false;
156 if (this.lane == null)
157 {
158 if (other.lane != null)
159 return false;
160 }
161 else if (!this.lane.equals(other.lane))
162 return false;
163 if (this.position == null)
164 {
165 if (other.position != null)
166 return false;
167 }
168 else if (!this.position.equals(other.position))
169 return false;
170 return true;
171 }
172
173
174 @Override
175 public final String toString()
176 {
177 return "DirectedLanePosition [lane=" + this.lane + ", position=" + this.position + ", gtuDirection=" + this.gtuDirection
178 + "]";
179 }
180
181 }