Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extWMS / src / org / gvsig / wms / fmap / layers / FLyrWMS.java @ 33738

History | View | Annotate | Download (66.8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.wms.fmap.layers;
42

    
43
import java.awt.Dimension;
44
import java.awt.Graphics2D;
45
import java.awt.Image;
46
import java.awt.Point;
47
import java.awt.Rectangle;
48
import java.awt.geom.AffineTransform;
49
import java.awt.geom.NoninvertibleTransformException;
50
import java.awt.geom.Point2D;
51
import java.awt.geom.Rectangle2D;
52
import java.awt.image.BufferedImage;
53
import java.io.File;
54
import java.io.IOException;
55
import java.lang.ref.WeakReference;
56
import java.net.MalformedURLException;
57
import java.net.URL;
58
import java.util.ArrayList;
59
import java.util.HashMap;
60
import java.util.Hashtable;
61
import java.util.Iterator;
62
import java.util.List;
63
import java.util.Map;
64
import java.util.Vector;
65
import java.util.prefs.Preferences;
66

    
67
import javax.print.attribute.PrintRequestAttributeSet;
68
import javax.swing.ImageIcon;
69

    
70
import org.cresques.cts.ICoordTrans;
71
import org.cresques.geo.ViewPortData;
72
import org.cresques.px.Extent;
73
import org.exolab.castor.xml.ValidationException;
74
import org.slf4j.Logger;
75
import org.slf4j.LoggerFactory;
76

    
77
import org.gvsig.andami.PluginServices;
78
import org.gvsig.andami.messages.NotificationManager;
79
import org.gvsig.compat.net.ICancellable;
80
import org.gvsig.fmap.crs.CRSFactory;
81
import org.gvsig.fmap.dal.DataTypes;
82
import org.gvsig.fmap.dal.exception.DataException;
83
import org.gvsig.fmap.dal.exception.ReadException;
84
import org.gvsig.fmap.geom.GeometryLocator;
85
import org.gvsig.fmap.geom.GeometryManager;
86
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
87
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
88
import org.gvsig.fmap.geom.primitive.Envelope;
89
import org.gvsig.fmap.mapcontext.ViewPort;
90
import org.gvsig.fmap.mapcontext.exceptions.ConnectionErrorLayerException;
91
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
92
import org.gvsig.fmap.mapcontext.exceptions.URLLayerException;
93
import org.gvsig.fmap.mapcontext.exceptions.UnsupportedVersionLayerException;
94
import org.gvsig.fmap.mapcontext.layers.FLayer;
95
import org.gvsig.fmap.mapcontext.layers.Tiling;
96
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
97
import org.gvsig.fmap.mapcontext.layers.operations.IHasImageLegend;
98
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
99
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
100
import org.gvsig.fmap.raster.layers.IRasterLayerActions;
101
import org.gvsig.fmap.raster.layers.IStatusRaster;
102
import org.gvsig.raster.dataset.CompositeDataset;
103
import org.gvsig.raster.dataset.IBuffer;
104
import org.gvsig.raster.dataset.MosaicNotValidException;
105
import org.gvsig.raster.dataset.MultiRasterDataset;
106
import org.gvsig.raster.dataset.NotSupportedExtensionException;
107
import org.gvsig.raster.dataset.RasterDriverException;
108
import org.gvsig.raster.grid.GridPalette;
109
import org.gvsig.raster.grid.GridTransparency;
110
import org.gvsig.raster.grid.filter.FilterTypeException;
111
import org.gvsig.raster.grid.filter.RasterFilterList;
112
import org.gvsig.raster.grid.filter.RasterFilterListManager;
113
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
114
import org.gvsig.raster.grid.filter.bands.ColorTableListManager;
115
import org.gvsig.remoteclient.utils.Utilities;
116
import org.gvsig.remoteclient.wms.WMSStatus;
117
import org.gvsig.tools.ToolsLocator;
118
import org.gvsig.tools.dynobject.DynClass;
119
import org.gvsig.tools.dynobject.DynObjectSet;
120
import org.gvsig.tools.dynobject.DynStruct;
121
import org.gvsig.tools.persistence.PersistenceManager;
122
import org.gvsig.tools.persistence.PersistentState;
123
import org.gvsig.tools.persistence.exception.PersistenceException;
124
import org.gvsig.tools.task.Cancellable;
125
import org.gvsig.wmc.WebMapContextTags;
126
import org.gvsig.wmc.XmlBuilder;
127
import org.gvsig.wms.fmap.WMSDriverExceptionType;
128
import org.gvsig.wms.fmap.drivers.wms.FMapWMSDriver;
129
import org.gvsig.wms.fmap.drivers.wms.FMapWMSDriverFactory;
130
import org.gvsig.wms.fmap.drivers.wms.WMSException;
131
import org.gvsig.wms.fmap.layers.WMSLayerNode.FMapWMSStyle;
132

    
133

    
134

    
135

    
136
/**
137
 * FMap's WMS Layer class.
138
 *
139
 * Las capas WMS son tileadas para descargarlas del servidor. Esto quiere decir que
140
 * est?n formadas por multiples ficheros raster. Por esto la fuente de datos raster (IRasterDatasource)
141
 * de la capa FLyrWMS es un objeto de tipo CompositeDataset. Este objeto est? compuesto por un array
142
 * bidimensional de MultiRasterDataset. Cada uno de los MultiRasterDataset corresponde con un tile
143
 * salvado en disco. Estos MultiRasterDataset se crean cada vez que se repinta ya que en WMS a cada
144
 * zoom varian los ficheros fuente. La secuencia de creaci?n de un CompositeDataset ser?a la siguiente:
145
 * <UL>
146
 * <LI>Se hace una petici?n de dibujado por parte del usuario llamando al m?todo draw de FLyrWMS</LI>
147
 * <LI>Se tilea la petici?n</LI>
148
 * <LI>Cada tile se dibuja abriendo una FLyerRaster para ese tile</LI>
149
 * <LI>Si es el primer dibujado se guarda una referencia en la capa WMS a las propiedades de renderizado, orden de bandas,
150
 * transparencia, filtros aplicados, ...</LI>
151
 * <LI>Si no es el primer dibujado se asignan las propiedades de renderizado cuya referencia se guarda en la capa WMS</LI>
152
 * <LI>Se guarda el MultiRasterDataset de cada tile</LI>
153
 * <LI>Al acabar todos los tiles creamos un CompositeDataset con los MultiRasterDataset de todos los tiles</LI>
154
 * <LI>Asignamos a la capa la referencia de las propiedades de renderizado que tenemos almacenadas. De esta forma si hay
155
 * alguna modificaci?n desde el cuadro de propiedades ser? efectiva sobre los tiles que se dibujan.</LI>
156
 * </UL>
157
 *
158
 *
159
 * @author Jaume Dominguez Faus
160
 *
161
 */
162
public class FLyrWMS extends FLyrRasterSE implements IHasImageLegend{
163
        public static final String     PERSISTENT_NAME        = "FLyrWMS_Persistent";
164
        public static final String     PERSISTENT_DESCRIPTION = "FLyrWMS Persistent Definition";
165

    
166
        private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
167
        private static final Logger                 logger = LoggerFactory.getLogger(FLyrWMS.class);
168
        private boolean                                         isPrinting = false;
169
        private boolean                                         mustTileDraw = true;
170
        private boolean                                         mustTilePrint = true;
171
        private final int                                         maxTileDrawWidth = 1023;
172
        private final int                                         maxTileDrawHeight = 1023;
173
        private final int                                         maxTilePrintWidth = 1023;
174
        private final int                                         maxTilePrintHeight = 1023;
175
        private final int                                        minTilePrintWidth = 12;
176
        private final int                                        minTilePrintHeight = 12;
177

    
178
        public URL                                                         host;
179
        public String                                                 m_Format;
180

    
181
        private String                                                 m_SRS;
182
        private String                                                 layerQuery;
183
        private String                                                 infoLayerQuery;
184
        private FMapWMSDriver                                 wms;
185
        private WMSStatus                                         wmsStatus = new WMSStatus();
186
        private boolean                                                wmsTransparency;
187
        private Vector<String>                                styles;
188
        private Vector<String>                                dimensions;
189
        private boolean                                                firstLoad = false;
190
        private Map<String,String>                    onlineResources = new Hashtable<String,String>();
191
        private Dimension                                         fixedSize;
192
        private boolean                                         queryable = true;
193
        private VisualStatus                                visualStatus = new VisualStatus();
194
        /**
195
         * Lista de filtros aplicada en la renderizaci?n
196
         */
197
        private RasterFilterList            filterList = null;
198
        private GridTransparency                        transparency = null;
199
        private int[]                       renderBands = null;
200
        private FLyrRasterSE[]                                layerRaster = null;
201
        private List<String>                filterArguments = null;
202

    
203
        private List<WeakReference<Thread>>        disableUpdateDrawVersion;
204
        private int                         lastNColumns = 0;
205
        private int                         lastNRows = 0;
206

    
207
        //FIXME DynValue???
208
        private Envelope                                        fullEnvelope=null;
209

    
210
        private class MyCancellable implements ICancellable
211
        {
212
                private Cancellable original;
213
                public MyCancellable(Cancellable cancelOriginal)
214
                {
215
                        this.original = cancelOriginal;
216
                }
217
                public boolean isCanceled() {
218
                        if (original == null) {
219
                                return false;
220
                        }
221
                        return original.isCanceled();
222
                }
223
                public Object getID() {
224
                        return this;
225
                }
226

    
227
        }
228

    
229
        public FLyrWMS(){
230
                super();
231
                this.updateDrawVersion();
232
        }
233

    
234
        public FLyrWMS(Map args) throws LoadLayerException{
235
                this.updateDrawVersion();
236
                FMapWMSDriver drv = null;
237
                String host = (String)args.get("host");
238
                String sLayer = (String)args.get("layer");
239
                Rectangle2D fullExtent = (Rectangle2D)args.get("FullExtent");
240
                String sSRS = (String)args.get("SRS");
241
                String sFormat = (String)args.get("Format");
242
                String[] sLayers = sLayer.split(",");
243

    
244
                try {
245
                        this.setHost(new URL(host));
246
                } catch (MalformedURLException e) {
247
                        //e.printStackTrace();
248
                        throw new URLLayerException(getName(),e);
249
                }
250
                try {
251
                        drv = this.getDriver();
252
                } catch (IllegalStateException e) {
253
                        throw new LoadLayerException(getName(),e);
254
                } catch (ValidationException e) {
255
                        throw new LoadLayerException(getName(),e);
256
                } catch (IOException e) {
257
                        throw new ConnectionErrorLayerException(getName(),e);
258
                }
259
                if( sFormat == null || sSRS == null || fullExtent == null ) {
260
                        if (!drv.connect(null)) {
261
                                throw new ConnectionErrorLayerException(getName(),null);
262
                        }
263

    
264
                        WMSLayerNode wmsNode = drv.getLayer(sLayer);
265

    
266
                        if (wmsNode == null){
267
                                throw new LoadLayerException(getName(),null);
268
                        }
269
                        if( sFormat == null ) {
270
                                sFormat = this.getGreatFormat(drv.getFormats());
271
                        }
272
                        // SRS
273
                        Vector allSrs = wmsNode.getAllSrs();
274
                        boolean isSRSSupported = false;
275
                        if( sSRS != null ) {
276
                                for (int i=0; i<allSrs.size() ; i++){
277
                                        if (((String)allSrs.get(i)).compareTo(sSRS) == 0){
278
                                                isSRSSupported = true;
279
                                        }
280
                                }
281
                        }
282

    
283
                        if(!isSRSSupported) {
284
                                for (int i=0; i<allSrs.size() ; i++){
285
                                        if (((String)wmsNode.getAllSrs().get(i)).compareTo("EPSG:4326") == 0){
286
                                                sSRS = (String)wmsNode.getAllSrs().get(i);
287
                                        }
288
                                }
289
                                if (sSRS==null){
290
                                        sSRS = (String)wmsNode.getAllSrs().get(0);
291
                                }
292
                        }
293
                        if( fullExtent == null ) {
294
                                fullExtent = drv.getLayersExtent(sLayers,sSRS);
295
                        }
296
                }
297

    
298

    
299
                this.setFullExtent(fullExtent);
300
                this.setFormat(sFormat);
301
                this.setLayerQuery(sLayer);
302
                this.setInfoLayerQuery("");
303
                this.setSRS(sSRS);
304
                this.setName(sLayer);
305
                this.setOnlineResources(drv.getOnlineResources());
306
                load();
307
        }
308

    
309
        /**
310
         * It choose the best format to load different maps if the server
311
         * supports it. This format could be png, because it supports
312
         * transparency.
313
         * @param formats
314
         * Arraywith all the formats supported by the server
315
         * @return
316
         */
317
        private String getGreatFormat(Vector formats){
318
                for (int i=0 ; i<formats.size() ; i++){
319
                        String format = (String) formats.get(i);
320
                        if (format.equals("image/jpg")){
321
                                return format;
322
                        }
323
                        if (format.equals("image/jpeg")){
324
                                return format;
325
                        }
326
                }
327

    
328
                return (String)formats.get(0);
329
        }
330

    
331
        /**
332
         * Clase que contiene los datos de visualizaci?n de WMS.
333
         * @author Nacho Brodin (brodin_ign@gva.es)
334
         */
335
        private class VisualStatus{
336
                /**
337
                 * Ancho y alto de la imagen o del conjunto de tiles si los tiene. Coincide con
338
                 * el ancho y alto del viewPort
339
                 */
340
                private double                                                minX = 0D;
341
                private double                                                minY = 0D;
342
                private double                                                maxX = 0D;
343
                private double                                                maxY = 0D;
344
                /**
345
                 * Lista de nombre de fichero que componen toda la visualizaci?n.
346
                 */
347
                private String[]                                        fileNames = null;
348

    
349
                public Object clone() {
350
                        VisualStatus s = new VisualStatus();
351
                        s.maxX = maxX;
352
                        s.maxY = maxY;
353
                        s.minX = minX;
354
                        s.minY = minY;
355
                        s.fileNames = new String[fileNames.length];
356
                        for (int i = 0; i < fileNames.length; i++) 
357
                                s.fileNames[i] = fileNames[i];
358
                        return s;
359
                }
360
        }
361

    
362
        @Override
363
        public void loadFromState(PersistentState state)
364
        throws PersistenceException {
365
                super.loadFromState(state);
366

    
367
                this.fullEnvelope = (Envelope) state.get("fullExtent");
368

    
369
                // Host
370
                host = (URL) state.get("host");
371

    
372
                // Part of the query that is not the host, or the
373
                // layer names, or other not listed bellow
374
                infoLayerQuery = state.getString("infoLayerQuery");
375

    
376
                // Part of the query containing the layer names
377
                layerQuery = state.getString("layerQuery");
378

    
379
                // Format
380
                m_Format = state.getString("format");
381

    
382
                // SRS
383
                m_SRS = state.getString("srs");
384

    
385
                // Transparency
386
                if (state.hasValue("wms_transparency")) {
387
                        wmsTransparency = state.getBoolean("wms_transparency");
388
                }
389

    
390
                // Styles
391
                if (state.hasValue("styles")){
392
                        styles = new Vector(state.getList("styles"));
393
                }
394

    
395
                // Dimensions
396
                if (state.hasValue("dimensions")){
397
                        dimensions = new Vector(state.getList("dimensions"));
398
                }
399

    
400
                // OnlineResources
401
                if (state.hasValue("onlineResources")) {
402
                        onlineResources = new Hashtable(state.getMap("onlineResources"));
403
                }
404

    
405
                // Queryable
406
                queryable = true; // let's assume that the layer is queryable by default
407
                if (state.hasValue("queryable")) {
408
                        queryable = state.getBoolean("queryable");
409
                }
410

    
411
                // fixedSize
412
                if (state.hasValue("fixedSize")) {
413
                        fixedSize = (Dimension) state.get("fixedSize");
414
                } else {
415
                        fixedSize = null;
416
                }
417
                firstLoad = true;
418
        }
419

    
420
        @Override
421
        public void saveToState(PersistentState state) throws PersistenceException {
422
                super.saveToState(state);
423

    
424
                state.set("fullEnvelope", this.fullEnvelope);
425

    
426
                // Host
427
                state.set("host", host);
428

    
429
                // Part of the query that is not the host, or the
430
                // layer names, or other not listed bellow
431
                state.set("infoLayerQuery", infoLayerQuery);
432

    
433
                // Part of the query containing the layer names
434
                state.set("layerQuery", layerQuery);
435

    
436
                // Format
437
                state.set("format", m_Format);
438

    
439
                // SRS
440
                state.set("srs", m_SRS);
441

    
442
                // Transparency
443
                state.set("wms_transparency", wmsTransparency);
444

    
445
                // Styles
446
                if (styles!=null){
447
                        state.set("styles", styles);
448
                }
449

    
450
                // Dimensions
451
                if (dimensions!=null){
452
                        state.set("dimensions", dimensions);
453
                }
454

    
455
                // OnlineResources
456
                state.set("onlineResources", onlineResources);
457

    
458
                // Queryable
459
                state.set("queryable", queryable);
460

    
461
                // fixedSize
462
                if (isSizeFixed()) {
463
                        state.set("fixedSize", fixedSize);
464
                }
465
        }
466

    
467
        public static void registerPersistent() {
468
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
469
                DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
470
                if( definition == null ) {
471
                        FLyrRasterSE.registerPersistent();
472
                        definition = manager.addDefinition(
473
                                        FLyrWMS.class,
474
                                        PERSISTENT_NAME,
475
                                        PERSISTENT_DESCRIPTION,
476
                                        null, 
477
                                        null
478
                        );
479
                        definition.extend(
480
                                        (DynClass)ToolsLocator.getPersistenceManager()
481
                                                .getDefinition(FLyrRasterSE.class)
482
                        );
483
        
484
                        definition.addDynFieldObject("fullExtent")
485
                                .setType(DataTypes.ENVELOPE)
486
                                .setMandatory(true);
487
                        definition.addDynFieldURL("host")
488
                                .setMandatory(true);
489
                        definition.addDynFieldString("infoLayerQuery").setMandatory(true);                
490
                        definition.addDynFieldString("layerQuery").setMandatory(true);
491
                        definition.addDynFieldString("format").setMandatory(true);
492
                        definition.addDynFieldString("srs").setMandatory(true);
493
                        definition.addDynFieldBoolean("wms_transparency").setMandatory(true);
494
                        definition.addDynFieldList("styles")
495
                                .setClassOfItems(String.class)
496
                                .setMandatory(false);
497
                        definition.addDynFieldList("dimensions")
498
                                .setClassOfItems(String.class)
499
                                .setMandatory(false);
500
                        definition.addDynFieldMap("onlineResources")
501
                                .setClassOfItems(String.class)
502
                                .setMandatory(true);
503
                        definition.addDynFieldBoolean("queryable").setMandatory(false);
504
                        definition.addDynFieldObject("fixedSize")
505
                                .setClassOfValue(Dimension.class)
506
                                .setMandatory(false);
507
                }
508
        }
509

    
510

    
511
        //        /**
512
        //         * @throws ReadDriverException
513
        //         * @throws LoadLayerException
514
        //         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(com.iver.cit.gvsig.fmap.operations.QueriedPoint)
515
        //         */
516
        //        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancellable)
517
        //                        throws ReadException {
518
        //                XMLItem[] item = new XMLItem[1];
519
        //                try {
520
        //                        if (queryable)         {
521
        //                                //TODO
522
        //                                // check if there are layers which are not queryable
523
        //                                ViewPort viewPort = getMapContext().getViewPort();
524
        //
525
        //                                Point tiledPoint = new Point((int) p.getX() % maxTilePrintWidth, (int) p.getY() % maxTilePrintHeight);
526
        //                                Rectangle rect = new Rectangle(0, 0, viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1);
527
        //                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, rect);
528
        //                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
529
        //                                int nCols = tiles.getNumCols();
530
        //
531
        //                                int col = (int) p.getX() / maxTilePrintWidth;
532
        //                                int row = (int) p.getY() / maxTilePrintHeight;
533
        //                                int tileIndex = (row*nCols) + col;
534
        //
535
        //                                ViewPort vp = tiles.getTileViewPort(viewPort, tileIndex);
536
        //                                wmsStatus.setExtent(this.getRectable2DFromEnvelope(vp
537
        //                                                .getAdjustedExtent()));
538
        //                                wmsStatus.setHeight(vp.getImageHeight());
539
        //                                wmsStatus.setWidth(vp.getImageWidth());
540
        //                                wmsStatus.setOnlineResource((String) onlineResources.get("GetFeatureInfo"));
541
        //
542
        //
543
        //                                wmsStatus.setFormat( m_Format );
544
        //                                wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
545
        //                                wmsStatus.setSrs(m_SRS);
546
        //                                wmsStatus.setStyles(styles);
547
        //                                wmsStatus.setDimensions(dimensions);
548
        //                                wmsStatus.setTransparency(wmsTransparency);
549
        //                                wmsStatus.setSrs(m_SRS);
550
        //                                MyCancellable c = new MyCancellable(cancellable);
551
        //                                try {
552
        //                                        item[0] = new StringXMLItem(new String(getDriver()
553
        //                                                        .getFeatureInfo(wmsStatus, (int) tiledPoint.getX(), (int) tiledPoint.getY(), Integer.MAX_VALUE, c)),this);
554
        //                                } catch (UnsupportedVersionLayerException e) {
555
        //                                        throw new ReadException(FMapWMSDriver.class.getName()
556
        //                                                        + "::" + getName()
557
        //                                                        + " - UnsupportedVersionLayerException", e);
558
        //                                } catch (IllegalStateException e) {
559
        //                                        throw new ReadException(FMapWMSDriver.class.getName()
560
        //                                                        + "::" + getName() + " - IllegalStateException", e);
561
        //                                }
562
        //                                return item;
563
        //                        }
564
        //                        else
565
        //                        {
566
        //                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),this.getName() + " " +
567
        //                                                PluginServices.getText(this,"layer_not_queryable"));
568
        //                                item[0] =  new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><info></info>",this);
569
        //                                return item;
570
        //                                //return null;
571
        //                        }
572
        //                } catch (WMSException  e) {
573
        //                        item[0] = new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
574
        //                        e.getMessage() + "</exception>", this);
575
        //                        return item;
576
        //                } catch (ValidationException e) {
577
        //                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
578
        //                                        + getName() + " - ValidationException", e);
579
        //                } catch (IOException e) {
580
        //                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
581
        //                                        + getName() + " - IOException", e);
582
        //                } catch (NoninvertibleTransformException e) {
583
        //                        NotificationManager.addError("NotinvertibleTransform", e);
584
        //                }
585
        //                return null;
586
        //        }
587

    
588
        /*
589
         *
590
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#draw(java.awt.image.BufferedImage,
591
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
592
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
593
         */
594
        private int callCount; // mess code, represents the amount of times the methods drawFixedSize or drawTile where tried for an extent
595
        private static final int MAX_RETRY_TIMES = 5; // mess code, represents the max amount of retries allowed.
596
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
597
                        Cancellable cancel, double scale) throws ReadException {
598
                callCount = 0; // mess code
599
                lastNColumns = lastNRows = 0;
600

    
601
                enableStopped();
602

    
603
                closeAndFree();
604

    
605
                if (isWithinScale(scale)){
606
                        Point2D p = viewPort.getOffset();
607
                        // p will be (0, 0) when drawing a view or other when painting onto
608
                        // the Layout.
609
                        Envelope vpEnvelope = viewPort.getAdjustedExtent();
610
                        visualStatus.minX = vpEnvelope.getMinimum(0);
611
                        visualStatus.minY = vpEnvelope.getMinimum(1);
612
                        visualStatus.maxX = vpEnvelope.getMaximum(0);
613
                        visualStatus.maxY = vpEnvelope.getMaximum(1);
614

    
615

    
616
                        if (isSizeFixed()) {
617
                                // This condition handles those situations in which the server can
618
                                // only give static extent and resolution maps despite we need
619
                                // a specific BBOX and pixel WIDTH and HEIGHT
620
                                try {
621
                                        visualStatus.fileNames = new String[1];
622
                                        layerRaster = new FLyrRasterSE[1];
623
                                        drawFixedSize(g, viewPort, cancel, scale);
624
                                        if(layerRaster != null && layerRaster[0] != null) {
625
                                                dataset = layerRaster[0].getDataSource();
626
                                                initializeRasterLayer(null, new IBuffer[][]{{layerRaster[0].getRender().getLastRenderBuffer()}});
627
                                                getRender().setLastRenderBuffer(layerRaster[0].getRender().getLastRenderBuffer());
628
                                        }
629
                                } catch (LoadLayerException e) {
630
                                        // TODO Auto-generated catch block
631
                                        e.printStackTrace();
632
                                } 
633

    
634
                        } else {
635
                                if(mustTileDraw){
636
                                        Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth(), viewPort.getImageHeight());
637
                                        Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
638
                                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
639
                                        visualStatus.fileNames = new String[tiles.getNumTiles()];
640
                                        MultiRasterDataset[][] datasets = new MultiRasterDataset[tiles.getNumRows()][tiles.getNumCols()];
641
                                        IBuffer[][] buf = new IBuffer[tiles.getNumRows()][tiles.getNumCols()];
642
                                        layerRaster = new FLyrRasterSE[tiles.getNumTiles()];
643
                                        lastNColumns = tiles.getNumCols();
644
                                        lastNRows = tiles.getNumRows();
645
                                        for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
646
                                                // drawing part
647
                                                try {
648
                                                        ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
649
                                                        boolean painted = drawTile(g, vp, cancel, tileNr, scale, tileNr);
650
                                                        if(        layerRaster != null && 
651
                                                                        layerRaster[tileNr] != null && 
652
                                                                        painted) {
653
                                                                datasets[(int)(tileNr / tiles.getNumCols())][tileNr % tiles.getNumCols()] = (MultiRasterDataset)layerRaster[tileNr].getDataSource().newDataset();
654
                                                                buf[(int)(tileNr / tiles.getNumCols())][tileNr % tiles.getNumCols()] = layerRaster[tileNr].getRender().getLastRenderBuffer();
655
                                                        }
656
                                                } catch (NoninvertibleTransformException e) {
657
                                                        e.printStackTrace();
658
                                                } catch (LoadLayerException e) {
659
                                                        // TODO Auto-generated catch block
660
                                                        e.printStackTrace();
661
                                                }
662
                                        }
663
                                        try {
664
                                                if(datasets != null && datasets[0][0] != null) {
665
                                                        dataset = new CompositeDataset(datasets);
666
                                                        initializeRasterLayer(datasets, buf);
667
                                                        buf = null;
668
                                                }
669
                                        } catch (MosaicNotValidException e) {
670
                                                throw new ReadException(
671
                                                                "No hay continuidad en el mosaico.", e);
672
                                        } catch (LoadLayerException e) {
673
                                                throw new ReadException("Error inicializando la capa.",
674
                                                                e);
675
                                        }
676
                                } else {
677
                                        try {
678
                                                layerRaster = new FLyrRasterSE[1];
679
                                                visualStatus.fileNames = new String[1];
680
                                                drawTile(g, viewPort, cancel, 0, scale, 0);
681
                                                if(layerRaster != null && layerRaster[0] != null) {
682
                                                        dataset = layerRaster[0].getDataSource();
683
                                                        getRender().setLastRenderBuffer(layerRaster[0].getRender().getLastRenderBuffer());
684
                                                        initializeRasterLayer(null, new IBuffer[][]{{layerRaster[0].getRender().getLastRenderBuffer()}});
685
                                                }
686
                                        } catch (LoadLayerException e) {
687
                                                // TODO Auto-generated catch block
688
                                                e.printStackTrace();
689
                                        }
690
                                }
691
                        }
692
                }
