Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extWMS / src / com / iver / cit / gvsig / fmap / layers / FLyrWMS.java @ 38898

History | View | Annotate | Download (72.7 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 com.iver.cit.gvsig.fmap.layers;
42

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

    
73
import javax.print.attribute.PrintRequestAttributeSet;
74
import javax.swing.ImageIcon;
75
import javax.swing.JOptionPane;
76

    
77
import org.cresques.cts.IProjection;
78
import org.cresques.geo.ViewPortData;
79
import org.cresques.px.Extent;
80
import org.exolab.castor.xml.ValidationException;
81
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
82
import org.gvsig.fmap.raster.layers.IRasterLayerActions;
83
import org.gvsig.fmap.raster.layers.IStatusRaster;
84
import org.gvsig.fmap.raster.layers.StatusLayerRaster;
85
import org.gvsig.raster.dataset.CompositeDataset;
86
import org.gvsig.raster.dataset.IBuffer;
87
import org.gvsig.raster.dataset.MosaicNotValidException;
88
import org.gvsig.raster.dataset.MultiRasterDataset;
89
import org.gvsig.raster.dataset.NotSupportedExtensionException;
90
import org.gvsig.raster.dataset.io.RasterDriverException;
91
import org.gvsig.raster.grid.GridPalette;
92
import org.gvsig.raster.grid.GridTransparency;
93
import org.gvsig.raster.grid.filter.FilterTypeException;
94
import org.gvsig.raster.grid.filter.RasterFilterList;
95
import org.gvsig.raster.grid.filter.RasterFilterListManager;
96
import org.gvsig.raster.grid.filter.bands.ColorTableFilter;
97
import org.gvsig.raster.grid.filter.bands.ColorTableListManager;
98
import org.gvsig.remoteClient.utils.Utilities;
99
import org.gvsig.remoteClient.wms.ICancellable;
100
import org.gvsig.remoteClient.wms.WMSStatus;
101

    
102
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
103
import com.hardcode.gdbms.engine.data.driver.DriverException;
104
import com.iver.andami.PluginServices;
105
import com.iver.andami.messages.NotificationManager;
106
import com.iver.cit.gvsig.exceptions.layers.ConnectionErrorLayerException;
107
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
108
import com.iver.cit.gvsig.exceptions.layers.URLLayerException;
109
import com.iver.cit.gvsig.exceptions.layers.UnsupportedVersionLayerException;
110
import com.iver.cit.gvsig.fmap.ConnectionErrorExceptionType;
111
import com.iver.cit.gvsig.fmap.MapContext;
112
import com.iver.cit.gvsig.fmap.ViewPort;
113
import com.iver.cit.gvsig.fmap.WMSDriverExceptionType;
114
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
115
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
116
import com.iver.cit.gvsig.fmap.drivers.wms.FMapWMSDriver;
117
import com.iver.cit.gvsig.fmap.drivers.wms.FMapWMSDriverFactory;
118
import com.iver.cit.gvsig.fmap.drivers.wms.WMSException;
119
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode.FMapWMSStyle;
120
import com.iver.cit.gvsig.fmap.layers.layerOperations.ComposedLayer;
121
import com.iver.cit.gvsig.fmap.layers.layerOperations.IHasImageLegend;
122
import com.iver.cit.gvsig.fmap.layers.layerOperations.StringXMLItem;
123
import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem;
124
import com.iver.cit.gvsig.fmap.rendering.ILegend;
125
import com.iver.cit.gvsig.fmap.rendering.XmlBuilder;
126
import com.iver.cit.gvsig.wmc.WebMapContextTags;
127
import com.iver.utiles.StringUtilities;
128
import com.iver.utiles.XMLEntity;
129
import com.iver.utiles.swing.threads.Cancellable;
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 boolean                                         isPrinting = false;
161
        private boolean                                         mustTileDraw = true;
162
        private boolean                                         mustTilePrint = true;
163
        private final int                                         maxTileDrawWidth = 1023;
164
        private final int                                         maxTileDrawHeight = 1023;
165
        private final int                                         maxTilePrintWidth = 1023;
166
        private final int                                         maxTilePrintHeight = 1023;
167
        private final int                                        minTilePrintWidth = 12;
168
        private final int                                        minTilePrintHeight = 12;
169

    
170
        public URL                                                         host;
171
        public String                                                 m_Format;
172

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

    
196
        private List                                                disableUpdateDrawVersion;
197
        private int                         lastNColumns = 0;
198
        private int                         lastNRows = 0;
199
        private boolean                                         hasImageLegend = false;
200
        
201
        private int cachedAxisOrientation = WMSStatus.CRS_AXIS_OTHER_OR_UNKNOWN;
202

    
203
        /***
204
         * WMS 1.3 standard defines a fixed pixel size of 0.28 mm for the server.
205
         * As
206
         *   1 inch = 25.4 mm
207
         * then the server is supposed to have the following DPI:
208
         *   25.4 / 0.28 = 90.714285714 dpi
209
         */
210

    
211
        private final double WMS_DPI = 90.714285714;
212
        private String infoFormat;
213
   
214

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

    
230
        }
231

    
232
        public FLyrWMS(){
233
                super();
234
                this.updateDrawVersion();
235
        }
236

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

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

    
266
                        WMSLayerNode wmsNode = drv.getLayer(sLayer);
267

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

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

    
300

    
301
                this.setFullExtent(fullExtent);
302
                this.setFormat(sFormat);
303
                this.setLayerQuery(sLayer);
304
                this.setInfoLayerQuery("");
305
                this.setSRS(sSRS);
306
                this.setName(sLayer);
307
                this.setOnlineResources(drv.getOnlineResources());
308
                if (drv.getInfoFormats() != null) {
309
                        if (drv.getInfoFormats().size() > 0)
310
                                this.setInfoFormat((String) drv.getInfoFormats().get(0));
311
                }
312
                
313
                this.setDriver(drv);
314
                initServerScale();
315
                load();
316
        }
317

    
318
        private void setInfoFormat(String infoFormat) {
319
                this.infoFormat = infoFormat;
320
        }
321

    
322
        /**
323
         * It choose the best format to load different maps if the server
324
         * supports it. This format could be png, because it supports
325
         * transparency.
326
         * @param formats
327
         * Arraywith all the formats supported by the server
328
         * @return
329
         */
330
        private String getGreatFormat(Vector formats){
331
                        for (int i=0 ; i<formats.size() ; i++){
332
                                        String format = (String) formats.get(i);
333
                                if (format.equals("image/jpg")){
334
                                                        return format;
335
                                }
336
                                if (format.equals("image/jpeg")){
337
                                                        return format;
338
                                }
339
                        }
340

    
341
                        return (String)formats.get(0);
342
        }
343

    
344
        /**
345
         * Clase que contiene los datos de visualizaci?n de WMS.
346
         * @author Nacho Brodin (brodin_ign@gva.es)
347
         */
348
        private class VisualStatus{
349
                /**
350
                 * Ancho y alto de la imagen o del conjunto de tiles si los tiene. Coincide con
351
                 * el ancho y alto del viewPort
352
                 */
353
                private double                                                minX = 0D;
354
                private double                                                minY = 0D;
355
                private double                                                maxX = 0D;
356
                private double                                                maxY = 0D;
357
                /**
358
                 * Lista de nombre de fichero que componen toda la visualizaci?n.
359
                 */
360
                private String[]                                        fileNames = null;
361

    
362
                public Object clone() {
363
                        VisualStatus s = new VisualStatus();
364
                        s.maxX = maxX;
365
                        s.maxY = maxY;
366
                        s.minX = minX;
367
                        s.minY = minY;
368
                        s.fileNames = new String[fileNames.length];
369
                        for (int i = 0; i < fileNames.length; i++)
370
                                s.fileNames[i] = fileNames[i];
371
                        return s;
372
                }
373
        }
374

    
375

    
376
        /**
377
         * Devuelve el XMLEntity con la informaci?n necesaria para reproducir la
378
         * capa.
379
         *
380
         * @return XMLEntity.
381
         * @throws XMLException
382
         */
383
        public XMLEntity getXMLEntity() throws XMLException {
384
                XMLEntity xml = super.getXMLEntityWithoutChecks();
385
                if (xml != null){
386

    
387
                        // Full extent
388
                        xml.putProperty("fullExtent", StringUtilities.rect2String(fullExtent));
389

    
390
                        // Host
391
                        xml.putProperty("host", host.toExternalForm());
392

    
393
                        // Part of the query that is not the host, or the
394
                        // layer names, or other not listed bellow
395
                        xml.putProperty("infoLayerQuery", infoLayerQuery);
396

    
397
                        // Part of the query containing the layer names
398
                        xml.putProperty("layerQuery", layerQuery);
399

    
400
                        // Format
401
                        xml.putProperty("format", m_Format);
402

    
403
                        // SRS
404
                        xml.putProperty("srs", m_SRS);
405
                        if (status!=null)
406
                                status.getXMLEntity(xml, true, this);
407
                        else{
408
                                status = new StatusLayerRaster();
409
                                status.getXMLEntity(xml, true, this);
410
                        }
411

    
412
                        // Transparency
413
                        xml.putProperty("wms_transparency", wmsTransparency);
414

    
415
                        // Styles
416
                        if (styles!=null){
417
                                String stylePr = "";
418
                                for (int i = 0; i < styles.size(); i++) {
419
                                        stylePr += styles.get(i).toString();
420
                                        if (i<styles.size()-1)
421
                                                stylePr += ",";
422
                                }
423
                                if (stylePr.endsWith(","))
424
                                        stylePr += " ";
425
                                xml.putProperty("styles", stylePr);
426
                        }
427

    
428
                        // Dimensions
429
                        if (dimensions!=null){
430
                                String dim = "";
431
                                for (int i = 0; i < dimensions.size(); i++) {
432
                                        dim += (String) dimensions.get(i);
433
                                        if (i<dimensions.size()-1)
434
                                                dim += ",";
435
                                }
436
                                if (dim.endsWith(","))
437
                                        dim += " ";
438
                                xml.putProperty("dimensions", dim);
439
                        }
440

    
441
                        // OnlineResources
442
                        Iterator it = onlineResources.keySet().iterator();
443
                        String strOnlines = "";
444
                        while (it.hasNext()) {
445
                                String key = (String) it.next();
446
                                String value = (String) onlineResources.get(key);
447
                                strOnlines += key+"~##SEP2##~"+value;
448
                                if (it.hasNext())
449
                                        strOnlines += "~##SEP1##~";
450
                        }
451
                        xml.putProperty("onlineResources", strOnlines);
452

    
453
                        // Queryable
454
                        xml.putProperty("queryable", queryable);
455
                        if(wms != null)
456
                                xml.putProperty("hasImageLegend", wms.hasLegendGraphic());
457

    
458
                        // fixedSize
459
                        if (isSizeFixed()) {
460
                                xml.putProperty("fixedSize", true);
461
                                xml.putProperty("fixedWidth", fixedSize.width);
462
                                xml.putProperty("fixedHeight", fixedSize.height);
463
                        }
464
                }
465
                return xml;
466
        }
