Statistics
| Revision:

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

History | View | Annotate | Download (68.2 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.lang.reflect.Constructor;
57
import java.lang.reflect.InvocationTargetException;
58
import java.net.MalformedURLException;
59
import java.net.URL;
60
import java.util.ArrayList;
61
import java.util.HashMap;
62
import java.util.Hashtable;
63
import java.util.Iterator;
64
import java.util.List;
65
import java.util.Map;
66
import java.util.Vector;
67
import java.util.prefs.Preferences;
68

    
69
import javax.print.attribute.PrintRequestAttributeSet;
70
import javax.swing.ImageIcon;
71

    
72
import org.cresques.cts.ICoordTrans;
73
import org.cresques.geo.ViewPortData;
74
import org.cresques.px.Extent;
75
import org.exolab.castor.xml.ValidationException;
76
import org.gvsig.andami.PluginServices;
77
import org.gvsig.andami.messages.NotificationManager;
78
import org.gvsig.fmap.crs.CRSFactory;
79
import org.gvsig.fmap.dal.exception.DataException;
80
import org.gvsig.fmap.dal.exception.ReadException;
81
import org.gvsig.fmap.geom.GeometryLocator;
82
import org.gvsig.fmap.geom.GeometryManager;
83
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
84
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
85
import org.gvsig.fmap.geom.primitive.Envelope;
86
import org.gvsig.fmap.mapcontext.ViewPort;
87
import org.gvsig.fmap.mapcontext.exceptions.ConnectionErrorLayerException;
88
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
89
import org.gvsig.fmap.mapcontext.exceptions.URLLayerException;
90
import org.gvsig.fmap.mapcontext.exceptions.UnsupportedVersionLayerException;
91
import org.gvsig.fmap.mapcontext.layers.FLayer;
92
import org.gvsig.fmap.mapcontext.layers.Tiling;
93
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
94
import org.gvsig.fmap.mapcontext.layers.operations.IHasImageLegend;
95
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
96
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
97
import org.gvsig.fmap.raster.layers.IRasterLayerActions;
98
import org.gvsig.fmap.raster.layers.IStatusRaster;
99
import org.gvsig.fmap.raster.layers.StatusLayerRaster;
100
import org.gvsig.raster.dataset.CompositeDataset;
101
import org.gvsig.raster.dataset.IBuffer;
102
import org.gvsig.raster.dataset.MosaicNotValidException;
103
import org.gvsig.raster.dataset.MultiRasterDataset;
104
import org.gvsig.raster.dataset.NotSupportedExtensionException;
105
import org.gvsig.raster.dataset.RasterDriverException;
106
import org.gvsig.raster.grid.GridPalette;
107
import org.gvsig.raster.grid.GridTransparency;
108
import org.gvsig.raster.grid.filter.FilterTypeException;
109
import org.gvsig.raster.grid.filter.RasterFilterList;
110
import org.gvsig.raster.grid.filter.RasterFilterListManager;
111
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
112
import org.gvsig.raster.grid.filter.bands.ColorTableListManager;
113
import org.gvsig.remoteclient.utils.Utilities;
114
import org.gvsig.remoteclient.wms.ICancellable;
115
import org.gvsig.remoteclient.wms.WMSStatus;
116
import org.gvsig.symbology.fmap.mapcontext.rendering.legend.XmlBuilder;
117
import org.gvsig.tools.task.Cancellable;
118
import org.gvsig.utils.StringUtilities;
119
import org.gvsig.utils.XMLEntity;
120
import org.gvsig.utils.XMLException;
121
import org.gvsig.wmc.WebMapContextTags;
122
import org.gvsig.wms.fmap.WMSDriverExceptionType;
123
import org.gvsig.wms.fmap.drivers.wms.FMapWMSDriver;
124
import org.gvsig.wms.fmap.drivers.wms.FMapWMSDriverFactory;
125
import org.gvsig.wms.fmap.drivers.wms.WMSException;
126
import org.gvsig.wms.fmap.layers.WMSLayerNode.FMapWMSStyle;
127
import org.slf4j.Logger;
128
import org.slf4j.LoggerFactory;
129

    
130

    
131

    
132

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

    
172
        public URL                                                         host;
173
        public String                                                 m_Format;
174

    
175
        private String                                                 m_SRS;
176
        private String                                                 layerQuery;
177
        private String                                                 infoLayerQuery;
178
        private FMapWMSDriver                                 wms;
179
        private WMSStatus                                         wmsStatus = new WMSStatus();
180
        private boolean                                                wmsTransparency;
181
        private Vector                                                 styles;
182
        private Vector                                                 dimensions;
183
        private boolean                                                firstLoad = false;
184
        private Hashtable                                         onlineResources = new Hashtable();
185
        private Dimension                                         fixedSize;
186
        private boolean                                         queryable = true;
187
        private VisualStatus                                visualStatus = new VisualStatus();
188
        /**
189
         * Lista de filtros aplicada en la renderizaci?n
190
         */
191
        private RasterFilterList            filterList = null;
192
        private GridTransparency                        transparency = null;
193
        private int[]                       renderBands = null;
194
        private FLyrRasterSE[]                                layerRaster = null;
195
        private ArrayList                   filterArguments = null;
196

    
197
        private List                                                disableUpdateDrawVersion;
198
        private int                         lastNColumns = 0;
199
        private int                         lastNRows = 0;
200

    
201
        //FIXME DynValue???
202
        private Envelope                                        fullEnvelope=null;
203

    
204
        private class MyCancellable implements ICancellable
205
        {
206
                private Cancellable original;
207
                public MyCancellable(Cancellable cancelOriginal)
208
                {
209
                        this.original = cancelOriginal;
210
                }
211
                public boolean isCanceled() {
212
                        if (original == null) {
213
                                return false;
214
                        }
215
                        return original.isCanceled();
216
                }
217
                public Object getID() {
218
                        return this;
219
                }
220

    
221
        }
222

    
223
        public FLyrWMS(){
224
                super();
225
                this.updateDrawVersion();
226
        }
227

    
228
        public FLyrWMS(Map args) throws LoadLayerException{
229
                this.updateDrawVersion();
230
                FMapWMSDriver drv = null;
231
                String host = (String)args.get("host");
232
                String sLayer = (String)args.get("layer");
233
                Rectangle2D fullExtent = (Rectangle2D)args.get("FullExtent");
234
                String sSRS = (String)args.get("SRS");
235
                String sFormat = (String)args.get("Format");
236
                String[] sLayers = sLayer.split(",");
237

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

    
258
                        WMSLayerNode wmsNode = drv.getLayer(sLayer);
259

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

    
277
                                 if(!isSRSSupported) {
278
                                         for (int i=0; i<allSrs.size() ; i++){
279
                                                 if (((String)wmsNode.getAllSrs().get(i)).compareTo("EPSG:4326") == 0){
280
                                                         sSRS = (String)wmsNode.getAllSrs().get(i);
281
                                                 }
282
                                         }
283
                                         if (sSRS==null){
284
                                                 sSRS = (String)wmsNode.getAllSrs().get(0);
285
                                         }
286
                                 }
287
                        if( fullExtent == null ) {
288
                                fullExtent = drv.getLayersExtent(sLayers,sSRS);
289
                        }
290
                }
291

    
292

    
293
                this.setFullExtent(fullExtent);
294
                this.setFormat(sFormat);
295
                this.setLayerQuery(sLayer);
296
                this.setInfoLayerQuery("");
297
                this.setSRS(sSRS);
298
                this.setName(sLayer);
299
                this.setOnlineResources(drv.getOnlineResources());
300
                load();
301
        }
302

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

    
322
                        return (String)formats.get(0);
323
        }
324

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

    
343
                public Object clone() {
344
                        VisualStatus s = new VisualStatus();
345
                        s.maxX = maxX;
346
                        s.maxY = maxY;
347
                        s.minX = minX;
348
                        s.minY = minY;
349
                        s.fileNames = new String[fileNames.length];
350
                        for (int i = 0; i < fileNames.length; i++) 
351
                                s.fileNames[i] = fileNames[i];
352
                        return s;
353
                }
354
        }
355

    
356

    
357
        /**
358
         * Devuelve el XMLEntity con la informaci?n necesaria para reproducir la
359
         * capa.
360
         *
361
         * @return XMLEntity.
362
         * @throws XMLException
363
         */
364
        public XMLEntity getXMLEntity() throws XMLException {
365
                XMLEntity xml = super.getXMLEntity();
366

    
367
                // Full extent
368
                // FIXME
369
                xml.putProperty("fullExtent", StringUtilities.rect2String(this
370
                                .getRectable2DFromEnvelope(this.fullEnvelope)));
371

    
372
                // Host
373
                xml.putProperty("host", host.toExternalForm());
374

    
375
                // Part of the query that is not the host, or the
376
                // layer names, or other not listed bellow
377
                xml.putProperty("infoLayerQuery", infoLayerQuery);
378

    
379
                // Part of the query containing the layer names
380
                xml.putProperty("layerQuery", layerQuery);
381

    
382
                // Format
383
                xml.putProperty("format", m_Format);
384

    
385
                // SRS
386
                xml.putProperty("srs", m_SRS);
387
                if (status!=null) {
388
                        status.getXMLEntity(xml, true, this);
389
                } else{
390
                        status = new StatusLayerRaster();
391
                        status.getXMLEntity(xml, true, this);
392
                }
393

    
394
                                // Transparency
395
                                xml.putProperty("wms_transparency", wmsTransparency);
396

    
397
                                // Styles
398
                                if (styles!=null){
399
                                                String stylePr = "";
400
                                                for (int i = 0; i < styles.size(); i++) {
401
                                                                stylePr += (String) styles.get(i);
402
                                                                if (i<styles.size()-1) {
403
                                                                        stylePr += ",";
404
                                                                }
405
                                                }
406
                                                if (stylePr.endsWith(",")) {
407
                                                        stylePr += " ";
408
                                                }
409
                                                xml.putProperty("styles", stylePr);
410
                                }
411

    
412
                                // Dimensions
413
                                if (dimensions!=null){
414
                                                String dim = "";
415
                                                for (int i = 0; i < dimensions.size(); i++) {
416
                                                                dim += (String) dimensions.get(i);
417
                                                                if (i<dimensions.size()-1) {
418
                                                                        dim += ",";
419
                                                                }
420
                                                }
421
                                                if (dim.endsWith(",")) {
422
                                                        dim += " ";
423
                                                }
424
                                                xml.putProperty("dimensions", dim);
425
                                }
426

    
427
                                // OnlineResources
428
                                Iterator it = onlineResources.keySet().iterator();
429
                                String strOnlines = "";
430
                                while (it.hasNext()) {
431
                                        String key = (String) it.next();
432
                                        String value = (String) onlineResources.get(key);
433
                                        strOnlines += key+"~##SEP2##~"+value;
434
                                        if (it.hasNext()) {
435
                                                strOnlines += "~##SEP1##~";
436
                                        }
437
                                }
438
                                xml.putProperty("onlineResources", strOnlines);
439

    
440
                                // Queryable
441
                                xml.putProperty("queryable", queryable);
442

    
443
                                // fixedSize
444
                                if (isSizeFixed()) {
445
                                        xml.putProperty("fixedSize", true);
446
                                        xml.putProperty("fixedWidth", fixedSize.width);
447
                                        xml.putProperty("fixedHeight", fixedSize.height);
448
                                }
449
                                return xml;
450
        }
