1 package org.opentrafficsim.road.network.lane;
2
3 import javax.media.j3d.Bounds;
4 import javax.vecmath.Point3d;
5
6 import org.djunits.unit.LengthUnit;
7 import org.djunits.value.vdouble.scalar.Length;
8 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
9 import org.opentrafficsim.core.geometry.OTSGeometryException;
10 import org.opentrafficsim.core.gtu.RelativePosition;
11
12 import nl.tudelft.simulation.event.EventProducer;
13 import nl.tudelft.simulation.language.d3.BoundingBox;
14 import nl.tudelft.simulation.language.d3.DirectedPoint;
15
16
17
18
19
20
21
22
23
24
25
26 public abstract class AbstractSensor extends EventProducer implements Sensor
27 {
28
29 private static final long serialVersionUID = 20141231L;
30
31
32 private final Lane lane;
33
34
35 private final double longitudinalPositionSI;
36
37
38 private final RelativePosition.TYPE positionType;
39
40
41 private final String name;
42
43
44 private DirectedPoint location = null;
45
46
47 private Bounds bounds = null;
48
49
50 private final OTSDEVSSimulatorInterface simulator;
51
52
53
54
55
56
57
58
59
60
61 public AbstractSensor(final Lane lane, final Length longitudinalPosition,
62 final RelativePosition.TYPE positionType, final String name, final OTSDEVSSimulatorInterface simulator)
63 {
64 this.lane = lane;
65 this.longitudinalPositionSI = longitudinalPosition.getSI();
66 this.positionType = positionType;
67 this.name = name;
68 this.simulator = simulator;
69 }
70
71
72 @Override
73 public final Lane getLane()
74 {
75 return this.lane;
76 }
77
78
79 @Override
80 public final Length getLongitudinalPosition()
81 {
82 return new Length(this.longitudinalPositionSI, LengthUnit.METER);
83 }
84
85
86 @Override
87 public final RelativePosition.TYPE getPositionType()
88 {
89 return this.positionType;
90 }
91
92
93 @Override
94 public final double getLongitudinalPositionSI()
95 {
96 return this.longitudinalPositionSI;
97 }
98
99
100 @Override
101 public final DirectedPoint getLocation()
102 {
103 if (this.location == null)
104 {
105 try
106 {
107 this.location = this.lane.getCenterLine().getLocationSI(this.longitudinalPositionSI);
108 this.location.z = this.lane.getLocation().z + 0.01;
109 }
110 catch (OTSGeometryException exception)
111 {
112 exception.printStackTrace();
113 return null;
114 }
115 }
116 return this.location;
117 }
118
119
120 @Override
121 public final Bounds getBounds()
122 {
123 if (this.bounds == null)
124 {
125 this.bounds =
126 new BoundingBox(new Point3d(-0.4, -this.lane.getWidth(0.0).getSI() * 0.4, 0.0), new Point3d(0.4,
127 this.lane.getWidth(0.0).getSI() * 0.4, this.lane.getLocation().z + 0.01));
128 }
129 return this.bounds;
130 }
131
132
133
134
135 public final String getName()
136 {
137 return this.name;
138 }
139
140
141
142
143 public final OTSDEVSSimulatorInterface getSimulator()
144 {
145 return this.simulator;
146 }
147
148
149 @SuppressWarnings("checkstyle:designforextension")
150 @Override
151 public int hashCode()
152 {
153 final int prime = 31;
154 int result = 1;
155 result = prime * result + ((this.lane == null) ? 0 : this.lane.hashCode());
156 long temp;
157 temp = Double.doubleToLongBits(this.longitudinalPositionSI);
158 result = prime * result + (int) (temp ^ (temp >>> 32));
159 result = prime * result + ((this.positionType == null) ? 0 : this.positionType.hashCode());
160 return result;
161 }
162
163
164 @SuppressWarnings({"checkstyle:needbraces", "checkstyle:designforextension"})
165 @Override
166 public boolean equals(final Object obj)
167 {
168 if (this == obj)
169 return true;
170 if (obj == null)
171 return false;
172 if (getClass() != obj.getClass())
173 return false;
174 AbstractSensor other = (AbstractSensor) obj;
175 if (this.lane == null)
176 {
177 if (other.lane != null)
178 return false;
179 }
180 else if (!this.lane.equals(other.lane))
181 return false;
182 if (Double.doubleToLongBits(this.longitudinalPositionSI) != Double
183 .doubleToLongBits(other.longitudinalPositionSI))
184 return false;
185 if (this.positionType == null)
186 {
187 if (other.positionType != null)
188 return false;
189 }
190 else if (!this.positionType.equals(other.positionType))
191 return false;
192 return true;
193 }
194
195
196 @SuppressWarnings("checkstyle:designforextension")
197 @Override
198 public int compareTo(final Sensor o)
199 {
200 if (this.lane != o.getLane())
201 {
202 return this.lane.hashCode() < o.getLane().hashCode() ? -1 : 1;
203 }
204 if (this.longitudinalPositionSI != o.getLongitudinalPositionSI())
205 {
206 return this.longitudinalPositionSI < o.getLongitudinalPositionSI() ? -1 : 1;
207 }
208 if (!this.positionType.equals(o.getPositionType()))
209 {
210 return this.positionType.hashCode() < o.getPositionType().hashCode() ? -1 : 1;
211 }
212 if (!this.equals(o))
213 {
214 return this.hashCode() < o.hashCode() ? -1 : 1;
215 }
216 return 0;
217 }
218
219 }