693
                disableStopped();
694

    
695
                /*Runtime r = Runtime.getRuntime();
696
                System.err.println("********************WMS**********************");
697
                System.err.println("Memoria Total: " + (r.totalMemory() / 1024) +"KB");
698
                System.err.println("Memoria Usada: " + ((r.totalMemory() - r.freeMemory()) / 1024) +"KB");
699
                System.err.println("Memoria Libre: " + (r.freeMemory() / 1024) +"KB");
700
                System.err.println("Memoria MaxMemory: " + (r.maxMemory() / 1024) +"KB");
701
                System.err.println("*********************************************");*/
702
        }
703

    
704
        /**
705
         * Closes files and releases memory (pointers to null)
706
         */
707
        private void closeAndFree() {
708
                while(readingData != null && readingData.compareTo(Thread.currentThread().toString()) != 0)
709
                        try {
710
                                Thread.sleep(100);
711
                        } catch (InterruptedException e) {
712
                        }
713

    
714
                        if(dataset != null) {
715
                                dataset.close();
716
                                dataset = null;
717
                        }
718

    
719
                        //Cerramos el dataset asociado a la capa si est? abierto.
720
                        if(layerRaster != null) {
721
                                for (int i = 0; i < layerRaster.length; i++) {
722
                                        if(layerRaster[i] != null) {
723
                                                layerRaster[i].setRemoveRasterFlag(true);
724
                                                layerRaster[i].getDataSource().close();
725
                                                layerRaster[i].getRender().free();
726
                                                layerRaster[i].getBufferFactory().free();
727
                                                layerRaster[i] = null;
728
                                        }
729
                                }
730
                        }
731
                        getRender().free();
732
                        System.gc();
733
        }