451

    
452
        /**
453
         * A partir del XMLEntity reproduce la capa.
454
         *
455
         * @param xml XMLEntity
456
         *
457
         * @throws XMLException
458
         */
459
        public void setXMLEntity(XMLEntity xml)
460
                throws XMLException {
461
                super.setXMLEntity(xml);
462

    
463
                // FIXME
464
                this.setFullEnvelope(this.getEnvelopeFromRectable2D(StringUtilities
465
                                .string2Rect(xml.getStringProperty("fullExtent"))));
466

    
467
                // Host
468
                try {
469
                        host = new URL(xml.getStringProperty("host"));
470
                } catch (MalformedURLException e) {
471
                        throw new XMLLayerException("", e);
472
                }
473

    
474
                // Part of the query that is not the host, or the
475
                // layer names, or other not listed bellow
476
                infoLayerQuery = xml.getStringProperty("infoLayerQuery");
477

    
478
                // Part of the query containing the layer names
479
                layerQuery = xml.getStringProperty("layerQuery");
480

    
481
                // Format
482
                m_Format = xml.getStringProperty("format");
483

    
484
                // SRS
485
                m_SRS = xml.getStringProperty("srs");
486

    
487
                String claseStr = StatusLayerRaster.defaultClass;
488
                if (xml.contains("raster.class")) {
489
                        claseStr = xml.getStringProperty("raster.class");
490
                }
491

    
492
                // Transparency
493
                                if (xml.contains("wms_transparency")) {
494
                                        wmsTransparency = xml.getBooleanProperty("wms_transparency");
495
                                }
496

    
497
                                // Styles
498
                                if (xml.contains("styles")){
499
                                                styles = new Vector();
500
                                                String[] stl = xml.getStringProperty("styles").split(",");
501

    
502
                                                for (int i = 0; i < stl.length; i++) {
503
                                                        if (stl[i].equals(" ")) {
504
                                                                stl[i]="";
505
                                                        }
506
                                                                styles.add(stl[i]);
507
                                                }
508
                                }
509

    
510
                                // Dimensions
511
                                if (xml.contains("dimensions")){
512
                                                dimensions = new Vector();
513
                                                String[] dims = xml.getStringProperty("dimensions").split(",");
514
                                                for (int i = 0; i < dims.length; i++){
515
                                                        if (dims[i].equals(" ")) {
516
                                                                dims[i]="";
517
                                                        }
518

    
519
                                                                dimensions.add(dims[i]);
520
                                                }
521
                                }
522

    
523
                                // OnlineResources
524
                                if (xml.contains("onlineResources")) {
525
                                        String[] operations = xml.getStringProperty("onlineResources").split("~##SEP1##~");
526
                                        for (int i = 0; i < operations.length; i++) {
527
                                String[] resources = operations[i].split("~##SEP2##~");
528
                                if (resources.length==2 && resources[1]!="") {
529
                                        onlineResources.put(resources[0], resources[1]);
530
                                }
531
                        }
532
                                }
533

    
534
                                // Queryable
535
                                queryable = true; // let's assume that the layer is queryable by default
536
                                if (xml.contains("queryable")) {
537
                                        queryable = xml.getBooleanProperty("queryable");
538
                                }
539

    
540
                                // fixedSize
541
                                if (xml.contains("fixedSize")) {
542
                                        fixedSize = new Dimension(xml.getIntProperty("fixedWidth"),
543
                                                                                                                                xml.getIntProperty("fixedHeight"));
544
                                }
545

    
546
                if(status!=null) {
547
                        status.setXMLEntity(xml, this);
548
                } else{
549
                        if(claseStr != null && !claseStr.equals("")){
550
                                try{
551
                                        // Class clase =
552
                                        // LayerFactory.getLayerClassForLayerClassName(claseStr);
553
                                        Class clase = this.getClass();
554
                                        Constructor constr = clase.getConstructor(null);
555
                                        status = (IStatusRaster)constr.newInstance(null);
556
                                        if(status != null) {
557
                                                ((StatusLayerRaster)status).setNameClass(claseStr);
558
                                                status.setXMLEntity(xml, this);
559
                                                filterArguments = status.getFilterArguments();
560
                                                transparency = status.getTransparency();
561
                                                renderBands = status.getRenderBands();
562
                                        }
563
//                                }catch(ClassNotFoundException exc){
564
//                                        exc.printStackTrace();
565
                                }catch(InstantiationException exc){
566
                                        exc.printStackTrace();
567
                                }catch(IllegalAccessException exc){
568
                                        exc.printStackTrace();
569
                                }catch(NoSuchMethodException exc){
570
                                        exc.printStackTrace();
571
                                }catch(InvocationTargetException exc){
572
                                        exc.printStackTrace();
573
                                }
574
                        }
575
                }
576
                firstLoad = true;
577
        }
578

    
579
//        /**
580
//         * @throws ReadDriverException
581
//         * @throws LoadLayerException
582
//         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(com.iver.cit.gvsig.fmap.operations.QueriedPoint)
583
//         */
584
//        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancellable)
585
//                        throws ReadException {
586
//                XMLItem[] item = new XMLItem[1];
587
//                try {
588
//                        if (queryable)         {
589
//                                //TODO
590
//                                // check if there are layers which are not queryable
591
//                                ViewPort viewPort = getMapContext().getViewPort();
592
//
593
//                                Point tiledPoint = new Point((int) p.getX() % maxTilePrintWidth, (int) p.getY() % maxTilePrintHeight);
594
//                                Rectangle rect = new Rectangle(0, 0, viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1);
595
//                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, rect);
596
//                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
597
//                                int nCols = tiles.getNumCols();
598
//
599
//                                int col = (int) p.getX() / maxTilePrintWidth;
600
//                                int row = (int) p.getY() / maxTilePrintHeight;
601
//                                int tileIndex = (row*nCols) + col;
602
//
603
//                                ViewPort vp = tiles.getTileViewPort(viewPort, tileIndex);
604
//                                wmsStatus.setExtent(this.getRectable2DFromEnvelope(vp
605
//                                                .getAdjustedExtent()));
606
//                                wmsStatus.setHeight(vp.getImageHeight());
607
//                                wmsStatus.setWidth(vp.getImageWidth());
608
//                                wmsStatus.setOnlineResource((String) onlineResources.get("GetFeatureInfo"));
609
//
610
//
611
//                                wmsStatus.setFormat( m_Format );
612
//                                wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
613
//                                wmsStatus.setSrs(m_SRS);
614
//                                wmsStatus.setStyles(styles);
615
//                                wmsStatus.setDimensions(dimensions);
616
//                                wmsStatus.setTransparency(wmsTransparency);
617
//                                wmsStatus.setSrs(m_SRS);
618
//                                MyCancellable c = new MyCancellable(cancellable);
619
//                                try {
620
//                                        item[0] = new StringXMLItem(new String(getDriver()
621
//                                                        .getFeatureInfo(wmsStatus, (int) tiledPoint.getX(), (int) tiledPoint.getY(), Integer.MAX_VALUE, c)),this);
622
//                                } catch (UnsupportedVersionLayerException e) {
623
//                                        throw new ReadException(FMapWMSDriver.class.getName()
624
//                                                        + "::" + getName()
625
//                                                        + " - UnsupportedVersionLayerException", e);
626
//                                } catch (IllegalStateException e) {
627
//                                        throw new ReadException(FMapWMSDriver.class.getName()
628
//                                                        + "::" + getName() + " - IllegalStateException", e);
629
//                                }
630
//                                return item;
631
//                        }
632
//                        else
633
//                        {
634
//                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),this.getName() + " " +
635
//                                                PluginServices.getText(this,"layer_not_queryable"));
636
//                                item[0] =  new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><info></info>",this);
637
//                                return item;
638
//                                //return null;
639
//                        }
640
//                } catch (WMSException  e) {
641
//                        item[0] = new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
642
//                        e.getMessage() + "</exception>", this);
643
//                        return item;
644
//                } catch (ValidationException e) {
645
//                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
646
//                                        + getName() + " - ValidationException", e);
647
//                } catch (IOException e) {
648
//                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
649
//                                        + getName() + " - IOException", e);
650
//                } catch (NoninvertibleTransformException e) {
651
//                        NotificationManager.addError("NotinvertibleTransform", e);
652
//                }
653
//                return null;
654
//        }
655

    
656
        /*
657
         *
658
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#draw(java.awt.image.BufferedImage,
659
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
660
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
661
         */
662
        private int callCount; // mess code, represents the amount of times the methods drawFixedSize or drawTile where tried for an extent
663
        private static final int MAX_RETRY_TIMES = 5; // mess code, represents the max amount of retries allowed.