467

    
468
        /**
469
         * A partir del XMLEntity reproduce la capa.
470
         *
471
         * @param xml XMLEntity
472
         *
473
         * @throws XMLException
474
         * @throws DriverException
475
         * @throws DriverIOException
476
         */
477
        public void setXMLEntity03(XMLEntity xml)
478
                throws XMLException {
479
                super.setXMLEntity(xml);
480
                fullExtent = StringUtilities.string2Rect(xml.getStringProperty(
481
                                        "fullExtent"));
482

    
483
                try {
484
                        host = new URL(xml.getStringProperty("host"));
485
                } catch (MalformedURLException e) {
486
                        throw new XMLException(e);
487
                }
488

    
489
                infoLayerQuery = xml.getStringProperty("infoLayerQuery");
490
                layerQuery = xml.getStringProperty("layerQuery");
491
                m_Format = xml.getStringProperty("format");
492
                m_SRS = xml.getStringProperty("srs");
493
        }
494

    
495
        /**
496
         * A partir del XMLEntity reproduce la capa.
497
         *
498
         * @param xml XMLEntity
499
         *
500
         * @throws XMLException
501
         * @throws DriverException
502
         * @throws DriverIOException
503
         */
504
        public void setXMLEntity(XMLEntity xml)
505
                throws XMLException {
506
                for (int i = 0; i < xml.getPropertyCount(); i++) {
507
                        String key = xml.getPropertyName(i);
508
                        if(key.startsWith("raster.file")) {
509
                                xml.putProperty(key, "");
510
                        }
511
                }
512

    
513

    
514
                super.setXMLEntity(xml);
515
                fullExtent = StringUtilities.string2Rect(xml.getStringProperty(
516
                                        "fullExtent"));
517

    
518
                // Host
519
                try {
520
                        host = new URL(xml.getStringProperty("host"));
521
                } catch (MalformedURLException e) {
522
                        throw new XMLException(e);
523
                }
524

    
525
                // Part of the query that is not the host, or the
526
                // layer names, or other not listed bellow
527
                infoLayerQuery = xml.getStringProperty("infoLayerQuery");
528

    
529
                // Part of the query containing the layer names
530
                layerQuery = xml.getStringProperty("layerQuery");
531

    
532
                // Format
533
                m_Format = xml.getStringProperty("format");
534

    
535
                // SRS
536
                m_SRS = xml.getStringProperty("srs");
537

    
538
                String claseStr = StatusLayerRaster.defaultClass;
539
                if (xml.contains("raster.class")) {
540
                        claseStr = xml.getStringProperty("raster.class");
541
                }
542

    
543
                // Transparency
544
                                if (xml.contains("wms_transparency"))
545
                                                wmsTransparency = xml.getBooleanProperty("wms_transparency");
546

    
547
                                // Styles
548
                                if (xml.contains("styles")){
549
                                                styles = new Vector();
550
                                                String[] stl = xml.getStringProperty("styles").split(",");
551

    
552
                                                for (int i = 0; i < stl.length; i++) {
553
                                                        if (stl[i].equals(" "))
554
                                                                stl[i]="";
555
                                                                styles.add(stl[i]);
556
                                                }
557
                                }
558

    
559
                                // Dimensions
560
                                if (xml.contains("dimensions")){
561
                                                dimensions = new Vector();
562
                                                String[] dims = xml.getStringProperty("dimensions").split(",");
563
                                                for (int i = 0; i < dims.length; i++){
564
                                                        if (dims[i].equals(" "))
565
                                                                dims[i]="";
566

    
567
                                                                dimensions.add(dims[i]);
568
                                                }
569
                                }
570

    
571
                                // OnlineResources
572
                                if (xml.contains("onlineResources")) {
573
                                        String[] operations = xml.getStringProperty("onlineResources").split("~##SEP1##~");
574
                                        for (int i = 0; i < operations.length; i++) {
575
                                String[] resources = operations[i].split("~##SEP2##~");
576
                                if (resources.length==2 && resources[1]!="")
577
                                        onlineResources.put(resources[0], resources[1]);
578
                        }
579
                                }
580

    
581
                                // Queryable
582
                                queryable = true; // let's assume that the layer is queryable by default
583
                                if (xml.contains("queryable"))
584
                                        queryable = xml.getBooleanProperty("queryable");
585

    
586
                                hasImageLegend=false;
587
                                if (xml.contains("hasImageLegend")){
588
                                        hasImageLegend=xml.getBooleanProperty("hasImageLegend");
589
                                }
590

    
591
                                // fixedSize
592
                                if (xml.contains("fixedSize")) {
593
                                        fixedSize = new Dimension(xml.getIntProperty("fixedWidth"),
594
                                                                                                                                xml.getIntProperty("fixedHeight"));
595
                                }
596

    
597
                if(status!=null)
598
                        status.setXMLEntity(xml, this);
599
                else{
600
                        if(claseStr != null && !claseStr.equals("")){
601
                                try{
602
                                        Class clase = LayerFactory.getLayerClassForLayerClassName(claseStr);
603
                                        Constructor constr = clase.getConstructor(null);
604
                                        status = (IStatusRaster)constr.newInstance(null);
605
                                        if(status != null) {
606
                                                ((StatusLayerRaster)status).setNameClass(claseStr);
607
                                                status.setXMLEntity(xml, this);
608
                                                filterArguments = status.getFilterArguments();
609
                                                transparency = status.getTransparency();
610
                                                renderBands = status.getRenderBands();
611
                                        }
612
                                }catch(ClassNotFoundException exc){
613
                                        exc.printStackTrace();
614
                                }catch(InstantiationException exc){
615
                                        exc.printStackTrace();
616
                                }catch(IllegalAccessException exc){
617
                                        exc.printStackTrace();
618
                                }catch(NoSuchMethodException exc){
619
                                        exc.printStackTrace();
620
                                }catch(InvocationTargetException exc){
621
                                        exc.printStackTrace();
622
                                }
623
                        }
624
                }
625
                firstLoad = true;
626
        }
627

    
628
        /**
629
         * @throws ReadDriverException
630
         * @throws LoadLayerException
631
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(com.iver.cit.gvsig.fmap.operations.QueriedPoint)
632
         */
633
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancellable) throws ReadDriverException {
634
                XMLItem[] item = new XMLItem[1];
635
                try {
636
                        if (queryable)         {
637
                                //TODO
638
                                // check if there are layers which are not queryable
639
                                ViewPort viewPort = getMapContext().getViewPort();
640

    
641
                                Point tiledPoint = new Point((int) p.getX() % maxTilePrintWidth, (int) p.getY() % maxTilePrintHeight);
642
                                Rectangle rect = new Rectangle(0, 0, viewPort.getImageWidth() - 1, viewPort.getImageHeight() - 1);
643
                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, rect);
644
                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
645
                                int nCols = tiles.getNumCols();
646

    
647
                                int col = (int) p.getX() / maxTilePrintWidth;
648
                                int row = (int) p.getY() / maxTilePrintHeight;
649
                                int tileIndex = (row*nCols) + col;
650

    
651
                                ViewPort vp = tiles.getTileViewPort(viewPort, tileIndex);
652
                                wmsStatus.setExtent(vp.getAdjustedExtent());
653
                                wmsStatus.setHeight(vp.getImageHeight());
654
                                wmsStatus.setWidth(vp.getImageWidth());
655
                                wmsStatus.setOnlineResource((String) onlineResources.get("GetFeatureInfo"));
656
                                
657
                                // We search for application string
658
                                // TODO: Maybe the user wants to select the format        
659
                                if (infoFormat == null) {
660
                                        try {
661
                                                infoFormat = "text/xml"; // bydefault
662
                                                if (getDriver().getInfoFormats().size() > 0) {
663
                                                        for (int iFormat = 0; iFormat < getDriver().getInfoFormats().size(); iFormat++ ) {
664
                                                                String auxFormat = (String) getDriver().getInfoFormats().get(iFormat);
665
                                                                if (auxFormat.contains("vnd.ogc")) {
666
                                                                        infoFormat = auxFormat;
667
                                                                        break;
668
                                                                }
669
                                                        }
670
                                                }
671
                                        } catch (UnsupportedVersionLayerException e) {
672
                                                e.printStackTrace();
673
                                                throw new ReadDriverException(FMapWMSDriver.class.getName()+"::"+getName()+" - UnsupportedVersionLayerException", e);
674
                                        } catch (IllegalStateException e) {
675
                                                e.printStackTrace();
676
                                                throw new ReadDriverException(FMapWMSDriver.class.getName()+"::"+getName()+" - UnsupportedVersionLayerException", e);
677
                                        }
678
                                }
679
                                wmsStatus.setInfoFormat(infoFormat);
680

    
681

    
682
                                wmsStatus.setFormat( m_Format );
683
                                wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
684
                                wmsStatus.setSrs(m_SRS);
685
                                wmsStatus.setCrsAxisOrder(cachedAxisOrientation);
686
                                wmsStatus.setStyles(styles);
687
                                wmsStatus.setDimensions(dimensions);
688
                                wmsStatus.setTransparency(wmsTransparency);
689
                                MyCancellable c = new MyCancellable(cancellable);
690
                                try {
691
                                        item[0] = new StringXMLItem(new String(getDriver()
692
                                                        .getFeatureInfo(wmsStatus, (int) tiledPoint.getX(), (int) tiledPoint.getY(), Integer.MAX_VALUE, c)),this);
693
                                } catch (UnsupportedVersionLayerException e) {
694
                                        throw new ReadDriverException(FMapWMSDriver.class.getName()+"::"+getName()+" - UnsupportedVersionLayerException", e);
695
                                } catch (IllegalStateException e) {
696
                                        throw new ReadDriverException(FMapWMSDriver.class.getName()+"::"+getName()+" - IllegalStateException", e);
697
                                }
698
                                return item;
699
                        }
700
                        else
701
                        {
702
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),this.getName() + " " +
703
                                                PluginServices.getText(this,"layer_not_queryable"));
704
                                item[0] =  new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><info></info>",this);
705
                                return item;
706
                                //return null;
707
                        }
708
                } catch (WMSException  e) {
709
                        item[0] = new StringXMLItem("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><exception>" +
710
                        e.getMessage() + "</exception>", this);
711
                        return item;
712
                } catch (ValidationException e) {
713
                        throw new ReadDriverException(FMapWMSDriver.class.getName()+"::"+getName()+" - ValidationException", e);
714
                } catch (IOException e) {
715
                        throw new ReadDriverException(FMapWMSDriver.class.getName()+"::"+getName()+" - IOException", e);
716
                } catch (NoninvertibleTransformException e) {
717
                        NotificationManager.addError("NotinvertibleTransform", e);
718
                }
719
                return null;
720
        }
721

    
722
        /*
723
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFullExtent()
724
         */
725
        public Rectangle2D getFullExtent() {
726
                return fullExtent;
727
        }
728

    
729
        /*
730
         *
731
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#draw(java.awt.image.BufferedImage,
732
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
733
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
734
         */
735
        private int callCount; // mess code, represents the amount of times the methods drawFixedSize or drawTile where tried for an extent
736
        private static final int MAX_RETRY_TIMES = 5; // mess code, represents the max amount of retries allowed.
