1 package org.opentrafficsim.draw.road;
2
3 import java.awt.Color;
4 import java.awt.Graphics2D;
5 import java.awt.geom.Path2D;
6 import java.awt.image.ImageObserver;
7 import java.util.function.Supplier;
8
9 import org.djutils.base.Identifiable;
10 import org.djutils.draw.line.PolyLine2d;
11 import org.djutils.draw.line.Polygon2d;
12 import org.djutils.draw.point.DirectedPoint2d;
13 import org.opentrafficsim.base.geometry.OtsShape;
14 import org.opentrafficsim.draw.DrawLevel;
15 import org.opentrafficsim.draw.LineLocatable;
16 import org.opentrafficsim.draw.OtsRenderable;
17 import org.opentrafficsim.draw.PaintLine;
18 import org.opentrafficsim.draw.RenderableTextSource;
19 import org.opentrafficsim.draw.TextAlignment;
20 import org.opentrafficsim.draw.road.CrossSectionElementAnimation.CrossSectionElementData;
21 import org.opentrafficsim.draw.road.LaneAnimation.LaneData;
22
23 import nl.tudelft.simulation.naming.context.Contextualized;
24
25
26
27
28
29
30
31
32
33
34 public class LaneAnimation extends CrossSectionElementAnimation<LaneData>
35 {
36
37 private final Color color;
38
39
40 private final Text text;
41
42
43 private final CenterLineAnimation centerLineAnimation;
44
45
46
47
48
49
50
51 public LaneAnimation(final LaneData lane, final Contextualized contextualized, final Color color)
52 {
53 super(lane, contextualized, color);
54 this.color = color;
55 this.text = new Text(lane, lane::getId, 0.0f, 0.0f, TextAlignment.CENTER, Color.BLACK, contextualized);
56 this.centerLineAnimation = new CenterLineAnimation(
57 new CenterLine(lane.getCenterLine(), lane.getLinkId() + "." + lane.getId()), contextualized);
58 }
59
60
61
62
63
64 public final Text getText()
65 {
66 return this.text;
67 }
68
69 @Override
70 public void destroy(final Contextualized contextProvider)
71 {
72 super.destroy(contextProvider);
73 this.text.destroy(contextProvider);
74 this.centerLineAnimation.destroy(contextProvider);
75 }
76
77 @Override
78 public final String toString()
79 {
80 return "LaneAnimation [lane = " + getSource().toString() + ", color=" + this.color + "]";
81 }
82
83
84
85
86 public static class CenterLine implements LineLocatable
87 {
88
89 private final PolyLine2d centerLine;
90
91
92 private final DirectedPoint2d location;
93
94
95 private Polygon2d relativeContour;
96
97
98 private final String fullId;
99
100
101
102
103
104
105 CenterLine(final PolyLine2d centerLine, final String fullId)
106 {
107 this.centerLine = centerLine;
108 this.location = new DirectedPoint2d(this.centerLine.getAbsoluteBounds().midPoint(), 0.0);
109 this.fullId = fullId;
110 }
111
112 @Override
113 public final DirectedPoint2d getLocation()
114 {
115 return this.location;
116 }
117
118 @Override
119 public Polygon2d getRelativeContour()
120 {
121 if (this.relativeContour == null)
122 {
123 this.relativeContour =
124 new Polygon2d(OtsShape.toRelativeTransform(getLocation()).transform(getAbsoluteContour().iterator()));
125 }
126 return this.relativeContour;
127 }
128
129 @Override
130 public Polygon2d getAbsoluteContour()
131 {
132 return new Polygon2d(this.centerLine.iterator());
133 }
134
135
136
137
138
139 public PolyLine2d getCenterLine()
140 {
141 return this.centerLine;
142 }
143
144 @Override
145 public PolyLine2d getLine()
146 {
147 return OtsShape.transformLine(this.centerLine, getLocation());
148 }
149
150 @Override
151 public double getZ()
152 {
153 return DrawLevel.CENTER_LINE.getZ();
154 }
155
156 @Override
157 public String toString()
158 {
159 return "Center line " + this.fullId;
160 }
161
162 }
163
164
165
166
167 public static class CenterLineAnimation extends OtsRenderable<CenterLine>
168 {
169
170 private static final Color COLOR = Color.MAGENTA.darker().darker();
171
172
173 private final Path2D.Float path;
174
175
176
177
178
179
180 public CenterLineAnimation(final CenterLine centerLine, final Contextualized contextualized)
181 {
182 super(centerLine, contextualized);
183 this.path = PaintLine.getPath(getSource().getLocation(), getSource().getCenterLine());
184 }
185
186 @Override
187 public final void paint(final Graphics2D graphics, final ImageObserver observer)
188 {
189 setRendering(graphics);
190 PaintLine.paintLine(graphics, COLOR, 0.1, this.path);
191 resetRendering(graphics);
192 }
193
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207 public static class Text extends RenderableTextSource<LaneData, Text>
208 {
209
210
211
212
213
214
215
216
217
218
219 public Text(final LaneData source, final Supplier<String> text, final float dx, final float dy,
220 final TextAlignment textPlacement, final Color color, final Contextualized contextualized)
221 {
222 super(source, text, dx, dy, textPlacement, color, contextualized, RenderableTextSource.RENDERWHEN10);
223 }
224
225 @Override
226 public final String toString()
227 {
228 return "Text []";
229 }
230
231 }
232
233
234
235
236
237
238
239
240
241
242 public interface LaneData extends CrossSectionElementData, Identifiable
243 {
244 @Override
245 default double getZ()
246 {
247 return DrawLevel.LANE.getZ();
248 }
249 }
250
251 }