664
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
665
                        Cancellable cancel, double scale) throws ReadException {
666
                callCount = 0; // mess code
667
                lastNColumns = lastNRows = 0;
668
                
669
                enableStopped();
670
        
671
                closeAndFree();
672
                
673
                if (isWithinScale(scale)){
674
                        Point2D p = viewPort.getOffset();
675
                        // p will be (0, 0) when drawing a view or other when painting onto
676
                        // the Layout.
677
                        Envelope vpEnvelope = viewPort.getAdjustedExtent();
678
                        visualStatus.minX = vpEnvelope.getMinimum(0);
679
                        visualStatus.minY = vpEnvelope.getMinimum(1);
680
                        visualStatus.maxX = vpEnvelope.getMaximum(0);
681
                        visualStatus.maxY = vpEnvelope.getMaximum(1);
682

    
683

    
684
                        if (isSizeFixed()) {
685
                                // This condition handles those situations in which the server can
686
                                // only give static extent and resolution maps despite we need
687
                                // a specific BBOX and pixel WIDTH and HEIGHT
688
                                try {
689
                                        visualStatus.fileNames = new String[1];
690
                                        layerRaster = new FLyrRasterSE[1];
691
                                        drawFixedSize(g, viewPort, cancel, scale);
692
                                        if(layerRaster != null && layerRaster[0] != null) {
693
                                                dataset = layerRaster[0].getDataSource();
694
                                                initializeRasterLayer(null, new IBuffer[][]{{layerRaster[0].getRender().getLastRenderBuffer()}});
695
                                                getRender().setLastRenderBuffer(layerRaster[0].getRender().getLastRenderBuffer());
696
                                        }
697
                                } catch (LoadLayerException e) {
698
                                        // TODO Auto-generated catch block
699
                                        e.printStackTrace();
700
                                } 
701

    
702
                        } else {
703
                                if(mustTileDraw){
704
                                        Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth(), viewPort.getImageHeight());
705
                                        Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
706
                                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
707
                                        visualStatus.fileNames = new String[tiles.getNumTiles()];
708
                                        MultiRasterDataset[][] datasets = new MultiRasterDataset[tiles.getNumRows()][tiles.getNumCols()];
709
                                        IBuffer[][] buf = new IBuffer[tiles.getNumRows()][tiles.getNumCols()];
710
                                        layerRaster = new FLyrRasterSE[tiles.getNumTiles()];
711
                                        lastNColumns = tiles.getNumCols();
712
                                        lastNRows = tiles.getNumRows();
713
                                        for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
714
                                                // drawing part
715
                                                try {
716
                                                        ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
717
                                                        boolean painted = drawTile(g, vp, cancel, tileNr, scale, tileNr);
718
                                                        if(        layerRaster != null && 
719
                                                                        layerRaster[tileNr] != null && 
720
                                                                        painted) {
721
                                                                        datasets[(int)(tileNr / tiles.getNumCols())][tileNr % tiles.getNumCols()] = (MultiRasterDataset)layerRaster[tileNr].getDataSource().newDataset();
722
                                                                        buf[(int)(tileNr / tiles.getNumCols())][tileNr % tiles.getNumCols()] = layerRaster[tileNr].getRender().getLastRenderBuffer();
723
                                                                }
724
                                                } catch (NoninvertibleTransformException e) {
725
                                                        e.printStackTrace();
726
                                                } catch (LoadLayerException e) {
727
                                                        // TODO Auto-generated catch block
728
                                                        e.printStackTrace();
729
                                                }
730
                                        }
731
                                        try {
732
                                                if(datasets != null && datasets[0][0] != null) {
733
                                                        dataset = new CompositeDataset(datasets);
734
                                                        initializeRasterLayer(datasets, buf);
735
                                                        buf = null;
736
                                                }
737
                                        } catch (MosaicNotValidException e) {
738
                                                throw new ReadException(
739
                                                                "No hay continuidad en el mosaico.", e);
740
                                        } catch (LoadLayerException e) {
741
                                                throw new ReadException("Error inicializando la capa.",
742
                                                                e);
743
                                        }
744
                                } else {
745
                                        try {
746
                                                layerRaster = new FLyrRasterSE[1];
747
                                                visualStatus.fileNames = new String[1];
748
                                                drawTile(g, viewPort, cancel, 0, scale, 0);
749
                                                if(layerRaster != null && layerRaster[0] != null) {
750
                                                        dataset = layerRaster[0].getDataSource();
751
                                                        getRender().setLastRenderBuffer(layerRaster[0].getRender().getLastRenderBuffer());
752
                                                        initializeRasterLayer(null, new IBuffer[][]{{layerRaster[0].getRender().getLastRenderBuffer()}});
753
                                                }
754
                                        } catch (LoadLayerException e) {
755
                                                // TODO Auto-generated catch block
756
                                                e.printStackTrace();
757
                                        }
758
                                }
759
                        }
760
                }
761
                disableStopped();
762
                
763
                /*Runtime r = Runtime.getRuntime();
764
                System.err.println("********************WMS**********************");
765
                System.err.println("Memoria Total: " + (r.totalMemory() / 1024) +"KB");
766
                System.err.println("Memoria Usada: " + ((r.totalMemory() - r.freeMemory()) / 1024) +"KB");
767
                System.err.println("Memoria Libre: " + (r.freeMemory() / 1024) +"KB");
768
                System.err.println("Memoria MaxMemory: " + (r.maxMemory() / 1024) +"KB");
769
                System.err.println("*********************************************");*/
770
        }
771
        
772
        /**
773
         * Closes files and releases memory (pointers to null)
774
         */
775
        private void closeAndFree() {
776
                while(readingData != null && readingData.compareTo(Thread.currentThread().toString()) != 0)
777
                        try {
778
                                Thread.sleep(100);
779
                        } catch (InterruptedException e) {
780
                        }
781
                
782
                if(dataset != null) {
783
                        dataset.close();
784
                        dataset = null;
785
                }
786
                
787
                //Cerramos el dataset asociado a la capa si est? abierto.
788
                if(layerRaster != null) {
789
                        for (int i = 0; i < layerRaster.length; i++) {
790
                                if(layerRaster[i] != null) {
791
                                        layerRaster[i].setRemoveRasterFlag(true);
792
                                        layerRaster[i].getDataSource().close();
793
                                        layerRaster[i].getRender().free();
794
                                        layerRaster[i].getBufferFactory().free();
795
                                        layerRaster[i] = null;
796
                                }
797
                        }
798
                }
799
                getRender().free();
800
                System.gc();
801
        }
802

    
803
        /**
804
         * Acciones que se realizan despu?s de asignar la fuente de datos a
805
         * la capa raster.
806
         *
807
         * @throws LoadLayerException
808
         */
809
        private void initializeRasterLayer(MultiRasterDataset[][] datasets, IBuffer[][] buf) throws LoadLayerException {
810
                if(this.filterList != null)
811
                        getRender().setFilterList(filterList);
812
                if(this.transparency != null)
813
                        getRender().setLastTransparency(transparency);
814
                if(this.renderBands != null)
815
                        getRender().setRenderBands(renderBands);
816
                if(datasets != null) {
817
                        String[][] names = new String[datasets.length][datasets[0].length];
818
                        for (int i = 0; i < datasets.length; i++) {
819
                                for (int j = 0; j < datasets[i].length; j++) {
820
                                        if(datasets[i][j] != null)
821
                                                names[i][j] = datasets[i][j].getDataset(0)[0].getFName();
822
                                }
823
                        }
824
                        super.setLoadParams(names);
825
                }
826
                super.init();
827
                if(buf != null && buf[0][0] != null) {
828
                        int drawablesBandCount = layerRaster[0].getDataSource().getBands().getDrawableBandsCount();
829
                        IBuffer buff = null;
830
                        if(dataset instanceof CompositeDataset)
831
                                buff = ((CompositeDataset)dataset).generateBuffer(buf, drawablesBandCount);
832
                        else
833
                                buff = buf[0][0];
834
                        
835
                        if(getRender().getLastRenderBuffer() != null)
836
                                getRender().getLastRenderBuffer().free();
837
                        getRender().setLastRenderBuffer(buff);
838
                }
839
        }
840

    
841
        private void drawFixedSize(Graphics2D g, ViewPort vp, Cancellable cancel,
842
                        double scale) throws ReadException, LoadLayerException {
843
                callCount++; // mess code, it is not unusual a wms server to response an error which is completely
844
                                         // temporal and the response is available if we retry requesting.
845
                                         //
846

    
847

    
848
                // This is the extent that will be requested
849
                Rectangle2D bBox = getRectable2DFromEnvelope(getFullEnvelope());
850
                MyCancellable c = new MyCancellable(cancel);
851

    
852
                try {
853
                        wmsStatus.setExtent( bBox );
854
                        wmsStatus.setFormat( m_Format );
855
                        wmsStatus.setHeight( fixedSize.height );
856
                        wmsStatus.setWidth( fixedSize.width );
857
                        wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
858
                        wmsStatus.setSrs(m_SRS);
859
                        wmsStatus.setStyles(styles);
860
                        wmsStatus.setDimensions(dimensions);
861
                        wmsStatus.setTransparency(wmsTransparency);
862
                        wmsStatus.setOnlineResource((String) onlineResources.get("GetMap"));
863
                        File f = getDriver().getMap(wmsStatus, c);
864
                        if (f == null) {
865
                                return;
866
                        }
867
                        String nameWorldFile = f.getPath() + getExtensionWorldFile();
868
                        org.gvsig.andami.Utilities.createTemp(nameWorldFile, this.getDataWorldFile(bBox, fixedSize));
869

    
870
                        IStatusRaster status = getStatus();
871
                        if(status!=null && firstLoad){
872
                                try {
873
                                        status.applyStatus(this);
874
                                } catch (NotSupportedExtensionException e) {
875
                                        throw new ReadException("", e);
876
                                } catch (RasterDriverException e) {
877
                                        throw new ReadException("", e);
878
                                } catch (FilterTypeException e) {
879
                                        throw new ReadException("", e);
880
                                }
881
                                firstLoad = false;
882
                        }
883

    
884
                        // And finally, obtain the extent intersecting the view and the BBox
885
                        // to draw to.
886
                        Rectangle2D extent = new Rectangle2D.Double();
887
                        Envelope vpEnv = vp.getAdjustedExtent();
888
                        Rectangle2D.Double vpExtent = this.getRectable2DFromEnvelope(vpEnv);
889

    
890
                        Rectangle2D.intersect(vpExtent, bBox, extent);
891

    
892
                        ViewPortData vpData = new ViewPortData(
893
                                vp.getProjection(), new Extent(extent), fixedSize );
894
                        vpData.setMat(vp.getAffineTransform());
895

    
896
                        String filePath = f.getAbsolutePath();
897
                        visualStatus.fileNames[0] = filePath;
898

    
899
                        try {
900
                                rasterProcess(filePath, g, vp, scale, cancel, 0);
901
                                this.updateDrawVersion();
902
                        } catch (FilterTypeException e) {
903
                        }
904
                } catch (ValidationException e) {
905
                        if (!c.isCanceled())
906
                        {
907
                                LoadLayerException exception = new LoadLayerException(getName(),e);
908
                                throw exception;
909
                        }
910
                } catch (IOException e) {
911
                        if (!c.isCanceled()) {
912
                                if (callCount<MAX_RETRY_TIMES) { // mess code
913
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
914
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
915
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
916
                                        drawFixedSize(g, vp, cancel, scale); // mess code
917
                                } // mess code
918
                        }
919

    
920
                                if (callCount == 1) { // mess code
921
//                                ConnectionErrorExceptionType type = new ConnectionErrorExceptionType();
922
//                                        type.setLayerName(getName());
923
//                                        try {
924
//                                                type.setDriverName("WMS Driver");
925
//                                        } catch (Exception e1) {
926
//                                        }
927
//                                        type.setHost(host);
928
                                        throw new ConnectionErrorLayerException(getName(),e);
929
                                } // mess code
930

    
931
                } catch (WMSException e) {
932
                        if (!c.isCanceled()) {
933
                                if (callCount<MAX_RETRY_TIMES) { // mess code
934
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
935
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
936
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
937
                                        drawFixedSize(g, vp, cancel, scale); // mess code
938
                                } // mess code
939
                                if (callCount == 1) { // mess code
940
                                        if (!isPrinting) {
941
                                                this.setVisible(false);
942
                                        }
943
                                        throw new LoadLayerException(getName(),e);
944

    
945

    
946
                                } // mess code
947
                        }
948
                }
949
                callCount--; // mess code
950
        }