734

    
735
        /**
736
         * Acciones que se realizan despu?s de asignar la fuente de datos a
737
         * la capa raster.
738
         *
739
         * @throws LoadLayerException
740
         */
741
        private void initializeRasterLayer(MultiRasterDataset[][] datasets, IBuffer[][] buf) throws LoadLayerException {
742
                if(this.filterList != null)
743
                        getRender().setFilterList(filterList);
744
                if(this.transparency != null)
745
                        getRender().setLastTransparency(transparency);
746
                if(this.renderBands != null)
747
                        getRender().setRenderBands(renderBands);
748
                if(datasets != null) {
749
                        String[][] names = new String[datasets.length][datasets[0].length];
750
                        for (int i = 0; i < datasets.length; i++) {
751
                                for (int j = 0; j < datasets[i].length; j++) {
752
                                        if(datasets[i][j] != null)
753
                                                names[i][j] = datasets[i][j].getDataset(0)[0].getFName();
754
                                }
755
                        }
756
                        super.setLoadParams(names);
757
                }
758
                super.init();
759
                if(buf != null && buf[0][0] != null) {
760
                        int drawablesBandCount = layerRaster[0].getDataSource().getBands().getDrawableBandsCount();
761
                        IBuffer buff = null;
762
                        if(dataset instanceof CompositeDataset)
763
                                buff = ((CompositeDataset)dataset).generateBuffer(buf, drawablesBandCount);
764
                        else
765
                                buff = buf[0][0];
766

    
767
                        if(getRender().getLastRenderBuffer() != null)
768
                                getRender().getLastRenderBuffer().free();
769
                        getRender().setLastRenderBuffer(buff);
770
                }
771
        }
