Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extArcims / src / es / prodevelop / cit / gvsig / arcims / fmap / layers / FRasterLyrArcIMS.java @ 9034

History | View | Annotate | Download (30.6 KB)

1
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 javax.print.attribute.PrintRequestAttributeSet;
33
import javax.swing.ImageIcon;
34

    
35
import org.apache.log4j.Logger;
36
import org.cresques.geo.ViewPortData;
37
import org.cresques.io.GdalFile;
38
import org.cresques.io.GeoRasterFile;
39
import org.cresques.cts.IProjection;
40
import org.cresques.filter.RasterFilterStack;
41
import org.cresques.filter.RasterFilterStackManager;
42
import org.cresques.px.Extent;
43
import org.cresques.px.PxRaster;
44
import org.gvsig.remoteClient.arcims.ArcImsClientP;
45
import org.gvsig.remoteClient.arcims.ArcImsProtImageHandler;
46
import org.gvsig.remoteClient.arcims.ArcImsProtocolHandler;
47
import org.gvsig.remoteClient.arcims.ArcImsStatus;
48
import org.gvsig.remoteClient.arcims.exceptions.ArcImsException;
49
import org.gvsig.remoteClient.arcims.utils.MyCancellable;
50
import org.gvsig.remoteClient.arcims.utils.ServiceInfoTags;
51
import org.gvsig.remoteClient.arcims.utils.ServiceInformation;
52
import org.gvsig.remoteClient.arcims.utils.ServiceInformationLayer;
53
import org.gvsig.remoteClient.utils.Utilities;
54

    
55
import com.iver.andami.PluginServices;
56
import com.iver.cit.gvsig.fmap.DriverException;
57
import com.iver.cit.gvsig.fmap.ViewPort;
58
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
59
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
60

    
61
import com.iver.cit.gvsig.fmap.layers.FLayer;
62
import com.iver.cit.gvsig.fmap.layers.FLyrDefault;
63
import com.iver.cit.gvsig.fmap.layers.RasterAdapter;
64
import com.iver.cit.gvsig.fmap.layers.RasterOperations;
65
import com.iver.cit.gvsig.fmap.layers.StatusLayerRaster;
66
import com.iver.cit.gvsig.fmap.layers.StatusRasterInterface;
67
import com.iver.cit.gvsig.fmap.layers.Tiling;
68
import com.iver.cit.gvsig.fmap.layers.XMLException;
69
import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint;
70
import com.iver.cit.gvsig.fmap.layers.layerOperations.StringXMLItem;
71
import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem;
72
import com.iver.utiles.StringUtilities;
73
import com.iver.utiles.XMLEntity;
74
import com.iver.utiles.connections.ConnectionException;
75
import com.iver.utiles.swing.threads.Cancellable;
76
import com.iver.utiles.swing.threads.DefaultCancellableMonitorable;
77

    
78
import org.gvsig.remoteClient.wms.ICancellable;
79

    
80
/**
81
 * This class implements an ArcIMS raster layer.
82
 * 
83
 * @author jldominguez
84
 */
85
public class FRasterLyrArcIMS extends FLyrDefault implements RasterOperations, InfoByPoint {
86
        
87
        private MyCancellable myCanc;
88

    
89
        private static Logger logger = Logger.getLogger(FRasterLyrArcIMS.class.getName());
90
        
91
        private URL host;
92
        private String service;
93
        private String serviceType;
94
        private Rectangle2D fullExtent;
95
        private boolean firstLoad = false;
96
        private ArcImsStatus arcimsStatus = new ArcImsStatus();
97
        private String SRS;
98
        private String layerQuery;
99
        private ArcImsDriver driver;
100
        private VisualStatusArcIms visualStatus = new VisualStatusArcIms();
101
        
102
        private int transparency = -1;
103
        private boolean arcImsTransparency = true;
104

    
105
        private String format;
106
        private StatusRasterInterface status = null;
107
        private GeoRasterFile rasterFile = null;
108
        private PxRaster raster = null;
109
        private int rband = 0, gband = 1, bband = 2;
110
        private RasterFilterStackManager stackManager = null;
111
        private RasterFilterStack filterStack = null;
112
        private int posX = 0, posY = 0;
113
        private double posXWC = 0, posYWC = 0;
114
        private int r = 0, g = 0, b = 0;
115
        private ArrayList actionListeners = new ArrayList();
116
        private int maxTileWidth = 1023;
117
        private int maxTileHeight = 1023;
118
        
119
        private boolean nameQueryChange = false;
120
        
121
        private ArrayList listeners = new ArrayList();
122
        
123
        private boolean tiled = false;
124
        private int[] tileSize = new int[2];
125
        
126
        
127
        public static final String SCALE_CHANGED_COMMAND = "SCALE_HAS_CHANGED";
128
        private ActionEvent scaleChangedEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, SCALE_CHANGED_COMMAND);
129
        
130
        public FRasterLyrArcIMS() {
131
                myCanc = new MyCancellable(new DefaultCancellableMonitorable());
132
        }