737
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
738
                        Cancellable cancel,double scale) throws ReadDriverException {
739
                callCount = 0; // mess code
740
                lastNColumns = lastNRows = 0;
741

    
742
                enableStopped();
743

    
744
                closeAndFree();
745

    
746
                if (isWithinScale(scale)){
747
                        Point2D p = viewPort.getOffset();
748
                        // p will be (0, 0) when drawing a view or other when painting onto
749
                        // the Layout.
750
                        visualStatus.minX = viewPort.getAdjustedExtent().getMinX();
751
                        visualStatus.minY = viewPort.getAdjustedExtent().getMinY();
752
                        visualStatus.maxX = viewPort.getAdjustedExtent().getMaxX();
753
                        visualStatus.maxY = viewPort.getAdjustedExtent().getMaxY();
754

    
755

    
756
                        if (isSizeFixed()) {
757
                                // This condition handles those situations in which the server can
758
                                // only give static extent and resolution maps despite we need
759
                                // a specific BBOX and pixel WIDTH and HEIGHT
760
                                try {
761
                                        visualStatus.fileNames = new String[1];
762
                                        layerRaster = new FLyrRasterSE[1];
763
                                        drawFixedSize(g, viewPort, cancel, scale);
764
                                        if(layerRaster != null && layerRaster[0] != null) {
765
                                                dataset = layerRaster[0].getDataSource();
766
                                                initializeRasterLayer(null, new IBuffer[][]{{layerRaster[0].getRender().getLastRenderBuffer()}});
767
                                                getRender().setLastRenderBuffer(layerRaster[0].getRender().getLastRenderBuffer());
768
                                        }
769
                                } catch (LoadLayerException e) {
770
                                        // TODO Auto-generated catch block
771
                                        e.printStackTrace();
772
                                } catch (InterruptedException e) {
773
                                }
774

    
775
                        } else {
776
                                if(mustTileDraw){
777
                                        Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), viewPort.getImageWidth(), viewPort.getImageHeight());
778
                                        Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
779
                                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
780
                                        visualStatus.fileNames = new String[tiles.getNumTiles()];
781
                                        MultiRasterDataset[][] datasets = new MultiRasterDataset[tiles.getNumRows()][tiles.getNumCols()];
782
                                        IBuffer[][] buf = new IBuffer[tiles.getNumRows()][tiles.getNumCols()];
783
                                        layerRaster = new FLyrRasterSE[tiles.getNumTiles()];
784
                                        lastNColumns = tiles.getNumCols();
785
                                        lastNRows = tiles.getNumRows();
786
                                        for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
787
                                                // drawing part
788
                                                try {
789
                                                        ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
790
                                                        boolean painted = drawTile(g, vp, cancel, tileNr, scale, tileNr);
791
                                                        if(        layerRaster != null &&
792
                                                                        layerRaster[tileNr] != null &&
793
                                                                        painted) {
794
                                                                        datasets[(int)(tileNr / tiles.getNumCols())][tileNr % tiles.getNumCols()] = (MultiRasterDataset)layerRaster[tileNr].getDataSource().newDataset();
795
                                                                        buf[(int)(tileNr / tiles.getNumCols())][tileNr % tiles.getNumCols()] = layerRaster[tileNr].getRender().getLastRenderBuffer();
796
                                                                }
797
                                                } catch (NoninvertibleTransformException e) {
798
                                                        e.printStackTrace();
799
                                                } catch (LoadLayerException e) {
800
                                                        // TODO Auto-generated catch block
801
                                                        e.printStackTrace();
802
                                                }
803
                                        }
804
                                        try {
805
                                                if(datasets != null && datasets[0][0] != null) {
806
                                                        dataset = new CompositeDataset(datasets);
807
                                                        initializeRasterLayer(datasets, buf);
808
                                                        buf = null;
809
                                                }
810
                                        } catch (MosaicNotValidException e) {
811
                                                throw new ReadDriverException("No hay continuidad en el mosaico.", e);
812
                                        } catch (LoadLayerException e) {
813
                                                throw new ReadDriverException("Error inicializando la capa.", e);
814
                                        } catch (InterruptedException e) {
815
                                        }
816
                                } else
817
                                        try {
818
                                                layerRaster = new FLyrRasterSE[1];
819
                                                visualStatus.fileNames = new String[1];
820
                                                drawTile(g, viewPort, cancel, 0, scale, 0);
821
                                                if(layerRaster != null && layerRaster[0] != null) {
822
                                                        dataset = layerRaster[0].getDataSource();
823
                                                        getRender().setLastRenderBuffer(layerRaster[0].getRender().getLastRenderBuffer());
824
                                                        initializeRasterLayer(null, new IBuffer[][]{{layerRaster[0].getRender().getLastRenderBuffer()}});
825
                                                }
826
                                        } catch (LoadLayerException e) {
827
                                                // TODO Auto-generated catch block
828
                                                e.printStackTrace();
829
                                        } catch (InterruptedException e) {
830
                                        }
831
                        }
832
                }
833
                disableStopped();
834

    
835
                /*Runtime r = Runtime.getRuntime();
836
                System.err.println("********************WMS**********************");
837
                System.err.println("Memoria Total: " + (r.totalMemory() / 1024) +"KB");
838
                System.err.println("Memoria Usada: " + ((r.totalMemory() - r.freeMemory()) / 1024) +"KB");
839
                System.err.println("Memoria Libre: " + (r.freeMemory() / 1024) +"KB");
840
                System.err.println("Memoria MaxMemory: " + (r.maxMemory() / 1024) +"KB");
841
                System.err.println("*********************************************");*/
842
        }
843

    
844
        /**
845
         * Closes files and releases memory (pointers to null)
846
         */
847
        synchronized private void closeAndFree() {
848
                int count = 0;
849
                while(readingData != null && readingData.compareTo(Thread.currentThread().toString()) != 0)
850
                        try {
851
                                Thread.sleep(100);
852
                                count++;
853
                                if (count==1000)
854
                                        readingData = null;
855
                        } catch (InterruptedException e) {
856
                        }
857

    
858
                if(dataset != null) {
859
                        dataset.close();
860
                        dataset = null;
861
                }
862

    
863
                //Cerramos el dataset asociado a la capa si est? abierto.
864
                if(layerRaster != null) {
865
                        for (int i = 0; i < layerRaster.length; i++) {
866
                                if(layerRaster[i] != null) {
867
                                        layerRaster[i].setRemoveRasterFlag(true);
868
                                        layerRaster[i].getDataSource().close();
869
                                        System.out.println("CloseAndFree WMS" + this.getName());
870
                                        if (layerRaster[i] != null) {
871
                                                layerRaster[i].getRender().free();
872
                                                System.out.println("CloseAndFree WMS after render free" + this.getName());
873
                                                if(layerRaster[i].getBufferFactory() != null)
874
                                                        layerRaster[i].getBufferFactory().free();
875
                                                layerRaster[i] = null;
876
                                                System.out.println("CloseAndFree WMS after bufferFactory free");
877
                                        }
878
                                }
879
                        }
880
                }
881
                if (getRender() != null)
882
                        getRender().free();
883
                System.out.println("CloseAndFree WMS before System.gc");
884
                System.gc();
885
        }
886

    
887
        /**
888
         * Acciones que se realizan despu?s de asignar la fuente de datos a
889
         * la capa raster.
890
         *
891
         * @throws LoadLayerException
892
         * @throws InterruptedException
893
         */
894
        private void initializeRasterLayer(MultiRasterDataset[][] datasets, IBuffer[][] buf) throws LoadLayerException, InterruptedException {
895
                if(this.filterList != null)
896
                        getRender().setFilterList(filterList);
897
                if(this.transparency != null)
898
                        getRender().setLastTransparency(transparency);
899
                if(this.renderBands != null)
900
                        getRender().setRenderBands(renderBands);
901
                if(datasets != null) {
902
                        String[][] names = new String[datasets.length][datasets[0].length];
903
                        for (int i = 0; i < datasets.length; i++) {
904
                                for (int j = 0; j < datasets[i].length; j++) {
905
                                        if(datasets[i][j] != null)
906
                                                names[i][j] = datasets[i][j].getDataset(0)[0].getFName();
907
                                }
908
                        }
909
                        super.setLoadParams(names);
910
                }
911
                super.init();
912
                if(buf != null && buf[0][0] != null) {
913
                        int drawablesBandCount = layerRaster[0].getDataSource().getBands().getDrawableBandsCount();
914
                        IBuffer buff = null;
915
                        if(dataset instanceof CompositeDataset)
916
                                buff = ((CompositeDataset)dataset).generateBuffer(buf, drawablesBandCount);
917
                        else
918
                                buff = buf[0][0];
919

    
920
                        if(getRender().getLastRenderBuffer() != null)
921
                                getRender().getLastRenderBuffer().free();
922
                        getRender().setLastRenderBuffer(buff);
923
                }
924
        }
925

    
926
        private void drawFixedSize(Graphics2D g, ViewPort vp, Cancellable cancel, double scale) throws ReadDriverException, LoadLayerException {
927
                callCount++; // mess code, it is not unusual a wms server to response an error which is completely
928
                                         // temporal and the response is available if we retry requesting.
929
                                         //
930

    
931

    
932
                // This is the extent that will be requested
933
                Rectangle2D bBox = getFullExtent();
934
                MyCancellable c = new MyCancellable(cancel);
935

    
936
                try {
937
                        wmsStatus.setExtent( bBox );
938
                        wmsStatus.setFormat( m_Format );
939
                        wmsStatus.setHeight( fixedSize.height );
940
                        wmsStatus.setWidth( fixedSize.width );
941
                        wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
942
                        wmsStatus.setSrs(m_SRS);
943
                        wmsStatus.setCrsAxisOrder(cachedAxisOrientation);
944
                        wmsStatus.setStyles(styles);
945
                        wmsStatus.setDimensions(dimensions);
946
                        wmsStatus.setTransparency(wmsTransparency);
947
                        wmsStatus.setOnlineResource((String) onlineResources.get("GetMap"));
948
                        File f = getDriver().getMap(wmsStatus, c);
949
                        if (f == null)
950
                                return;
951
                        String nameWorldFile = f.getPath() + getExtensionWorldFile();
952
                        com.iver.andami.Utilities.createTemp(nameWorldFile, this.getDataWorldFile(bBox, fixedSize));
953

    
954
                        IStatusRaster status = getStatus();
955
                        if(status!=null && firstLoad){
956
                                try {
957
                                        status.applyStatus(this);
958
                                } catch (NotSupportedExtensionException e) {
959
                                        throw new ReadDriverException("", e);
960
                                } catch (RasterDriverException e) {
961
                                        throw new ReadDriverException("", e);
962
                                } catch (FilterTypeException e) {
963
                                        throw new ReadDriverException("", e);
964
                                }
965
                                firstLoad = false;
966
                        }
967

    
968
                        // And finally, obtain the extent intersecting the view and the BBox
969
                        // to draw to.
970
                        Rectangle2D extent = new Rectangle2D.Double();
971
                        Rectangle2D.intersect(vp.getAdjustedExtent(), bBox, extent);
972

    
973
                        ViewPortData vpData = new ViewPortData(
974
                                vp.getProjection(), new Extent(extent), fixedSize );
975
                        vpData.setMat(vp.getAffineTransform());
976

    
977
                        String filePath = f.getAbsolutePath();
978
                        visualStatus.fileNames[0] = filePath;
979

    
980
                        try {
981
                                rasterProcess(filePath, g, vp, scale, cancel, 0);
982
                                this.updateDrawVersion();
983
                        } catch (FilterTypeException e) {
984
                        }
985
                } catch (ValidationException e) {
986
                        if (!c.isCanceled())
987
                        {
988
                                LoadLayerException exception = new LoadLayerException(getName(),e);
989
                                throw exception;
990
                        }
991
                } catch (IOException e) {
992
                        if (!c.isCanceled())
993
                                if (callCount<MAX_RETRY_TIMES) { // mess code
994
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
995
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
996
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
997
                                        drawFixedSize(g, vp, cancel, scale); // mess code
998
                                } // mess code
999

    
1000
                                if (callCount == 1) { // mess code
1001
                                        ConnectionErrorExceptionType type = new ConnectionErrorExceptionType();
1002
                                        type.setLayerName(getName());
1003
                                        try {
1004
                                                type.setDriverName("WMS Driver");
1005
                                        } catch (Exception e1) {
1006
                                        }
1007
                                        type.setHost(host);
1008
                                        throw new ConnectionErrorLayerException(getName(),e);
1009
                                } // mess code
1010

    
1011
                } catch (WMSException e) {
1012
                        if (!c.isCanceled()) {
1013
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1014
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
1015
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1016
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1017
                                        drawFixedSize(g, vp, cancel, scale); // mess code
1018
                                } // mess code
1019
                                if (callCount == 1) { // mess code
1020
                                        if (!isPrinting)
1021
                                                this.setVisible(false);
1022
                                        throw new LoadLayerException(getName(),e);
1023

    
1024

    
1025
                                } // mess code
1026
                        }
1027
                }catch (NullPointerException e) {
1028
                        this.setVisible(false);
1029
                }
