1 package nl.tudelft.simulation.dsol.animation.gis.esri;
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 EsriRenderable2d 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 EsriRenderable2d(final Contextualized contextProvider, final GisMapInterface map)
69 {
70 this(contextProvider, map, new CoordinateTransform.NoTransform());
71 }
72
73
74
75
76
77
78
79 public EsriRenderable2d(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 EsriRenderable2d(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
135 if (extent.equals(this.cachedExtent) && screen.equals(this.cachedScreenSize) && this.map.isSame())
136 {
137 graphics.drawImage(this.cachedImage, 0, 0, null);
138 return;
139 }
140 this.map.setExtent(extent);
141 this.map.getImage().setSize(screen);
142 this.cacheImage();
143 this.paintComponent(graphics, extent, screen, renderableScale, observer);
144 }
145 catch (Exception exception)
146 {
147 CategoryLogger.always().warn(exception, "paint");
148 }
149 }
150
151
152 @Override
153 public EsriRenderable2d getSource()
154 {
155 return this;
156 }
157
158
159 @Override
160 public Bounds3d getBounds()
161 {
162 return this.bounds;
163 }
164
165
166 @Override
167 public OrientedPoint3d getLocation()
168 {
169 return this.location;
170 }
171
172
173
174
175 @Override
176 public GisMapInterface getMap()
177 {
178 return this.map;
179 }
180
181
182
183
184
185 private void cacheImage() throws Exception
186 {
187 this.cachedImage = new BufferedImage((int) this.map.getImage().getSize().getWidth(),
188 (int) this.map.getImage().getSize().getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
189 Graphics2D bg = this.cachedImage.createGraphics();
190 this.map.drawMap(bg);
191 bg.dispose();
192 this.cachedScreenSize = (Dimension) this.map.getImage().getSize().clone();
193 this.cachedExtent = this.map.getExtent();
194 this.location = new OrientedPoint3d(this.cachedExtent.midPoint().getX(), this.cachedExtent.midPoint().getY(),
195 -Double.MIN_VALUE);
196 this.bounds = new Bounds3d(this.cachedExtent.getDeltaX(), this.cachedExtent.getDeltaY(), 0.0);
197 }
198
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 }