133

    
134
        /**
135
         * Gets the driver object onto which <tt>getMap()</tt> and
136
         * <tt>getFeatureInfo()</tt> requests are passed. If the driver was not
137
         * created, this methdo creates it with the server's URL and the service
138
         * name.
139
         * 
140
         * @return the driver that actually performs the requests.
141
         */
142
        public ArcImsDriver getDriver() {
143
                if (driver == null) {
144
                        driver = new FMapRasterArcImsDriver(host.toString(), service,
145
                                        this.serviceType);
146
                }
147
                return driver;
148
        }
149

    
150
        public void setDriver(FMapRasterArcImsDriver d) {
151
                driver = d;
152
        }
153

    
154
        /**
155
         * Gets the transformation matrix to be written in the georeference file.
156
         * The second and the third coefficients will always be zero (it doesn't
157
         * implement image rotation)
158
         * 
159
         * @param bBox
160
         *            Image's size and position (user's coordinates)
161
         * @param sz
162
         *            Images' size in pixels
163
         * @return the worldfile, as a String
164
         * @throws IOException
165
         */
166
        public String getDataWorldFile(Rectangle2D bBox, Dimension sz)
167
                        throws IOException {
168
                StringBuffer data = new StringBuffer();
169
                data.append((bBox.getMaxX() - bBox.getMinX()) / (sz.getWidth() - 1)
170
                                + "\n");
171
                data.append("0.0\n");
172
                data.append("0.0\n");
173
                data.append("-" + (bBox.getMaxY() - bBox.getMinY()) / (sz.getHeight() - 1) + "\n");
174
                // guardalo por si acaso :)
175
                // data.append((bBox.getMaxY() - bBox.getMinY()) / (sz.getHeight() - 1) + "\n");
176
                data.append("" + bBox.getMinX() + "\n");
177
                // data.append("" + bBox.getMinY() + "\n");
178
                data.append("" + bBox.getMaxY() + "\n");
179
                return data.toString();
180
        }
181

    
182
        /**
183
         * Gets the raster status
184
         * 
185
         * @return the raster status
186
         */
187
        public StatusRasterInterface getStatus() {
188
                return this.status;
189
        }
190

    
191
        public void setStatus(StatusRasterInterface s) {
192
                this.status = s;
193
        }
194

    
195
        /**
196
         * This method must be invoqued with <b>true</b> if the layer must show its
197
         * transparency. The level of transparency is set by another method.
198
         * 
199
         * @param t
200
         *            Whether or not the transparency must be shown.
201
         */
202
        public void setArcImsTransparency(boolean t) {
203
                this.arcImsTransparency = t;
204
        }
205

    
206
        /**
207
         * Drawing method invoqued from outside the plugin.
208
         * 
209
         * @param g
210
         *            graphic object on which drawing is made.
211
         * @param vp
212
         *            the view
213
         * @param cancel
214
         *            allows drawing abortion
215
         * @throws DriverException
216
         */
217
        private void drawTile(Graphics2D g, ViewPort vp, Cancellable cancel)
218
                        throws DriverException {
219
                // This is the extent that will be requested
220
                Rectangle2D bBox = vp.getAdjustedExtent();// getFullExtent();
221
                Dimension sz = vp.getImageSize();
222

    
223
                try {
224
                        arcimsStatus.setExtent(bBox);
225
                        arcimsStatus.setFormat(getFormat());
226
                        arcimsStatus.setHeight(vp.getImageHeight());
227
                        arcimsStatus.setWidth(vp.getImageWidth());
228
                        arcimsStatus.setLayerIds(Utilities.createVector(layerQuery, ","));
229
                        arcimsStatus.setServer(host.toString());
230
                        arcimsStatus.setService(service);
231
                        arcimsStatus.setSrs(this.getProjection().getAbrev());
232
                        arcimsStatus.setTransparency(this.arcImsTransparency);
233

    
234
                        // We need to cast because driver returns an Object
235
                        File f = (File) getDriver().getMap(arcimsStatus);
236
                        
237
                        int lastp = f.getPath().lastIndexOf(".");
238
                        String noext = f.getPath().substring(0,lastp);
239
                        
240
                        String nameWorldFile = noext
241
                                        + getExtensionWordFile(getFormat());
242

    
243
                        com.iver.andami.Utilities.createTemp(nameWorldFile, this
244
                                        .getDataWorldFile(bBox, sz));
245

    
246
                        if (status != null && firstLoad) {
247
                                status.applyStatus(this);
248
                                firstLoad = false;
249
                        }
250

    
251
                        // And finally, obtain the extent intersecting the view and the BBox
252
                        // to draw to.
253
                        // ------------------------------ START (?)
254
                        // Rectangle2D extent = new Rectangle2D.Double();
255
                        // Rectangle2D.intersect(vp.getAdjustedExtent(), bBox, extent);
256
                        // ViewPortData vpData = new ViewPortData(vp.getProjection(),
257
                        // new Extent(extent), sz);
258
                        // vpData.setMat(vp.getAffineTransform());
259
                        // ------------------------------ END (?)
260

    
261
                        // ------------------------------ START
262
                        ViewPortData vpData = new ViewPortData(vp.getProjection(),
263
                                        new Extent(bBox), sz);
264
                        vpData.setMat(vp.getAffineTransform());
265
                        // ------------------------------ END
266

    
267
                        rasterProcess(g, vpData, f);
268

    
269
                } catch (IOException e) {
270
                        DriverException de = new DriverException("connect_error");
271
                        logger.error("While connecting ", e);
272
                        throw de;
273
                } catch (ArcImsException e) {
274
                        logger.error("While drawing ", e);
275
                        this.setVisible(false);
276
                        DriverException de = new DriverException(e.getMessage());
277
                        throw de;
278
                }
279

    
280
        }