951

    
952
        /**
953
         * Carga y dibuja el raster usando la librer?a
954
         *
955
         * @param filePath
956
         *            Ruta al fichero en disco
957
         * @param g
958
         *            Graphics2D
959
         * @param vp
960
         *            ViewPort
961
         * @param scale
962
         *            Escala para el draw
963
         * @param cancel
964
         *            Cancelaci?n para el draw
965
         * @throws ReadException
966
         * @throws LoadLayerException
967
         * @throws ReadException 
968
         */
969
        private void rasterProcess(String filePath, Graphics2D g, ViewPort vp, double scale, Cancellable cancel, int nLyr) throws LoadLayerException, FilterTypeException, ReadException {
970
                //Cargamos el dataset con el raster de disco.
971
                layerRaster[nLyr] = FLyrRasterSE.createLayer("", filePath, vp.getProjection());
972
                //layerRaster[nLyr].getRender().setBufferFactory(layerRaster[nLyr].getBufferFactory());
973
                layerRaster[nLyr].setNoDataValue(getNoDataValue());
974
                layerRaster[nLyr].setNoDataType(getNoDataType());
975

    
976
                //Obtenemos la tabla de color del raster abierto ya que se le va a sustituir la lista
977
                //de filtros y el de tabla de color no queremos sustituirlo.
978
                RasterFilterList rasterFilterList = layerRaster[nLyr].getRender().getFilterList();
979
                ColorTableFilter ct = (ColorTableFilter)rasterFilterList.getFilterByBaseClass(ColorTableFilter.class);
980
                Object param = null;
981
                if(ct != null)
982
                        param = ct.getParam("colorTable");
983

    
984
                //En caso de cargar un proyecto con XMLEntity se crean los filtros
985
                if(filterArguments != null) {
986
                        RasterFilterList fl = new RasterFilterList();
987
                        fl.addEnvParam("IStatistics", layerRaster[nLyr].getDataSource().getStatistics());
988
                        fl.addEnvParam("MultiRasterDataset", layerRaster[nLyr].getDataSource());
989
                        fl.setInitDataType(layerRaster[nLyr].getDataType()[0]);
990
                        RasterFilterListManager filterListManager = new RasterFilterListManager(fl);
991
                        filterListManager.createFilterListFromStrings(filterArguments);
992
                        filterArguments = null;
993
                        filterList = fl;
994
                }
995

    
996
                //Como el raster se carga a cada zoom el render se crea nuevamente y la lista de
997
                //filtros siempre estar? vacia a cada visualizaci?n. Para evitarlo tenemos que
998
                //guardar la lista de filtro aplicada en la visualizaci?n anterior.
999
                if(this.filterList != null) {
1000
                        this.disableUpdateDrawVersion();
1001
                        //Si ten?a tabla de color le asignamos la original
1002
                        if(param != null && param instanceof GridPalette) {
1003
                                this.filterList.remove(ColorTableFilter.class);
1004
                                RasterFilterListManager filterManager = new RasterFilterListManager(filterList);
1005
                                ColorTableListManager ctm = new ColorTableListManager(filterManager);
1006
                                ctm.addColorTableFilter((GridPalette)param);
1007
                                filterList.move(ColorTableFilter.class, 0);
1008
                                filterList.controlTypes();
1009
                        }
1010
                        layerRaster[nLyr].getRender().setFilterList(filterList);
1011
                        this.enableUpdateDrawVersion();
1012
                }
1013
                if(this.transparency != null)
1014
                        layerRaster[nLyr].getRender().setLastTransparency(transparency);
1015
                if(this.renderBands != null)
1016
                        layerRaster[nLyr].getRender().setRenderBands(renderBands);
1017

    
1018
                //Dibujamos
1019
                disableUpdateDrawVersion();
1020
                layerRaster[nLyr].draw(null, g, vp, cancel, scale);
1021
                enableUpdateDrawVersion();
1022

    
1023
                //La primera vez asignamos la lista de filtros asociada al renderizador. Guardamos una referencia
1024
                //en esta clase para que a cada zoom no se pierda.
1025
                if (this.filterList == null)
1026
                        filterList = layerRaster[nLyr].getRender().getFilterList();
1027
                if (this.transparency == null)
1028
                        transparency = layerRaster[nLyr].getRender().getLastTransparency();
1029
                if (this.renderBands == null)
1030
                        renderBands = layerRaster[nLyr].getRender().getRenderBands();
1031

    
1032
        }
1033

    
1034
        /*
1035
         * (non-Javadoc)
1036
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderFilterList()
1037
         */
1038
        public RasterFilterList getRenderFilterList(){
1039
                return (filterList != null) ? filterList : getRender().getFilterList();
1040
        }
1041

    
1042
        /*
1043
         * (non-Javadoc)
1044
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderFilterList(org.gvsig.raster.grid.filter.RasterFilterList)
1045
         */
1046
        public void setRenderFilterList(RasterFilterList filterList) {
1047
                if (filterList == this.filterList){
1048
                        return;
1049
                }
1050
                this.filterList = filterList;
1051
                this.updateDrawVersion();
1052
                super.getRender().setFilterList(filterList);
1053
        }
1054

    
1055
        /*
1056
         * (non-Javadoc)
1057
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderTransparency()
1058
         */
1059
        public GridTransparency getRenderTransparency() {
1060
                return (transparency != null) ? transparency : getRender().getLastTransparency();
1061
        }
1062

    
1063
        /*
1064
         * (non-Javadoc)
1065
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getRenderBands()
1066
         */
1067
        public int[] getRenderBands() {
1068
                return (renderBands != null) ? renderBands : getRender().getRenderBands();
1069
        }
1070

    
1071
        /*
1072
         * (non-Javadoc)
1073
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderBands(int[])
1074
         */
1075
        public void setRenderBands(int[] renderBands) {
1076
                //TODO: Comprobar si hay cambios
1077
                this.renderBands = renderBands;
1078
                this.updateDrawVersion();
1079
                getRender().setRenderBands(renderBands);
1080
        }
1081

    
1082
        /**
1083
         * This is the method used to draw a tile in a WMS mosaic layer.
1084
         *
1085
         * @throws LoadLayerException
1086
         * @throws ReadException
1087
         * @return true when a tile has been painted
1088
         */
