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