281

    
282
        /**
283
         * Drawing method invoqued from gvSIG to draw this layer. Uses a <tt>Tiling</tt>
284
         * object to prevent downloading images too large to be retrieved
285
         * (pixel count limit)
286
         * 
287
         * @param image
288
         *            used to speed up drawing process
289
         * @param g
290
         *            graphic object on which drawing is make
291
         * @param viewPort
292
         *            the view's properties
293
         * @param cancel
294
         *            allows drawing abortion
295
         * @param scale the current scale
296
         *                                 
297
         * @throws DriverException
298
         */
299
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
300
                        Cancellable cancel, double scale) throws DriverException {
301
                
302
                if (! isVisible()) return;
303
                if (! isWithinScale(scale)) return;
304
                
305
                visualStatus.width = viewPort.getImageWidth();
306
                visualStatus.height = viewPort.getImageHeight();
307
                visualStatus.minX = viewPort.getAdjustedExtent().getMinX();
308
                visualStatus.minY = viewPort.getAdjustedExtent().getMinY();
309
                visualStatus.maxX = viewPort.getAdjustedExtent().getMaxX();
310
                visualStatus.maxY = viewPort.getAdjustedExtent().getMaxY();
311
                
312
                setTileDimensions(viewPort);
313
                        
314
                Point2D p = viewPort.getOffset();
315
                Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1);
316
                Tiling tiles = new Tiling(maxTileWidth, maxTileHeight, r);
317
                tiles.setAffineTransform((AffineTransform) viewPort
318
                                .getAffineTransform().clone());
319
                
320
                tiled = false;
321
                if (tiles.getNumTiles() > 1) {
322
                        tiled = true;
323
                        tileSize[0] = tiles.getMaxTileWidth();
324
                        tileSize[1] = tiles.getMaxTileHeight();
325
                }
326
                for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
327
                        // drawing part
328
                        try {
329
                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
330
                                drawTile(g, vp, cancel);
331
                        } catch (NoninvertibleTransformException e) {
332
                                logger.error("Non invertible matrix ", e);
333
                        }
334
                }
335
                
336
                // the status needs to be reset because the drawTile
337
                // method had changed its extent and dimension:
338
                arcimsStatus.setExtent(viewPort.getAdjustedExtent());
339
                arcimsStatus.setHeight(viewPort.getImageHeight());
340
                arcimsStatus.setWidth(viewPort.getImageWidth());
341

    
342
                callActionListeners(scaleChangedEvent);
343
                if (nameQueryChange) {
344
                        callNameOrQueryListeners();
345
                        nameQueryChange = false;
346
                }
347
        }
348

    
349
        private void setTileDimensions(ViewPort vp) {
350
                maxTileHeight =  vp.getImageHeight();
351
                try {
352
                        maxTileWidth =
353
                                Integer.parseInt(arcimsStatus.getServiceInfo().getImagelimit_pixelcount()) / maxTileHeight;
354
                        maxTileWidth--;
355
                } catch (NumberFormatException nfe) {
356
                        logger.error("getImagelimit_pixelcount() returned a non parseable string. maxTileWidth was set to 100.", nfe);
357
                        maxTileWidth = 100;
358
                }
359
                logger.info("Tile size = [ " + maxTileWidth + " , " + maxTileHeight + " ]");
360
        }
361

    
362
        /**
363
         * Gets the georeference file extension depending on the image's format.
364
         * 
365
         * @param f
366
         *            raster file format
367
         * @return georeference file extension (".wld", ".tfw", etc)
368
         */
369
        private String getExtensionWordFile(String f) {
370
                String extWorldFile = ".wld";
371
                if (f.equals("tif") || f.equals("tiff"))
372
                        extWorldFile = ".tfw";
373
                if (f.equals("jpeg"))
374
                        extWorldFile = ".jpgw";
375
                return extWorldFile;
376
        }
377

    
378
        /**
379
         * Draws an image using PxRaster
380
         * 
381
         * @param g
382
         *            graphics object on which drawing will be made
383
         * @param vpData
384
         *            viewport's properties
385
         * @param file
386
         *            the image file
387
         */