1030
                callCount--; // mess code
1031
        }
1032

    
1033
        /**
1034
         * Carga y dibuja el raster usando la librer?a
1035
         * @param filePath Ruta al fichero en disco
1036
         * @param g Graphics2D
1037
         * @param vp ViewPort
1038
         * @param scale Escala para el draw
1039
         * @param cancel Cancelaci?n para el draw
1040
         * @throws ReadDriverException
1041
         * @throws LoadLayerException
1042
         */
1043
        private void rasterProcess(String filePath, Graphics2D g, ViewPort vp, double scale, Cancellable cancel, int nLyr) throws ReadDriverException, LoadLayerException, FilterTypeException {
1044
                //Cargamos el dataset con el raster de disco.
1045
                layerRaster[nLyr] = FLyrRasterSE.createLayer("", filePath, vp.getProjection());
1046
                //layerRaster[nLyr].getRender().setBufferFactory(layerRaster[nLyr].getBufferFactory());
1047
                layerRaster[nLyr].setNoDataValue(getNoDataValue());
1048
                layerRaster[nLyr].setNoDataType(getNoDataType());
1049
//                layerRaster[nLyr].init();
1050

    
1051
                //Obtenemos la tabla de color del raster abierto ya que se le va a sustituir la lista
1052
                //de filtros y el de tabla de color no queremos sustituirlo.
1053
                RasterFilterList rasterFilterList = layerRaster[nLyr].getRender().getFilterList();
1054
                ColorTableFilter ct = (ColorTableFilter)rasterFilterList.getFilterByBaseClass(ColorTableFilter.class);
1055
                Object param = null;
1056
                if(ct != null)
1057
                        param = ct.getParam("colorTable");
1058

    
1059
                //En caso de cargar un proyecto con XMLEntity se crean los filtros
1060
                if(filterArguments != null) {
1061
                        RasterFilterList fl = new RasterFilterList();
1062
                        fl.addEnvParam("IStatistics", layerRaster[nLyr].getDataSource().getStatistics());
1063
                        fl.addEnvParam("MultiRasterDataset", layerRaster[nLyr].getDataSource());
1064
                        fl.setInitDataType(layerRaster[nLyr].getDataType()[0]);
1065
                        RasterFilterListManager filterListManager = new RasterFilterListManager(fl);
1066
                        filterListManager.createFilterListFromStrings(filterArguments);
1067
                        filterArguments = null;
1068
                        filterList = fl;
1069
                }
1070

    
1071
                //Como el raster se carga a cada zoom el render se crea nuevamente y la lista de
1072
                //filtros siempre estar? vacia a cada visualizaci?n. Para evitarlo tenemos que
1073
                //guardar la lista de filtro aplicada en la visualizaci?n anterior.
1074
                if(this.filterList != null) {
1075
                        this.disableUpdateDrawVersion();
1076
                        //Si ten?a tabla de color le asignamos la original
1077
                        if(param != null && param instanceof GridPalette) {
1078
                                this.filterList.remove(ColorTableFilter.class);
1079
                                RasterFilterListManager filterManager = new RasterFilterListManager(filterList);
1080
                                ColorTableListManager ctm = new ColorTableListManager(filterManager);
1081
                                ctm.addColorTableFilter((GridPalette)param);
1082
                                filterList.move(ColorTableFilter.class, 0);
1083
                                filterList.controlTypes();
1084
                        }
1085
                        layerRaster[nLyr].getRender().setFilterList(filterList);
1086
                        this.enableUpdateDrawVersion();
1087
                }
1088
                if(this.transparency != null)
1089
                        layerRaster[nLyr].getRender().setLastTransparency(transparency);
1090
                if(this.renderBands != null)
1091
                        layerRaster[nLyr].getRender().setRenderBands(renderBands);
1092

    
1093
                //Dibujamos
1094
                disableUpdateDrawVersion();
1095
                layerRaster[nLyr].draw(null, g, vp, cancel, scale);
1096
                enableUpdateDrawVersion();
1097

    
1098
                //La primera vez asignamos la lista de filtros asociada al renderizador. Guardamos una referencia
1099
                //en esta clase para que a cada zoom no se pierda.
1100
                if (this.filterList == null)
1101
                        filterList = layerRaster[nLyr].getRender().getFilterList();
1102
                if (this.transparency == null)
1103
                        transparency = layerRaster[nLyr].getRender().getLastTransparency();
1104
                if (this.renderBands == null)
1105
                        renderBands = layerRaster[nLyr].getRender().getRenderBands();
1106

    
1107
        }
1108

    
1109
        /*
1110
         * (non-Javadoc)
1111
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderFilterList()
1112
         */
1113
        public RasterFilterList getRenderFilterList(){
1114
                return (filterList != null) ? filterList : getRender().getFilterList();
1115
        }
1116

    
1117
        /*
1118
         * (non-Javadoc)
1119
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderFilterList(org.gvsig.raster.grid.filter.RasterFilterList)
1120
         */
1121
        public void setRenderFilterList(RasterFilterList filterList) {
1122
                if (filterList == this.filterList){
1123
                        return;
1124
                }
1125
                this.filterList = filterList;
1126
                this.updateDrawVersion();
1127
                super.getRender().setFilterList(filterList);
1128
        }
1129

    
1130
        /*
1131
         * (non-Javadoc)
1132
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderTransparency()
1133
         */
1134
        public GridTransparency getRenderTransparency() {
1135
                return (transparency != null) ? transparency : getRender().getLastTransparency();
1136
        }
1137

    
1138
        /*
1139
         * (non-Javadoc)
1140
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getRenderBands()
1141
         */
1142
        public int[] getRenderBands() {
1143
                return (renderBands != null) ? renderBands : getRender().getRenderBands();
1144
        }
1145

    
1146
        /*
1147
         * (non-Javadoc)
1148
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderBands(int[])
1149
         */
1150
        public void setRenderBands(int[] renderBands) {
1151
                //TODO: Comprobar si hay cambios
1152
                this.renderBands = renderBands;
1153
                this.updateDrawVersion();
1154
                getRender().setRenderBands(renderBands);
1155
        }
1156

    
1157
        /**
1158
         * This is the method used to draw a tile in a WMS mosaic layer.
1159
         * @throws LoadLayerException
1160
         * @throws ReadDriverException
1161
         * @return true when a tile has been painted
1162
         */
