1 package nl.tudelft.simulation.dsol.animation.gis.osm;
2
3 import java.awt.Dimension;
4 import java.awt.Graphics2D;
5 import java.awt.geom.Point2D;
6 import java.awt.image.BufferedImage;
7 import java.awt.image.ImageObserver;
8 import java.rmi.RemoteException;
9
10 import javax.naming.NamingException;
11
12 import org.djutils.draw.bounds.Bounds2d;
13 import org.djutils.draw.bounds.Bounds3d;
14 import org.djutils.draw.point.OrientedPoint3d;
15 import org.djutils.draw.point.Point2d;
16 import org.djutils.logger.CategoryLogger;
17
18 import nl.tudelft.simulation.dsol.animation.d2.RenderableScale;
19 import nl.tudelft.simulation.dsol.animation.gis.GisMapInterface;
20 import nl.tudelft.simulation.dsol.animation.gis.GisRenderable2d;
21 import nl.tudelft.simulation.dsol.animation.gis.transform.CoordinateTransform;
22 import nl.tudelft.simulation.naming.context.Contextualized;
23 import nl.tudelft.simulation.naming.context.util.ContextUtil;
24
25
26
27
28
29
30
31
32
33
34
35 public class OsmRenderable2d implements GisRenderable2d
36 {
37
38 private static final long serialVersionUID = 20200108L;
39
40
41 @SuppressWarnings("checkstyle:visibilitymodifier")
42 protected GisMapInterface map = null;
43
44
45 @SuppressWarnings("checkstyle:visibilitymodifier")
46 protected BufferedImage cachedImage = null;
47
48
49 @SuppressWarnings("checkstyle:visibilitymodifier")
50 protected Bounds2d cachedExtent = new Bounds2d(0, 0, 0, 0);
51
52
53 @SuppressWarnings("checkstyle:visibilitymodifier")
54 protected Dimension cachedScreenSize = new Dimension();
55
56
57 @SuppressWarnings("checkstyle:visibilitymodifier")
58 protected OrientedPoint3d location = null;
59
60
61 @SuppressWarnings("checkstyle:visibilitymodifier")
62 protected Bounds3d bounds = null;
63
64
65
66
67
68
69 public OsmRenderable2d(final Contextualized contextProvider, final GisMapInterface map)
70 {
71 this(contextProvider, map, new CoordinateTransform.NoTransform());
72 }
73
74
75
76
77
78
79
80 public OsmRenderable2d(final Contextualized contextProvider, final GisMapInterface map,
81 final CoordinateTransform coordinateTransform)
82 {
83 this(contextProvider, map, coordinateTransform, -Double.MAX_VALUE);
84 }
85
86
87
88
89
90
91
92
93 public OsmRenderable2d(final Contextualized contextProvider, final GisMapInterface map,
94 final CoordinateTransform coordinateTransform, final double z)
95 {
96 try
97 {
98 this.map = map;
99 this.location = new OrientedPoint3d(this.cachedExtent.midPoint().getX(), this.cachedExtent.midPoint().getY(), z);
100 this.bounds = new Bounds3d(this.cachedExtent.getDeltaX(), this.cachedExtent.getDeltaY(), 0.0);
101 this.bind2Context(contextProvider);
102 }
103 catch (Exception exception)
104 {
105 CategoryLogger.always().warn(exception, "<init>");
106 }
107 }
108
109
110
111
112
113
114
115 protected void bind2Context(final Contextualized contextProvider)
116 {
117 try
118 {
119 ContextUtil.lookupOrCreateSubContext(contextProvider.getContext(), "animation/2D")
120 .bindObject(Integer.toString(System.identityHashCode(this)), this);
121 }
122 catch (NamingException | RemoteException exception)
123 {
124 CategoryLogger.always().warn(exception, "<init>");
125 }
126 }
127
128 @Override
129 public void paintComponent(final Graphics2D graphics, final Bounds2d extent, final Dimension screen,
130 final RenderableScale renderableScale, final ImageObserver observer)
131 {
132 try
133 {
134 this.map.setDrawBackground(false);
135
136
137 if (extent.equals(this.cachedExtent) && screen.equals(this.cachedScreenSize) && this.map.isSame())
138 {
139 graphics.drawImage(this.cachedImage, 0, 0, null);
140 return;
141 }
142 this.map.setExtent(extent);
143 this.map.getImage().setSize(screen);
144 this.cacheImage();
145 this.paintComponent(graphics, extent, screen, renderableScale, observer);
146 }
147 catch (Exception exception)
148 {
149 CategoryLogger.always().warn(exception, "paint");
150 }
151 }
152
153 @Override
154 public OsmRenderable2d getSource()
155 {
156 return this;
157 }
158
159 @Override
160 public Bounds3d getBounds()
161 {
162 return this.bounds;
163 }
164
165 @Override
166 public OrientedPoint3d getLocation()
167 {
168 return this.location;
169 }
170
171
172
173
174 @Override
175 public GisMapInterface getMap()
176 {
177 return this.map;
178 }
179
180
181
182
183
184 private void cacheImage() throws Exception
185 {
186 this.cachedImage = new BufferedImage((int) this.map.getImage().getSize().getWidth(),
187 (int) this.map.getImage().getSize().getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
188 Graphics2D bg = this.cachedImage.createGraphics();
189 this.map.drawMap(bg);
190 bg.dispose();
191 this.cachedScreenSize = (Dimension) this.map.getImage().getSize().clone();
192 this.cachedExtent = this.map.getExtent();
193 this.location = new OrientedPoint3d(this.cachedExtent.midPoint().getX(), this.cachedExtent.midPoint().getY(),
194 -Double.MIN_VALUE);
195 this.bounds = new Bounds3d(this.cachedExtent.getDeltaX(), this.cachedExtent.getDeltaY(), 0.0);
196 }
197
198 @Override
199 public void destroy(final Contextualized contextProvider)
200 {
201 try
202 {
203 ContextUtil.lookupOrCreateSubContext(contextProvider.getContext(), "animation/2D")
204 .unbindObject(Integer.toString(System.identityHashCode(this)));
205 }
206 catch (Throwable throwable)
207 {
208 CategoryLogger.always().warn(throwable, "finalize");
209 }
210 }
211
212 @Override
213 public boolean contains(final Point2d pointWorldCoordinates, final Bounds2d extent)
214 {
215 return false;
216 }
217
218 @Override
219 public boolean contains(final Point2D pointScreenCoordinates, final Bounds2d extent, final Dimension screenSize,
220 final RenderableScale scale, final double worldMargin, final double pixelMargin)
221 {
222 return false;
223 }
224
225 @Override
226 public long getId()
227 {
228 return -1;
229 }
230
231 }