388
        private void rasterProcess(Graphics2D g, ViewPortData vpData, File file) {
389

    
390
                // PxRaster is created
391
                rasterFile = new GdalFile(vpData.getProjection(), file
392
                                .getAbsolutePath());
393
                raster = new PxRaster(rasterFile, null, rasterFile.getExtent());
394

    
395
                if (this.filterStack != null)
396
                        raster.filterStack = this.filterStack;
397

    
398
                raster.setTransparency(false); 
399

    
400
                if (this.transparency == -1 && !firstLoad)
401
                        ;
402
                else
403
                        raster.setTransparency(this.transparency);
404

    
405
                raster.setBand(GeoRasterFile.RED_BAND, rband);
406
                raster.setBand(GeoRasterFile.GREEN_BAND, gband);
407
                raster.setBand(GeoRasterFile.BLUE_BAND, bband);
408

    
409
                if (this.stackManager != null)
410
                        raster.setStackManager(this.stackManager);
411
                
412
                if(visualStatus != null){
413
                        visualStatus.bandCount = raster.getBandCount();
414
                        visualStatus.dataType = raster.getDataType();
415
                }
416

    
417
                raster.draw(g, vpData);
418

    
419
                // We get the Stack Manager with the first pxRaster of an image
420
                // so we can modify it afterwards from the properties dialog
421
                if (this.stackManager == null)
422
                        this.stackManager = raster.getStackManager();
423

    
424
                if (this.filterStack == null)
425
                        this.filterStack = raster.filterStack;
426
        }
427

    
428
        public void repaintRaster(Graphics2D g, ViewPortData vpData, File file) {
429
                rasterProcess(g, vpData, file);
430
        }
431

    
432
        public String getFormat() {
433
                return format;
434
        }
435

    
436
        public void setFormat(String format) {
437
                this.format = format;
438
        }
439

    
440

    
441
        /**
442
         * Gets a series of attributes that describe the layer's raster: Filename,
443
         * Filesize, Height, Width and Bands.
444
         * 
445
         * @return A list of 2-element arrays { "Attribute name" , Value }
446
         */
447
        public ArrayList getAttributes() {
448
                if (rasterFile != null) {
449
                        ArrayList attr = new ArrayList();
450
                        Object[][] a = {
451
                                        {
452
                                                        "Filename",
453
                                                        rasterFile.getName().substring(
454
                                                                        rasterFile.getName().lastIndexOf("/") + 1,
455
                                                                        rasterFile.getName().length()) },
456
                                        { "Filesize", new Long(rasterFile.getFileSize()) },
457
                                        {
458
                                                        "Width",
459
                                                        new Integer((new Double(this.getWidth()))
460
                                                                        .intValue()) },
461
                                        {
462
                                                        "Height",
463
                                                        new Integer((new Double(this.getHeight()))
464
                                                                        .intValue()) },
465
                                        { "Bands", new Integer(rasterFile.getBandCount()) } };
466
                        for (int i = 0; i < a.length; i++) {
467
                                attr.add(a[i]);
468
                        }
469
                        return attr;
470
                }
471
                return null;
472
        }
473

    
474
        /**
475
         * 
476
        /**
477
         * Invoqued from gvSIG to draw this layer on a printable map. Uses a
478
         * <tt>Tiling</tt> object to prevent downloading images too large to be
479
         * retrieved (pixel count limit).
480
         * 
481
         * @param g
482
         *            graphic object on which drawing is make
483
         * @param viewPort
484
         *            the view's properties
485
         * @param cancel
486
         *            allows drawing abortion
487
         * @param scale the current scale
488
         *                                 
489
         * @throws DriverException
490
         */
491
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
492
                        double scale, PrintRequestAttributeSet properties) throws DriverException {
493

    
494
                draw(null, g, viewPort, cancel, scale);
495
        }
496

    
497
        public HashMap getProperties() {
498
                HashMap info = new HashMap();
499
                String[] layerNames = getLayerQuery().split(",");
500
                Vector layers = new Vector(layerNames.length);
501
                try {
502
                        if (((FMapRasterArcImsDriver) getDriver()).connect(myCanc)) {
503
                                info.put("layerName", this.getName());
504
                                info.put("serverUrl", this.getHost());
505
                                info.put("serviceName", this.getService());
506
                                info.put("serviceType", this.getServiceType());
507
                                info.put("format", this.format);
508
                                for (int i = 0; i < layerNames.length; i++)
509
                                        layers.add(layerNames[i]);
510
                                info.put("layerIds", layers);
511
                                return info;
512
                        }
513
                } catch (Exception e) {
514
                        logger.error("Error while reading FRasterLyrArcIMS properties. ", e);
515
                }
516
                return null;
517
        }
518

    
519
        public RasterFilterStack getFilterStack() {
520
                if (raster != null)
521
                        return raster.filterStack;
522
                return null;
523
        }
524

    
525
        public double getHeight() {
526
                return visualStatus.height;
527
        }
528

    
529
        public double getMaxX() {
530
                return visualStatus.maxX;
531
        }
532

    
533
        public double getMaxY() {
534
                return visualStatus.maxY;
535
        }
536

    
537
        public double getMinX() {
538
                return visualStatus.minX;
539
        }
540

    
541
        public double getMinY() {
542
                return visualStatus.minY;
543
        }
544

    
545
        public int[] getPixel(double wcx, double wcy) {
546
                if (getPxRaster() != null)
547
                        return getPxRaster().getPixel(wcx, wcy);
548
                return null;
549
        }