1163
        private boolean drawTile(Graphics2D g, ViewPort vp, Cancellable cancel, int tile, double scale, int nLyr) throws LoadLayerException, ReadDriverException {
1164
                callCount++;
1165
                // Compute the query geometry
1166
                // 1. Check if it is within borders
1167
//                Rectangle2D extent = getFullExtent();
1168
//                                if ((vp.getAdjustedExtent().getMinX() > extent.getMaxX()) ||
1169
//                                                                (vp.getAdjustedExtent().getMinY() > extent.getMaxY()) ||
1170
//                                                                (vp.getAdjustedExtent().getMaxX() < extent.getMinX()) ||
1171
//                                                                (vp.getAdjustedExtent().getMaxY() < extent.getMinY())) {
1172
//                                                return false;
1173
//                                }
1174

    
1175
                                // 2. Compute extent to be requested.
1176
//                                Rectangle2D bBox = new Rectangle2D.Double();
1177
//                                Rectangle2D.intersect(vp.getAdjustedExtent(), extent, bBox); // FIXME: ESTO PROVOCA FALLOS SI EL EXTENT (fullextent) no es correcto
1178

    
1179
                                Rectangle2D bBox = vp.getAdjustedExtent();
1180
                                
1181
                                // 3. Compute size in pixels
1182
                                double scalex = vp.getAffineTransform().getScaleX();
1183
                                double scaley = vp.getAffineTransform().getScaleY();
1184
                                int wImg = (int) Math.ceil(Math.abs(bBox.getWidth() * scalex) + 1);
1185
                                int hImg = (int) Math.ceil(Math.abs(bBox.getHeight() * scaley) + 1);
1186

    
1187
                                Dimension sz = new Dimension(wImg, hImg);
1188

    
1189
                                if ((wImg <= 0) || (hImg <= 0)) {
1190
                                                return false;
1191
                                }
1192
                                MyCancellable c = new MyCancellable(cancel);
1193

    
1194
                try {
1195
                        sz = new Dimension(wImg, hImg);
1196
                        // Rectangle2D.intersect(vp.getAdjustedExtent(), extent, bBox);
1197

    
1198

    
1199
                        wmsStatus.setExtent( bBox );
1200
                        wmsStatus.setFormat(m_Format);
1201
                        wmsStatus.setHeight( hImg );
1202
                        wmsStatus.setWidth( wImg );
1203
                        wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
1204
                        wmsStatus.setSrs(m_SRS);
1205
                        wmsStatus.setCrsAxisOrder(cachedAxisOrientation);
1206
                        wmsStatus.setStyles(styles);
1207
                        wmsStatus.setDimensions(dimensions);
1208
                        wmsStatus.setTransparency(wmsTransparency);
1209
                        wmsStatus.setOnlineResource((String) onlineResources.get("GetMap"));
1210

    
1211
                        // begin patch; Avoid to request too small tiles.
1212
                        // This generally occurs when printing
1213

    
1214
                        if (wImg < minTilePrintWidth) {
1215
                                double wScale = (double) minTilePrintWidth / wImg;
1216
                                wmsStatus.setWidth(minTilePrintWidth);
1217
                                Rectangle2D sExtent = wmsStatus.getExtent();
1218
                                Point2D initialPoint = new Point2D.Double(sExtent.getX(), sExtent.getY());
1219
                                sExtent.setRect(sExtent.getX()*wScale, sExtent.getY(), sExtent.getWidth()*wScale, sExtent.getHeight());
1220
                                if (!bBox.contains(initialPoint)) {
1221
                                        sExtent.setRect(sExtent.getX() - initialPoint.getX(), sExtent.getY(), sExtent.getWidth(), sExtent.getHeight());
1222
                                }
1223
                        }
1224

    
1225
                        if (hImg < minTilePrintHeight) {
1226
                                double hScale = (double) minTilePrintHeight / hImg;
1227
                                wmsStatus.setHeight(minTilePrintHeight);
1228
                                Rectangle2D sExtent = wmsStatus.getExtent();
1229
                                Point2D initialPoint = new Point2D.Double(sExtent.getX(), sExtent.getY());
1230
                                sExtent.setRect(sExtent.getX(), sExtent.getY()*hScale, sExtent.getWidth(), sExtent.getHeight()*hScale);
1231
                                if (!bBox.contains(initialPoint)) {
1232
                                        sExtent.setRect(sExtent.getX(), sExtent.getY() - initialPoint.getY(), sExtent.getWidth(), sExtent.getHeight());
1233
                                }
1234
                        }
1235

    
1236
                        // end patch
1237
                        File f = getDriver().getMap(wmsStatus, c);
1238
                        if (f == null)
1239
                                return false;
1240
                        String nameWordFile = f.getPath() + getExtensionWorldFile();
1241
                        com.iver.andami.Utilities.createTemp(nameWordFile, this.getDataWorldFile(bBox, sz));
1242

    
1243
                        ViewPortData vpData = new ViewPortData(
1244
                                vp.getProjection(), new Extent(bBox), sz );
1245
                        vpData.setMat(vp.getAffineTransform());
1246

    
1247
                        String filePath = f.getAbsolutePath();
1248
                        visualStatus.fileNames[tile] = filePath;
1249
                        try {
1250
                                rasterProcess(filePath, g, vp, scale, cancel, nLyr);
1251
//                                this.updateDrawVersion();
1252
                        } catch (FilterTypeException e) {
1253
                        }
1254

    
1255
                } catch (ValidationException e) {
1256
                        if (!c.isCanceled())
1257
                        {
1258
                                LoadLayerException exception = new LoadLayerException(getName(),e);
1259
                                throw exception;
1260
                        }
1261
                } catch (IOException e) {
1262
                        if (!c.isCanceled()){
1263
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1264
                                        NotificationManager.addWarning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n", null); // mess code
1265
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1266
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1267

    
1268
                                        drawFixedSize(g, vp, cancel, scale); // mess code
1269
                                } // mess code
1270
                        }
1271
                        if (callCount == 1) { // mess code
1272
                                throw new ConnectionErrorLayerException(getName(),e);
1273
                        }//if
1274
                } catch (WMSException e) {
1275
                        if (!c.isCanceled()) {
1276
                                if (callCount<MAX_RETRY_TIMES) { // mess code
1277
                                        Logger.getAnonymousLogger().warning("\n[ FLyrWMS.drawFixedSize() ]  Failed in trying " + callCount + "/" + MAX_RETRY_TIMES + ")\n"); // mess code
1278
                                        // I'll try again requesting up to MAX_RETRY_TIMES times before throw an error // mess code
1279
                                        // (this is mess code, should be replaced by a layer status handler which is scheduled for version > 1.0) // mess code
1280
                                        drawTile(g, vp, cancel, tile, scale, nLyr);
1281
                                } // mess code
1282
                                if (callCount == 1) { // mess code
1283
//                azabala                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(), e.getMessage());
1284
                                        WMSDriverExceptionType type = new WMSDriverExceptionType();
1285
                                        type.setLayerName(getName());
1286
                                        try {
1287
                                                type.setDriverName("WMS Driver");
1288
                                        } catch (Exception e1) {
1289
                                        }
1290
                                        type.setWcsStatus(this.wmsStatus);
1291
                                        if (!isPrinting)
1292
                                                this.setVisible(false);
1293
                                        throw new LoadLayerException(getName(),e);
1294

    
1295

    
1296
                                } //if
1297
                        }//if
1298
                }//catch
1299
                callCount--;
1300
                return true;
1301
        }
1302

    
1303
   /**
1304
    * Applies server min/max scale as layer min/max scale.
1305
    * The purpose is to update the TOC icon according with
1306
    * the WMS layer visibilitiy. 
1307
    */
1308
   private void initServerScale() {
1309
       /**
1310
        * We have to calculate the equivalent scale for our system, taking into account the
1311
        * server DPI and our real DPI.
1312
        */
1313
       double minScale = getCorrectedServerMinScale();
1314
       double maxScale = getCorrectedServerMaxScale();
1315
       if (minScale>0) {
1316
           setMinScale(minScale);
1317
       }
1318
       if (maxScale>0 &&
1319
               maxScale>minScale) {
1320
           setMaxScale(maxScale);
1321
       }
1322
   }
1323
        
1324
        /**
1325
    * Calculates the equivalent MinScaleDenominator for our system, taking into account the
1326
    * server DPI and our real DPI.
1327
    * 
1328
    * WMS 1.3 standard defines a fixed pixel size of 0.28 mm for the server,
1329
    * which may not match our real settings, so this conversion is required
1330
    * to properly use MinScaleDenominator and MaxScaleDenominator values.
1331
    *
1332
    * @return
1333
    */
1334
   public double getCorrectedServerMinScale() {
1335
       return (getServerMinScale()*MapContext.getScreenDPI())/WMS_DPI;
1336
   }
1337
   
1338
   /**
1339
    * Calculates the equivalent MaxScaleDenominator for our system, taking into account the
1340
    * server DPI and our real DPI.
1341
    * 
1342
    * WMS 1.3 standard defines a fixed pixel size of 0.28 mm for the server,
1343
    * which may not match our real settings, so this conversion is required
1344
    * to properly use MinScaleDenominator and MaxScaleDenominator values.
1345
    *
1346
    * @return
1347
    */
1348
   public double getCorrectedServerMaxScale() {
1349
       return (getServerMaxScale()*MapContext.getScreenDPI())/WMS_DPI;
1350
   }
1351
   
1352
   /**
1353
    * Returns the value of MinScaleDenominator tag, if available,
1354
    * or -1 otherwise.
1355
    *  
1356
    * @return
1357
    */
1358
   public double getServerMinScale() {
1359
       String[] layers = getLayerNames();
1360
       double minScale=Double.MAX_VALUE;
1361
       for (int i=0; i<layers.length; i++) {
1362
           WMSLayerNode layer = wms.getLayer(layers[i]);
1363
           double lyrMinScale = layer.getScaleMin(); 
1364
           if ((lyrMinScale > 0) && (lyrMinScale<minScale)) {
1365
               minScale = lyrMinScale;
1366
           }
1367
       }
1368
       if (minScale==Double.MAX_VALUE) {
1369
           return -1;
1370
       }
1371
       else {
1372
           return minScale;
1373
       }
1374
   }
1375

    
1376
   /**
1377
    * Returns the value of MaxScaleDenominator tag, if available,
1378
    * or -1 otherwise.
1379
    *  
1380
    * @return
1381
    */
1382
   public double getServerMaxScale() {
1383
       String[] layers = getLayerNames();
1384
       double maxScale=-1, lyrMaxScale;
1385
       for (int i=0; i<layers.length; i++) {
1386
           WMSLayerNode layer = wms.getLayer(layers[i]);
1387
           lyrMaxScale = layer.getScaleMax();
1388
           if (lyrMaxScale!=-1
1389
                   && lyrMaxScale>maxScale) {
1390
               maxScale = lyrMaxScale;
1391
           }
1392
           
1393
       }
1394
       return maxScale;
1395
   }
1396
   
1397
   
1398
   /**
1399
         * Obtiene la extensi?n del fichero de georreferenciaci?n
1400
         * @return String con la extensi?n del fichero de georreferenciaci?n dependiendo
1401
         * del valor del formato obtenido del servidor. Por defecto asignaremos un .wld
1402
         */
1403
        private String getExtensionWorldFile(){
1404
                String extWorldFile = ".wld";
1405
                        if(m_Format.equals("image/tif") || m_Format.equals("image/tiff"))
1406
                                extWorldFile = ".tfw";
1407
                        //En la versi?n 1.6 de gdal no soporta jpgw si el fichero de imagen no 
1408
                        //tiene extensi?n. Solo lo lee si es wld
1409
                        /*if(m_Format.equals("image/jpeg"))
1410
                                extWorldFile = ".jpgw";*/
1411
                        return extWorldFile;
1412
        }
1413

    
1414
        /**
1415
         * Calcula el contenido del fichero de georreferenciaci?n de una imagen.
1416
         * @param bBox Tama?o y posici?n de la imagen (en coordenadas de usuario)
1417
         * @param sz Tama?o de la imagen en pixeles.
1418
         * @return el 'WorldFile', como String.
1419
         * @throws IOException
1420
         */
1421
        public String getDataWorldFile(Rectangle2D bBox, Dimension sz) throws IOException {
1422
                StringBuffer data = new StringBuffer();
1423
                        data.append((bBox.getMaxX() - bBox.getMinX())/(sz.getWidth() - 1)+"\n");
1424
                        data.append("0.0\n");
1425
                        data.append("0.0\n");
1426
                        data.append("-"+(bBox.getMaxY() - bBox.getMinY())/(sz.getHeight() - 1)+"\n");
1427
                        data.append(""+bBox.getMinX()+"\n");
1428
                        data.append(""+bBox.getMaxY()+"\n");
1429
                        return data.toString();
1430
        }
1431

    
1432
        /**
1433
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
1434
         *                 com.iver.cit.gvsig.fmap.ViewPort,
1435
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
1436
         */
1437
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties)
1438
                throws ReadDriverException {
1439

    
1440
                closeAndFree();
1441

    
1442
                if (isVisible() && isWithinScale(scale)) {
1443
                        isPrinting = true;
1444
                        if (!mustTilePrint) {
1445
                                draw(null, g, viewPort, cancel,scale);
1446
                        } else {
1447
                                // Para no pedir imagenes demasiado grandes, vamos
1448
                                // a hacer lo mismo que hace EcwFile: chunkear.
1449
                                // Llamamos a drawView con cuadraditos m?s peque?os
1450
                                // del BufferedImage ni caso, cuando se imprime viene con null
1451

    
1452
                                Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
1453
                                tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
1454
                                visualStatus.fileNames = new String[tiles.getNumTiles()];
1455
                                layerRaster = new FLyrRasterSE[tiles.getNumTiles()];
1456
                                for (int tileNr=0; tileNr < tiles.getNumTiles(); tileNr++) {
1457
                                        // Parte que dibuja
1458
                                        try {
1459
                                                ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
1460
                                                drawTile(g, vp, cancel, tileNr, scale, tileNr);
1461
                                        } catch (NoninvertibleTransformException e) {
1462
                                                e.printStackTrace();
1463
                                        } catch (LoadLayerException e) {
1464
                                                // TODO Auto-generated catch block
1465
                                                e.printStackTrace();
1466
                                        }
1467
                                }
1468
                        }
1469
                        isPrinting = false;
1470
                }
1471
        }