772

    
773
        private void drawFixedSize(Graphics2D g, ViewPort vp, Cancellable cancel,
774
                        double scale) throws ReadException, LoadLayerException {
775
                callCount++; // mess code, it is not unusual a wms server to response an error which is completely
776
                // temporal and the response is available if we retry requesting.
777
                //
778

    
779

    
780
                // This is the extent that will be requested
781
                Rectangle2D bBox = getRectable2DFromEnvelope(getFullEnvelope());
782
                MyCancellable c = new MyCancellable(cancel);
783

    
784
                try {
785
                        wmsStatus.setExtent( bBox );
786
                        wmsStatus.setFormat( m_Format );
787
                        wmsStatus.setHeight( fixedSize.height );
788
                        wmsStatus.setWidth( fixedSize.width );
789
                        wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
790
                        wmsStatus.setSrs(m_SRS);
791
                        wmsStatus.setStyles(styles);
792
                        wmsStatus.setDimensions(dimensions);
793
                        wmsStatus.setTransparency(wmsTransparency);
794
                        wmsStatus.setOnlineResource((String) onlineResources.get("GetMap"));
795
                        File f = getDriver().getMap(wmsStatus, c);
796
                        if (f == null) {
797
                                return;
798
                        }
799
                        String nameWorldFile = getWorldFile(f.getPath());
800
                        org.gvsig.andami.Utilities.createTemp(nameWorldFile, this.getDataWorldFile(bBox, fixedSize));
801

    
802
                        IStatusRaster status = getStatus();
803
                        if(status!=null && firstLoad){
804
                                try {
805
                                        status.applyStatus(this);
806
                                } catch (NotSupportedExtensionException e) {
807
                                        throw new ReadException("", e);
808
                                } catch (RasterDriverException e) {
809
                                        throw new ReadException("", e);
810
                                } catch (FilterTypeException e) {
811
                                        throw new ReadException("", e);
812
                                }
813
                                firstLoad = false;
814
                        }
815

    
816
                        // And finally, obtain the extent intersecting the view and the BBox
817
                        // to draw to.
818
                        Rectangle2D extent = new Rectangle2D.Double();
819
                        Envelope vpEnv = vp.getAdjustedExtent();
820
                        Rectangle2D.Double vpExtent = this.getRectable2DFromEnvelope(vpEnv);
821

    
822
                        Rectangle2D.intersect(vpExtent, bBox, extent);
823

    
824
                        ViewPortData vpData = new ViewPortData(
825
                                        vp.getProjection(), new Extent(extent), fixedSize );
826
                        vpData.setMat(vp.getAffineTransform());
827

    
828
                        String filePath = f.getAbsolutePath();
829
                        visualStatus.fileNames[0] = filePath;
830

    
831
                        try {
832
                                rasterProcess(filePath, g, vp, scale, cancel, 0);
833
                                this.updateDrawVersion();
834
                        } catch (FilterTypeException e) {
835
                        }
836
                } catch (ValidationException e) {
837
                        if (!c.isCanceled())
838
                        {
839
                                LoadLayerException exception = new LoadLayerException(getName(),e);
840
                                throw exception;
841
                        }
842
                } catch (IOException e) {
843
                        if (!c.isCanceled()) {
844
                                if (callCount<MAX_RETRY_TIMES) { // mess code
845
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
846
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
847
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
848
                                        drawFixedSize(g, vp, cancel, scale); // mess code
849
                                } // mess code
850
                        }
851

    
852
                        if (callCount == 1) { // mess code
853
                                //                                ConnectionErrorExceptionType type = new ConnectionErrorExceptionType();
854
                                //                                        type.setLayerName(getName());
855
                                //                                        try {
856
                                //                                                type.setDriverName("WMS Driver");
857
                                //                                        } catch (Exception e1) {
858
                                //                                        }
859
                                //                                        type.setHost(host);
860
                                throw new ConnectionErrorLayerException(getName(),e);
861
                        } // mess code
862

    
863
                } catch (WMSException e) {
864
                        if (!c.isCanceled()) {
865
                                if (callCount<MAX_RETRY_TIMES) { // mess code
866
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
867
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
868
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
869
                                        drawFixedSize(g, vp, cancel, scale); // mess code
870
                                } // mess code
871
                                if (callCount == 1) { // mess code
872
                                        if (!isPrinting) {
873
                                                this.setVisible(false);
874
                                        }
875
                                        throw new LoadLayerException(getName(),e);
876

    
877

    
878
                                } // mess code
879
                        }
880
                }
881
                callCount--; // mess code
882
        }
883

    
884
        /**
885
         * Carga y dibuja el raster usando la librer?a
886
         *
887
         * @param filePath
888
         *            Ruta al fichero en disco
889
         * @param g
890
         *            Graphics2D
891
         * @param vp
892
         *            ViewPort
893
         * @param scale
894
         *            Escala para el draw
895
         * @param cancel
896
         *            Cancelaci?n para el draw
897
         * @throws ReadException
898
         * @throws LoadLayerException
899
         * @throws ReadException 
900
         */
901
        private void rasterProcess(String filePath, Graphics2D g, ViewPort vp, double scale, Cancellable cancel, int nLyr) throws LoadLayerException, FilterTypeException, ReadException {
902
                //Cargamos el dataset con el raster de disco.
903
                layerRaster[nLyr] = FLyrRasterSE.createLayer("", filePath, vp.getProjection());
904
                //layerRaster[nLyr].getRender().setBufferFactory(layerRaster[nLyr].getBufferFactory());
905
                layerRaster[nLyr].setNoDataValue(getNoDataValue());
906
                layerRaster[nLyr].setNoDataType(getNoDataType());
907

    
908
                //Obtenemos la tabla de color del raster abierto ya que se le va a sustituir la lista
909
                //de filtros y el de tabla de color no queremos sustituirlo.
910
                RasterFilterList rasterFilterList = layerRaster[nLyr].getRender().getFilterList();
911
                ColorTableFilter ct = (ColorTableFilter)rasterFilterList.getFilterByBaseClass(ColorTableFilter.class);
912
                Object param = null;
913
                if(ct != null)
914
                        param = ct.getParam("colorTable");
915

    
916
                //En caso de cargar un proyecto con XMLEntity se crean los filtros
917
                if(filterArguments != null) {
918
                        RasterFilterList fl = new RasterFilterList();
919
                        fl.addEnvParam("IStatistics", layerRaster[nLyr].getDataSource().getStatistics());
920
                        fl.addEnvParam("MultiRasterDataset", layerRaster[nLyr].getDataSource());
921
                        fl.setInitDataType(layerRaster[nLyr].getDataType()[0]);
922
                        RasterFilterListManager filterListManager = new RasterFilterListManager(fl);
923
                        filterListManager.createFilterListFromStrings((ArrayList) filterArguments);
924
                        filterArguments = null;
925
                        filterList = fl;
926
                }
927

    
928
                //Como el raster se carga a cada zoom el render se crea nuevamente y la lista de
929
                //filtros siempre estar? vacia a cada visualizaci?n. Para evitarlo tenemos que
930
                //guardar la lista de filtro aplicada en la visualizaci?n anterior.
931
                if(this.filterList != null) {
932
                        this.disableUpdateDrawVersion();
933
                        //Si ten?a tabla de color le asignamos la original
934
                        if(param != null && param instanceof GridPalette) {
935
                                this.filterList.remove(ColorTableFilter.class);
936
                                RasterFilterListManager filterManager = new RasterFilterListManager(filterList);
937
                                ColorTableListManager ctm = new ColorTableListManager(filterManager);
938
                                ctm.addColorTableFilter((GridPalette)param);
939
                                filterList.move(ColorTableFilter.class, 0);
940
                                filterList.controlTypes();
941
                        }
942
                        layerRaster[nLyr].getRender().setFilterList(filterList);
943
                        this.enableUpdateDrawVersion();
944
                }
945
                if(this.transparency != null)
946
                        layerRaster[nLyr].getRender().setLastTransparency(transparency);
947
                if(this.renderBands != null)
948
                        layerRaster[nLyr].getRender().setRenderBands(renderBands);
949

    
950
                //Dibujamos
951
                disableUpdateDrawVersion();
952
                layerRaster[nLyr].draw(null, g, vp, cancel, scale);
953
                enableUpdateDrawVersion();
954

    
955
                //La primera vez asignamos la lista de filtros asociada al renderizador. Guardamos una referencia
956
                //en esta clase para que a cada zoom no se pierda.
957
                if (this.filterList == null)
958
                        filterList = layerRaster[nLyr].getRender().getFilterList();
959
                if (this.transparency == null)
960
                        transparency = layerRaster[nLyr].getRender().getLastTransparency();
961
                if (this.renderBands == null)
962
                        renderBands = layerRaster[nLyr].getRender().getRenderBands();
963

    
964
        }
965

    
966
        /*
967
         * (non-Javadoc)
968
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderFilterList()
969
         */
970
        public RasterFilterList getRenderFilterList(){
971
                return (filterList != null) ? filterList : getRender().getFilterList();
972
        }
973

    
974
        /*
975
         * (non-Javadoc)
976
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderFilterList(org.gvsig.raster.grid.filter.RasterFilterList)
977
         */
978
        public void setRenderFilterList(RasterFilterList filterList) {
979
                if (filterList == this.filterList){
980
                        return;
981
                }
982
                this.filterList = filterList;
983
                this.updateDrawVersion();
984
                super.getRender().setFilterList(filterList);
985
        }
986

    
987
        /*
988
         * (non-Javadoc)
989
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderTransparency()
990
         */
991
        public GridTransparency getRenderTransparency() {
992
                return (transparency != null) ? transparency : getRender().getLastTransparency();
993
        }
994

    
995
        /*
996
         * (non-Javadoc)
997
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getRenderBands()
998
         */
999
        public int[] getRenderBands() {
1000
                return (renderBands != null) ? renderBands : getRender().getRenderBands();
1001
        }
1002

    
1003
        /*
1004
         * (non-Javadoc)
1005
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderBands(int[])
1006
         */
1007
        public void setRenderBands(int[] renderBands) {
1008
                //TODO: Comprobar si hay cambios
1009
                this.renderBands = renderBands;
1010
                this.updateDrawVersion();
1011
                getRender().setRenderBands(renderBands);
1012
        }
1013

    
1014
        /**
1015
         * This is the method used to draw a tile in a WMS mosaic layer.
1016
         *
1017
         * @throws LoadLayerException
1018
         * @throws ReadException
1019
         * @return true when a tile has been painted
1020
         */