550

    
551
        public RasterAdapter getSource() {
552
                return null;
553
        }
554

    
555
        public double getWidth() {
556
                return visualStatus.width;
557
        }
558

    
559
        public void setBand(int flag, int nBand) {
560
                switch (flag) {
561
                case GeoRasterFile.RED_BAND:
562
                        setBandR(nBand);
563
                        break;
564
                case GeoRasterFile.GREEN_BAND:
565
                        setBandG(nBand);
566
                        break;
567
                case GeoRasterFile.BLUE_BAND:
568
                        setBandB(nBand);
569
                        break;
570
                }
571
        }
572

    
573
        
574
        public void setFilterStack(RasterFilterStack stack) {
575
                this.filterStack = stack;
576
        }
577

    
578
        public void setPos(int x, int y) {
579
                this.posX = x;
580
                this.posY = y;
581
        }
582

    
583
        public void setPosWC(double x, double y) {
584
                this.posXWC = x;
585
                this.posYWC = y;
586
        }
587

    
588
        public void setRGB(int r, int g, int b) {
589
                this.r = r;
590
                this.g = g;
591
                this.b = b;
592
        }
593
        
594
        public Color getRGB() {
595
                return new Color(r, g, b);
596
        }
597

    
598
        public void setSource(RasterAdapter ra) {
599
        }
600

    
601
        /**
602
         * @return Returns the raster.
603
         */
604
        public PxRaster getPxRaster() {
605
                return raster;
606
        }
607

    
608
        /**
609
         * @return Returns the rasterFile.
610
         */
611
        public GeoRasterFile getGeoRasterFile() {
612
                return rasterFile;
613
        }
614

    
615

    
616
        /**
617
         * Sets the R-band.
618
         * 
619
         * @param r
620
         */
621
        public void setBandR(int r) {
622
                this.rband = r;
623
        }
624

    
625
        /**
626
         * Sets the G-band.
627
         * 
628
         * @param g
629
         */
630
        public void setBandG(int g) {
631
                this.gband = g;
632
        }
633

    
634
        /**
635
         * Sets the B-band.
636
         * 
637
         * @param b
638
         */
639
        public void setBandB(int b) {
640
                this.bband = b;
641
        }
642

    
643
        /**
644
         * 
645
         * @return XMLEntity.
646
         * @throws XMLException
647
         */
648
        public XMLEntity getXMLEntity() throws XMLException {
649
                XMLEntity xml = super.getXMLEntity();
650

    
651
                xml.putProperty("fullExtent", StringUtilities.rect2String(fullExtent));
652
                xml.putProperty("host", host.toExternalForm());
653
                xml.putProperty("serviceName", service);
654
                xml.putProperty("serviceType", serviceType);
655
                xml.putProperty("layerQuery", layerQuery);
656
                xml.putProperty("format", format);
657
                if (status != null) {
658
                        status.getXMLEntity(xml, true, this);
659
                } else {
660
                        status = new StatusLayerRaster();
661
                        status.getXMLEntity(xml, true, this);
662
                }
663
                xml.putProperty("arcims_transparency", arcImsTransparency);
664
                return xml;
665
        }
666

    
667
        /**
668
         * 
669
         * @param xml
670
         *            XMLEntity
671
         * 
672
         * @throws XMLException
673
         * @throws DriverException
674
         * @throws DriverIOException
675
         */
676
        public void setXMLEntity(XMLEntity xml) throws XMLException {
677

    
678
                super.setXMLEntity(xml);
679
                fullExtent = StringUtilities.string2Rect(xml
680
                                .getStringProperty("fullExtent"));
681
                try {
682
                        host = new URL(xml.getStringProperty("host"));
683
                } catch (MalformedURLException e) {
684
                        logger.error("Whle reading XML file ", e);
685
                        throw new XMLException(e);
686
                }
687

    
688
                this.layerQuery = xml.getStringProperty("layerQuery");
689
                this.service = xml.getStringProperty("serviceName");
690
                this.serviceType = xml.getStringProperty("serviceType");
691
                this.format = xml.getStringProperty("format");
692
                
693
                FMapRasterArcImsDriver drv = new FMapRasterArcImsDriver(host.toString(), service, serviceType);
694
                if (!drv.connect(myCanc)) {
695
                        logger.error("Error while loading service information. ");
696
                }
697
                ArcImsClientP cli = (ArcImsClientP) drv.getClient();
698
                ServiceInformation si = cli.getServiceInformation();
699
                this.arcimsStatus.setServiceInformation(si);
700

    
701
                if (xml.contains("arcims_transparency"))
702
                        this.arcImsTransparency = xml
703
                                        .getBooleanProperty("arcims_transparency");
704

    
705
                String claseStr = StatusLayerRaster.defaultClass;
706
                if (xml.contains("raster.class"))
707
                        claseStr = xml.getStringProperty("raster.class");
708

    
709
                if (status != null) {
710
                        status.setXMLEntity(xml, this);
711
                } else {
712
                        // When we load a project
713
                        if (claseStr != null && !claseStr.equals("")) {
714
                                try {
715
                                        Class clase = Class.forName(claseStr);
716
                                        Constructor constr = clase.getConstructor(null);
717
                                        status = (StatusRasterInterface) constr.newInstance(null);
718
                                        if (status != null)
719
                                                status.setXMLEntity(xml, this);
720
                                } catch (ClassNotFoundException exc) {
721
                                        logger.error("Whle reading XML file ", exc);
722
                                } catch (InstantiationException exc) {
723
                                        logger.error("Whle reading XML file ", exc);
724
                                } catch (IllegalAccessException exc) {
725
                                        logger.error("Whle reading XML file ", exc);
726
                                } catch (NoSuchMethodException exc) {
727
                                        logger.error("Whle reading XML file ", exc);
728
                                } catch (InvocationTargetException exc) {
729
                                        logger.error("Whle reading XML file ", exc);
730
                                }
731
                        }
732
                }
733
                firstLoad = true;
734
        }