1472

    
1473
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
1474
                throws ReadDriverException {
1475
                draw(null, g, viewPort, cancel,scale);
1476
        }
1477

    
1478
        /**
1479
         * Devuelve el FMapWMSDriver.
1480
         *
1481
         * @return FMapWMSDriver
1482
         *
1483
         * @throws IllegalStateException
1484
         * @throws ValidationException
1485
         * @throws UnsupportedVersionLayerException
1486
         * @throws IOException
1487
         */
1488
        public FMapWMSDriver getDriver()
1489
                throws IllegalStateException, ValidationException,
1490
                        UnsupportedVersionLayerException, IOException {
1491
                return FMapWMSDriverFactory.getFMapDriverForURL(host);
1492
        }
1493

    
1494
        /**
1495
         * Devuelve el FMapWMSDriver.
1496
         *
1497
         * @return FMapWMSDriver
1498
         *
1499
         * @throws IllegalStateException
1500
         * @throws ValidationException
1501
         * @throws UnsupportedVersionLayerException
1502
         * @throws IOException
1503
         */
1504
        public void setDriver(FMapWMSDriver drv) {
1505
                //TODO: Comprobar cambio
1506
                wms = drv;
1507
                initServerScale();
1508
                this.updateDrawVersion();
1509
        }
1510

    
1511
        /**
1512
         * Devuelve el URL.
1513
         *
1514
         * @return URL.
1515
         */
1516
        public URL getHost() {
1517
                return host;
1518
        }
1519

    
1520
        /**
1521
         * Inserta el URL.
1522
         *
1523
         * @param host URL.
1524
         */
1525
        public void setHost(URL host) {
1526
                if (this.host == host){
1527
                        return;
1528
                }
1529
                if (this.host != null && this.fullExtent.equals(host)){
1530
                        return;
1531
                }
1532

    
1533
                this.host = host;
1534
                this.updateDrawVersion();
1535
        }
1536

    
1537
        /**
1538
         * Devuelve la informaci?n de la consulta.
1539
         *
1540
         * @return String.
1541
         */
1542
        public String getInfoLayerQuery() {
1543
                return infoLayerQuery;
1544
        }
1545

    
1546
        /**
1547
         * Inserta la informaci?n de la consulta.
1548
         *
1549
         * @param infoLayerQuery String.
1550
         */
1551
        public void setInfoLayerQuery(String infoLayerQuery) {
1552
                this.infoLayerQuery = infoLayerQuery;
1553
        }
1554

    
1555
        /**
1556
         * Devuelve la consulta.
1557
         *
1558
         * @return String.
1559
         */
1560
        public String getLayerQuery() {
1561
                return layerQuery;
1562
        }
1563

    
1564
        /**
1565
         * Inserta la consulta.
1566
         *
1567
         * @param layerQuery consulta.
1568
         */
1569
        public void setLayerQuery(String layerQuery) {
1570
                if (this.layerQuery == layerQuery){
1571
                        return;
1572
                }
1573
                if (this.layerQuery != null && this.layerQuery.equals(layerQuery)){
1574
                        return;
1575
                }
1576

    
1577
                this.layerQuery = layerQuery;
1578
       wmsStatus.setLayerNames(Utilities.createVector(layerQuery,","));
1579
                this.updateDrawVersion();
1580
        }
1581

    
1582
        /**
1583
         * Devuelve el formato.
1584
         *
1585
         * @return Formato.
1586
         */
1587
        public String getFormat() {
1588
                return m_Format;
1589
        }
1590

    
1591
        /**
1592
         * Inserta el formato.
1593
         *
1594
         * @param format Formato.
1595
         */
1596
        public void setFormat(String format) {
1597
                if (this.m_Format == format){
1598
                        return;
1599
                }
1600
                if (this.m_Format != null && this.m_Format.equals(format)){
1601
                        return;
1602
                }
1603
                m_Format = format;
1604
                this.updateDrawVersion();
1605
        }
1606

    
1607
        /**
1608
         * Devuelve el SRS.
1609
         *
1610
         * @return SRS.
1611
         */
1612
        public String getSRS() {
1613
                return m_SRS;
1614
        }
1615

    
1616
        /**
1617
         * Inserta el SRS.
1618
         *
1619
         * @param m_srs SRS.
1620
         */
1621
        public void setSRS(String m_srs) {
1622
                if (m_SRS == m_srs){
1623
                        return;
1624
                }
1625
                if (m_SRS != null && m_SRS.equals(m_srs)){
1626
                        return;
1627
                }
1628
                m_SRS = m_srs;
1629
                this.updateDrawVersion();
1630
                setProjection(CRSFactory.getCRS(getSRS()));
1631
        }
1632

    
1633
        /**
1634
         * Inserta la extensi?n total de la capa.
1635
         *
1636
         * @param fullExtent Rect?ngulo.
1637
         */
1638
        public void setFullExtent(Rectangle2D fullExtent) {
1639
                if (this.fullExtent == fullExtent){
1640
                        return;
1641
                }
1642
                if (this.fullExtent != null && this.fullExtent.equals(fullExtent)){
1643
                        return;
1644
                }
1645

    
1646
                this.fullExtent = fullExtent;
1647
                this.updateDrawVersion();
1648
        }
1649

    
1650
        public HashMap getProperties() {
1651
                HashMap info = new HashMap();
1652
                                String[] layerNames = getLayerQuery().split(",");
1653
                                Vector layers = new Vector(layerNames.length);
1654
                                try {
1655
                                                if(getDriver().connect(null)){
1656
                                                                for (int i = 0; i < layerNames.length; i++) {
1657
                                                                                layers.add(i, getDriver().getLayer(layerNames[i]));
1658
                                                                }
1659
                                                                info.put("name", getName());
1660
                                                                info.put("selectedLayers", layers);
1661
                                                                info.put("host", getHost());
1662
                                                                info.put("srs", getSRS());
1663
                                                                info.put("format", getFormat());
1664
                                                                info.put("wmsTransparency", new Boolean(wmsTransparency));
1665
                                                                info.put("styles", styles);
1666
                                                                info.put("dimensions", dimensions);
1667
                                                                info.put("fixedSize", fixedSize);
1668
                                                                return info;
1669
                                                }
1670
                                } catch (Exception e) {
1671
                                                e.printStackTrace();
1672
                                }
1673
                                return null;
1674
        }
1675

    
1676
        public double getMaxX() {
1677
                return visualStatus.maxX;
1678
        }
1679

    
1680
        public double getMaxY() {
1681
                return visualStatus.maxY;
1682
        }
1683

    
1684
        public double getMinX() {
1685
                return visualStatus.minX;
1686
        }
1687

    
1688
        public double getMinY() {
1689
                return visualStatus.minY;
1690
        }
1691

    
1692
  
1693
   /**
1694
    * Returns the names of the WMS layers that are loaded in this
1695
    * gvSIG layer.
1696
    * 
1697
    * @return An array containing the names of the WMS layers
1698
    */
1699
   public String[] getLayerNames() {
1700
       Vector namesList = wmsStatus.getLayerNames();
1701
       String[] names = new String[namesList.size()];
1702
       for (int i=0; i<names.length; i++) {
1703
           Object o = namesList.get(i);
1704
           if (o instanceof String) {
1705
               names[i] = (String) o;
1706
           }
1707
           else { // this should not happen
1708
               names[i] = o.toString();
1709
           }
1710
       }
1711
       return names;
1712
   }
1713

    
1714
        /**
1715
         * @return Returns the wmsTransparency.
1716
         */
1717
        public boolean isWmsTransparent() {
1718
                return wmsTransparency;
1719
        }
1720

    
1721
        /**
1722
         * @param wmsTransparency The wmsTransparency to set.
1723
         */
1724
        public void setWmsTransparency(boolean wmsTransparency) {
1725
                if (this.wmsTransparency == wmsTransparency){
1726
                        return;
1727
                }
1728
                this.wmsTransparency = wmsTransparency;
1729
                this.updateDrawVersion();
1730
        }
1731

    
1732
        /**
1733
         * @param styles
1734
         */
1735
        public void setStyles(Vector styles) {
1736
                if (this.styles == styles){
1737
                        return;
1738
                }
1739
                if (this.styles != null && styles != null ){
1740
                        if (this.styles.containsAll(styles) && this.styles.size() ==styles.size()){
1741
                                return;
1742
                        }
1743
                }
1744
                this.styles = styles;
1745
                this.updateDrawVersion();
1746
        }
1747

    
1748
        /**
1749
         * Sets the dimension vector that is a list of key-value pairs containing
1750
         * the name of the dimension and the value for it
1751
         * @param dimensions
1752
         */
1753
        public void setDimensions(Vector dimensions) {
1754
                if (this.dimensions == dimensions){
1755
                        return;
1756
                }
1757
                if (this.dimensions != null && dimensions != null ){
1758
                        if (this.dimensions.containsAll(dimensions) && this.dimensions.size() ==dimensions.size()){
1759
                                return;
1760
                        }
1761
                }
1762
                this.dimensions = dimensions;
1763
                this.updateDrawVersion();
1764
        }
1765

    
1766
        /**
1767
         * Sets the set of URLs that should be accessed for each operation performed
1768
         * to the server.
1769
         *
1770
         * @param onlineResources
1771
         */
1772
        public void setOnlineResources(Hashtable onlineResources) {
1773
                if (this.onlineResources == onlineResources){
1774
                        return;
1775
                }
1776
                if (this.onlineResources != null && this.onlineResources.equals(onlineResources)){
1777
                        return;
1778
                }
1779

    
1780
                this.onlineResources = onlineResources;
1781
                this.updateDrawVersion();
1782
        }
1783

    
1784
        /**
1785
         * Gets the URL that should be accessed for an operation performed
1786
         * to the server.
1787
         *
1788
         * @param onlineResources
1789
         */
1790
        public String getOnlineResource(String operation) {
1791
                return ((String) onlineResources.get(operation));
1792
        }
1793

    
1794
        /**
1795
         * When a server is not fully featured and it only can serve constant map
1796
         * sizes this value must be set. It expresses the size in pixels (width, height)
1797
         * that the map will be requested.
1798
         * @param Dimension sz
1799
         */
1800
        public void setFixedSize(Dimension sz) {
1801
                if (this.fixedSize == sz){
1802
                        return;
1803
                }
1804
                if (this.fixedSize != null && this.fixedSize.equals(sz)){
1805
                        return;
1806
                }
1807
                fixedSize = sz;
1808
                this.updateDrawVersion();
1809
        }
1810

    
1811
        /**
1812
         * Tells whether if this layer must deal with the server with the constant-size
1813
         * limitations or not.
1814
         * @return boolean.
1815
         */
1816
        private boolean isSizeFixed() {
1817
                return fixedSize != null && fixedSize.getWidth() > 0 && fixedSize.getHeight() > 0;
1818
        }