1021
        private boolean drawTile(Graphics2D g, ViewPort vp, Cancellable cancel,
1022
                        int tile, double scale, int nLyr) throws LoadLayerException, ReadException {
1023
                callCount++;
1024
                // Compute the query geometry
1025
                // 1. Check if it is within borders
1026
                Envelope envelope = getFullEnvelope();
1027
                Envelope vpEnv = vp.getAdjustedExtent();
1028
                if (!vpEnv.intersects(envelope)) {
1029
                        return false;
1030
                }
1031

    
1032

    
1033
                // 2. Compute extent to be requested.
1034
                Rectangle2D bBox = new Rectangle2D.Double();
1035
                Rectangle2D.intersect(getRectable2DFromEnvelope(vpEnv),
1036
                                getRectable2DFromEnvelope(envelope), bBox);
1037

    
1038
                // 3. Compute size in pixels
1039
                double scalex = vp.getAffineTransform().getScaleX();
1040
                double scaley = vp.getAffineTransform().getScaleY();
1041
                int wImg = (int) Math.ceil(Math.abs(bBox.getWidth() * scalex) + 1);
1042
                int hImg = (int) Math.ceil(Math.abs(bBox.getHeight() * scaley) + 1);
1043

    
1044
                Dimension sz = new Dimension(wImg, hImg);
1045

    
1046
                if ((wImg <= 0) || (hImg <= 0)) {
1047
                        return false;
1048
                }
1049
                MyCancellable c = new MyCancellable(cancel);
1050

    
1051
                try {
1052
                        sz = new Dimension(wImg, hImg);
1053

    
1054

    
1055
                        wmsStatus.setExtent( bBox );
1056
                        wmsStatus.setFormat(m_Format);
1057
                        wmsStatus.setHeight( hImg );
1058
                        wmsStatus.setWidth( wImg );
1059
                        wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
1060
                        wmsStatus.setSrs(m_SRS);
1061
                        wmsStatus.setStyles(styles);
1062
                        wmsStatus.setDimensions(dimensions);
1063
                        wmsStatus.setTransparency(wmsTransparency);
1064
                        wmsStatus.setOnlineResource((String) onlineResources.get("GetMap"));
1065

    
1066
                        // begin patch; Avoid to request too small tiles.
1067
                        // This generally occurs when printing
1068

    
1069
                        if (wImg < minTilePrintWidth) {
1070
                                double wScale = (double) minTilePrintWidth / wImg;
1071
                                wmsStatus.setWidth(minTilePrintWidth);
1072
                                Rectangle2D sExtent = wmsStatus.getExtent();
1073
                                Point2D initialPoint = new Point2D.Double(sExtent.getX(), sExtent.getY());
1074
                                sExtent.setRect(sExtent.getX()*wScale, sExtent.getY(), sExtent.getWidth()*wScale, sExtent.getHeight());
1075
                                if (!bBox.contains(initialPoint)) {
1076
                                        sExtent.setRect(sExtent.getX() - initialPoint.getX(), sExtent.getY(), sExtent.getWidth(), sExtent.getHeight());
1077
                                }
1078
                        }
1079

    
1080
                        if (hImg < minTilePrintHeight) {
1081
                                double hScale = (double) minTilePrintHeight / hImg;
1082
                                wmsStatus.setHeight(minTilePrintHeight);
1083
                                Rectangle2D sExtent = wmsStatus.getExtent();
1084
                                Point2D initialPoint = new Point2D.Double(sExtent.getX(), sExtent.getY());
1085
                                sExtent.setRect(sExtent.getX(), sExtent.getY()*hScale, sExtent.getWidth(), sExtent.getHeight()*hScale);
1086
                                if (!bBox.contains(initialPoint)) {
1087
                                        sExtent.setRect(sExtent.getX(), sExtent.getY() - initialPoint.getY(), sExtent.getWidth(), sExtent.getHeight());
1088
                                }
1089
                        }
1090

    
1091
                        // end patch
1092
                        File f = getDriver().getMap(wmsStatus, c);
1093
                        if (f == null) {
1094
                                return false;
1095
                        }
1096
                        String nameWordFile = getWorldFile(f.getPath());
1097
                        org.gvsig.andami.Utilities.createTemp(nameWordFile, this.getDataWorldFile(bBox, sz));
1098

    
1099
                        ViewPortData vpData = new ViewPortData(
1100
                                        vp.getProjection(), new Extent(bBox), sz );
1101
                        vpData.setMat(vp.getAffineTransform());
1102

    
1103
                        String filePath = f.getAbsolutePath();
1104
                        visualStatus.fileNames[tile] = filePath;
1105
                        try {
1106
                                rasterProcess(filePath, g, vp, scale, cancel, nLyr);
1107
                                //                                this.updateDrawVersion();
1108
                        } catch (FilterTypeException e) {
1109
                        }
1110

    
1111
                } catch (ValidationException e) {
1112
                        if (!c.isCanceled())
1113
                        {
1114
                                LoadLayerException exception = new LoadLayerException(getName(),e);
1115
                                throw exception;
1116
                        }
1117
                } catch (IOException e) {
1118
                        if (!c.isCanceled()){
1119
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1120
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
1121
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1122
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1123

    
1124
                                        drawFixedSize(g, vp, cancel, scale); // mess code
1125
                                } // mess code
1126
                        }
1127
                        if (callCount == 1) { // mess code
1128
                                throw new ConnectionErrorLayerException(getName(),e);
1129
                        }//if
1130
                } catch (WMSException e) {
1131
                        if (!c.isCanceled()) {
1132
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1133
                                        logger.warn("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n"); // mess code
1134
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1135
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1136
                                        drawTile(g, vp, cancel, tile, scale, nLyr);
1137
                                } // mess code
1138
                                if (callCount == 1) { // mess code
1139
                                        //                azabala                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), e.getMessage());
1140
                                        WMSDriverExceptionType type = new WMSDriverExceptionType();
1141
                                        type.setLayerName(getName());
1142
                                        try {
1143
                                                type.setDriverName("WMS Driver");
1144
                                        } catch (Exception e1) {
1145
                                        }
1146
                                        type.setWcsStatus(this.wmsStatus);
1147
                                        if (!isPrinting) {
1148
                                                this.setVisible(false);
1149
                                        }
1150
                                        throw new LoadLayerException(getName(),e);
1151

    
1152

    
1153
                                } //if
1154
                        }//if
1155
                }//catch
1156
                callCount--;
1157
                return true;
1158
        }
1159

    
1160
        /**
1161
         * Gets the georeferencing file name form a raster file
1162
         * @param file
1163
         * a raster file
1164
         * @return
1165
         * a georeferencing file
1166
         */
1167
        private String getWorldFile(String file){                
1168
                String worldFile = file;
1169
                int index = file.lastIndexOf(".");
1170
                if (index > 0){                        
1171
                        worldFile = file.substring(0, index) + getExtensionWorldFile();
1172
                }
1173
                return worldFile;
1174
        }        
1175
        
1176
        /**
1177
         * Obtiene la extensi?n del fichero de georreferenciaci?n
1178
         * @return String con la extensi?n del fichero de georreferenciaci?n dependiendo
1179
         * del valor del formato obtenido del servidor. Por defecto asignaremos un .wld
1180
         */
1181
        private String getExtensionWorldFile(){
1182
                String extWorldFile = ".wld";
1183
                if(m_Format.equals("image/tif") || m_Format.equals("image/tiff")) {
1184
                        extWorldFile = ".tfw";
1185
                }
1186
                return extWorldFile;
1187
        }
1188

    
1189
        /**
1190
         * Calcula el contenido del fichero de georreferenciaci?n de una imagen.
1191
         * @param bBox Tama?o y posici?n de la imagen (en coordenadas de usuario)
1192
         * @param sz Tama?o de la imagen en pixeles.
1193
         * @return el 'WorldFile', como String.
1194
         * @throws IOException
1195
         */
1196
        public String getDataWorldFile(Rectangle2D bBox, Dimension sz) throws IOException {
1197
                StringBuffer data = new StringBuffer();
1198
                data.append((bBox.getMaxX() - bBox.getMinX())/(sz.getWidth() - 1)+"\n");
1199
                data.append("0.0\n");
1200
                data.append("0.0\n");
1201
                data.append("-"+(bBox.getMaxY() - bBox.getMinY())/(sz.getHeight() - 1)+"\n");
1202
                data.append(""+bBox.getMinX()+"\n");
1203
                data.append(""+bBox.getMaxY()+"\n");
1204
                return data.toString();
1205
        }
1206

    
1207
        /**
1208
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
1209
         *                 com.iver.cit.gvsig.fmap.ViewPort,
1210
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
1211
         */
1212
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties)
1213
        throws ReadException {
1214

    
1215
                closeAndFree();
1216

    
1217
                if (isVisible() && isWithinScale(scale)){
1218
                        isPrinting = true;
1219
                        if (!mustTilePrint) {
1220
                                draw(null, g, viewPort, cancel,scale);
1221
                        } else {
1222
                                // Para no pedir imagenes demasiado grandes, vamos
1223
                                // a hacer lo mismo que hace EcwFile: chunkear.
1224
                                // Llamamos a drawView con cuadraditos m?s peque?os
1225
                                // del BufferedImage ni caso, cuando se imprime viene con null
1226

    
1227
                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
1228
                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
1229
                                visualStatus.fileNames = new String[tiles.getNumTiles()];
1230
                                layerRaster = new FLyrRasterSE[tiles.getNumTiles()];
1231
                                for (int tileNr=0; tileNr < tiles.getNumTiles(); tileNr++) {
1232
                                        // Parte que dibuja
1233
                                        try {
1234
                                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
1235
                                                drawTile(g, vp, cancel, tileNr, scale, tileNr);
1236
                                        } catch (NoninvertibleTransformException e) {
1237
                                                e.printStackTrace();
1238
                                        } catch (LoadLayerException e) {
1239
                                                // TODO Auto-generated catch block
1240
                                                e.printStackTrace();
1241
                                        }
1242
                                }
1243
                        }
1244
                        isPrinting = false;
1245
                }
1246
        }
1247

    
1248
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
1249
                        double scale) throws ReadException {
1250
                draw(null, g, viewPort, cancel,scale);
1251
        }
1252

    
1253
        /**
1254
         * Devuelve el FMapWMSDriver.
1255
         *
1256
         * @return FMapWMSDriver
1257
         *
1258
         * @throws IllegalStateException
1259
         * @throws ValidationException
1260
         * @throws UnsupportedVersionLayerException
1261
         * @throws IOException
1262
         */
1263
        public FMapWMSDriver getDriver()
1264
        throws IllegalStateException, ValidationException,
1265
        UnsupportedVersionLayerException, IOException {
1266
                return FMapWMSDriverFactory.getFMapDriverForURL(host);
1267
        }
1268

    
1269
        /**
1270
         * Devuelve el FMapWMSDriver.
1271
         *
1272
         * @return FMapWMSDriver
1273
         *
1274
         * @throws IllegalStateException
1275
         * @throws ValidationException
1276
         * @throws UnsupportedVersionLayerException
1277
         * @throws IOException
1278
         */
1279
        public void setDriver(FMapWMSDriver drv) {
1280
                //TODO: Comprobar cambio
1281
                wms = drv;
1282
                this.updateDrawVersion();
1283
        }
1284

    
1285
        /**
1286
         * Devuelve el URL.
1287
         *
1288
         * @return URL.
1289
         */
1290
        public URL getHost() {
1291
                return host;
1292
        }
1293

    
1294
        /**
1295
         * Inserta el URL.
1296
         *
1297
         * @param host URL.
1298
         */
1299
        public void setHost(URL host) {
1300
                if (this.host == host){
1301
                        return;
1302
                }
1303
                if (this.host != null && this.host.equals(host)) {
1304
                        return;
1305
                }
1306

    
1307
                this.host = host;
1308
                this.updateDrawVersion();
1309
        }
1310

    
1311
        /**
1312
         * Devuelve la informaci?n de la consulta.
1313
         *
1314
         * @return String.
1315
         */
