svn-gvsig-desktop / trunk / extensions / extArcims / src / es / prodevelop / cit / gvsig / arcims / fmap / layers / FRasterLyrArcIMS.java @ 8707
History | View | Annotate | Download (29.8 KB)
1 | 8110 | jsanz | package es.prodevelop.cit.gvsig.arcims.fmap.layers; |
---|---|---|---|
2 | |||
3 | import es.prodevelop.cit.gvsig.arcims.fmap.drivers.ArcImsDriver; |
||
4 | import es.prodevelop.cit.gvsig.arcims.fmap.drivers.FMapFeatureArcImsDriver; |
||
5 | import es.prodevelop.cit.gvsig.arcims.fmap.drivers.FMapRasterArcImsDriver; |
||
6 | import es.prodevelop.cit.gvsig.arcims.fmap.listeners.FRasterLyrArcIMSListener; |
||
7 | |||
8 | import java.awt.Color; |
||
9 | import java.awt.Dimension; |
||
10 | import java.awt.Graphics2D; |
||
11 | import java.awt.Point; |
||
12 | import java.awt.Rectangle; |
||
13 | import java.awt.event.ActionEvent; |
||
14 | import java.awt.event.ActionListener; |
||
15 | import java.awt.geom.AffineTransform; |
||
16 | import java.awt.geom.NoninvertibleTransformException; |
||
17 | import java.awt.geom.Point2D; |
||
18 | import java.awt.geom.Rectangle2D; |
||
19 | import java.awt.image.BufferedImage; |
||
20 | import java.awt.image.DataBuffer; |
||
21 | import java.io.File; |
||
22 | import java.io.IOException; |
||
23 | import java.lang.reflect.Constructor; |
||
24 | import java.lang.reflect.InvocationTargetException; |
||
25 | import java.net.MalformedURLException; |
||
26 | import java.net.URL; |
||
27 | import java.util.ArrayList; |
||
28 | import java.util.HashMap; |
||
29 | import java.util.Map; |
||
30 | import java.util.Vector; |
||
31 | |||
32 | import org.apache.log4j.Logger; |
||
33 | import org.cresques.geo.ViewPortData; |
||
34 | import org.cresques.io.GdalFile; |
||
35 | import org.cresques.io.GeoRasterFile; |
||
36 | import org.cresques.cts.IProjection; |
||
37 | import org.cresques.filter.RasterFilterStack; |
||
38 | import org.cresques.filter.RasterFilterStackManager; |
||
39 | import org.cresques.px.Extent; |
||
40 | import org.cresques.px.PxRaster; |
||
41 | import org.gvsig.remoteClient.arcims.ArcImsClientP; |
||
42 | import org.gvsig.remoteClient.arcims.ArcImsProtImageHandler; |
||
43 | import org.gvsig.remoteClient.arcims.ArcImsProtocolHandler; |
||
44 | import org.gvsig.remoteClient.arcims.ArcImsStatus; |
||
45 | import org.gvsig.remoteClient.arcims.exceptions.ArcImsException; |
||
46 | import org.gvsig.remoteClient.arcims.utils.MyCancellable; |
||
47 | import org.gvsig.remoteClient.arcims.utils.ServiceInfoTags; |
||
48 | import org.gvsig.remoteClient.arcims.utils.ServiceInformation; |
||
49 | import org.gvsig.remoteClient.arcims.utils.ServiceInformationLayer; |
||
50 | import org.gvsig.remoteClient.utils.Utilities; |
||
51 | |||
52 | import com.iver.cit.gvsig.fmap.DriverException; |
||
53 | import com.iver.cit.gvsig.fmap.ViewPort; |
||
54 | import com.iver.cit.gvsig.fmap.crs.CRSFactory; |
||
55 | import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
||
56 | |||
57 | import com.iver.cit.gvsig.fmap.layers.FLayer; |
||
58 | import com.iver.cit.gvsig.fmap.layers.FLyrDefault; |
||
59 | import com.iver.cit.gvsig.fmap.layers.RasterAdapter; |
||
60 | import com.iver.cit.gvsig.fmap.layers.RasterOperations; |
||
61 | import com.iver.cit.gvsig.fmap.layers.StatusLayerRaster; |
||
62 | import com.iver.cit.gvsig.fmap.layers.StatusRasterInterface; |
||
63 | import com.iver.cit.gvsig.fmap.layers.Tiling; |
||
64 | import com.iver.cit.gvsig.fmap.layers.XMLException; |
||
65 | import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint; |
||
66 | import com.iver.cit.gvsig.fmap.layers.layerOperations.StringXMLItem; |
||
67 | import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem; |
||
68 | import com.iver.utiles.StringUtilities; |
||
69 | import com.iver.utiles.XMLEntity; |
||
70 | import com.iver.utiles.connections.ConnectionException; |
||
71 | import com.iver.utiles.swing.threads.Cancellable; |
||
72 | import com.iver.utiles.swing.threads.DefaultCancellableMonitorable; |
||
73 | |||
74 | import org.gvsig.remoteClient.wms.ICancellable; |
||
75 | |||
76 | /**
|
||
77 | * This class implements an ArcIMS raster layer.
|
||
78 | *
|
||
79 | * @author jldominguez
|
||
80 | */
|
||
81 | public class FRasterLyrArcIMS extends FLyrDefault implements RasterOperations, InfoByPoint { |
||
82 | |||
83 | private MyCancellable myCanc;
|
||
84 | |||
85 | private static Logger logger = Logger.getLogger(FRasterLyrArcIMS.class.getName()); |
||
86 | |||
87 | private URL host; |
||
88 | private String service; |
||
89 | private String serviceType; |
||
90 | private Rectangle2D fullExtent; |
||
91 | private boolean firstLoad = false; |
||
92 | private ArcImsStatus arcimsStatus = new ArcImsStatus(); |
||
93 | private String SRS; |
||
94 | private String layerQuery; |
||
95 | private ArcImsDriver driver;
|
||
96 | private VisualStatusArcIms visualStatus = new VisualStatusArcIms(); |
||
97 | |||
98 | private int transparency = -1; |
||
99 | private boolean arcImsTransparency = true; |
||
100 | |||
101 | private String format; |
||
102 | private StatusRasterInterface status = null; |
||
103 | private GeoRasterFile rasterFile = null; |
||
104 | private PxRaster raster = null; |
||
105 | private int rband = 0, gband = 1, bband = 2; |
||
106 | private RasterFilterStackManager stackManager = null; |
||
107 | private RasterFilterStack filterStack = null; |
||
108 | private int posX = 0, posY = 0; |
||
109 | private double posXWC = 0, posYWC = 0; |
||
110 | private int r = 0, g = 0, b = 0; |
||
111 | private ArrayList actionListeners = new ArrayList(); |
||
112 | private int maxTileWidth = 1023; |
||
113 | private int maxTileHeight = 1023; |
||
114 | |||
115 | private boolean nameQueryChange = false; |
||
116 | |||
117 | private ArrayList listeners = new ArrayList(); |
||
118 | |||
119 | private boolean tiled = false; |
||
120 | private int[] tileSize = new int[2]; |
||
121 | |||
122 | |||
123 | public static final String SCALE_CHANGED_COMMAND = "SCALE_HAS_CHANGED"; |
||
124 | private ActionEvent scaleChangedEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, SCALE_CHANGED_COMMAND); |
||
125 | |||
126 | public FRasterLyrArcIMS() {
|
||
127 | myCanc = new MyCancellable(new DefaultCancellableMonitorable()); |
||
128 | } |
||
129 | |||
130 | /**
|
||
131 | * Gets the driver object onto which <tt>getMap()</tt> and
|
||
132 | * <tt>getFeatureInfo()</tt> requests are passed. If the driver was not
|
||
133 | * created, this methdo creates it with the server's URL and the service
|
||
134 | * name.
|
||
135 | *
|
||
136 | * @return the driver that actually performs the requests.
|
||
137 | */
|
||
138 | public ArcImsDriver getDriver() {
|
||
139 | if (driver == null) { |
||
140 | driver = new FMapRasterArcImsDriver(host.toString(), service,
|
||
141 | this.serviceType);
|
||
142 | } |
||
143 | return driver;
|
||
144 | } |
||
145 | |||
146 | public void setDriver(FMapRasterArcImsDriver d) { |
||
147 | driver = d; |
||
148 | } |
||
149 | |||
150 | /**
|
||
151 | * Gets the transformation matrix to be written in the georeference file.
|
||
152 | * The second and the third coefficients will always be zero (it doesn't
|
||
153 | * implement image rotation)
|
||
154 | *
|
||
155 | * @param bBox
|
||
156 | * Image's size and position (user's coordinates)
|
||
157 | * @param sz
|
||
158 | * Images' size in pixels
|
||
159 | * @return the worldfile, as a String
|
||
160 | * @throws IOException
|
||
161 | */
|
||
162 | public String getDataWorldFile(Rectangle2D bBox, Dimension sz) |
||
163 | throws IOException { |
||
164 | StringBuffer data = new StringBuffer(); |
||
165 | data.append((bBox.getMaxX() - bBox.getMinX()) / (sz.getWidth() - 1)
|
||
166 | + "\n");
|
||
167 | data.append("0.0\n");
|
||
168 | data.append("0.0\n");
|
||
169 | 8424 | jldominguez | data.append("-" + (bBox.getMaxY() - bBox.getMinY()) / (sz.getHeight() - 1) + "\n"); |
170 | // guardalo por si acaso :)
|
||
171 | // data.append((bBox.getMaxY() - bBox.getMinY()) / (sz.getHeight() - 1) + "\n");
|
||
172 | 8110 | jsanz | data.append("" + bBox.getMinX() + "\n"); |
173 | 8424 | jldominguez | // data.append("" + bBox.getMinY() + "\n");
|
174 | data.append("" + bBox.getMaxY() + "\n"); |
||
175 | 8110 | jsanz | return data.toString();
|
176 | } |
||
177 | |||
178 | /**
|
||
179 | * Gets the raster status
|
||
180 | *
|
||
181 | * @return the raster status
|
||
182 | */
|
||
183 | public StatusRasterInterface getStatus() {
|
||
184 | return this.status; |
||
185 | } |
||
186 | |||
187 | public void setStatus(StatusRasterInterface s) { |
||
188 | this.status = s;
|
||
189 | } |
||
190 | |||
191 | /**
|
||
192 | * This method must be invoqued with <b>true</b> if the layer must show its
|
||
193 | * transparency. The level of transparency is set by another method.
|
||
194 | *
|
||
195 | * @param t
|
||
196 | * Whether or not the transparency must be shown.
|
||
197 | */
|
||
198 | public void setArcImsTransparency(boolean t) { |
||
199 | this.arcImsTransparency = t;
|
||
200 | } |
||
201 | |||
202 | /**
|
||
203 | * Drawing method invoqued from outside the plugin.
|
||
204 | *
|
||
205 | * @param g
|
||
206 | * graphic object on which drawing is made.
|
||
207 | * @param vp
|
||
208 | * the view
|
||
209 | * @param cancel
|
||
210 | * allows drawing abortion
|
||
211 | * @throws DriverException
|
||
212 | */
|
||
213 | private void drawTile(Graphics2D g, ViewPort vp, Cancellable cancel) |
||
214 | throws DriverException {
|
||
215 | // This is the extent that will be requested
|
||
216 | Rectangle2D bBox = vp.getAdjustedExtent();// getFullExtent(); |
||
217 | Dimension sz = vp.getImageSize();
|
||
218 | |||
219 | try {
|
||
220 | arcimsStatus.setExtent(bBox); |
||
221 | arcimsStatus.setFormat(getFormat()); |
||
222 | arcimsStatus.setHeight(vp.getImageHeight()); |
||
223 | arcimsStatus.setWidth(vp.getImageWidth()); |
||
224 | arcimsStatus.setLayerIds(Utilities.createVector(layerQuery, ",")); |
||
225 | arcimsStatus.setServer(host.toString()); |
||
226 | arcimsStatus.setService(service); |
||
227 | arcimsStatus.setSrs(this.getProjection().getAbrev());
|
||
228 | arcimsStatus.setTransparency(this.arcImsTransparency);
|
||
229 | |||
230 | // We need to cast because driver returns an Object
|
||
231 | File f = (File) getDriver().getMap(arcimsStatus); |
||
232 | |||
233 | int lastp = f.getPath().lastIndexOf("."); |
||
234 | String noext = f.getPath().substring(0,lastp); |
||
235 | |||
236 | String nameWorldFile = noext
|
||
237 | + getExtensionWordFile(getFormat()); |
||
238 | |||
239 | com.iver.andami.Utilities.createTemp(nameWorldFile, this
|
||
240 | .getDataWorldFile(bBox, sz)); |
||
241 | |||
242 | if (status != null && firstLoad) { |
||
243 | status.applyStatus(this);
|
||
244 | firstLoad = false;
|
||
245 | } |
||
246 | |||
247 | // And finally, obtain the extent intersecting the view and the BBox
|
||
248 | // to draw to.
|
||
249 | // ------------------------------ START (?)
|
||
250 | // Rectangle2D extent = new Rectangle2D.Double();
|
||
251 | // Rectangle2D.intersect(vp.getAdjustedExtent(), bBox, extent);
|
||
252 | // ViewPortData vpData = new ViewPortData(vp.getProjection(),
|
||
253 | // new Extent(extent), sz);
|
||
254 | // vpData.setMat(vp.getAffineTransform());
|
||
255 | // ------------------------------ END (?)
|
||
256 | |||
257 | // ------------------------------ START
|
||
258 | ViewPortData vpData = new ViewPortData(vp.getProjection(),
|
||
259 | new Extent(bBox), sz);
|
||
260 | vpData.setMat(vp.getAffineTransform()); |
||
261 | // ------------------------------ END
|
||
262 | |||
263 | rasterProcess(g, vpData, f); |
||
264 | |||
265 | } catch (IOException e) { |
||
266 | DriverException de = new DriverException("connect_error"); |
||
267 | logger.error("While connecting ", e);
|
||
268 | throw de;
|
||
269 | } catch (ArcImsException e) {
|
||
270 | logger.error("While drawing ", e);
|
||
271 | this.setVisible(false); |
||
272 | DriverException de = new DriverException(e.getMessage());
|
||
273 | throw de;
|
||
274 | } |
||
275 | |||
276 | } |
||
277 | |||
278 | /**
|
||
279 | * Drawing method invoqued from gvSIG to draw this layer. Uses a <tt>Tiling</tt>
|
||
280 | * object to prevent downloading images too large to be retrieved
|
||
281 | * (pixel count limit)
|
||
282 | *
|
||
283 | * @param image
|
||
284 | * used to speed up drawing process
|
||
285 | * @param g
|
||
286 | * graphic object on which drawing is make
|
||
287 | * @param viewPort
|
||
288 | * the view's properties
|
||
289 | * @param cancel
|
||
290 | * allows drawing abortion
|
||
291 | * @param scale the current scale
|
||
292 | *
|
||
293 | * @throws DriverException
|
||
294 | */
|
||
295 | public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort, |
||
296 | Cancellable cancel, double scale) throws DriverException { |
||
297 | |||
298 | if (! isVisible()) return; |
||
299 | if (! isWithinScale(scale)) return; |
||
300 | |||
301 | visualStatus.width = viewPort.getImageWidth(); |
||
302 | visualStatus.height = viewPort.getImageHeight(); |
||
303 | visualStatus.minX = viewPort.getAdjustedExtent().getMinX(); |
||
304 | visualStatus.minY = viewPort.getAdjustedExtent().getMinY(); |
||
305 | visualStatus.maxX = viewPort.getAdjustedExtent().getMaxX(); |
||
306 | visualStatus.maxY = viewPort.getAdjustedExtent().getMaxY(); |
||
307 | |||
308 | setTileDimensions(viewPort); |
||
309 | |||
310 | Point2D p = viewPort.getOffset();
|
||
311 | Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1); |
||
312 | Tiling tiles = new Tiling(maxTileWidth, maxTileHeight, r);
|
||
313 | tiles.setAffineTransform((AffineTransform) viewPort
|
||
314 | .getAffineTransform().clone()); |
||
315 | |||
316 | tiled = false;
|
||
317 | if (tiles.getNumTiles() > 1) { |
||
318 | tiled = true;
|
||
319 | tileSize[0] = tiles.getMaxTileWidth();
|
||
320 | tileSize[1] = tiles.getMaxTileHeight();
|
||
321 | } |
||
322 | for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) { |
||
323 | // drawing part
|
||
324 | try {
|
||
325 | ViewPort vp = tiles.getTileViewPort(viewPort, tileNr); |
||
326 | drawTile(g, vp, cancel); |
||
327 | } catch (NoninvertibleTransformException e) { |
||
328 | logger.error("Non invertible matrix ", e);
|
||
329 | } |
||
330 | } |
||
331 | |||
332 | // the status needs to be reset because the drawTile
|
||
333 | // method had changed its extent and dimension:
|
||
334 | arcimsStatus.setExtent(viewPort.getAdjustedExtent()); |
||
335 | arcimsStatus.setHeight(viewPort.getImageHeight()); |
||
336 | arcimsStatus.setWidth(viewPort.getImageWidth()); |
||
337 | |||
338 | callActionListeners(scaleChangedEvent); |
||
339 | if (nameQueryChange) {
|
||
340 | callNameOrQueryListeners(); |
||
341 | nameQueryChange = false;
|
||
342 | } |
||
343 | } |
||
344 | |||
345 | private void setTileDimensions(ViewPort vp) { |
||
346 | maxTileHeight = vp.getImageHeight(); |
||
347 | try {
|
||
348 | maxTileWidth = |
||
349 | Integer.parseInt(arcimsStatus.getServiceInfo().getImagelimit_pixelcount()) / maxTileHeight;
|
||
350 | maxTileWidth--; |
||
351 | } catch (NumberFormatException nfe) { |
||
352 | logger.error("getImagelimit_pixelcount() returned a non parseable string. maxTileWidth was set to 100.", nfe);
|
||
353 | maxTileWidth = 100;
|
||
354 | } |
||
355 | logger.info("Tile size = [ " + maxTileWidth + " , " + maxTileHeight + " ]"); |
||
356 | } |
||
357 | |||
358 | /**
|
||
359 | * Gets the georeference file extension depending on the image's format.
|
||
360 | *
|
||
361 | * @param f
|
||
362 | * raster file format
|
||
363 | * @return georeference file extension (".wld", ".tfw", etc)
|
||
364 | */
|
||
365 | private String getExtensionWordFile(String f) { |
||
366 | String extWorldFile = ".wld"; |
||
367 | if (f.equals("tif") || f.equals("tiff")) |
||
368 | extWorldFile = ".tfw";
|
||
369 | if (f.equals("jpeg")) |
||
370 | extWorldFile = ".jpgw";
|
||
371 | return extWorldFile;
|
||
372 | } |
||
373 | |||
374 | /**
|
||
375 | * Draws an image using PxRaster
|
||
376 | *
|
||
377 | * @param g
|
||
378 | * graphics object on which drawing will be made
|
||
379 | * @param vpData
|
||
380 | * viewport's properties
|
||
381 | * @param file
|
||
382 | * the image file
|
||
383 | */
|
||
384 | private void rasterProcess(Graphics2D g, ViewPortData vpData, File file) { |
||
385 | |||
386 | // PxRaster is created
|
||
387 | rasterFile = new GdalFile(vpData.getProjection(), file
|
||
388 | .getAbsolutePath()); |
||
389 | raster = new PxRaster(rasterFile, null, rasterFile.getExtent()); |
||
390 | |||
391 | if (this.filterStack != null) |
||
392 | raster.filterStack = this.filterStack;
|
||
393 | |||
394 | raster.setTransparency(false);
|
||
395 | |||
396 | if (this.transparency == -1 && !firstLoad) |
||
397 | ; |
||
398 | else
|
||
399 | raster.setTransparency(this.transparency);
|
||
400 | |||
401 | raster.setBand(GeoRasterFile.RED_BAND, rband); |
||
402 | raster.setBand(GeoRasterFile.GREEN_BAND, gband); |
||
403 | raster.setBand(GeoRasterFile.BLUE_BAND, bband); |
||
404 | |||
405 | if (this.stackManager != null) |
||
406 | raster.setStackManager(this.stackManager);
|
||
407 | |||
408 | if(visualStatus != null){ |
||
409 | visualStatus.bandCount = raster.getBandCount(); |
||
410 | visualStatus.dataType = raster.getDataType(); |
||
411 | } |
||
412 | |||
413 | raster.draw(g, vpData); |
||
414 | |||
415 | // We get the Stack Manager with the first pxRaster of an image
|
||
416 | // so we can modify it afterwards from the properties dialog
|
||
417 | if (this.stackManager == null) |
||
418 | this.stackManager = raster.getStackManager();
|
||
419 | |||
420 | if (this.filterStack == null) |
||
421 | this.filterStack = raster.filterStack;
|
||
422 | } |
||
423 | |||
424 | public void repaintRaster(Graphics2D g, ViewPortData vpData, File file) { |
||
425 | rasterProcess(g, vpData, file); |
||
426 | } |
||
427 | |||
428 | public String getFormat() { |
||
429 | return format;
|
||
430 | } |
||
431 | |||
432 | public void setFormat(String format) { |
||
433 | this.format = format;
|
||
434 | } |
||
435 | |||
436 | |||
437 | /**
|
||
438 | * Gets a series of attributes that describe the layer's raster: Filename,
|
||
439 | * Filesize, Height, Width and Bands.
|
||
440 | *
|
||
441 | * @return A list of 2-element arrays { "Attribute name" , Value }
|
||
442 | */
|
||
443 | public ArrayList getAttributes() { |
||
444 | if (rasterFile != null) { |
||
445 | ArrayList attr = new ArrayList(); |
||
446 | Object[][] a = { |
||
447 | { |
||
448 | "Filename",
|
||
449 | rasterFile.getName().substring( |
||
450 | rasterFile.getName().lastIndexOf("/") + 1, |
||
451 | rasterFile.getName().length()) }, |
||
452 | { "Filesize", new Long(rasterFile.getFileSize()) }, |
||
453 | { |
||
454 | "Width",
|
||
455 | new Integer((new Double(this.getWidth())) |
||
456 | .intValue()) }, |
||
457 | { |
||
458 | "Height",
|
||
459 | new Integer((new Double(this.getHeight())) |
||
460 | .intValue()) }, |
||
461 | { "Bands", new Integer(rasterFile.getBandCount()) } }; |
||
462 | for (int i = 0; i < a.length; i++) { |
||
463 | attr.add(a[i]); |
||
464 | } |
||
465 | return attr;
|
||
466 | } |
||
467 | return null; |
||
468 | } |
||
469 | |||
470 | /**
|
||
471 | *
|
||
472 | /**
|
||
473 | * Invoqued from gvSIG to draw this layer on a printable map. Uses a
|
||
474 | * <tt>Tiling</tt> object to prevent downloading images too large to be
|
||
475 | * retrieved (pixel count limit).
|
||
476 | *
|
||
477 | * @param g
|
||
478 | * graphic object on which drawing is make
|
||
479 | * @param viewPort
|
||
480 | * the view's properties
|
||
481 | * @param cancel
|
||
482 | * allows drawing abortion
|
||
483 | * @param scale the current scale
|
||
484 | *
|
||
485 | * @throws DriverException
|
||
486 | */
|
||
487 | public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, |
||
488 | double scale) throws DriverException { |
||
489 | |||
490 | draw(null, g, viewPort, cancel, scale);
|
||
491 | } |
||
492 | |||
493 | public HashMap getProperties() { |
||
494 | HashMap info = new HashMap(); |
||
495 | String[] layerNames = getLayerQuery().split(","); |
||
496 | Vector layers = new Vector(layerNames.length); |
||
497 | try {
|
||
498 | if (((FMapRasterArcImsDriver) getDriver()).connect(myCanc)) {
|
||
499 | info.put("layerName", this.getName()); |
||
500 | info.put("serverUrl", this.getHost()); |
||
501 | info.put("serviceName", this.getService()); |
||
502 | info.put("serviceType", this.getServiceType()); |
||
503 | info.put("format", this.format); |
||
504 | for (int i = 0; i < layerNames.length; i++) |
||
505 | layers.add(layerNames[i]); |
||
506 | info.put("layerIds", layers);
|
||
507 | return info;
|
||
508 | } |
||
509 | } catch (Exception e) { |
||
510 | logger.error("Error while reading FRasterLyrArcIMS properties. ", e);
|
||
511 | } |
||
512 | return null; |
||
513 | } |
||
514 | |||
515 | public RasterFilterStack getFilterStack() {
|
||
516 | if (raster != null) |
||
517 | return raster.filterStack;
|
||
518 | return null; |
||
519 | } |
||
520 | |||
521 | public double getHeight() { |
||
522 | return visualStatus.height;
|
||
523 | } |
||
524 | |||
525 | public double getMaxX() { |
||
526 | return visualStatus.maxX;
|
||
527 | } |
||
528 | |||
529 | public double getMaxY() { |
||
530 | return visualStatus.maxY;
|
||
531 | } |
||
532 | |||
533 | public double getMinX() { |
||
534 | return visualStatus.minX;
|
||
535 | } |
||
536 | |||
537 | public double getMinY() { |
||
538 | return visualStatus.minY;
|
||
539 | } |
||
540 | |||
541 | public int[] getPixel(double wcx, double wcy) { |
||
542 | if (getPxRaster() != null) |
||
543 | return getPxRaster().getPixel(wcx, wcy);
|
||
544 | return null; |
||
545 | } |
||
546 | |||
547 | public RasterAdapter getSource() {
|
||
548 | return null; |
||
549 | } |
||
550 | |||
551 | public double getWidth() { |
||
552 | return visualStatus.width;
|
||
553 | } |
||
554 | |||
555 | public void setBand(int flag, int nBand) { |
||
556 | switch (flag) {
|
||
557 | case GeoRasterFile.RED_BAND:
|
||
558 | setBandR(nBand); |
||
559 | break;
|
||
560 | case GeoRasterFile.GREEN_BAND:
|
||
561 | setBandG(nBand); |
||
562 | break;
|
||
563 | case GeoRasterFile.BLUE_BAND:
|
||
564 | setBandB(nBand); |
||
565 | break;
|
||
566 | } |
||
567 | } |
||
568 | |||
569 | |||
570 | public void setFilterStack(RasterFilterStack stack) { |
||
571 | this.filterStack = stack;
|
||
572 | } |
||
573 | |||
574 | public void setPos(int x, int y) { |
||
575 | this.posX = x;
|
||
576 | this.posY = y;
|
||
577 | } |
||
578 | |||
579 | public void setPosWC(double x, double y) { |
||
580 | this.posXWC = x;
|
||
581 | this.posYWC = y;
|
||
582 | } |
||
583 | |||
584 | public void setRGB(int r, int g, int b) { |
||
585 | this.r = r;
|
||
586 | this.g = g;
|
||
587 | this.b = b;
|
||
588 | } |
||
589 | |||
590 | public Color getRGB() { |
||
591 | return new Color(r, g, b); |
||
592 | } |
||
593 | |||
594 | public void setSource(RasterAdapter ra) { |
||
595 | } |
||
596 | |||
597 | /**
|
||
598 | * @return Returns the raster.
|
||
599 | */
|
||
600 | public PxRaster getPxRaster() {
|
||
601 | return raster;
|
||
602 | } |
||
603 | |||
604 | /**
|
||
605 | * @return Returns the rasterFile.
|
||
606 | */
|
||
607 | public GeoRasterFile getGeoRasterFile() {
|
||
608 | return rasterFile;
|
||
609 | } |
||
610 | |||
611 | |||
612 | /**
|
||
613 | * Sets the R-band.
|
||
614 | *
|
||
615 | * @param r
|
||
616 | */
|
||
617 | public void setBandR(int r) { |
||
618 | this.rband = r;
|
||
619 | } |
||
620 | |||
621 | /**
|
||
622 | * Sets the G-band.
|
||
623 | *
|
||
624 | * @param g
|
||
625 | */
|
||
626 | public void setBandG(int g) { |
||
627 | this.gband = g;
|
||
628 | } |
||
629 | |||
630 | /**
|
||
631 | * Sets the B-band.
|
||
632 | *
|
||
633 | * @param b
|
||
634 | */
|
||
635 | public void setBandB(int b) { |
||
636 | this.bband = b;
|
||
637 | } |
||
638 | |||
639 | /**
|
||
640 | *
|
||
641 | * @return XMLEntity.
|
||
642 | * @throws XMLException
|
||
643 | */
|
||
644 | public XMLEntity getXMLEntity() throws XMLException { |
||
645 | XMLEntity xml = super.getXMLEntity();
|
||
646 | |||
647 | xml.putProperty("fullExtent", StringUtilities.rect2String(fullExtent));
|
||
648 | xml.putProperty("host", host.toExternalForm());
|
||
649 | xml.putProperty("serviceName", service);
|
||
650 | xml.putProperty("serviceType", serviceType);
|
||
651 | xml.putProperty("layerQuery", layerQuery);
|
||
652 | xml.putProperty("format", format);
|
||
653 | if (status != null) { |
||
654 | status.getXMLEntity(xml, true, this); |
||
655 | } else {
|
||
656 | status = new StatusLayerRaster();
|
||
657 | status.getXMLEntity(xml, true, this); |
||
658 | } |
||
659 | xml.putProperty("arcims_transparency", arcImsTransparency);
|
||
660 | return xml;
|
||
661 | } |
||
662 | |||
663 | /**
|
||
664 | *
|
||
665 | * @param xml
|
||
666 | * XMLEntity
|
||
667 | *
|
||
668 | * @throws XMLException
|
||
669 | * @throws DriverException
|
||
670 | * @throws DriverIOException
|
||
671 | */
|
||
672 | public void setXMLEntity(XMLEntity xml) throws XMLException { |
||
673 | |||
674 | super.setXMLEntity(xml);
|
||
675 | fullExtent = StringUtilities.string2Rect(xml |
||
676 | .getStringProperty("fullExtent"));
|
||
677 | try {
|
||
678 | host = new URL(xml.getStringProperty("host")); |
||
679 | } catch (MalformedURLException e) { |
||
680 | logger.error("Whle reading XML file ", e);
|
||
681 | throw new XMLException(e); |
||
682 | } |
||
683 | |||
684 | this.layerQuery = xml.getStringProperty("layerQuery"); |
||
685 | this.service = xml.getStringProperty("serviceName"); |
||
686 | this.serviceType = xml.getStringProperty("serviceType"); |
||
687 | this.format = xml.getStringProperty("format"); |
||
688 | |||
689 | FMapRasterArcImsDriver drv = new FMapRasterArcImsDriver(host.toString(), service, serviceType);
|
||
690 | if (!drv.connect(myCanc)) {
|
||
691 | logger.error("Error while loading service information. ");
|
||
692 | } |
||
693 | ArcImsClientP cli = (ArcImsClientP) drv.getClient(); |
||
694 | ServiceInformation si = cli.getServiceInformation(); |
||
695 | this.arcimsStatus.setServiceInformation(si);
|
||
696 | |||
697 | if (xml.contains("arcims_transparency")) |
||
698 | this.arcImsTransparency = xml
|
||
699 | .getBooleanProperty("arcims_transparency");
|
||
700 | |||
701 | String claseStr = StatusLayerRaster.defaultClass;
|
||
702 | if (xml.contains("raster.class")) |
||
703 | claseStr = xml.getStringProperty("raster.class");
|
||
704 | |||
705 | if (status != null) { |
||
706 | status.setXMLEntity(xml, this);
|
||
707 | } else {
|
||
708 | // When we load a project
|
||
709 | if (claseStr != null && !claseStr.equals("")) { |
||
710 | try {
|
||
711 | Class clase = Class.forName(claseStr); |
||
712 | Constructor constr = clase.getConstructor(null); |
||
713 | status = (StatusRasterInterface) constr.newInstance(null);
|
||
714 | if (status != null) |
||
715 | status.setXMLEntity(xml, this);
|
||
716 | } catch (ClassNotFoundException exc) { |
||
717 | logger.error("Whle reading XML file ", exc);
|
||
718 | } catch (InstantiationException exc) { |
||
719 | logger.error("Whle reading XML file ", exc);
|
||
720 | } catch (IllegalAccessException exc) { |
||
721 | logger.error("Whle reading XML file ", exc);
|
||
722 | } catch (NoSuchMethodException exc) { |
||
723 | logger.error("Whle reading XML file ", exc);
|
||
724 | } catch (InvocationTargetException exc) { |
||
725 | logger.error("Whle reading XML file ", exc);
|
||
726 | } |
||
727 | } |
||
728 | } |
||
729 | firstLoad = true;
|
||
730 | } |
||
731 | |||
732 | public Vector getLayerScaleInfoVector() { |
||
733 | Vector v = new Vector(); |
||
734 | String id;
|
||
735 | |||
736 | for (int i = 0; i < arcimsStatus.getLayerIds().size(); i++) { |
||
737 | id = (String) arcimsStatus.getLayerIds().get(i);
|
||
738 | v.add(getScaleInfo(id)); |
||
739 | } |
||
740 | return v;
|
||
741 | } |
||
742 | |||
743 | public LayerScaleData getScaleInfo(String theId) { |
||
744 | ServiceInformation si; |
||
745 | ServiceInformationLayer sil; |
||
746 | int noflayers;
|
||
747 | long true_max_scale, true_min_scale;
|
||
748 | |||
749 | LayerScaleData theLayerScaleData = null;
|
||
750 | |||
751 | si = arcimsStatus.getServiceInfo(); |
||
752 | int _dpi = si.getScreen_dpi();
|
||
753 | String mapUnits = si.getMapunits();
|
||
754 | |||
755 | noflayers = si.getLayers().size(); |
||
756 | for (int i = 0; i < noflayers; i++) { |
||
757 | sil = (ServiceInformationLayer) si.getLayer(i); |
||
758 | if ((sil.getId().compareTo(theId)) == 0) { |
||
759 | true_max_scale = LayerScaleData |
||
760 | .getTrueScaleFromRelativeScaleAndMapUnits(sil.getMaxscale(), |
||
761 | mapUnits, _dpi); |
||
762 | true_min_scale = LayerScaleData |
||
763 | .getTrueScaleFromRelativeScaleAndMapUnits(sil.getMinscale(), |
||
764 | mapUnits, _dpi); |
||
765 | theLayerScaleData = new LayerScaleData(sil.getName(), sil.getId(),
|
||
766 | true_min_scale, true_max_scale, sil.getType()); |
||
767 | } |
||
768 | } |
||
769 | return theLayerScaleData;
|
||
770 | } |
||
771 | |||
772 | public void addActionlistener(ActionListener al) { |
||
773 | if (actionListeners.contains(al)) return; |
||
774 | actionListeners.add(al); |
||
775 | } |
||
776 | |||
777 | public void removeActionlistener(ActionListener al) { |
||
778 | actionListeners.remove(al); |
||
779 | } |
||
780 | |||
781 | private void callActionListeners(ActionEvent ae) { |
||
782 | ActionListener al;
|
||
783 | for (int i=0; i<actionListeners.size(); i++) { |
||
784 | al = (ActionListener) actionListeners.get(i);
|
||
785 | al.actionPerformed(ae); |
||
786 | } |
||
787 | } |
||
788 | |||
789 | public long getScale() { |
||
790 | return getMapContext().getScaleView();
|
||
791 | } |
||
792 | |||
793 | public int getMaxTileHeight() { |
||
794 | return maxTileHeight;
|
||
795 | } |
||
796 | |||
797 | public void setMaxTileHeight(int maxTileHeight) { |
||
798 | this.maxTileHeight = maxTileHeight;
|
||
799 | } |
||
800 | |||
801 | public int getMaxTileWidth() { |
||
802 | return maxTileWidth;
|
||
803 | } |
||
804 | |||
805 | public void setMaxTileWidth(int maxTileWidth) { |
||
806 | this.maxTileWidth = maxTileWidth;
|
||
807 | } |
||
808 | |||
809 | public void setServiceInformationInStatus(ServiceInformation si) { |
||
810 | this.arcimsStatus.setServiceInformation(si);
|
||
811 | } |
||
812 | |||
813 | /**
|
||
814 | * This is the <tt>getDriver</tt> method. The <tt>getDriver</tt>
|
||
815 | * method will be implemented by sub-classes.
|
||
816 | *
|
||
817 | * @param d the new driver.
|
||
818 | */
|
||
819 | public void setDriver(ArcImsDriver d) { |
||
820 | driver = d; |
||
821 | } |
||
822 | |||
823 | public ArcImsStatus getArcimsStatus() {
|
||
824 | return arcimsStatus;
|
||
825 | } |
||
826 | |||
827 | public void setArcimsStatus(ArcImsStatus arcimsStatus) { |
||
828 | this.arcimsStatus = arcimsStatus;
|
||
829 | } |
||
830 | |||
831 | public boolean isFirstLoad() { |
||
832 | return firstLoad;
|
||
833 | } |
||
834 | |||
835 | public void setFirstLoad(boolean firstLoad) { |
||
836 | this.firstLoad = firstLoad;
|
||
837 | } |
||
838 | |||
839 | public URL getHost() { |
||
840 | return host;
|
||
841 | } |
||
842 | |||
843 | public void setHost(URL host) { |
||
844 | this.host = host;
|
||
845 | } |
||
846 | |||
847 | public String getLayerQuery() { |
||
848 | return layerQuery;
|
||
849 | } |
||
850 | |||
851 | public void setLayerQuery(String lQuery) { |
||
852 | this.layerQuery = lQuery;
|
||
853 | if (layerQuery.substring(0, 1).compareTo(",") == 0) |
||
854 | layerQuery = layerQuery.substring(1);
|
||
855 | } |
||
856 | |||
857 | public String getService() { |
||
858 | return service;
|
||
859 | } |
||
860 | |||
861 | public void setService(String service) { |
||
862 | this.service = service;
|
||
863 | } |
||
864 | |||
865 | public String getServiceType() { |
||
866 | return serviceType;
|
||
867 | } |
||
868 | |||
869 | public void setServiceType(String serviceType) { |
||
870 | this.serviceType = serviceType;
|
||
871 | } |
||
872 | |||
873 | public String getSRS() { |
||
874 | return SRS;
|
||
875 | } |
||
876 | |||
877 | public void setSRS(String srs) { |
||
878 | SRS = srs; |
||
879 | } |
||
880 | |||
881 | public void setFullExtent(Rectangle2D fullExtent) { |
||
882 | this.fullExtent = fullExtent;
|
||
883 | } |
||
884 | |||
885 | public Rectangle2D getFullExtent() { |
||
886 | return fullExtent;
|
||
887 | } |
||
888 | |||
889 | public boolean getArcImsTransparency() { |
||
890 | return arcImsTransparency;
|
||
891 | } |
||
892 | |||
893 | public int getTransparency() { |
||
894 | return transparency;
|
||
895 | } |
||
896 | |||
897 | public void setTransparency(int transparency) { |
||
898 | this.transparency = transparency;
|
||
899 | } |
||
900 | |||
901 | |||
902 | |||
903 | private class VisualStatusArcIms { |
||
904 | /**
|
||
905 | * Ancho y alto de la imagen o del conjunto de tiles si los tiene. Coincide con
|
||
906 | * el ancho y alto del viewPort
|
||
907 | */
|
||
908 | private int width = 0, height = 0; |
||
909 | private double minX = 0D, minY = 0D, maxX = 0D, maxY = 0D; |
||
910 | private int bandCount = 0; |
||
911 | private int dataType = DataBuffer.TYPE_UNDEFINED; |
||
912 | } |
||
913 | |||
914 | |||
915 | |||
916 | public int getPosX() { |
||
917 | return posX;
|
||
918 | } |
||
919 | |||
920 | public void setPosX(int posX) { |
||
921 | this.posX = posX;
|
||
922 | } |
||
923 | |||
924 | public double getPosXWC() { |
||
925 | return posXWC;
|
||
926 | } |
||
927 | |||
928 | public void setPosXWC(double posXWC) { |
||
929 | this.posXWC = posXWC;
|
||
930 | } |
||
931 | |||
932 | public int getPosY() { |
||
933 | return posY;
|
||
934 | } |
||
935 | |||
936 | public void setPosY(int posY) { |
||
937 | this.posY = posY;
|
||
938 | } |
||
939 | |||
940 | public double getPosYWC() { |
||
941 | return posYWC;
|
||
942 | } |
||
943 | |||
944 | public void setPosYWC(double posYWC) { |
||
945 | this.posYWC = posYWC;
|
||
946 | } |
||
947 | |||
948 | public void setFormatInStatus(String imgFormat) { |
||
949 | arcimsStatus.setFormat(imgFormat); |
||
950 | } |
||
951 | |||
952 | /**
|
||
953 | * This method invoques the <tt>FMapRasterArcImsDriver</tt>'s
|
||
954 | * <tt>getFeatureInfo</tt> method with the given coordinates as a
|
||
955 | * parameter
|
||
956 | *
|
||
957 | * @param p
|
||
958 | * the corrdinates of the screen pixel to be queried
|
||
959 | *
|
||
960 | * @return the data retrieved for that pixel
|
||
961 | * @throws DriverException
|
||
962 | */
|
||
963 | 8707 | jldominguez | public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws DriverException { |
964 | 8110 | jsanz | StringXMLItem[] resp = new StringXMLItem[1]; |
965 | String respStr;
|
||
966 | |||
967 | if ( ((FMapRasterArcImsDriver) driver).isQueryable()) {
|
||
968 | try {
|
||
969 | respStr = ((FMapRasterArcImsDriver) driver).getFeatureInfo(arcimsStatus, (int) p.getX(), (int) p |
||
970 | .getY(), Integer.MAX_VALUE);
|
||
971 | } catch (ArcImsException e) {
|
||
972 | DriverException de = new DriverException(e.getMessage());
|
||
973 | logger.error("In query by point ", e);
|
||
974 | throw de;
|
||
975 | } |
||
976 | } else {
|
||
977 | DriverException de = new DriverException("layer_not_queriable"); |
||
978 | throw de;
|
||
979 | } |
||
980 | System.err.println(resp); //TODO BORRAR ESTO |
||
981 | resp[0] = new StringXMLItem(respStr, this); |
||
982 | return resp;
|
||
983 | } |
||
984 | |||
985 | public boolean isTiled() { |
||
986 | return tiled;
|
||
987 | } |
||
988 | |||
989 | public int[] getTileSize() { |
||
990 | return tileSize;
|
||
991 | } |
||
992 | |||
993 | /**
|
||
994 | * The extCatalogYNomenclator needs this creator.
|
||
995 | *
|
||
996 | * @param p a Map object with the following keys:
|
||
997 | *
|
||
998 | * (key, object type returned)
|
||
999 | * ---------------------------
|
||
1000 | * "host", String (with or without the servlet path, example:
|
||
1001 | * "http://www.geographynetwork.com")
|
||
1002 | * "service_name", String (remote service name)
|
||
1003 | * "srs", String (coordinate system)
|
||
1004 | * "layer_name", String (local layer's name)
|
||
1005 | *
|
||
1006 | * @return a FRasterLyrArcIMS layer
|
||
1007 | */
|
||
1008 | public FRasterLyrArcIMS(Map m) throws ConnectionException { |
||
1009 | myCanc = new MyCancellable(new DefaultCancellableMonitorable()); |
||
1010 | String _host = ""; |
||
1011 | try {
|
||
1012 | _host = (String) m.get("host"); |
||
1013 | String _service_name = (String) m.get("service_name"); |
||
1014 | String _srs = (String) m.get("srs"); |
||
1015 | String _image_format = "JPG"; |
||
1016 | String _layer_name = (String) m.get("layer_name"); |
||
1017 | |||
1018 | // in case layer_name is missing or equals the empty string:
|
||
1019 | if ((_layer_name == null) || (_layer_name.length() == 0)) { |
||
1020 | _layer_name = _service_name; |
||
1021 | } |
||
1022 | // ----------------------------
|
||
1023 | |||
1024 | URL _true_host = ArcImsProtocolHandler.getUrlWithServlet(new URL(_host)); |
||
1025 | IProjection _true_srs = CRSFactory.getCRS(_srs); |
||
1026 | |||
1027 | |||
1028 | |||
1029 | FMapRasterArcImsDriver _drv = new FMapRasterArcImsDriver(
|
||
1030 | _true_host.toString(), |
||
1031 | _service_name, ServiceInfoTags.vIMAGESERVICE); |
||
1032 | if (!_drv.connect(myCanc))
|
||
1033 | throw new ConnectionException("Unable to connect to host ", |
||
1034 | new Exception(_host)); |
||
1035 | |||
1036 | setDriver(_drv); |
||
1037 | setHost(_true_host); |
||
1038 | setService(_service_name); |
||
1039 | setServiceType(ServiceInfoTags.vIMAGESERVICE); |
||
1040 | setServiceInformationInStatus(_drv.getClient() |
||
1041 | .getServiceInformation()); |
||
1042 | ServiceInformation _si = getArcimsStatus().getServiceInfo(); |
||
1043 | |||
1044 | if ((_si.getFeaturecoordsys() == null) |
||
1045 | || (_si.getFeaturecoordsys().equals(""))) {
|
||
1046 | _si.setFeaturecoordsys(_true_srs.getAbrev().substring( |
||
1047 | ServiceInfoTags.vINI_SRS.length()).trim()); |
||
1048 | logger.warn("Server provides no SRS. ");
|
||
1049 | } |
||
1050 | setFullExtent(((ArcImsProtImageHandler) _drv.getClient() |
||
1051 | .getHandler()).getServiceExtent(_true_srs, getArcimsStatus())); |
||
1052 | |||
1053 | // JPG
|
||
1054 | setFormat(_image_format); |
||
1055 | setTransparency(0);
|
||
1056 | |||
1057 | // =================================== query
|
||
1058 | int layercount = _si.getLayers().size();
|
||
1059 | String _layer_query = ""; |
||
1060 | for (int i=0; i<layercount; i++) { |
||
1061 | if (isTrueString(((ServiceInformationLayer) _si.getLayer(i)).getVisible())) {
|
||
1062 | _layer_query = _layer_query + "," + ((ServiceInformationLayer) _si.getLayer(i)).getId();
|
||
1063 | } |
||
1064 | } |
||
1065 | if (_layer_query.length() == 0) { |
||
1066 | throw new Exception("No layers are visible by default "); |
||
1067 | } else {
|
||
1068 | _layer_query = _layer_query.substring(1);
|
||
1069 | } |
||
1070 | // ===================================
|
||
1071 | |||
1072 | setLayerQuery(_layer_query); |
||
1073 | setProjection(_true_srs); |
||
1074 | setName(_layer_name); |
||
1075 | } catch (Exception e) { |
||
1076 | new ConnectionException("Unable to connect to host " + _host, e); |
||
1077 | } |
||
1078 | } |
||
1079 | |||
1080 | private boolean isTrueString(String visible) { |
||
1081 | if (visible.compareToIgnoreCase("true") == 0) { |
||
1082 | return true; |
||
1083 | } |
||
1084 | return false; |
||
1085 | } |
||
1086 | |||
1087 | public void callNameOrQueryListeners() { |
||
1088 | for (int i=0; i<listeners.size(); i++) { |
||
1089 | ((FRasterLyrArcIMSListener) listeners.get(i)).thingsHaveChanged( |
||
1090 | getLayerQuery(), getName()); |
||
1091 | } |
||
1092 | } |
||
1093 | |||
1094 | public void addNameOrQueryListener(FRasterLyrArcIMSListener l) { |
||
1095 | if (! listeners.contains(l)) {
|
||
1096 | listeners.add(l); |
||
1097 | } |
||
1098 | } |
||
1099 | |||
1100 | public void removeNameOrQueryListener(FRasterLyrArcIMSListener l) { |
||
1101 | listeners.remove(l); |
||
1102 | } |
||
1103 | |||
1104 | public void setNameQueryChange(boolean c) { |
||
1105 | nameQueryChange = c; |
||
1106 | } |
||
1107 | |||
1108 | |||
1109 | } |