735

    
736
        public Vector getLayerScaleInfoVector() {
737
                Vector v = new Vector();
738
                String id;
739

    
740
                for (int i = 0; i < arcimsStatus.getLayerIds().size(); i++) {
741
                        id = (String) arcimsStatus.getLayerIds().get(i);
742
                        v.add(getScaleInfo(id));
743
                }
744
                return v;
745
        }
746

    
747
        public LayerScaleData getScaleInfo(String theId) {
748
                ServiceInformation si;
749
                ServiceInformationLayer sil;
750
                int noflayers;
751
                long true_max_scale, true_min_scale;
752

    
753
                LayerScaleData theLayerScaleData = null;
754

    
755
                si = arcimsStatus.getServiceInfo();
756
                int _dpi = si.getScreen_dpi();
757
                String mapUnits = si.getMapunits();
758

    
759
                noflayers = si.getLayers().size();
760
                for (int i = 0; i < noflayers; i++) {
761
                        sil = (ServiceInformationLayer) si.getLayer(i);
762
                        if ((sil.getId().compareTo(theId)) == 0) {
763
                                true_max_scale = LayerScaleData
764
                                                .getTrueScaleFromRelativeScaleAndMapUnits(sil.getMaxscale(),
765
                                                                mapUnits, _dpi);
766
                                true_min_scale = LayerScaleData
767
                                                .getTrueScaleFromRelativeScaleAndMapUnits(sil.getMinscale(),
768
                                                                mapUnits, _dpi);
769
                                theLayerScaleData = new LayerScaleData(sil.getName(), sil.getId(),
770
                                                true_min_scale, true_max_scale, sil.getType());
771
                        }
772
                }
773
                return theLayerScaleData;
774
        }
775

    
776
        public void addActionlistener(ActionListener al) {
777
                if (actionListeners.contains(al)) return;
778
                actionListeners.add(al);
779
        }
780
        
781
        public void removeActionlistener(ActionListener al) {
782
                actionListeners.remove(al);
783
        }
784
        
785
        private void callActionListeners(ActionEvent ae) {
786
                ActionListener al;
787
                for (int i=0; i<actionListeners.size(); i++) {
788
                        al = (ActionListener) actionListeners.get(i);
789
                        al.actionPerformed(ae);
790
                }
791
        }
792
        
793
        public long getScale() {
794
                return getMapContext().getScaleView();
795
        }
796

    
797
        public int getMaxTileHeight() {
798
                return maxTileHeight;
799
        }
800

    
801
        public void setMaxTileHeight(int maxTileHeight) {
802
                this.maxTileHeight = maxTileHeight;
803
        }
804

    
805
        public int getMaxTileWidth() {
806
                return maxTileWidth;
807
        }
808

    
809
        public void setMaxTileWidth(int maxTileWidth) {
810
                this.maxTileWidth = maxTileWidth;
811
        }
812
        
813
        public void setServiceInformationInStatus(ServiceInformation si) {
814
                this.arcimsStatus.setServiceInformation(si);
815
        }
816

    
817
        /**
818
         * This is the <tt>getDriver</tt> method. The <tt>getDriver</tt>
819
         * method will be implemented by sub-classes.
820
         *  
821
         * @param d the new driver.
822
         */
823
        public void setDriver(ArcImsDriver d) {
824
                driver = d;
825
        }
826

    
827
        public ArcImsStatus getArcimsStatus() {
828
                return arcimsStatus;
829
        }
830

    
831
        public void setArcimsStatus(ArcImsStatus arcimsStatus) {
832
                this.arcimsStatus = arcimsStatus;
833
        }
834

    
835
        public boolean isFirstLoad() {
836
                return firstLoad;
837
        }
838

    
839
        public void setFirstLoad(boolean firstLoad) {
840
                this.firstLoad = firstLoad;
841
        }
842

    
843
        public URL getHost() {
844
                return host;
845
        }
846

    
847
        public void setHost(URL host) {
848
                this.host = host;
849
        }
850

    
851
        public String getLayerQuery() {
852
                return layerQuery;
853
        }