1316
        public String getInfoLayerQuery() {
1317
                return infoLayerQuery;
1318
        }
1319

    
1320
        /**
1321
         * Inserta la informaci?n de la consulta.
1322
         *
1323
         * @param infoLayerQuery String.
1324
         */
1325
        public void setInfoLayerQuery(String infoLayerQuery) {
1326
                this.infoLayerQuery = infoLayerQuery;
1327
        }
1328

    
1329
        /**
1330
         * Devuelve la consulta.
1331
         *
1332
         * @return String.
1333
         */
1334
        public String getLayerQuery() {
1335
                return layerQuery;
1336
        }
1337

    
1338
        /**
1339
         * Inserta la consulta.
1340
         *
1341
         * @param layerQuery consulta.
1342
         */
1343
        public void setLayerQuery(String layerQuery) {
1344
                if (this.layerQuery == layerQuery){
1345
                        return;
1346
                }
1347
                if (this.layerQuery != null && this.layerQuery.equals(layerQuery)){
1348
                        return;
1349
                }
1350

    
1351
                this.layerQuery = layerQuery;
1352
                this.updateDrawVersion();
1353
        }
1354

    
1355
        /**
1356
         * Devuelve el formato.
1357
         *
1358
         * @return Formato.
1359
         */
1360
        public String getFormat() {
1361
                return m_Format;
1362
        }
1363

    
1364
        /**
1365
         * Inserta el formato.
1366
         *
1367
         * @param format Formato.
1368
         */
1369
        public void setFormat(String format) {
1370
                if (this.m_Format == format){
1371
                        return;
1372
                }
1373
                if (this.m_Format != null && this.m_Format.equals(format)){
1374
                        return;
1375
                }
1376
                m_Format = format;
1377
                this.updateDrawVersion();
1378
        }
1379

    
1380
        /**
1381
         * Devuelve el SRS.
1382
         *
1383
         * @return SRS.
1384
         */
1385
        public String getSRS() {
1386
                return m_SRS;
1387
        }
1388

    
1389
        /**
1390
         * Inserta el SRS.
1391
         *
1392
         * @param m_srs SRS.
1393
         */
1394
        public void setSRS(String m_srs) {
1395
                if (m_SRS == m_srs){
1396
                        return;
1397
                }
1398
                if (m_SRS != null && m_SRS.equals(m_srs)){
1399
                        return;
1400
                }
1401
                m_SRS = m_srs;
1402
                this.updateDrawVersion();
1403
                setProjection(CRSFactory.getCRS(getSRS()));
1404
        }
1405

    
1406
        /**
1407
         * Inserta la extensi?n total de la capa.
1408
         *
1409
         * @param fullExtent
1410
         *            Rect?ngulo.
1411
         * @deprecated
1412
         */
1413
        public void setFullExtent(Rectangle2D fullExtent) {
1414
                this.setFullEnvelope(this.getEnvelopeFromRectable2D(fullExtent));
1415
        }
1416

    
1417
        /**
1418
         * Inserta la extensi?n total de la capa en la proyeccion original.
1419
         *
1420
         * @param fullExtent
1421
         *            Rect?ngulo.
1422
         */
1423
        public void setFullEnvelope(Envelope envelope) {
1424
                Envelope cur = this.getFullEnvelope();
1425
                if (cur == envelope) {
1426
                        return;
1427
                }
1428
                if (cur != null && cur.equals(envelope)) {
1429
                        return;
1430
                }
1431

    
1432
                this.fullEnvelope = envelope;
1433
                this.updateDrawVersion();
1434
        }
1435

    
1436

    
1437

    
1438
        public HashMap getProperties() {
1439
                HashMap info = new HashMap();
1440
                String[] layerNames = getLayerQuery().split(",");
1441
                Vector layers = new Vector(layerNames.length);
1442
                try {
1443
                        if(getDriver().connect(null)){
1444
                                for (int i = 0; i < layerNames.length; i++) {
1445
                                        layers.add(i, getDriver().getLayer(layerNames[i]));
1446
                                }
1447
                                info.put("name", getName());
1448
                                info.put("selectedLayers", layers);
1449
                                info.put("host", getHost());
1450
                                info.put("srs", getSRS());
1451
                                info.put("format", getFormat());
1452
                                info.put("wmsTransparency", new Boolean(wmsTransparency));
1453
                                info.put("styles", styles);
1454
                                info.put("dimensions", dimensions);
1455
                                info.put("fixedSize", fixedSize);
1456
                                return info;
1457
                        }
1458
                } catch (Exception e) {
1459
                        e.printStackTrace();
1460
                }
1461
                return null;
1462
        }
1463

    
1464
        public double getMaxX() {
1465
                return visualStatus.maxX;
1466
        }
1467

    
1468
        public double getMaxY() {
1469
                return visualStatus.maxY;
1470
        }
1471

    
1472
        public double getMinX() {
1473
                return visualStatus.minX;
1474
        }
1475

    
1476
        public double getMinY() {
1477
                return visualStatus.minY;
1478
        }
1479

    
1480
        /**
1481
         * @return Returns the wmsTransparency.
1482
         */
1483
        public boolean isWmsTransparent() {
1484
                return wmsTransparency;
1485
        }
1486

    
1487
        /**
1488
         * @param wmsTransparency The wmsTransparency to set.
1489
         */
1490
        public void setWmsTransparency(boolean wmsTransparency) {
1491
                if (this.wmsTransparency == wmsTransparency){
1492
                        return;
1493
                }
1494
                this.wmsTransparency = wmsTransparency;
1495
                this.updateDrawVersion();
1496
        }
1497

    
1498
        /**
1499
         * @param styles
1500
         */
1501
        public void setStyles(Vector styles) {
1502
                if (this.styles == styles){
1503
                        return;
1504
                }
1505
                if (this.styles != null && styles != null ){
1506
                        if (this.styles.containsAll(styles) && this.styles.size() ==styles.size()){
1507
                                return;
1508
                        }
1509
                }
1510
                this.styles = styles;
1511
                this.updateDrawVersion();
1512
        }
1513

    
1514
        /**
1515
         * Sets the dimension vector that is a list of key-value pairs containing
1516
         * the name of the dimension and the value for it
1517
         * @param dimensions
1518
         */
1519
        public void setDimensions(Vector dimensions) {
1520
                if (this.dimensions == dimensions){
1521
                        return;
1522
                }
1523
                if (this.dimensions != null && dimensions != null ){
1524
                        if (this.dimensions.containsAll(dimensions) && this.dimensions.size() ==dimensions.size()){
1525
                                return;
1526
                        }
1527
                }
1528
                this.dimensions = dimensions;
1529
                this.updateDrawVersion();
1530
        }
1531

    
1532
        /**
1533
         * Sets the set of URLs that should be accessed for each operation performed
1534
         * to the server.
1535
         *
1536
         * @param onlineResources
1537
         */
1538
        public void setOnlineResources(Hashtable onlineResources) {
1539
                if (this.onlineResources == onlineResources){
1540
                        return;
1541
                }
1542
                if (this.onlineResources != null && this.onlineResources.equals(onlineResources)){
1543
                        return;
1544
                }
1545

    
1546
                this.onlineResources = onlineResources;
1547
                this.updateDrawVersion();
1548
        }
1549

    
1550
        /**
1551
         * Gets the URL that should be accessed for an operation performed
1552
         * to the server.
1553
         *
1554
         * @param onlineResources
1555
         */
1556
        public String getOnlineResource(String operation) {
1557
                return ((String) onlineResources.get(operation));
1558
        }
1559

    
1560
        /**
1561
         * When a server is not fully featured and it only can serve constant map
1562
         * sizes this value must be set. It expresses the size in pixels (width, height)
1563
         * that the map will be requested.
1564
         * @param Dimension sz
1565
         */
1566
        public void setFixedSize(Dimension sz) {
1567
                if (this.fixedSize == sz){
1568
                        return;
1569
                }
1570
                if (this.fixedSize != null && this.fixedSize.equals(sz)){
1571
                        return;
1572
                }
1573
                fixedSize = sz;
1574
                this.updateDrawVersion();
1575
        }
1576

    
1577
        /**
1578
         * Tells whether if this layer must deal with the server with the constant-size
1579
         * limitations or not.
1580
         * @return boolean.
1581
         */
1582
        private boolean isSizeFixed() {
1583
                return fixedSize != null && fixedSize.getWidth() > 0 && fixedSize.getHeight() > 0;
1584
        }
1585

    
1586
        /**
1587
         * If it is true, this layer accepts GetFeatureInfo operations. This WMS operations
1588
         * maps to FMap's infoByPoint(p) operation.
1589
         * @param b
1590
         */
1591
        public void setQueryable(boolean b) {
1592
                queryable = b;
1593
        }
1594

    
1595
        /**
1596
         * Creates the part of a OGC's MapContext document that would describe this
1597
         * layer(s).
1598
         * @param version, The desired version of the resulting document. (1.1.0)
1599
         * @return String containing the xml.
1600
         * @throws UnsupportedVersionLayerException
1601
         */