1089
        private boolean drawTile(Graphics2D g, ViewPort vp, Cancellable cancel,
1090
                        int tile, double scale, int nLyr) throws LoadLayerException, ReadException {
1091
                callCount++;
1092
                // Compute the query geometry
1093
                // 1. Check if it is within borders
1094
                Envelope envelope = getFullEnvelope();
1095
                Envelope vpEnv = vp.getAdjustedExtent();
1096
                if (!vpEnv.intersects(envelope)) {
1097
                        return false;
1098
                }
1099

    
1100

    
1101
                // 2. Compute extent to be requested.
1102
                Rectangle2D bBox = new Rectangle2D.Double();
1103
                Rectangle2D.intersect(getRectable2DFromEnvelope(vpEnv),
1104
                                getRectable2DFromEnvelope(envelope), bBox);
1105

    
1106
                // 3. Compute size in pixels
1107
                double scalex = vp.getAffineTransform().getScaleX();
1108
                double scaley = vp.getAffineTransform().getScaleY();
1109
                int wImg = (int) Math.ceil(Math.abs(bBox.getWidth() * scalex) + 1);
1110
                int hImg = (int) Math.ceil(Math.abs(bBox.getHeight() * scaley) + 1);
1111

    
1112
                Dimension sz = new Dimension(wImg, hImg);
1113

    
1114
                if ((wImg <= 0) || (hImg <= 0)) {
1115
                        return false;
1116
                }
1117
                MyCancellable c = new MyCancellable(cancel);
1118

    
1119
                try {
1120
                        sz = new Dimension(wImg, hImg);
1121

    
1122

    
1123
                        wmsStatus.setExtent( bBox );
1124
                        wmsStatus.setFormat(m_Format);
1125
                        wmsStatus.setHeight( hImg );
1126
                        wmsStatus.setWidth( wImg );
1127
                        wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
1128
                        wmsStatus.setSrs(m_SRS);
1129
                        wmsStatus.setStyles(styles);
1130
                        wmsStatus.setDimensions(dimensions);
1131
                        wmsStatus.setTransparency(wmsTransparency);
1132
                        wmsStatus.setOnlineResource((String) onlineResources.get("GetMap"));
1133

    
1134
                        // begin patch; Avoid to request too small tiles.
1135
                        // This generally occurs when printing
1136

    
1137
                        if (wImg < minTilePrintWidth) {
1138
                                double wScale = (double) minTilePrintWidth / wImg;
1139
                                wmsStatus.setWidth(minTilePrintWidth);
1140
                                Rectangle2D sExtent = wmsStatus.getExtent();
1141
                                Point2D initialPoint = new Point2D.Double(sExtent.getX(), sExtent.getY());
1142
                                sExtent.setRect(sExtent.getX()*wScale, sExtent.getY(), sExtent.getWidth()*wScale, sExtent.getHeight());
1143
                                if (!bBox.contains(initialPoint)) {
1144
                                        sExtent.setRect(sExtent.getX() - initialPoint.getX(), sExtent.getY(), sExtent.getWidth(), sExtent.getHeight());
1145
                                }
1146
                        }
1147

    
1148
                        if (hImg < minTilePrintHeight) {
1149
                                double hScale = (double) minTilePrintHeight / hImg;
1150
                                wmsStatus.setHeight(minTilePrintHeight);
1151
                                Rectangle2D sExtent = wmsStatus.getExtent();
1152
                                Point2D initialPoint = new Point2D.Double(sExtent.getX(), sExtent.getY());
1153
                                sExtent.setRect(sExtent.getX(), sExtent.getY()*hScale, sExtent.getWidth(), sExtent.getHeight()*hScale);
1154
                                if (!bBox.contains(initialPoint)) {
1155
                                        sExtent.setRect(sExtent.getX(), sExtent.getY() - initialPoint.getY(), sExtent.getWidth(), sExtent.getHeight());
1156
                                }
1157
                        }
1158

    
1159
                        // end patch
1160
                        File f = getDriver().getMap(wmsStatus, c);
1161
                        if (f == null) {
1162
                                return false;
1163
                        }
1164
                        String nameWordFile = f.getPath() + getExtensionWorldFile();
1165
                        org.gvsig.andami.Utilities.createTemp(nameWordFile, this.getDataWorldFile(bBox, sz));
1166

    
1167
                        ViewPortData vpData = new ViewPortData(
1168
                                vp.getProjection(), new Extent(bBox), sz );
1169
                        vpData.setMat(vp.getAffineTransform());
1170

    
1171
                        String filePath = f.getAbsolutePath();
1172
                        visualStatus.fileNames[tile] = filePath;
1173
                        try {
1174
                                rasterProcess(filePath, g, vp, scale, cancel, nLyr);
1175
//                                this.updateDrawVersion();
1176
                        } catch (FilterTypeException e) {
1177
                        }
1178

    
1179
                } catch (ValidationException e) {
1180
                        if (!c.isCanceled())
1181
                        {
1182
                                LoadLayerException exception = new LoadLayerException(getName(),e);
1183
                                throw exception;
1184
                        }
1185
                } catch (IOException e) {
1186
                        if (!c.isCanceled()){
1187
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1188
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
1189
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1190
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1191

    
1192
                                        drawFixedSize(g, vp, cancel, scale); // mess code
1193
                                } // mess code
1194
                        }
1195
                        if (callCount == 1) { // mess code
1196
                                throw new ConnectionErrorLayerException(getName(),e);
1197
                        }//if
1198
                } catch (WMSException e) {
1199
                        if (!c.isCanceled()) {
1200
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1201
                                        logger.warn("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n"); // mess code
1202
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1203
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1204
                                        drawTile(g, vp, cancel, tile, scale, nLyr);
1205
                                } // mess code
1206
                                if (callCount == 1) { // mess code
1207
//                azabala                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), e.getMessage());
1208
                                        WMSDriverExceptionType type = new WMSDriverExceptionType();
1209
                                        type.setLayerName(getName());
1210
                                        try {
1211
                                                type.setDriverName("WMS Driver");
1212
                                        } catch (Exception e1) {
1213
                                        }
1214
                                        type.setWcsStatus(this.wmsStatus);
1215
                                        if (!isPrinting) {
1216
                                                this.setVisible(false);
1217
                                        }
1218
                                        throw new LoadLayerException(getName(),e);
1219

    
1220

    
1221
                                } //if
1222
                        }//if
1223
                }//catch
1224
                callCount--;
1225
                return true;
1226
        }
1227

    
1228
        /**
1229
         * Obtiene la extensi?n del fichero de georreferenciaci?n
1230
         * @return String con la extensi?n del fichero de georreferenciaci?n dependiendo
1231
         * del valor del formato obtenido del servidor. Por defecto asignaremos un .wld
1232
         */
1233
        private String getExtensionWorldFile(){
1234
                String extWorldFile = ".wld";
1235
                        if(m_Format.equals("image/tif") || m_Format.equals("image/tiff")) {
1236
                                extWorldFile = ".tfw";
1237
                        }
1238
                        if(m_Format.equals("image/jpeg")) {
1239
                                extWorldFile = ".jpgw";
1240
                        }
1241
                        return extWorldFile;
1242
        }
1243

    
1244
        /**
1245
         * Calcula el contenido del fichero de georreferenciaci?n de una imagen.
1246
         * @param bBox Tama?o y posici?n de la imagen (en coordenadas de usuario)
1247
         * @param sz Tama?o de la imagen en pixeles.
1248
         * @return el 'WorldFile', como String.
1249
         * @throws IOException
1250
         */
1251
        public String getDataWorldFile(Rectangle2D bBox, Dimension sz) throws IOException {
1252
                StringBuffer data = new StringBuffer();
1253
                        data.append((bBox.getMaxX() - bBox.getMinX())/(sz.getWidth() - 1)+"\n");
1254
                        data.append("0.0\n");
1255
                        data.append("0.0\n");
1256
                        data.append("-"+(bBox.getMaxY() - bBox.getMinY())/(sz.getHeight() - 1)+"\n");
1257
                        data.append(""+bBox.getMinX()+"\n");
1258
                        data.append(""+bBox.getMaxY()+"\n");
1259
                        return data.toString();
1260
        }
1261

    
1262
        /**
1263
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
1264
         *                 com.iver.cit.gvsig.fmap.ViewPort,
1265
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
1266
         */
1267
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties)
1268
                throws ReadException {
1269
                
1270
                closeAndFree();
1271
                
1272
                if (isVisible() && isWithinScale(scale)){
1273
                        isPrinting = true;
1274
                        if (!mustTilePrint) {
1275
                                draw(null, g, viewPort, cancel,scale);
1276
                        } else {
1277
                                // Para no pedir imagenes demasiado grandes, vamos
1278
                                // a hacer lo mismo que hace EcwFile: chunkear.
1279
                                // Llamamos a drawView con cuadraditos m?s peque?os
1280
                                // del BufferedImage ni caso, cuando se imprime viene con null
1281

    
1282
                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
1283
                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
1284
                                visualStatus.fileNames = new String[tiles.getNumTiles()];
1285
                                for (int tileNr=0; tileNr < tiles.getNumTiles(); tileNr++) {
1286
                                        // Parte que dibuja
1287
                                        try {
1288
                                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
1289
                                                drawTile(g, vp, cancel, tileNr, scale, tileNr);
1290
                                        } catch (NoninvertibleTransformException e) {
1291
                                                e.printStackTrace();
1292
                                        } catch (LoadLayerException e) {
1293
                                                // TODO Auto-generated catch block
1294
                                                e.printStackTrace();
1295
                                        }
1296
                                }
1297
                        }
1298
                        isPrinting = false;
1299
                }
1300
        }
1301

    
1302
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
1303
                        double scale) throws ReadException {
1304
                draw(null, g, viewPort, cancel,scale);
1305
        }
1306

    
1307
        /**
1308
         * Devuelve el FMapWMSDriver.
1309
         *
1310
         * @return FMapWMSDriver
1311
         *
1312
         * @throws IllegalStateException
1313
         * @throws ValidationException
1314
         * @throws UnsupportedVersionLayerException
1315
         * @throws IOException
1316
         */
1317
        public FMapWMSDriver getDriver()
1318
                throws IllegalStateException, ValidationException,
1319
                        UnsupportedVersionLayerException, IOException {
1320
                return FMapWMSDriverFactory.getFMapDriverForURL(host);
1321
        }
1322

    
1323
        /**
1324
         * Devuelve el FMapWMSDriver.
1325
         *
1326
         * @return FMapWMSDriver
1327
         *
1328
         * @throws IllegalStateException
1329
         * @throws ValidationException
1330
         * @throws UnsupportedVersionLayerException
1331
         * @throws IOException
1332
         */
1333
        public void setDriver(FMapWMSDriver drv) {
1334
                //TODO: Comprobar cambio
1335
                wms = drv;
1336
                this.updateDrawVersion();
1337
        }
1338

    
1339
        /**
1340
         * Devuelve el URL.
1341
         *
1342
         * @return URL.
1343
         */
1344
        public URL getHost() {
1345
                return host;
1346
        }
1347

    
1348
        /**
1349
         * Inserta el URL.
1350
         *
1351
         * @param host URL.
1352
         */
1353
        public void setHost(URL host) {
1354
                if (this.host == host){
1355
                        return;
1356
                }
1357
                if (this.host != null && this.host.equals(host)) {
1358
                        return;
1359
                }
1360

    
1361
                this.host = host;
1362
                this.updateDrawVersion();
1363
        }
1364

    
1365
        /**
1366
         * Devuelve la informaci?n de la consulta.
1367
         *
1368
         * @return String.
1369
         */
1370
        public String getInfoLayerQuery() {
1371
                return infoLayerQuery;
1372
        }
1373

    
1374
        /**
1375
         * Inserta la informaci?n de la consulta.
1376
         *
1377
         * @param infoLayerQuery String.
1378
         */
1379
        public void setInfoLayerQuery(String infoLayerQuery) {
1380
                this.infoLayerQuery = infoLayerQuery;
1381
        }
1382

    
1383
        /**
1384
         * Devuelve la consulta.
1385
         *
1386
         * @return String.
1387
         */
1388
        public String getLayerQuery() {
1389
                return layerQuery;
1390
        }
1391

    
1392
        /**
1393
         * Inserta la consulta.
1394
         *
1395
         * @param layerQuery consulta.
1396
         */
1397
        public void setLayerQuery(String layerQuery) {
1398
                if (this.layerQuery == layerQuery){
1399
                        return;
1400
                }
1401
                if (this.layerQuery != null && this.layerQuery.equals(layerQuery)){
1402
                        return;
1403
                }
1404

    
1405
                this.layerQuery = layerQuery;
1406
                this.updateDrawVersion();
1407
        }
1408

    
1409
        /**
1410
         * Devuelve el formato.
1411
         *
1412
         * @return Formato.
1413
         */
1414
        public String getFormat() {
1415
                return m_Format;
1416
        }
1417

    
1418
        /**
1419
         * Inserta el formato.
1420
         *
1421
         * @param format Formato.
1422
         */