1819

    
1820
        /**
1821
         * If it is true, this layer accepts GetFeatureInfo operations. This WMS operations
1822
         * maps to FMap's infoByPoint(p) operation.
1823
         * @param b
1824
         */
1825
        public void setQueryable(boolean b) {
1826
                queryable = b;
1827
        }
1828

    
1829
        /**
1830
         * Creates the part of a OGC's MapContext document that would describe this
1831
         * layer(s).
1832
         * @param version, The desired version of the resulting document. (1.1.0)
1833
         * @return String containing the xml.
1834
         * @throws UnsupportedVersionLayerException
1835
         */
1836
        public String toMapContext(String mapContextVersion) {
1837
                XmlBuilder xml = new XmlBuilder();
1838
                FMapWMSDriver drv;
1839
                try {
1840
                        drv = getDriver();
1841
                } catch (Exception e) {
1842
                        return xml.toString();
1843
                }
1844
                String[] layerNames = getLayerQuery().split(",");
1845
                String[] styleNames = (String[]) styles.toArray(new String[0]);
1846
                for (int i = 0; i < layerNames.length; i++) {
1847
                        WMSLayerNode layer = drv.getLayer(layerNames[i]);
1848
                        HashMap xmlAttrs = new HashMap();
1849

    
1850
                        // <Layer>
1851
                        xmlAttrs.put(WebMapContextTags.HIDDEN, !isVisible()+"");
1852
                        xmlAttrs.put(WebMapContextTags.QUERYABLE, queryable+"");
1853
                        xml.openTag(WebMapContextTags.LAYER, xmlAttrs);
1854
                        xmlAttrs.clear();
1855
                        if (mapContextVersion.equals("1.1.0") || mapContextVersion.equals("1.0.0")) {
1856
                                // <Server>
1857
                                xmlAttrs.put(WebMapContextTags.SERVICE, WebMapContextTags.WMS);
1858
                                xmlAttrs.put(WebMapContextTags.VERSION, drv.getVersion());
1859
                                xmlAttrs.put(WebMapContextTags.SERVER_TITLE, drv.getServiceTitle());
1860
                                xml.openTag(WebMapContextTags.SERVER, xmlAttrs);
1861
                                xmlAttrs.clear();
1862

    
1863
                                        // <OnlineResource>
1864
                                        xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
1865
                                        xmlAttrs.put(WebMapContextTags.XLINK_HREF, getHost().toString());
1866
                                        xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
1867
                                        xmlAttrs.clear();
1868
                                        // </OnlineResource>
1869

    
1870
                                xml.closeTag();
1871
                                // </Server>
1872

    
1873
                                // <Name>
1874
                                xml.writeTag(WebMapContextTags.NAME, layer.getName().trim());
1875
                                // </Name>
1876

    
1877
                                // <Title>
1878
                                xml.writeTag(WebMapContextTags.TITLE, layer.getTitle().trim());
1879
                                //?xml.writeTag(WebMapContextTags.TITLE, getName().trim());
1880
                                // </Title>
1881

    
1882
                                // <Abstract>
1883
                                if (layer.getAbstract() != null)
1884
                                        xml.writeTag(WebMapContextTags.ABSTRACT, layer.getAbstract());
1885
                                // </Abstract>
1886

    
1887
                                // <SRS> (a list of available SRS for the enclosing layer)
1888
                                String[] strings = (String[]) layer.getAllSrs().toArray(new String[0]);
1889
                                String mySRS = strings[0];
1890
                                for (int j = 1; j < strings.length; j++) {
1891
                                        mySRS += ","+strings[j];
1892
                                }
1893
                                xml.writeTag(WebMapContextTags.SRS, mySRS);
1894
                                // </SRS>
1895

    
1896
                                // <FormatList>
1897
                                xml.openTag(WebMapContextTags.FORMAT_LIST);
1898
                                        strings = (String[]) drv.getFormats().toArray(new String[0]);
1899
                                        for (int j = 0; j < strings.length; j++) {
1900
                                                                                // <Format>
1901
                                                String str = strings[j].trim();
1902
                                                if (str.equals(getFormat()))
1903
                                                        xml.writeTag(WebMapContextTags.FORMAT, str, WebMapContextTags.CURRENT, "1");
1904
                                                else
1905
                                                        xml.writeTag(WebMapContextTags.FORMAT, str);
1906
                                                                                // </Format>
1907
                                        }
1908
                                xml.closeTag();
1909
                                // </FormatList>
1910

    
1911
                                // <StyleList>
1912
                                xml.openTag(WebMapContextTags.STYLE_LIST);
1913

    
1914
                                        if (layer.getStyles().size()>0) {
1915
                                                for (int j = 0; j < layer.getStyles().size(); j++) {
1916
                                                        // <Style>
1917
                                                        FMapWMSStyle st = (FMapWMSStyle) layer.getStyles().get(j);
1918
                                                        if (st.name.equals(styleNames[i]))
1919
                                                                xmlAttrs.put(WebMapContextTags.CURRENT, "1");
1920
                                                        xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
1921
                                                        xmlAttrs.clear();
1922

    
1923
                                                                // <Name>
1924
                                                                xml.writeTag(WebMapContextTags.NAME, st.name);
1925
                                                                // </Name>
1926

    
1927
                                                                // <Title>
1928
                                                                xml.writeTag(WebMapContextTags.TITLE, st.title);
1929
                                                                // </Title>
1930

    
1931
                                                                // <LegendURL width="180" format="image/gif" height="50">
1932
                                                                        // <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
1933
                                                                        // </OnlineResource>
1934
                                                                // </LegendURL>
1935
                                                        xml.closeTag();
1936
                                                        // </Style>
1937

    
1938
                                                }
1939

    
1940
                                        } else {
1941
                                                // Create fake style (for compatibility issues)
1942
                                                xmlAttrs.put(WebMapContextTags.CURRENT, "1");
1943
                                                // <Style>
1944
                                                xml.openTag(WebMapContextTags.STYLE, xmlAttrs);
1945
                                                        xmlAttrs.clear();
1946
                                                        // <Name>
1947
                                                        xml.writeTag(WebMapContextTags.NAME, "default");
1948
                                                        // </Name>
1949

    
1950
                                                        // <Title>
1951
                                                        xml.writeTag(WebMapContextTags.TITLE, "default");
1952
                                                        // </Title>
1953

    
1954
//                                                        // <LegendURL width="180" format="image/gif" height="50">
1955
//                                                        xmlAttrs.put(WebMapContextTags.WIDTH, "0");
1956
//                                                        xmlAttrs.put(WebMapContextTags.HEIGHT, "0");
1957
//                                                        xmlAttrs.put(WebMapContextTags.FORMAT.toLowerCase(), "image/gif");
1958
//                                                        xml.openTag(WebMapContextTags.LEGEND_URL, xmlAttrs);
1959
//                                                        xmlAttrs.clear();
1960
//                                                                // <OnlineResource xlink:type="simple" xlink:href="http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif"/>
1961
//                                                                xmlAttrs.put(WebMapContextTags.XLINK_TYPE, "simple");
1962
//                                                                xmlAttrs.put(WebMapContextTags.XLINK_HREF, "http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif");
1963
//                                                                xml.writeTag(WebMapContextTags.ONLINE_RESOURCE, xmlAttrs);
1964
//                                                                // </OnlineResource>
1965
//                                                    // </LegendURL>
1966
//                                                        xml.closeTag();
1967
                                                // </Style>
1968
                                                xml.closeTag();
1969
                                        }
1970
                                // </StyleList>
1971
                                xml.closeTag();
1972
                                if (mapContextVersion.compareTo("1.0.0") > 0) {
1973
                                // <DimensionList>
1974
                                        xml.openTag(WebMapContextTags.DIMENSION_LIST);
1975
                                        // <Dimension>
1976
                                        // </Dimension>
1977
                                        xml.closeTag();
1978
                                // </DimensionList>
1979
                                }
1980
                        } else {
1981
                                xml.writeTag("ERROR", PluginServices.getText(this, "unsupported_map_context_version"));
1982
                        }
1983
                        // </Layer>
1984
                        xml.closeTag();
1985
                }
1986
                return xml.getXML();
1987
        }
1988

    
1989
        public ImageIcon getTocImageIcon() {
1990
                return new ImageIcon(getClass().getResource("image/icon-layer-wms.png"));
1991
        }
1992

    
1993
        /*
1994
         *  (non-Javadoc)
1995
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#getTileSize()
1996
         */
1997
        public int[] getTileSize() {
1998
                int[] size = {maxTileDrawWidth, maxTileDrawHeight};
1999
                return size;
2000
        }
2001

    
2002
        /*
2003
         *  (non-Javadoc)
2004
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#isTiled()
2005
         */
2006
        public boolean isTiled() {
2007
                return mustTileDraw;
2008
        }
2009

    
2010
        public Image getImageLegend() {
2011
                try {
2012
                        if (wms == null)
2013
                                wms = getDriver();
2014
                        if (wms.hasLegendUrl(wmsStatus,layerQuery) ||wms.hasLegendGraphic() || hasImageLegend) {
2015
                                wmsStatus.setOnlineResource((String) onlineResources
2016
                                                .get("GetLegendGraphic"));
2017
                                String path = getPathImage();// File legend =
2018
                                                                                                // getDriver().getLegendGraphic(wmsStatus,
2019
                                                                                                // layerQuery, null);
2020
                                Image img = null;
2021
                                if ((path != null) && (path.length() > 0))
2022
                                        img = new ImageIcon(path).getImage();
2023
                                return img;
2024
                        }
2025
                } catch (Exception e) {
2026
                }
2027
                return null;
2028
        }
2029

    
2030
        public String getPathImage() {
2031
                try {
2032
                        File legend = getDriver().getLegendGraphic(wmsStatus, layerQuery, null);
2033
                        return legend.getAbsolutePath();
2034
                }catch(Exception e){
2035
                        e.printStackTrace();
2036
                        return null;
2037
                }
2038
        }
2039

    
2040
        /* (non-Javadoc)
2041
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#newComposedLayer()
2042
         */
2043
        public ComposedLayer newComposedLayer() {
2044
                Preferences prefs = Preferences.userRoot().node("gvsig.wms");
2045

    
2046
                /*
2047
                 * from java.util.prefs import Preferences
2048
                 * prefs = Preferences.userRoot().node("gvsig.wms")
2049
                 * prefs.put("useComposedLayer","true")
2050
                 */
2051

    
2052
                String str = prefs.get("useComposedLayer","false");
2053
                Boolean useComposedLayer = Boolean.TRUE; // por defecto ya se usan
2054
                try {
2055
                        useComposedLayer = Boolean.valueOf(str);
2056
                } catch (Exception e) {
2057

    
2058
                }
2059
                if (useComposedLayer.booleanValue()) {
2060
                        return new ComposedLayerWMS();
2061
                } else {
2062
                        return null;
2063
                }
2064
        }
2065

    
2066
        /**
2067
         * @param styles
2068
         */
2069
        public Vector getStyles() {
2070
                return this.styles;
2071
        }