1602
        public String toMapContext(String mapContextVersion) {
1603
                XmlBuilder xml = new XmlBuilder();
1604
                FMapWMSDriver drv;
1605
                try {
1606
                        drv = getDriver();
1607
                } catch (Exception e) {
1608
                        return xml.toString();
1609
                }
1610
                String[] layerNames = getLayerQuery().split(",");
1611
                String[] styleNames = (String[]) styles.toArray(new String[0]);
1612
                for (int i = 0; i < layerNames.length; i++) {
1613
                        WMSLayerNode layer = drv.getLayer(layerNames[i]);
1614
                        HashMap xmlAttrs = new HashMap();
1615

    
1616
                        // <Layer>
1617
                        xmlAttrs.put(WebMapContextTags.HIDDEN, !isVisible()+"");
1618
                        xmlAttrs.put(WebMapContextTags.QUERYABLE, queryable+"");
1619
                        xml.openTag(WebMapContextTags.LAYER, xmlAttrs);
1620
                        xmlAttrs.clear();
1621
                        if (mapContextVersion.equals("1.1.0") || mapContextVersion.equals("1.0.0")) {
1622
                                // <Server>
1623
                                xmlAttrs.put(WebMapContextTags.SERVICE, WebMapContextTags.WMS);
1624
                                xmlAttrs.put(WebMapContextTags.VERSION, drv.getVersion());
1625
                                xmlAttrs.put(WebMapContextTags.SERVER_TITLE, drv.getServiceTitle());
1626
                                xml.openTag(WebMapContextTags.SERVER, xmlAttrs);
1627
                                xmlAttrs.clear();
1628

    
1629
                                // <OnlineResource>
1630
                                xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
1631
                                xmlAttrs.put(WebMapContextTags.XLINK_HREF, getHost().toString());
1632
                                xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
1633
                                xmlAttrs.clear();
1634
                                // </OnlineResource>
1635

    
1636
                                xml.closeTag();
1637
                                // </Server>
1638

    
1639
                                // <Name>
1640
                                xml.writeTag(WebMapContextTags.NAME, layer.getName().trim());
1641
                                // </Name>
1642

    
1643
                                // <Title>
1644
                                xml.writeTag(WebMapContextTags.TITLE, layer.getTitle().trim());
1645
                                //?xml.writeTag(WebMapContextTags.TITLE, getName().trim());
1646
                                // </Title>
1647

    
1648
                                // <Abstract>
1649
                                if (layer.getAbstract() != null) {
1650
                                        xml.writeTag(WebMapContextTags.ABSTRACT, layer.getAbstract());
1651
                                        // </Abstract>
1652
                                }
1653

    
1654
                                // <SRS> (a list of available SRS for the enclosing layer)
1655
                                String[] strings = (String[]) layer.getAllSrs().toArray(new String[0]);
1656
                                String mySRS = strings[0];
1657
                                for (int j = 1; j < strings.length; j++) {
1658
                                        mySRS += ","+strings[j];
1659
                                }
1660
                                xml.writeTag(WebMapContextTags.SRS, mySRS);
1661
                                // </SRS>
1662

    
1663
                                // <FormatList>
1664
                                xml.openTag(WebMapContextTags.FORMAT_LIST);
1665
                                strings = (String[]) drv.getFormats().toArray(new String[0]);
1666
                                for (int j = 0; j < strings.length; j++) {
1667
                                        // <Format>
1668
                                        String str = strings[j].trim();
1669
                                        if (str.equals(getFormat())) {
1670
                                                xml.writeTag(WebMapContextTags.FORMAT, str, WebMapContextTags.CURRENT, "1");
1671
                                        } else {
1672
                                                xml.writeTag(WebMapContextTags.FORMAT, str);
1673
                                                // </Format>
1674
                                        }
1675
                                }
1676
                                xml.closeTag();
1677
                                // </FormatList>
1678

    
1679
                                // <StyleList>
1680
                                xml.openTag(WebMapContextTags.STYLE_LIST);
1681

    
1682
                                if (layer.getStyles().size()>0) {
1683
                                        for (int j = 0; j < layer.getStyles().size(); j++) {
1684
                                                // <Style>
1685
                                                FMapWMSStyle st = (FMapWMSStyle) layer.getStyles().get(j);
1686
                                                if (st.name.equals(styleNames[i])) {
1687
                                                        xmlAttrs.put(WebMapContextTags.CURRENT, "1");
1688
                                                }
1689
                                                xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
1690
                                                xmlAttrs.clear();
1691

    
1692
                                                // <Name>
1693
                                                xml.writeTag(WebMapContextTags.NAME, st.name);
1694
                                                // </Name>
1695

    
1696
                                                // <Title>
1697
                                                xml.writeTag(WebMapContextTags.TITLE, st.title);
1698
                                                // </Title>
1699

    
1700
                                                // <LegendURL width="180" format="image/gif" height="50">
1701
                                                // <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
1702
                                                // </OnlineResource>
1703
                                                // </LegendURL>
1704
                                                xml.closeTag();
1705
                                                // </Style>
1706

    
1707
                                        }
1708

    
1709
                                } else {
1710
                                        // Create fake style (for compatibility issues)
1711
                                        xmlAttrs.put(WebMapContextTags.CURRENT, "1");
1712
                                        // <Style>
1713
                                        xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
1714
                                        xmlAttrs.clear();
1715
                                        // <Name>
1716
                                        xml.writeTag(WebMapContextTags.NAME, "default");
1717
                                        // </Name>
1718

    
1719
                                        // <Title>
1720
                                        xml.writeTag(WebMapContextTags.TITLE, "default");
1721
                                        // </Title>
1722

    
1723
                                        //                                                        // <LegendURL width="180" format="image/gif" height="50">
1724
                                        //                                                        xmlAttrs.put(WebMapContextTags.WIDTH, "0");
1725
                                        //                                                        xmlAttrs.put(WebMapContextTags.HEIGHT, "0");
1726
                                        //                                                        xmlAttrs.put(WebMapContextTags.FORMAT.toLowerCase(), "image/gif");
1727
                                        //                                                        xml.openTag(WebMapContextTags.LEGEND_URL, xmlAttrs);
1728
                                        //                                                        xmlAttrs.clear();
1729
                                        //                                                                // <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
1730
                                        //                                                                xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
1731
                                        //                                                                xmlAttrs.put(WebMapContextTags.XLINK_HREF, "http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif");
1732
                                        //                                                                xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
1733
                                        //                                                                // </OnlineResource>
1734
                                        //                                                    // </LegendURL>
1735
                                        //                                                        xml.closeTag();
1736
                                        // </Style>
1737
                                        xml.closeTag();
1738
                                }
1739
                                // </StyleList>
1740
                                xml.closeTag();
1741
                                if (mapContextVersion.compareTo("1.0.0") > 0) {
1742
                                        // <DimensionList>
1743
                                        xml.openTag(WebMapContextTags.DIMENSION_LIST);
1744
                                        // <Dimension>
1745
                                        // </Dimension>
1746
                                        xml.closeTag();
1747
                                        // </DimensionList>
1748
                                }
1749
                        } else {
1750
                                xml.writeTag("ERROR", PluginServices.getText(this, "unsupported_map_context_version"));
1751
                        }
1752
                        // </Layer>
1753
                        xml.closeTag();
1754
                }
1755
                return xml.getXML();
1756
        }
1757

    
1758
        public String getTocImageIcon() {
1759
                return "icon-layer-wms";
1760
        }
1761

    
1762
        /*
1763
         *  (non-Javadoc)
1764
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#getTileSize()
1765
         */
1766
        public int[] getTileSize() {
1767
                int[] size = {maxTileDrawWidth, maxTileDrawHeight};
1768
                return size;
1769
        }
1770

    
1771
        /*
1772
         *  (non-Javadoc)
1773
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#isTiled()
1774
         */
1775
        public boolean isTiled() {
1776
                return mustTileDraw;
1777
        }
1778

    
1779
        public Image getImageLegend() {
1780
                try {
1781
                        if (wms == null) {
1782
                                wms = getDriver();
1783
                        }
1784
                        if (wms.hasLegendGraphic()) {
1785
                                wmsStatus.setOnlineResource((String) onlineResources
1786
                                                .get("GetLegendGraphic"));
1787
                                String path = getPathImage();// File legend =
1788
                                // getDriver().getLegendGraphic(wmsStatus,
1789
                                // layerQuery, null);
1790
                                Image img = null;
1791
                                if ((path != null) && (path.length() > 0)) {
1792
                                        img = new ImageIcon(path).getImage();
1793
                                }
1794
                                return img;
1795
                        }
1796
                } catch (Exception e) {
1797
                }
1798
                return null;
1799
        }
1800

    
1801
        public String getPathImage() {
1802
                try {
1803
                        File legend = getDriver().getLegendGraphic(wmsStatus, layerQuery, null);
1804
                        return legend.getAbsolutePath();
1805
                }catch(Exception e){
1806
                        e.printStackTrace();
1807
                        return null;
1808
                }
1809
        }
1810

    
1811
        /* (non-Javadoc)
1812
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#newComposedLayer()
1813
         */
1814
        public ComposedLayer newComposedLayer() {
1815
                Preferences prefs = Preferences.userRoot().node("gvsig.wms");
1816

    
1817
                /*
1818
                 * from java.util.prefs import Preferences
1819
                 * prefs = Preferences.userRoot().node("gvsig.wms")
1820
                 * prefs.put("useComposedLayer","true")
1821
                 */
1822

    
1823
                String str = prefs.get("useComposedLayer","false");
1824
                Boolean useComposedLayer = Boolean.TRUE; // por defecto ya se usan
1825
                try {
1826
                        useComposedLayer = Boolean.valueOf(str);
1827
                } catch (Exception e) {
1828

    
1829
                }
1830
                if (useComposedLayer.booleanValue()) {
1831
                        return new ComposedLayerWMS();
1832
                } else {
1833
                        return null;
1834
                }
1835
        }
1836

    
1837
        /**
1838
         * @param styles
1839
         */
1840
        public Vector getStyles() {
1841
                return this.styles;
1842
        }
1843

    
1844

    
1845
        /*
1846
         * Checks if can make a single petition for the two layers to the server
1847
         * @see com.iver.cit.gvsig.fmap.layers.ComposedLayerWMS#canAdd(com.iver.cit.gvsig.fmap.layers.FLayer)
1848
         */
1849
        boolean isComposedLayerCompatible(FLayer layer) {
1850
                FLyrWMS aLayer;
1851

    
1852
                if (!(layer instanceof FLyrWMS)) {
1853
                        return false;
1854
                }
1855
                aLayer = (FLyrWMS)layer;
1856
                if (!this.getHost().equals(aLayer.getHost())) {
1857
                        return false;
1858
                }
1859
                if (!this.getFormat().equals(aLayer.getFormat())) {
1860
                        return false;
1861
                }
1862
                if (!this.getSRS().equals(aLayer.getSRS())) {
1863
                        return false;
1864
                }
1865
                if (this.getInfoLayerQuery() != null) {
1866
                        if (!this.getInfoLayerQuery().equals(aLayer.getInfoLayerQuery())) {
1867
                                return false;
1868
                        }
1869
                }else if (aLayer.getInfoLayerQuery() != null) {
1870
                        return false;
1871
                }
1872

    
1873

    
1874
                // isFixedSize es privado
1875
                if ((this.fixedSize != null) &&
1876
                                (aLayer.fixedSize!= null)) {
1877
                        if (this.fixedSize.equals(aLayer.fixedSize)) {
1878
                                return false;
1879
                        }
1880
                } else if ((this.fixedSize != null) != (aLayer.fixedSize != null)) {
1881
                        return false;
1882
                }
1883

    
1884
                // time elevation (dimensions)
1885
                if ((this.dimensions != null) &&
1886
                                (aLayer.dimensions != null)) {
1887
                        if (this.dimensions.size() != aLayer.dimensions.size()) {
1888
                                return false;
1889
                        } else {
1890
                                Iterator iter = this.dimensions.iterator();
1891
                                while (iter.hasNext()) {
1892
                                        if (!aLayer.dimensions.contains(iter.next())) {
1893
                                                return false;
1894
                                        }
1895
                                }
1896
                        }
1897

    
1898
                } else if ((this.dimensions != null) != (aLayer.dimensions != null)) {
1899
                        return false;
1900
                }
1901

    
1902
                return true;
1903
        }
1904

    
1905
        /*
1906
         * (non-Javadoc)
1907
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#isActionEnabled(int)
1908
         */