1423
        public void setFormat(String format) {
1424
                if (this.m_Format == format){
1425
                        return;
1426
                }
1427
                if (this.m_Format != null && this.m_Format.equals(format)){
1428
                        return;
1429
                }
1430
                m_Format = format;
1431
                this.updateDrawVersion();
1432
        }
1433

    
1434
        /**
1435
         * Devuelve el SRS.
1436
         *
1437
         * @return SRS.
1438
         */
1439
        public String getSRS() {
1440
                return m_SRS;
1441
        }
1442

    
1443
        /**
1444
         * Inserta el SRS.
1445
         *
1446
         * @param m_srs SRS.
1447
         */
1448
        public void setSRS(String m_srs) {
1449
                if (m_SRS == m_srs){
1450
                        return;
1451
                }
1452
                if (m_SRS != null && m_SRS.equals(m_srs)){
1453
                        return;
1454
                }
1455
                m_SRS = m_srs;
1456
                this.updateDrawVersion();
1457
                setProjection(CRSFactory.getCRS(getSRS()));
1458
        }
1459

    
1460
        /**
1461
         * Inserta la extensi?n total de la capa.
1462
         *
1463
         * @param fullExtent
1464
         *            Rect?ngulo.
1465
         * @deprecated
1466
         */
1467
        public void setFullExtent(Rectangle2D fullExtent) {
1468
                this.setFullEnvelope(this.getEnvelopeFromRectable2D(fullExtent));
1469
        }
1470

    
1471
        /**
1472
         * Inserta la extensi?n total de la capa en la proyeccion original.
1473
         *
1474
         * @param fullExtent
1475
         *            Rect?ngulo.
1476
         */
1477
        public void setFullEnvelope(Envelope envelope) {
1478
                Envelope cur = this.getFullEnvelope();
1479
                if (cur == envelope) {
1480
                        return;
1481
                }
1482
                if (cur != null && cur.equals(envelope)) {
1483
                        return;
1484
                }
1485

    
1486
                this.fullEnvelope = envelope;
1487
                this.updateDrawVersion();
1488
        }
1489

    
1490

    
1491

    
1492
        public HashMap getProperties() {
1493
                HashMap info = new HashMap();
1494
                                String[] layerNames = getLayerQuery().split(",");
1495
                                Vector layers = new Vector(layerNames.length);
1496
                                try {
1497
                                                if(getDriver().connect(null)){
1498
                                                                for (int i = 0; i < layerNames.length; i++) {
1499
                                                                                layers.add(i, getDriver().getLayer(layerNames[i]));
1500
                                                                }
1501
                                                                info.put("name", getName());
1502
                                                                info.put("selectedLayers", layers);
1503
                                                                info.put("host", getHost());
1504
                                                                info.put("srs", getSRS());
1505
                                                                info.put("format", getFormat());
1506
                                                                info.put("wmsTransparency", new Boolean(wmsTransparency));
1507
                                                                info.put("styles", styles);
1508
                                                                info.put("dimensions", dimensions);
1509
                                                                info.put("fixedSize", fixedSize);
1510
                                                                return info;
1511
                                                }
1512
                                } catch (Exception e) {
1513
                                                e.printStackTrace();
1514
                                }
1515
                                return null;
1516
        }
1517

    
1518
        public double getMaxX() {
1519
                return visualStatus.maxX;
1520
        }
1521

    
1522
        public double getMaxY() {
1523
                return visualStatus.maxY;
1524
        }
1525

    
1526
        public double getMinX() {
1527
                return visualStatus.minX;
1528
        }
1529

    
1530
        public double getMinY() {
1531
                return visualStatus.minY;
1532
        }
1533

    
1534
                /**
1535
                 * @return Returns the wmsTransparency.
1536
                 */
1537
                public boolean isWmsTransparent() {
1538
                                return wmsTransparency;
1539
                }
1540

    
1541
                /**
1542
                 * @param wmsTransparency The wmsTransparency to set.
1543
                 */
1544
                public void setWmsTransparency(boolean wmsTransparency) {
1545
                        if (this.wmsTransparency == wmsTransparency){
1546
                                return;
1547
                        }
1548
                        this.wmsTransparency = wmsTransparency;
1549
                        this.updateDrawVersion();
1550
                }
1551

    
1552
                 /**
1553
                 * @param styles
1554
                 */
1555
                public void setStyles(Vector styles) {
1556
                    if (this.styles == styles){
1557
                            return;
1558
                    }
1559
                    if (this.styles != null && styles != null ){
1560
                            if (this.styles.containsAll(styles) && this.styles.size() ==styles.size()){
1561
                                    return;
1562
                            }
1563
                    }
1564
                    this.styles = styles;
1565
                    this.updateDrawVersion();
1566
                }
1567

    
1568
                /**
1569
                 * Sets the dimension vector that is a list of key-value pairs containing
1570
                 * the name of the dimension and the value for it
1571
                 * @param dimensions
1572
                 */
1573
                public void setDimensions(Vector dimensions) {
1574
                        if (this.dimensions == dimensions){
1575
                                return;
1576
                        }
1577
                        if (this.dimensions != null && dimensions != null ){
1578
                                if (this.dimensions.containsAll(dimensions) && this.dimensions.size() ==dimensions.size()){
1579
                                        return;
1580
                                }
1581
                        }
1582
                        this.dimensions = dimensions;
1583
                        this.updateDrawVersion();
1584
                }
1585

    
1586
                /**
1587
                 * Sets the set of URLs that should be accessed for each operation performed
1588
                 * to the server.
1589
                 *
1590
                 * @param onlineResources
1591
                 */
1592
        public void setOnlineResources(Hashtable onlineResources) {
1593
            if (this.onlineResources == onlineResources){
1594
                    return;
1595
            }
1596
            if (this.onlineResources != null && this.onlineResources.equals(onlineResources)){
1597
                    return;
1598
            }
1599

    
1600
                this.onlineResources = onlineResources;
1601
                this.updateDrawVersion();
1602
        }
1603

    
1604
                /**
1605
                 * Gets the URL that should be accessed for an operation performed
1606
                 * to the server.
1607
                 *
1608
                 * @param onlineResources
1609
                 */
1610
        public String getOnlineResource(String operation) {
1611
                return ((String) onlineResources.get(operation));
1612
        }
1613

    
1614
        /**
1615
         * When a server is not fully featured and it only can serve constant map
1616
         * sizes this value must be set. It expresses the size in pixels (width, height)
1617
         * that the map will be requested.
1618
         * @param Dimension sz
1619
         */
1620
        public void setFixedSize(Dimension sz) {
1621
                if (this.fixedSize == sz){
1622
                        return;
1623
                }
1624
                if (this.fixedSize != null && this.fixedSize.equals(sz)){
1625
                        return;
1626
                }
1627
                fixedSize = sz;
1628
                this.updateDrawVersion();
1629
        }
1630

    
1631
        /**
1632
         * Tells whether if this layer must deal with the server with the constant-size
1633
         * limitations or not.
1634
         * @return boolean.
1635
         */
1636
        private boolean isSizeFixed() {
1637
                return fixedSize != null && fixedSize.getWidth() > 0 && fixedSize.getHeight() > 0;
1638
        }
1639

    
1640
        /**
1641
         * If it is true, this layer accepts GetFeatureInfo operations. This WMS operations
1642
         * maps to FMap's infoByPoint(p) operation.
1643
         * @param b
1644
         */
1645
        public void setQueryable(boolean b) {
1646
                queryable = b;
1647
        }
1648

    
1649
        /**
1650
         * Creates the part of a OGC's MapContext document that would describe this
1651
         * layer(s).
1652
         * @param version, The desired version of the resulting document. (1.1.0)
1653
         * @return String containing the xml.
1654
         * @throws UnsupportedVersionLayerException
1655
         */