2072

    
2073

    
2074
        /*
2075
         * Checks if can make a single petition for the two layers to the server
2076
         * @see com.iver.cit.gvsig.fmap.layers.ComposedLayerWMS#canAdd(com.iver.cit.gvsig.fmap.layers.FLayer)
2077
         */
2078
        boolean isComposedLayerCompatible(FLayer layer) {
2079
                FLyrWMS aLayer;
2080

    
2081
                if (!(layer instanceof FLyrWMS)) {
2082
                        return false;
2083
                }
2084
                aLayer = (FLyrWMS)layer;
2085
                if (!this.getHost().equals(aLayer.getHost())) {
2086
                        return false;
2087
                }
2088
                if (!this.getFormat().equals(aLayer.getFormat())) {
2089
                        return false;
2090
                }
2091
                if (!this.getSRS().equals(aLayer.getSRS())) {
2092
                        return false;
2093
                }
2094
                if (this.getInfoLayerQuery() != null) {
2095
                        if (!this.getInfoLayerQuery().equals(aLayer.getInfoLayerQuery())) {
2096
                                return false;
2097
                        }
2098
                }else if (aLayer.getInfoLayerQuery() != null) {
2099
                        return false;
2100
                }
2101

    
2102

    
2103
                // isFixedSize es privado
2104
                if ((this.fixedSize != null) &&
2105
                                (aLayer.fixedSize!= null)) {
2106
                        if (this.fixedSize.equals(aLayer.fixedSize)) {
2107
                                return false;
2108
                        }
2109
                } else if ((this.fixedSize != null) != (aLayer.fixedSize != null)) {
2110
                        return false;
2111
                }
2112

    
2113
                // time elevation (dimensions)
2114
                if ((this.dimensions != null) &&
2115
                                (aLayer.dimensions != null)) {
2116
                        if (this.dimensions.size() != aLayer.dimensions.size()) {
2117
                                return false;
2118
                        } else {
2119
                                Iterator iter = this.dimensions.iterator();
2120
                                while (iter.hasNext()) {
2121
                                        if (!aLayer.dimensions.contains(iter.next())) {
2122
                                                return false;
2123
                                        }
2124
                                }
2125
                        }
2126

    
2127
                } else if ((this.dimensions != null) != (aLayer.dimensions != null)) {
2128
                        return false;
2129
                }
2130

    
2131
                return true;
2132
        }
2133

    
2134
        /*
2135
         * (non-Javadoc)
2136
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#isActionEnabled(int)
2137
         */
2138
        public boolean isActionEnabled(int action) {
2139
                switch (action) {
2140
                        case IRasterLayerActions.ZOOM_PIXEL_RESOLUTION:
2141
                        case IRasterLayerActions.FLYRASTER_BAR_TOOLS:
2142
                        case IRasterLayerActions.BANDS_FILE_LIST:
2143
                        case IRasterLayerActions.COLOR_TABLE:
2144
                        case IRasterLayerActions.GEOLOCATION:
2145
                        case IRasterLayerActions.PANSHARPENING:
2146
                        case IRasterLayerActions.SAVE_COLORINTERP:
2147
                                return false;
2148
                        case IRasterLayerActions.REMOTE_ACTIONS:
2149
                                return true;
2150
                }
2151

    
2152
                return super.isActionEnabled(action);
2153
        }
2154

    
2155
        /*
2156
         * (non-Javadoc)
2157
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#getLegend()
2158
         */
2159
        public ILegend getLegend() {
2160
                return null;
2161
        }
2162

    
2163
        /*
2164
         * (non-Javadoc)
2165
         * @see org.gvsig.fmap.raster.IRasterOperations#getDatatype()
2166
         */
2167
        public int[] getDataType(){
2168
                try {
2169
                        return dataset.getDataType();
2170
                } catch (NullPointerException e) {
2171
                        if(layerRaster != null && layerRaster[0] != null)
2172
                                return layerRaster[0].getDataType();
2173
                        else
2174
                                return new int[]{IBuffer.TYPE_UNDEFINED};
2175
                }
2176
        }
2177

    
2178
        /*
2179
         * (non-Javadoc)
2180
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#overviewsSupport()
2181
         */
2182
        public boolean overviewsSupport() {
2183
                return false;
2184
        }
2185

    
2186
        protected void updateDrawVersion() {
2187
                if (this.disableUpdateDrawVersion != null){
2188

    
2189
                        Thread curThread = Thread.currentThread();
2190

    
2191
                        Thread aThread;
2192

    
2193
                        Iterator iter = this.disableUpdateDrawVersion.iterator();
2194
                        while (iter.hasNext()){
2195
                                aThread = (Thread) ((WeakReference)iter.next()).get();
2196
                                if (aThread == null){
2197
                                        iter.remove();
2198
                                } else if(aThread.equals(curThread)){
2199
                                        return;
2200
                                }
2201
                        }
2202
                }
2203
//                Exception ex = new Exception();
2204
//                ex.printStackTrace();
2205
                super.updateDrawVersion();
2206
        }
2207

    
2208
        protected void disableUpdateDrawVersion(){
2209
                if (this.disableUpdateDrawVersion == null){
2210
                        this.disableUpdateDrawVersion = new ArrayList();
2211
                }
2212
                this.disableUpdateDrawVersion.add(new WeakReference(Thread.currentThread()));
2213
        }
2214

    
2215
        protected void enableUpdateDrawVersion(){
2216
                if (this.disableUpdateDrawVersion == null){
2217
                        return;
2218
                }
2219

    
2220
                Thread curThread = Thread.currentThread();
2221

    
2222
                Thread aThread;
2223

    
2224

    
2225
                Iterator iter = this.disableUpdateDrawVersion.iterator();
2226
                while (iter.hasNext()){
2227
                        aThread = (Thread) ((WeakReference)iter.next()).get();
2228
                        if (aThread == null){
2229
                                iter.remove();
2230
                        } else if(aThread.equals(curThread)){
2231
                                iter.remove();
2232
                                break;
2233
                        }
2234
                }
2235

    
2236
        }
2237
        
2238
        /*
2239
         * (non-Javadoc)
2240
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#cloneLayer()
2241
         */
2242
        public FLayer cloneLayer() throws Exception {
2243
                FLyrWMS layer = new FLyrWMS();
2244
                layer.setHost(this.getHost());
2245
                layer.setName(this.getName());
2246
                layer.setSRS(this.getSRS());
2247
                layer.setFormat(this.getFormat());
2248
                layer.setFullExtent(this.fullExtent);
2249
                layer.setDriver(this.getDriver());
2250
        layer.setStyles(getStyles());
2251
        layer.setOnlineResources(this.onlineResources);
2252
        layer.setFixedSize(this.fixedSize);
2253
        layer.setQueryable(this.queryable);
2254
        layer.setWmsTransparency(this.wmsTransparency);
2255
        layer.setDimensions(this.dimensions);
2256
        layer.setLayerQuery(this.layerQuery);
2257
        layer.setInfoLayerQuery(this.infoLayerQuery);
2258
        
2259
                ArrayList filters = null;
2260
                if(layer.getRender().getFilterList() == null) {
2261
                        layer.getRender().setFilterList(new RasterFilterList());
2262
                        filters = layer.getRender().getFilterList().getStatusCloned();
2263
                }
2264
                else
2265
                        filters = getRender().getFilterList().getStatusCloned();
2266
                layer.getRender().getFilterList().setStatus(filters);
2267
                
2268
                return layer;
2269
        }
2270

    
2271
        /*
2272
         * (non-Javadoc)
2273
         * @see org.gvsig.fmap.raster.layers.FLyrRasterSE#getFileLayer()
2274
         */
2275
        public FLayer getFileLayer() {
2276
                if(layerRaster != null && layerRaster[0] != null) {
2277
                        FLyrRasterSE ly = null;
2278
                        if(lastNColumns == 0 && lastNRows == 0) {
2279
                                try {
2280
                                        ly = createLayer(layerRaster[0].getName(), layerRaster[0].getLoadParams(), layerRaster[0].getProjection());
2281
                                } catch (LoadLayerException e) {
2282
                                        return null;
2283
                                }
2284
                        } else {
2285

    
2286
                                String[][] s = new String[lastNRows][lastNColumns];
2287

    
2288
                                for (int i = 0; i < s.length; i++) {
2289
                                        for (int j = 0; j < s[0].length; j++) {
2290
                                                s[i][j] = ((FLyrRasterSE)layerRaster[i]).getDataSource().getNameDatasetStringList(i, j)[0];
2291
                                        }
2292
                                }
2293
                                try {
2294
                                        ly = createLayer("preview", s, getProjection());
2295
                                } catch (LoadLayerException e) {
2296
                                        return null;
2297
                                }
2298
                        }
2299
                        return ly;
2300
                }
2301
                return null;
2302
        }
2303

    
2304
        /**
2305
         * Try to guess the axis orientation from the CRS WKT definition,
2306
         * as there is no good way to do this using libProjection API.
2307
         * 
2308
         * @return One of @link {@link WMSStatus#CRS_AXIS_EAST_NORTH},
2309
         * {@link WMSStatus#CRS_AXIS_NORTH_EAST}, {@link WMSStatus#CRS_AXIS_SOUTH_WEST},
2310
         * {@link WMSStatus#CRS_AXIS_WEST_SOUTH}, {@link WMSStatus#CRS_AXIS_OTHER_OR_UNKNOWN}.
2311
         */
2312
        private int guessAxisOrientation() {
2313
                if (this.getProjection()!=null) {
2314
                        String wkt = this.getProjection().getWKT();
2315
                        if (wkt!=null) {
2316
                                String wktup = wkt.toUpperCase();
2317
                                Pattern p = Pattern.compile(".*AXIS\\[(.*)\\]\\s*,\\s*AXIS\\[(.*)\\].*", Pattern.DOTALL);
2318
                                Matcher m = p.matcher(wkt);
2319
                                if (m.matches()) {
2320
                                        String firstAxis = m.group(1);
2321
                                        String secondAxis = m.group(2);
2322
                                        if (firstAxis.contains("EAST")
2323
                                                        && secondAxis.contains("NORTH")) {
2324
                                                return WMSStatus.CRS_AXIS_EAST_NORTH;
2325
                                        }
2326
                                        else if (firstAxis.contains("NORTH")
2327
                                                        && secondAxis.contains("EAST")) {
2328
                                                return WMSStatus.CRS_AXIS_NORTH_EAST;
2329
                                        }
2330
                                        else if (firstAxis.contains("WEST")
2331
                                                        && secondAxis.contains("SOUTH")) {
2332
                                                return WMSStatus.CRS_AXIS_WEST_SOUTH;
2333
                                        }
2334
                                        else if (firstAxis.contains("SOUTH")
2335
                                                        && secondAxis.contains("WEST")) {
2336
                                                return WMSStatus.CRS_AXIS_SOUTH_WEST;
2337
                                        }
2338
                                }
2339
                        }
2340
                }
2341
                return WMSStatus.CRS_AXIS_OTHER_OR_UNKNOWN;
2342
        }
2343
        
2344
        public void setProjection(IProjection proj) {
2345
                super.setProjection(proj);
2346
                cachedAxisOrientation = guessAxisOrientation();
2347
        }
2348
}