1909
        public boolean isActionEnabled(int action) {
1910
                switch (action) {
1911
                case IRasterLayerActions.ZOOM_PIXEL_RESOLUTION:
1912
                case IRasterLayerActions.FLYRASTER_BAR_TOOLS:
1913
                case IRasterLayerActions.BANDS_FILE_LIST:
1914
                case IRasterLayerActions.COLOR_TABLE:
1915
                case IRasterLayerActions.GEOLOCATION:
1916
                case IRasterLayerActions.PANSHARPENING:
1917
                case IRasterLayerActions.SAVE_COLORINTERP:
1918
                        return false;
1919
                case IRasterLayerActions.REMOTE_ACTIONS:
1920
                        return true;
1921
                }
1922

    
1923
                return super.isActionEnabled(action);
1924
        }
1925

    
1926
        /*
1927
         * (non-Javadoc)
1928
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#getLegend()
1929
         */
1930
        public ILegend getLegend() {
1931
                return null;
1932
        }
1933

    
1934
        /*
1935
         * (non-Javadoc)
1936
         * @see org.gvsig.fmap.raster.IRasterOperations#getDatatype()
1937
         */
1938
        public int[] getDataType(){
1939
                try {
1940
                        return dataset.getDataType();
1941
                } catch (NullPointerException e) {
1942
                        if(layerRaster != null && layerRaster[0] != null)
1943
                                return layerRaster[0].getDataType();
1944
                        else
1945
                                return new int[]{IBuffer.TYPE_UNDEFINED};
1946
                }
1947
        }
1948

    
1949

    
1950
        /*
1951
         * (non-Javadoc)
1952
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#overviewsSupport()
1953
         */
1954
        public boolean overviewsSupport() {
1955
                return false;
1956
        }
1957

    
1958
        protected void updateDrawVersion() {
1959
                if (this.disableUpdateDrawVersion != null){
1960

    
1961
                        Thread curThread = Thread.currentThread();
1962

    
1963
                        Thread aThread;
1964

    
1965
                        Iterator iter = this.disableUpdateDrawVersion.iterator();
1966
                        while (iter.hasNext()){
1967
                                aThread = (Thread) ((WeakReference)iter.next()).get();
1968
                                if (aThread == null){
1969
                                        iter.remove();
1970
                                } else if(aThread.equals(curThread)){
1971
                                        return;
1972
                                }
1973
                        }
1974
                }
1975
                //                Exception ex = new Exception();
1976
                //                ex.printStackTrace();
1977
                super.updateDrawVersion();
1978
        }
1979

    
1980
        protected void disableUpdateDrawVersion(){
1981
                if (this.disableUpdateDrawVersion == null){
1982
                        this.disableUpdateDrawVersion = new ArrayList();
1983
                }
1984
                this.disableUpdateDrawVersion.add(new WeakReference(Thread.currentThread()));
1985
        }
1986

    
1987
        protected void enableUpdateDrawVersion(){
1988
                if (this.disableUpdateDrawVersion == null){
1989
                        return;
1990
                }
1991

    
1992
                Thread curThread = Thread.currentThread();
1993

    
1994
                Thread aThread;
1995

    
1996

    
1997
                Iterator iter = this.disableUpdateDrawVersion.iterator();
1998
                while (iter.hasNext()){
1999
                        aThread = (Thread) ((WeakReference)iter.next()).get();
2000
                        if (aThread == null){
2001
                                iter.remove();
2002
                        } else if(aThread.equals(curThread)){
2003
                                iter.remove();
2004
                                break;
2005
                        }
2006
                }
2007

    
2008
        }
2009

    
2010
        private Rectangle2D.Double getRectable2DFromEnvelope(Envelope env) {
2011
                return new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env
2012
                                .getLength(0), env.getLength(1));
2013
        }
2014

    
2015
        private Envelope getEnvelopeFromRectable2D(Rectangle2D rect) {
2016
                try {
2017
                        return geomManager.createEnvelope(rect.getMinX(), rect.getMinY(),
2018
                                        rect
2019
                                        .getMaxX(), rect.getMaxY(),
2020
                                        SUBTYPES.GEOM2D);
2021
                } catch (CreateEnvelopeException e) {
2022
                        logger.error("Error creating the envelope", e);
2023
                }
2024
                return null;
2025
        }
2026

    
2027
        /**
2028
         * Devuelve el envelope en la proyeccion de la vista
2029
         *
2030
         */
2031
        public Envelope getFullEnvelope() {
2032
                Envelope rAux;
2033
                rAux = this.fullEnvelope;
2034

    
2035
                // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
2036
                // y alto 0.
2037
                if (rAux == null || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
2038
                                && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
2039
                        try {
2040
                                rAux = geomManager.createEnvelope(0, 0, 100, 100, SUBTYPES.GEOM2D);
2041
                        } catch (CreateEnvelopeException e) {
2042
                                logger.error("Error creating the envelope", e);
2043
                        }
2044
                }
2045
                // Si existe reproyecci?n, reproyectar el extent
2046
                ICoordTrans ct = getCoordTrans();
2047
                if (ct != null) {
2048
                        Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux
2049
                                        .getMinimum(1));
2050
                        Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux
2051
                                        .getMaximum(1));
2052
                        pt1 = ct.convert(pt1, null);
2053
                        pt2 = ct.convert(pt2, null);
2054
                        try {
2055
                                rAux = geomManager.createEnvelope(pt1.getX(), pt1.getY(), pt2
2056
                                                .getX(), pt2.getY(), SUBTYPES.GEOM2D);
2057
                        } catch (CreateEnvelopeException e) {
2058
                                logger.error("Error creating the envelope", e);
2059
                        }// new
2060
                        // Rectangle2D.Double();
2061
                }
2062
                return rAux;
2063

    
2064
        }
2065

    
2066
        /*
2067
         * (non-Javadoc)
2068
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#getFileLayer()
2069
         */
2070
        public FLayer getFileLayer() {
2071
                if(layerRaster != null && layerRaster[0] != null) {
2072
                        FLyrRasterSE ly = null;
2073
                        if(lastNColumns == 0 && lastNRows == 0) {
2074
                                try {
2075
                                        ly = createLayer(layerRaster[0].getName(), layerRaster[0].getLoadParams(), layerRaster[0].getProjection());
2076
                                } catch (LoadLayerException e) {
2077
                                        return null;
2078
                                }
2079
                        } else {
2080

    
2081
                                String[][] s = new String[lastNRows][lastNColumns];
2082

    
2083
                                for (int i = 0; i < s.length; i++) {
2084
                                        for (int j = 0; j < s[0].length; j++) {
2085
                                                s[i][j] = ((FLyrRasterSE)layerRaster[i]).getDataSource().getNameDatasetStringList(i, j)[0];
2086
                                        }
2087
                                }
2088
                                try {
2089
                                        ly = createLayer("preview", s, getProjection());
2090
                                } catch (LoadLayerException e) {
2091
                                        return null;
2092
                                }
2093
                        }
2094
                        return ly;
2095
                }
2096
                return null;
2097
        }
2098

    
2099
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel)
2100
        throws LoadLayerException, DataException {
2101
                // TODO Auto-generated method stub
2102
                //                XMLItem[] item = new XMLItem[1];
2103
                //                try {
2104
                //                        if (queryable)         {
2105
                //                                //TODO
2106
                //                                // check if there are layers which are not queryable
2107
                //                                ViewPort viewPort = getMapContext().getViewPort();
2108
                //
2109
                //                                Point tiledPoint = new Point((int) p.getX() % maxTilePrintWidth, (int) p.getY() % maxTilePrintHeight);
2110
                //                                Rectangle rect = new Rectangle(0, 0, viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1);
2111
                //                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, rect);
2112
                //                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
2113
                //                                int nCols = tiles.getNumCols();
2114
                //
2115
                //                                int col = (int) p.getX() / maxTilePrintWidth;
2116
                //                                int row = (int) p.getY() / maxTilePrintHeight;
2117
                //                                int tileIndex = (row*nCols) + col;
2118
                //
2119
                //                                ViewPort vp = tiles.getTileViewPort(viewPort, tileIndex);
2120
                //                                wmsStatus.setExtent(this.getRectable2DFromEnvelope(vp
2121
                //                                                .getAdjustedExtent()));
2122
                //                                wmsStatus.setHeight(vp.getImageHeight());
2123
                //                                wmsStatus.setWidth(vp.getImageWidth());
2124
                //                                wmsStatus.setOnlineResource((String) onlineResources.get("GetFeatureInfo"));
2125
                //
2126
                //
2127
                //                                wmsStatus.setFormat( m_Format );
2128
                //                                wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
2129
                //                                wmsStatus.setSrs(m_SRS);
2130
                //                                wmsStatus.setStyles(styles);
2131
                //                                wmsStatus.setDimensions(dimensions);
2132
                //                                wmsStatus.setTransparency(wmsTransparency);
2133
                //                                wmsStatus.setSrs(m_SRS);
2134
                //                                MyCancellable c = new MyCancellable(cancellable);
2135
                //                                try {
2136
                //                                        item[0] = new StringXMLItem(new String(getDriver()
2137
                //                                                        .getFeatureInfo(wmsStatus, (int) tiledPoint.getX(), (int) tiledPoint.getY(), Integer.MAX_VALUE, c)),this);
2138
                //                                } catch (UnsupportedVersionLayerException e) {
2139
                //                                        throw new ReadException(FMapWMSDriver.class.getName()
2140
                //                                                        + "::" + getName()
2141
                //                                                        + " - UnsupportedVersionLayerException", e);
2142
                //                                } catch (IllegalStateException e) {
2143
                //                                        throw new ReadException(FMapWMSDriver.class.getName()
2144
                //                                                        + "::" + getName() + " - IllegalStateException", e);
2145
                //                                }
2146
                //                                return item;
2147
                //                        }
2148
                //                        else
2149
                //                        {
2150
                //                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),this.getName() + " " +
2151
                //                                                PluginServices.getText(this,"layer_not_queryable"));
2152
                //                                item[0] =  new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><info></info>",this);
2153
                //                                return item;
2154
                //                                //return null;
2155
                //                        }
2156
                //                } catch (WMSException  e) {
2157
                //                        item[0] = new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
2158
                //                        e.getMessage() + "</exception>", this);
2159
                //                        return item;
2160
                //                } catch (ValidationException e) {
2161
                //                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
2162
                //                                        + getName() + " - ValidationException", e);
2163
                //                } catch (IOException e) {
2164
                //                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
2165
                //                                        + getName() + " - IOException", e);
2166
                //                } catch (NoninvertibleTransformException e) {
2167
                //                        NotificationManager.addError("NotinvertibleTransform", e);
2168
                //                }
2169
                //                return null;
2170
                return null;
2171
        }
2172

    
2173
}