854

    
855
        public void setLayerQuery(String lQuery) {
856
                this.layerQuery = lQuery;
857
                if (layerQuery.substring(0, 1).compareTo(",") == 0)
858
                        layerQuery = layerQuery.substring(1);
859
        }
860

    
861
        public String getService() {
862
                return service;
863
        }
864

    
865
        public void setService(String service) {
866
                this.service = service;
867
        }
868

    
869
        public String getServiceType() {
870
                return serviceType;
871
        }
872

    
873
        public void setServiceType(String serviceType) {
874
                this.serviceType = serviceType;
875
        }
876

    
877
        public String getSRS() {
878
                return SRS;
879
        }
880

    
881
        public void setSRS(String srs) {
882
                SRS = srs;
883
        }
884

    
885
        public void setFullExtent(Rectangle2D fullExtent) {
886
                this.fullExtent = fullExtent;
887
        }
888
        
889
        public Rectangle2D getFullExtent() {
890
                return fullExtent;
891
        }
892

    
893
        public boolean getArcImsTransparency() {
894
                return arcImsTransparency;
895
        }
896

    
897
        public int getTransparency() {
898
                return transparency;
899
        }
900

    
901
        public void setTransparency(int transparency) {
902
                this.transparency = transparency;
903
        }
904
        
905
        
906
        
907
        private class VisualStatusArcIms {
908
                /**
909
                 * Ancho y alto de la imagen o del conjunto de tiles si los tiene. Coincide con 
910
                 * el ancho y alto del viewPort
911
                 */
912
                private        int                                                        width = 0, height = 0;
913
                private double                                                minX = 0D, minY = 0D, maxX = 0D, maxY = 0D;
914
                private int                                                 bandCount = 0;
915
                private int                                                        dataType = DataBuffer.TYPE_UNDEFINED;
916
        }
917

    
918

    
919

    
920
        public int getPosX() {
921
                return posX;
922
        }
923

    
924
        public void setPosX(int posX) {
925
                this.posX = posX;
926
        }
927

    
928
        public double getPosXWC() {
929
                return posXWC;
930
        }
931

    
932
        public void setPosXWC(double posXWC) {
933
                this.posXWC = posXWC;
934
        }
935

    
936
        public int getPosY() {
937
                return posY;
938
        }
939

    
940
        public void setPosY(int posY) {
941
                this.posY = posY;
942
        }
943

    
944
        public double getPosYWC() {
945
                return posYWC;
946
        }
947

    
948
        public void setPosYWC(double posYWC) {
949
                this.posYWC = posYWC;
950
        }
951

    
952
        public void setFormatInStatus(String imgFormat) {
953
                arcimsStatus.setFormat(imgFormat);
954
        }
955

    
956
        /**
957
         * This method invoques the <tt>FMapRasterArcImsDriver</tt>'s
958
         * <tt>getFeatureInfo</tt> method with the given coordinates as a
959
         * parameter
960
         * 
961
         * @param p
962
         *            the corrdinates of the screen pixel to be queried
963
         * 
964
         * @return the data retrieved for that pixel
965
         * @throws DriverException 
966
         */
967
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws DriverException {
968
                StringXMLItem[] resp = new StringXMLItem[1];
969
                String respStr;
970

    
971
                if (  ((FMapRasterArcImsDriver) driver).isQueryable()) {
972
                        try {
973
                                respStr = ((FMapRasterArcImsDriver) driver).getFeatureInfo(arcimsStatus, (int) p.getX(), (int) p
974
                                                .getY(), Integer.MAX_VALUE);
975
                        } catch (ArcImsException e) {
976
                                DriverException de = new DriverException(e.getMessage());
977
                                logger.error("In query by point ", e);
978
                                throw de;
979
                        }
980
                } else {
981
                        DriverException de = new DriverException("layer_not_queriable");
982
                        throw de;
983
                }
984
                System.err.println(resp); //TODO BORRAR ESTO
985
                resp[0] = new StringXMLItem(respStr, this);
986
                return resp;
987
        }
988

    
989
        public boolean isTiled() {
990
                return tiled;
991
        }
992

    
993
        public int[] getTileSize() {
994
                return tileSize;
995
        }
996
        
997
        /**
998
         * The extCatalogYNomenclator needs this creator.
999
         * 
1000
         * @param p a Map object with the following keys:
1001
         * 
1002
         * (key, object type returned)
1003
         * ---------------------------
1004
         * "host", String (with or without the servlet path, example:
1005
         *                                         "http://www.geographynetwork.com")
1006
         * "service_name", String (remote service name)
1007
         * "srs", String (coordinate system)
1008
         * "layer_name", String (local layer's name)
1009
         * 
1010
         * @return a FRasterLyrArcIMS layer
1011
         */