1656
        public String toMapContext(String mapContextVersion) {
1657
                XmlBuilder xml = new XmlBuilder();
1658
                FMapWMSDriver drv;
1659
                try {
1660
                        drv = getDriver();
1661
                } catch (Exception e) {
1662
                        return xml.toString();
1663
                }
1664
                String[] layerNames = getLayerQuery().split(",");
1665
                String[] styleNames = (String[]) styles.toArray(new String[0]);
1666
                for (int i = 0; i < layerNames.length; i++) {
1667
                        WMSLayerNode layer = drv.getLayer(layerNames[i]);
1668
                        HashMap xmlAttrs = new HashMap();
1669

    
1670
                        // <Layer>
1671
                        xmlAttrs.put(WebMapContextTags.HIDDEN, !isVisible()+"");
1672
                        xmlAttrs.put(WebMapContextTags.QUERYABLE, queryable+"");
1673
                        xml.openTag(WebMapContextTags.LAYER, xmlAttrs);
1674
                        xmlAttrs.clear();
1675
                        if (mapContextVersion.equals("1.1.0") || mapContextVersion.equals("1.0.0")) {
1676
                                // <Server>
1677
                                xmlAttrs.put(WebMapContextTags.SERVICE, WebMapContextTags.WMS);
1678
                                xmlAttrs.put(WebMapContextTags.VERSION, drv.getVersion());
1679
                                xmlAttrs.put(WebMapContextTags.SERVER_TITLE, drv.getServiceTitle());
1680
                                xml.openTag(WebMapContextTags.SERVER, xmlAttrs);
1681
                                xmlAttrs.clear();
1682

    
1683
                                        // <OnlineResource>
1684
                                        xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
1685
                                        xmlAttrs.put(WebMapContextTags.XLINK_HREF, getHost().toString());
1686
                                        xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
1687
                                        xmlAttrs.clear();
1688
                                        // </OnlineResource>
1689

    
1690
                                xml.closeTag();
1691
                                // </Server>
1692

    
1693
                                // <Name>
1694
                                xml.writeTag(WebMapContextTags.NAME, layer.getName().trim());
1695
                                // </Name>
1696

    
1697
                                // <Title>
1698
                                xml.writeTag(WebMapContextTags.TITLE, layer.getTitle().trim());
1699
                                //?xml.writeTag(WebMapContextTags.TITLE, getName().trim());
1700
                                // </Title>
1701

    
1702
                                // <Abstract>
1703
                                if (layer.getAbstract() != null) {
1704
                                        xml.writeTag(WebMapContextTags.ABSTRACT, layer.getAbstract());
1705
                                // </Abstract>
1706
                                }
1707

    
1708
                                // <SRS> (a list of available SRS for the enclosing layer)
1709
                                String[] strings = (String[]) layer.getAllSrs().toArray(new String[0]);
1710
                                String mySRS = strings[0];
1711
                                for (int j = 1; j < strings.length; j++) {
1712
                                        mySRS += ","+strings[j];
1713
                                }
1714
                                xml.writeTag(WebMapContextTags.SRS, mySRS);
1715
                                // </SRS>
1716

    
1717
                                // <FormatList>
1718
                                xml.openTag(WebMapContextTags.FORMAT_LIST);
1719
                                        strings = (String[]) drv.getFormats().toArray(new String[0]);
1720
                                        for (int j = 0; j < strings.length; j++) {
1721
                                                                                // <Format>
1722
                                                String str = strings[j].trim();
1723
                                                if (str.equals(getFormat())) {
1724
                                                        xml.writeTag(WebMapContextTags.FORMAT, str, WebMapContextTags.CURRENT, "1");
1725
                                                } else {
1726
                                                        xml.writeTag(WebMapContextTags.FORMAT, str);
1727
                                                                                // </Format>
1728
                                                }
1729
                                        }
1730
                                xml.closeTag();
1731
                                // </FormatList>
1732

    
1733
                                // <StyleList>
1734
                                xml.openTag(WebMapContextTags.STYLE_LIST);
1735

    
1736
                                        if (layer.getStyles().size()>0) {
1737
                                                for (int j = 0; j < layer.getStyles().size(); j++) {
1738
                                                        // <Style>
1739
                                                        FMapWMSStyle st = (FMapWMSStyle) layer.getStyles().get(j);
1740
                                                        if (st.name.equals(styleNames[i])) {
1741
                                                                xmlAttrs.put(WebMapContextTags.CURRENT, "1");
1742
                                                        }
1743
                                                        xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
1744
                                                        xmlAttrs.clear();
1745

    
1746
                                                                // <Name>
1747
                                                                xml.writeTag(WebMapContextTags.NAME, st.name);
1748
                                                                // </Name>
1749

    
1750
                                                                // <Title>
1751
                                                                xml.writeTag(WebMapContextTags.TITLE, st.title);
1752
                                                                // </Title>
1753

    
1754
                                                                // <LegendURL width="180" format="image/gif" height="50">
1755
                                                                        // <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
1756
                                                                        // </OnlineResource>
1757
                                                                // </LegendURL>
1758
                                                        xml.closeTag();
1759
                                                        // </Style>
1760

    
1761
                                                }
1762

    
1763
                                        } else {
1764
                                                // Create fake style (for compatibility issues)
1765
                                                xmlAttrs.put(WebMapContextTags.CURRENT, "1");
1766
                                                // <Style>
1767
                                                xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
1768
                                                        xmlAttrs.clear();
1769
                                                        // <Name>
1770
                                                        xml.writeTag(WebMapContextTags.NAME, "default");
1771
                                                        // </Name>
1772

    
1773
                                                        // <Title>
1774
                                                        xml.writeTag(WebMapContextTags.TITLE, "default");
1775
                                                        // </Title>
1776

    
1777
//                                                        // <LegendURL width="180" format="image/gif" height="50">
1778
//                                                        xmlAttrs.put(WebMapContextTags.WIDTH, "0");
1779
//                                                        xmlAttrs.put(WebMapContextTags.HEIGHT, "0");
1780
//                                                        xmlAttrs.put(WebMapContextTags.FORMAT.toLowerCase(), "image/gif");
1781
//                                                        xml.openTag(WebMapContextTags.LEGEND_URL, xmlAttrs);
1782
//                                                        xmlAttrs.clear();
1783
//                                                                // <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
1784
//                                                                xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
1785
//                                                                xmlAttrs.put(WebMapContextTags.XLINK_HREF, "http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif");
1786
//                                                                xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
1787
//                                                                // </OnlineResource>
1788
//                                                    // </LegendURL>
1789
//                                                        xml.closeTag();
1790
                                                // </Style>
1791
                                                xml.closeTag();
1792
                                        }
1793
                                // </StyleList>
1794
                                xml.closeTag();
1795
                                if (mapContextVersion.compareTo("1.0.0") > 0) {
1796
                                // <DimensionList>
1797
                                        xml.openTag(WebMapContextTags.DIMENSION_LIST);
1798
                                        // <Dimension>
1799
                                        // </Dimension>
1800
                                        xml.closeTag();
1801
                                // </DimensionList>
1802
                                }
1803
                        } else {
1804
                                xml.writeTag("ERROR", PluginServices.getText(this, "unsupported_map_context_version"));
1805
                        }
1806
                        // </Layer>
1807
                        xml.closeTag();
1808
                }
1809
                return xml.getXML();
1810
        }
1811

    
1812
        public String getTocImageIcon() {
1813
                return "icon-layer-wms";
1814
        }
1815

    
1816
        /*
1817
         *  (non-Javadoc)
1818
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#getTileSize()
1819
         */
1820
        public int[] getTileSize() {
1821
                int[] size = {maxTileDrawWidth, maxTileDrawHeight};
1822
                return size;
1823
        }
1824

    
1825
        /*
1826
         *  (non-Javadoc)
1827
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#isTiled()
1828
         */
1829
        public boolean isTiled() {
1830
                return mustTileDraw;
1831
        }
1832

    
1833
        public Image getImageLegend() {
1834
                try {
1835
                        if (wms == null) {
1836
                                wms = getDriver();
1837
                        }
1838
                        if (wms.hasLegendGraphic()) {
1839
                                wmsStatus.setOnlineResource((String) onlineResources
1840
                                                .get("GetLegendGraphic"));
1841
                                String path = getPathImage();// File legend =
1842
                                                                                                // getDriver().getLegendGraphic(wmsStatus,
1843
                                                                                                // layerQuery, null);
1844
                                Image img = null;
1845
                                if ((path != null) && (path.length() > 0)) {
1846
                                        img = new ImageIcon(path).getImage();
1847
                                }
1848
                                return img;
1849
                        }
1850
                } catch (Exception e) {
1851
                }
1852
                return null;
1853
        }
1854

    
1855
        public String getPathImage() {
1856
                try {
1857
                        File legend = getDriver().getLegendGraphic(wmsStatus, layerQuery, null);
1858
                        return legend.getAbsolutePath();
1859
                }catch(Exception e){
1860
                        e.printStackTrace();
1861
                        return null;
1862
                }
1863
        }
1864

    
1865
        /* (non-Javadoc)
1866
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#newComposedLayer()
1867
         */
1868
        public ComposedLayer newComposedLayer() {
1869
                Preferences prefs = Preferences.userRoot().node("gvsig.wms");
1870

    
1871
                /*
1872
                 * from java.util.prefs import Preferences
1873
                 * prefs = Preferences.userRoot().node("gvsig.wms")
1874
                 * prefs.put("useComposedLayer","true")
1875
                 */
1876

    
1877
                String str = prefs.get("useComposedLayer","false");
1878
                Boolean useComposedLayer = Boolean.TRUE; // por defecto ya se usan
1879
                try {
1880
                        useComposedLayer = Boolean.valueOf(str);
1881
                } catch (Exception e) {
1882

    
1883
                }
1884
                if (useComposedLayer.booleanValue()) {
1885
                        return new ComposedLayerWMS();
1886
                } else {
1887
                        return null;
1888
                }
1889
        }
1890

    
1891
        /**
1892
         * @param styles
1893
         */
1894
        public Vector getStyles() {
1895
                return this.styles;
1896
        }
1897

    
1898

    
1899
        /*
1900
         * Checks if can make a single petition for the two layers to the server
1901
         * @see com.iver.cit.gvsig.fmap.layers.ComposedLayerWMS#canAdd(com.iver.cit.gvsig.fmap.layers.FLayer)
1902
         */
1903
        boolean isComposedLayerCompatible(FLayer layer) {
1904
                FLyrWMS aLayer;
1905

    
1906
                if (!(layer instanceof FLyrWMS)) {
1907
                        return false;
1908
                }
1909
                aLayer = (FLyrWMS)layer;
1910
                if (!this.getHost().equals(aLayer.getHost())) {
1911
                        return false;
1912
                }
1913
                if (!this.getFormat().equals(aLayer.getFormat())) {
1914
                        return false;
1915
                }
1916
                if (!this.getSRS().equals(aLayer.getSRS())) {
1917
                        return false;
1918
                }
1919
                if (this.getInfoLayerQuery() != null) {
1920
                        if (!this.getInfoLayerQuery().equals(aLayer.getInfoLayerQuery())) {
1921
                                return false;
1922
                        }
1923
                }else if (aLayer.getInfoLayerQuery() != null) {
1924
                        return false;
1925
                }
1926

    
1927

    
1928
                // isFixedSize es privado
1929
                if ((this.fixedSize != null) &&
1930
                                (aLayer.fixedSize!= null)) {
1931
                        if (this.fixedSize.equals(aLayer.fixedSize)) {
1932
                                return false;
1933
                        }
1934
                } else if ((this.fixedSize != null) != (aLayer.fixedSize != null)) {
1935
                        return false;
1936
                }
1937

    
1938
                // time elevation (dimensions)
1939
                if ((this.dimensions != null) &&
1940
                                (aLayer.dimensions != null)) {
1941
                        if (this.dimensions.size() != aLayer.dimensions.size()) {
1942
                                return false;
1943
                        } else {
1944
                                Iterator iter = this.dimensions.iterator();
1945
                                while (iter.hasNext()) {
1946
                                        if (!aLayer.dimensions.contains(iter.next())) {
1947
                                                return false;
1948
                                        }
1949
                                }
1950
                        }
1951

    
1952
                } else if ((this.dimensions != null) != (aLayer.dimensions != null)) {
1953
                        return false;
1954
                }
1955

    
1956
                return true;
1957
        }
1958

    
1959
        /*
1960
         * (non-Javadoc)
1961
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#isActionEnabled(int)
1962
         */
1963
        public boolean isActionEnabled(int action) {
1964
                switch (action) {
1965
                        case IRasterLayerActions.ZOOM_PIXEL_RESOLUTION:
1966
                        case IRasterLayerActions.FLYRASTER_BAR_TOOLS:
1967
                        case IRasterLayerActions.BANDS_FILE_LIST:
1968
                        case IRasterLayerActions.COLOR_TABLE:
1969
                        case IRasterLayerActions.GEOLOCATION:
1970
                        case IRasterLayerActions.PANSHARPENING:
1971
                        case IRasterLayerActions.SAVE_COLORINTERP:
1972
                                return false;
1973
                        case IRasterLayerActions.REMOTE_ACTIONS:
1974
                                return true;
1975
                }
1976

    
1977
                return super.isActionEnabled(action);
1978
        }