1012
        public FRasterLyrArcIMS(Map m) throws ConnectionException {
1013
                myCanc = new MyCancellable(new DefaultCancellableMonitorable());
1014
                String _host = "";
1015
                try {
1016
                        _host = (String) m.get("host");
1017
                        String _service_name = (String) m.get("service_name");
1018
                        String _srs = (String) m.get("srs");
1019
                        String _image_format = "JPG";
1020
                        String _layer_name = (String) m.get("layer_name");
1021
                        
1022
                        // in case layer_name is missing or equals the empty string:
1023
                        if ((_layer_name == null) || (_layer_name.length() == 0)) {
1024
                                _layer_name = _service_name;
1025
                        }
1026
                        // ----------------------------
1027
                        
1028
                        URL _true_host = ArcImsProtocolHandler.getUrlWithServlet(new URL(_host));
1029
                        IProjection _true_srs = CRSFactory.getCRS(_srs);
1030
                        
1031
                        
1032

    
1033
                        FMapRasterArcImsDriver _drv = new FMapRasterArcImsDriver(
1034
                                        _true_host.toString(),
1035
                                        _service_name, ServiceInfoTags.vIMAGESERVICE);
1036
                        if (!_drv.connect(myCanc))
1037
                                throw new ConnectionException("Unable to connect to host ",
1038
                                                new Exception(_host));
1039

    
1040
                        setDriver(_drv);
1041
                        setHost(_true_host);
1042
                        setService(_service_name);
1043
                        setServiceType(ServiceInfoTags.vIMAGESERVICE);
1044
                        setServiceInformationInStatus(_drv.getClient()
1045
                                        .getServiceInformation());
1046
                        ServiceInformation _si = getArcimsStatus().getServiceInfo();
1047

    
1048
                        if ((_si.getFeaturecoordsys() == null)
1049
                                        || (_si.getFeaturecoordsys().equals(""))) {
1050
                                _si.setFeaturecoordsys(_true_srs.getAbrev().substring(
1051
                                                ServiceInfoTags.vINI_SRS.length()).trim());
1052
                                logger.warn("Server provides no SRS. ");
1053
                        }
1054
                        setFullExtent(((ArcImsProtImageHandler) _drv.getClient()
1055
                                        .getHandler()).getServiceExtent(_true_srs, getArcimsStatus()));
1056

    
1057
                        //  JPG
1058
                        setFormat(_image_format);
1059
                        setTransparency(0);
1060
                        
1061
                        // =================================== query
1062
                        int layercount = _si.getLayers().size();
1063
                        String _layer_query = "";
1064
                        for (int i=0; i<layercount; i++) {
1065
                                if (isTrueString(((ServiceInformationLayer) _si.getLayer(i)).getVisible())) {
1066
                                        _layer_query = _layer_query + "," + ((ServiceInformationLayer) _si.getLayer(i)).getId();
1067
                                }
1068
                        }
1069
                        if (_layer_query.length() == 0) {
1070
                                throw new Exception("No layers are visible by default ");
1071
                        } else {
1072
                                _layer_query = _layer_query.substring(1);
1073
                        }
1074
                        // ===================================
1075
                        
1076
                        setLayerQuery(_layer_query);
1077
                        setProjection(_true_srs);
1078
                        setName(_layer_name);
1079
                } catch (Exception e) {
1080
                        new ConnectionException("Unable to connect to host " + _host, e);
1081
                }
1082
        }        
1083
        
1084
        private boolean isTrueString(String visible) {
1085
                if (visible.compareToIgnoreCase("true") == 0) {
1086
                        return true;
1087
                }
1088
                return false;
1089
        }
1090

    
1091
        public void callNameOrQueryListeners() {
1092
                for (int i=0; i<listeners.size(); i++) {
1093
                        ((FRasterLyrArcIMSListener) listeners.get(i)).thingsHaveChanged(
1094
                                        getLayerQuery(), getName());
1095
                }
1096
        }        
1097
        
1098
        public void addNameOrQueryListener(FRasterLyrArcIMSListener l) {
1099
                if (! listeners.contains(l)) {
1100
                        listeners.add(l);
1101
                }
1102
        }
1103
        
1104
        public void removeNameOrQueryListener(FRasterLyrArcIMSListener l) {
1105
                listeners.remove(l);
1106
        }
1107

    
1108
        public void setNameQueryChange(boolean c) {
1109
                nameQueryChange = c;
1110
        }
1111
        
1112
        public ImageIcon getTocImageIcon() {
1113
                
1114
                ImageIcon resp = null;
1115
                try {
1116
                        resp = createImageIcon("images/esrilogo.png");
1117
                } catch (Exception ex) {
1118
                }
1119
                
1120
                if (resp == null) {
1121
                        return super.getTocImageIcon();
1122
                } else {
1123
                        return resp;
1124
                }
1125
        }
1126
        
1127
        protected ImageIcon createImageIcon(String path) {
1128
                java.net.URL imgURL = createExtensionUrl(path);
1129
                if (imgURL != null) {
1130
                        return new ImageIcon(imgURL);
1131
                } else {
1132
                        logger.error("File not found: " + path);
1133
                        return null;
1134
                }
1135
        }
1136

    
1137
        protected java.net.URL createExtensionUrl(String path) {
1138
                return PluginServices.getPluginServices("es.prodevelop.cit.gvsig.arcims").getClassLoader().getResource(path);
1139
                // return getClass().getClassLoader().getResource(path);
1140
        }
1141
        
1142
        
1143

    
1144
}