1979

    
1980
        /*
1981
         * (non-Javadoc)
1982
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#getLegend()
1983
         */
1984
        public ILegend getLegend() {
1985
                return null;
1986
        }
1987

    
1988
        /*
1989
         * (non-Javadoc)
1990
         * @see org.gvsig.fmap.raster.IRasterOperations#getDatatype()
1991
         */
1992
        public int[] getDataType(){
1993
                try {
1994
                        return dataset.getDataType();
1995
                } catch (NullPointerException e) {
1996
                        if(layerRaster != null && layerRaster[0] != null)
1997
                                return layerRaster[0].getDataType();
1998
                        else
1999
                                return new int[]{IBuffer.TYPE_UNDEFINED};
2000
                }
2001
        }
2002

    
2003

    
2004
        /*
2005
         * (non-Javadoc)
2006
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#overviewsSupport()
2007
         */
2008
        public boolean overviewsSupport() {
2009
                return false;
2010
        }
2011

    
2012
        protected void updateDrawVersion() {
2013
                if (this.disableUpdateDrawVersion != null){
2014

    
2015
                        Thread curThread = Thread.currentThread();
2016

    
2017
                        Thread aThread;
2018

    
2019
                        Iterator iter = this.disableUpdateDrawVersion.iterator();
2020
                        while (iter.hasNext()){
2021
                                aThread = (Thread) ((WeakReference)iter.next()).get();
2022
                                if (aThread == null){
2023
                                        iter.remove();
2024
                                } else if(aThread.equals(curThread)){
2025
                                        return;
2026
                                }
2027
                        }
2028
                }
2029
//                Exception ex = new Exception();
2030
//                ex.printStackTrace();
2031
                super.updateDrawVersion();
2032
        }
2033

    
2034
        protected void disableUpdateDrawVersion(){
2035
                if (this.disableUpdateDrawVersion == null){
2036
                        this.disableUpdateDrawVersion = new ArrayList();
2037
                }
2038
                this.disableUpdateDrawVersion.add(new WeakReference(Thread.currentThread()));
2039
        }
2040

    
2041
        protected void enableUpdateDrawVersion(){
2042
                if (this.disableUpdateDrawVersion == null){
2043
                        return;
2044
                }
2045

    
2046
                Thread curThread = Thread.currentThread();
2047

    
2048
                Thread aThread;
2049

    
2050

    
2051
                Iterator iter = this.disableUpdateDrawVersion.iterator();
2052
                while (iter.hasNext()){
2053
                        aThread = (Thread) ((WeakReference)iter.next()).get();
2054
                        if (aThread == null){
2055
                                iter.remove();
2056
                        } else if(aThread.equals(curThread)){
2057
                                iter.remove();
2058
                                break;
2059
                        }
2060
                }
2061

    
2062
        }
2063

    
2064
        private Rectangle2D.Double getRectable2DFromEnvelope(Envelope env) {
2065
                return new Rectangle2D.Double(env.getMinimum(0), env.getMinimum(1), env
2066
                                .getLength(0), env.getLength(1));
2067
        }
2068

    
2069
        private Envelope getEnvelopeFromRectable2D(Rectangle2D rect) {
2070
                try {
2071
                        return geomManager.createEnvelope(rect.getMinX(), rect.getMinY(),
2072
                                        rect
2073
                                        .getMaxX(), rect.getMaxY(),
2074
                                        SUBTYPES.GEOM2D);
2075
                } catch (CreateEnvelopeException e) {
2076
                        logger.error("Error creating the envelope", e);
2077
                }
2078
                return null;
2079
        }
2080

    
2081
        /**
2082
         * Devuelve el envelope en la proyeccion de la vista
2083
         *
2084
         */
2085
        public Envelope getFullEnvelope() {
2086
                Envelope rAux;
2087
                rAux = this.fullEnvelope;
2088

    
2089
                // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
2090
                // y alto 0.
2091
                if (rAux == null || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
2092
                                && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
2093
                        try {
2094
                                rAux = geomManager.createEnvelope(0, 0, 100, 100, SUBTYPES.GEOM2D);
2095
                        } catch (CreateEnvelopeException e) {
2096
                                logger.error("Error creating the envelope", e);
2097
                        }
2098
                }
2099
                // Si existe reproyecci?n, reproyectar el extent
2100
                ICoordTrans ct = getCoordTrans();
2101
                if (ct != null) {
2102
                        Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux
2103
                                        .getMinimum(1));
2104
                        Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux
2105
                                        .getMaximum(1));
2106
                        pt1 = ct.convert(pt1, null);
2107
                        pt2 = ct.convert(pt2, null);
2108
                        try {
2109
                                rAux = geomManager.createEnvelope(pt1.getX(), pt1.getY(), pt2
2110
                                                .getX(), pt2.getY(), SUBTYPES.GEOM2D);
2111
                        } catch (CreateEnvelopeException e) {
2112
                                logger.error("Error creating the envelope", e);
2113
                        }// new
2114
                                                                                                                // Rectangle2D.Double();
2115
                }
2116
                return rAux;
2117

    
2118
        }
2119
        
2120
        /*
2121
         * (non-Javadoc)
2122
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#getFileLayer()
2123
         */
2124
        public FLayer getFileLayer() {
2125
                if(layerRaster != null && layerRaster[0] != null) {
2126
                        FLyrRasterSE ly = null;
2127
                        if(lastNColumns == 0 && lastNRows == 0) {
2128
                                try {
2129
                                        ly = createLayer(layerRaster[0].getName(), layerRaster[0].getLoadParams(), layerRaster[0].getProjection());
2130
                                } catch (LoadLayerException e) {
2131
                                        return null;
2132
                                }
2133
                        } else {
2134

    
2135
                                String[][] s = new String[lastNRows][lastNColumns];
2136

    
2137
                                for (int i = 0; i < s.length; i++) {
2138
                                        for (int j = 0; j < s[0].length; j++) {
2139
                                                s[i][j] = ((FLyrRasterSE)layerRaster[i]).getDataSource().getNameDatasetStringList(i, j)[0];
2140
                                        }
2141
                                }
2142
                                try {
2143
                                        ly = createLayer("preview", s, getProjection());
2144
                                } catch (LoadLayerException e) {
2145
                                        return null;
2146
                                }
2147
                        }
2148
                        return ly;
2149
                }
2150
                return null;
2151
        }
2152
        
2153
        public Iterator getInfo(Point p, double tolerance, Cancellable cancel)
2154
                throws LoadLayerException, DataException {
2155
                // TODO Auto-generated method stub
2156
//                XMLItem[] item = new XMLItem[1];
2157
//                try {
2158
//                        if (queryable)         {
2159
//                                //TODO
2160
//                                // check if there are layers which are not queryable
2161
//                                ViewPort viewPort = getMapContext().getViewPort();
2162
//
2163
//                                Point tiledPoint = new Point((int) p.getX() % maxTilePrintWidth, (int) p.getY() % maxTilePrintHeight);
2164
//                                Rectangle rect = new Rectangle(0, 0, viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1);
2165
//                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, rect);
2166
//                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
2167
//                                int nCols = tiles.getNumCols();
2168
//
2169
//                                int col = (int) p.getX() / maxTilePrintWidth;
2170
//                                int row = (int) p.getY() / maxTilePrintHeight;
2171
//                                int tileIndex = (row*nCols) + col;
2172
//
2173
//                                ViewPort vp = tiles.getTileViewPort(viewPort, tileIndex);
2174
//                                wmsStatus.setExtent(this.getRectable2DFromEnvelope(vp
2175
//                                                .getAdjustedExtent()));
2176
//                                wmsStatus.setHeight(vp.getImageHeight());
2177
//                                wmsStatus.setWidth(vp.getImageWidth());
2178
//                                wmsStatus.setOnlineResource((String) onlineResources.get("GetFeatureInfo"));
2179
//
2180
//
2181
//                                wmsStatus.setFormat( m_Format );
2182
//                                wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
2183
//                                wmsStatus.setSrs(m_SRS);
2184
//                                wmsStatus.setStyles(styles);
2185
//                                wmsStatus.setDimensions(dimensions);
2186
//                                wmsStatus.setTransparency(wmsTransparency);
2187
//                                wmsStatus.setSrs(m_SRS);
2188
//                                MyCancellable c = new MyCancellable(cancellable);
2189
//                                try {
2190
//                                        item[0] = new StringXMLItem(new String(getDriver()
2191
//                                                        .getFeatureInfo(wmsStatus, (int) tiledPoint.getX(), (int) tiledPoint.getY(), Integer.MAX_VALUE, c)),this);
2192
//                                } catch (UnsupportedVersionLayerException e) {
2193
//                                        throw new ReadException(FMapWMSDriver.class.getName()
2194
//                                                        + "::" + getName()
2195
//                                                        + " - UnsupportedVersionLayerException", e);
2196
//                                } catch (IllegalStateException e) {
2197
//                                        throw new ReadException(FMapWMSDriver.class.getName()
2198
//                                                        + "::" + getName() + " - IllegalStateException", e);
2199
//                                }
2200
//                                return item;
2201
//                        }
2202
//                        else
2203
//                        {
2204
//                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),this.getName() + " " +
2205
//                                                PluginServices.getText(this,"layer_not_queryable"));
2206
//                                item[0] =  new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><info></info>",this);
2207
//                                return item;
2208
//                                //return null;
2209
//                        }
2210
//                } catch (WMSException  e) {
2211
//                        item[0] = new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
2212
//                        e.getMessage() + "</exception>", this);
2213
//                        return item;
2214
//                } catch (ValidationException e) {
2215
//                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
2216
//                                        + getName() + " - ValidationException", e);
2217
//                } catch (IOException e) {
2218
//                        throw new ReadException(FMapWMSDriver.class.getName() + "::"
2219
//                                        + getName() + " - IOException", e);
2220
//                } catch (NoninvertibleTransformException e) {
2221
//                        NotificationManager.addError("NotinvertibleTransform", e);
2222
//                }
2223
//                return null;
2224
                return null;
2225
        }
2226

    
2227
}