Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRasterTools-SE / src / org / gvsig / fmap / raster / layers / FLyrRasterSE.java @ 33329

History | View | Annotate | Download (66 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.fmap.raster.layers;
23

    
24
import java.awt.Dimension;
25
import java.awt.Graphics2D;
26
import java.awt.Point;
27
import java.awt.Rectangle;
28
import java.awt.geom.AffineTransform;
29
import java.awt.geom.NoninvertibleTransformException;
30
import java.awt.geom.Point2D;
31
import java.awt.geom.Rectangle2D;
32
import java.awt.image.BufferedImage;
33
import java.io.File;
34
import java.io.IOException;
35
import java.lang.reflect.Constructor;
36
import java.lang.reflect.InvocationTargetException;
37
import java.util.ArrayList;
38
import java.util.HashMap;
39
import java.util.Hashtable;
40

    
41
import javax.print.attribute.PrintRequestAttributeSet;
42
import javax.swing.ImageIcon;
43

    
44
import org.cresques.cts.IProjection;
45
import org.gvsig.fmap.raster.legend.ColorTableLegend;
46
import org.gvsig.raster.FileNotFoundSolve;
47
import org.gvsig.raster.RasterLibrary;
48
import org.gvsig.raster.buffer.BufferFactory;
49
import org.gvsig.raster.dataset.CompositeDataset;
50
import org.gvsig.raster.dataset.FileNotOpenException;
51
import org.gvsig.raster.dataset.IBuffer;
52
import org.gvsig.raster.dataset.IRasterDataSource;
53
import org.gvsig.raster.dataset.InvalidSetViewException;
54
import org.gvsig.raster.dataset.MosaicNotValidException;
55
import org.gvsig.raster.dataset.MultiRasterDataset;
56
import org.gvsig.raster.dataset.NotSupportedExtensionException;
57
import org.gvsig.raster.dataset.RasterDataset;
58
import org.gvsig.raster.dataset.io.RasterDriverException;
59
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
60
import org.gvsig.raster.dataset.properties.DatasetMetadata;
61
import org.gvsig.raster.dataset.serializer.RmfSerializerException;
62
import org.gvsig.raster.datastruct.ColorTable;
63
import org.gvsig.raster.datastruct.Extent;
64
import org.gvsig.raster.datastruct.ViewPortData;
65
import org.gvsig.raster.datastruct.persistence.ColorTableLibraryPersistence;
66
import org.gvsig.raster.grid.Grid;
67
import org.gvsig.raster.grid.GridException;
68
import org.gvsig.raster.grid.GridPalette;
69
import org.gvsig.raster.grid.GridTransparency;
70
import org.gvsig.raster.grid.filter.FilterTypeException;
71
import org.gvsig.raster.grid.filter.RasterFilterList;
72
import org.gvsig.raster.grid.filter.RasterFilterListManager;
73
import org.gvsig.raster.grid.filter.bands.ColorTableListManager;
74
import org.gvsig.raster.grid.filter.enhancement.EnhancementStretchListManager;
75
import org.gvsig.raster.grid.filter.enhancement.LinearStretchParams;
76
import org.gvsig.raster.grid.render.Rendering;
77
import org.gvsig.raster.grid.render.VisualPropertyEvent;
78
import org.gvsig.raster.grid.render.VisualPropertyListener;
79
import org.gvsig.raster.hierarchy.IRasterDataset;
80
import org.gvsig.raster.hierarchy.IRasterOperations;
81
import org.gvsig.raster.hierarchy.IRasterProperties;
82
import org.gvsig.raster.hierarchy.IStatistics;
83
import org.gvsig.raster.process.RasterTask;
84
import org.gvsig.raster.process.RasterTaskQueue;
85
import org.gvsig.raster.projection.CRS;
86
import org.gvsig.raster.util.ColorConversion;
87
import org.gvsig.raster.util.Historical;
88
import org.gvsig.raster.util.MathUtils;
89
import org.gvsig.raster.util.RasterToolsUtil;
90
import org.gvsig.tools.file.PathGenerator;
91

    
92
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
93
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
94
import com.iver.cit.gvsig.exceptions.layers.ReloadLayerException;
95
import com.iver.cit.gvsig.fmap.ViewPort;
96
import com.iver.cit.gvsig.fmap.core.FShape;
97
import com.iver.cit.gvsig.fmap.crs.CRSFactory;
98
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
99
import com.iver.cit.gvsig.fmap.layers.FLayer;
100
import com.iver.cit.gvsig.fmap.layers.FLyrDefault;
101
import com.iver.cit.gvsig.fmap.layers.LayerChangeSupport;
102
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
103
import com.iver.cit.gvsig.fmap.layers.LayerListener;
104
import com.iver.cit.gvsig.fmap.layers.Tiling;
105
import com.iver.cit.gvsig.fmap.layers.XMLException;
106
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
107
import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint;
108
import com.iver.cit.gvsig.fmap.layers.layerOperations.StringXMLItem;
109
import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem;
110
import com.iver.cit.gvsig.fmap.rendering.ILegend;
111
import com.iver.cit.gvsig.fmap.rendering.LegendListener;
112
import com.iver.utiles.FileUtils;
113
import com.iver.utiles.NotExistInXMLEntity;
114
import com.iver.utiles.XMLEntity;
115
import com.iver.utiles.swing.threads.Cancellable;
116
/**
117
 * Capa raster
118
 * @author Nacho Brodin (nachobrodin@gmail.com)
119
 */
120
public class FLyrRasterSE extends FLyrDefault implements IRasterProperties, IRasterDataset, InfoByPoint, Classifiable, IRasterOperations, IRasterLayerActions, ILayerState, VisualPropertyListener {
121
        private boolean               mustTileDraw        = false;
122
        private boolean               mustTilePrint       = true;
123
        private int                   maxTileDrawWidth    = 200;
124
        private int                   maxTileDrawHeight   = 200;
125
        private int                   maxTilePrintWidth   = 1500;
126
        private int                   maxTilePrintHeight  = 1500;
127
        protected IStatusRaster       status              = null;
128
        private boolean               firstLoad           = false;
129
        private boolean               removeRasterFlag    = true;
130
        private Object                params              = null;
131
        protected IRasterDataSource   dataset             = null;
132
        protected Rendering           render              = null;
133
        protected BufferFactory       bufferFactory       = null;
134
        private int                   posX                = 0;
135
        private int                   posY                = 0;
136
        private double                posXWC              = 0;
137
        private int                   posYWC              = 0;
138
        private int                   r                   = 0;
139
        private int                   g                   = 0;
140
        private int                   b                   = 0;
141
        private LayerChangeSupport    layerChangeSupport  = new LayerChangeSupport();
142
        private FLyrState             state               = new FLyrState();
143
        private ArrayList             filterArguments     = null;
144
        protected ILegend             lastLegend          = null;
145
        protected ColorTable          loadedFromProject   = null;
146
        private ArrayList             rois                = null;
147
        private RasterDrawStrategy    strategy            = null;
148
        static private IConfiguration configuration       = new DefaultLayerConfiguration();
149
        
150
        private BufferedImage         image               = null;
151
        private static Hashtable<Class, ISolveErrorListener> 
152
                                      solveListeners      = new Hashtable<Class, ISolveErrorListener>();
153

    
154
        /**
155
         * Tipo de valor no data asociado a la capa.
156
         * Sirve para diferenciar los estados seleccionados por el usuario. Siendo
157
         * estos 'Sin Valor NoData', 'NoData de Capa'(Por defecto) y 'Personalizado'
158
         */
159
        private int                   noDataType          = RasterLibrary.NODATATYPE_LAYER;
160

    
161
        /**
162
         * Lista de transformaciones afines que son aplicadas. Esta lista es
163
         * simplemente un historico que no se utiliza. Es posible utilizarlo para
164
         * recuperar transformaciones anteriores.
165
         */
166
        private Historical            affineTransformList   = new Historical();
167
        private boolean               loadingFromProject    = false;
168
        
169
        protected String              readingData           = null;
170

    
171
        private static PathGenerator pathGenerator=PathGenerator.getInstance();
172
        
173
        static {
174
                 RasterLibrary.wakeUp();
175
                 //TODO: Problema de dependencia entre appgvSIG y libFMap. La resoluci?n de errores en la ruta de las capas deber?a ser un mecanismo general.
176
                 FLyrRasterSE.addSolveErrorForLayer(NotSupportedExtensionException.class, new FileNotFoundSolve());
177
        }
178

    
179
        /**
180
         * Crea una capa Raster a partir del nombre driver, fichero y proyecci?n.
181
         * @param layerName Nombre de la capa..
182
         * @param params Par?metros de carga del formato. El caso m?s simple es la ruta de la capa en disco.
183
         * @param d RasterDriver.
184
         * @param f Fichero.
185
         * @param proj Proyecci?n.
186
         * @return Nueva capa de tipo raster.
187
         * @throws DriverIOException
188
         */
189
        public static FLyrRasterSE createLayer(String layerName, Object params,
190
                        IProjection proj) throws LoadLayerException {
191
                FLyrRasterSE capa = new FLyrRasterSE();
192
                capa.setLoadParams(params);
193
                capa.setName(layerName);
194
                capa.setProjection(proj);
195
                capa.load();
196
                return capa;
197
        }
198

    
199
        private static FLyrRasterSE tryToSolveError(Exception e, FLayer layer) {
200
                ISolveErrorListener sel = solveListeners.get(e.getClass());
201
                if (sel != null) {
202
                        FLyrRasterSE solvedLayer = null;
203
                        solvedLayer = (FLyrRasterSE)sel.solve(layer, null);
204
                        if (solvedLayer != null && sel != null){
205
                                return solvedLayer;
206
                        }
207
                }
208
                layer.setAvailable(false);
209
                return (FLyrRasterSE)layer;
210
        }
211
        
212
        /**
213
         * A?ade un gestor de errores en la carga de la capa
214
         * @param exception
215
         * @param sel
216
         */
217
        public static void addSolveErrorForLayer(Class exception, ISolveErrorListener sel) {
218
                solveListeners.put(exception, sel);
219
        }
220
        
221
        /**
222
         * Asigna los par?metros para la carga de la capa
223
         * @param param Par?metros.
224
         */
225
        public void setLoadParams(Object param){
226
                this.params = param;
227

    
228
                //Si la capa tiene nombre acivamos el estado awake
229
                if(params != null && getName() != null) {
230
                        try {
231
                                enableAwake();
232
                        } catch (NotAvailableStateException e) {
233
                                RasterToolsUtil.messageBoxError("Fallo el estado de open. Closed=" + isClosed() + " Active=" + isOpen(), this, e);
234
                        }
235
                }
236
        }
237

    
238
        /**
239
         * Obtiene los par?metros para la carga de la capa
240
         * @return param Par?metros.
241
         */
242
        public Object getLoadParams() {
243
                return params;
244
        }
245

    
246
        /*
247
         * (non-Javadoc)
248
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setName(java.lang.String)
249
         */
250
        public void setName(String name) {
251
                super.setName(name);
252

    
253
                //Si la capa tiene nombre acivamos el estado awake
254
                if(getLoadParams() != null && name != null) {
255
                        try {
256
                                if(isClosed())
257
                                        enableAwake();
258
                        } catch (NotAvailableStateException e) {
259
                                RasterToolsUtil.messageBoxError("Fallo el estado de open. Closed=" + isClosed() + " Active=" + isOpen(), this, e);
260
                        }
261
                }
262
        }
263

    
264
        /*
265
         * (non-Javadoc)
266
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#wakeUp()
267
         */
268
        public void wakeUp(){
269
                if (bufferFactory == null) {
270
                        try {
271
                                reload();
272
                        } catch (ReloadLayerException e) {
273
                                // No se ha podido recuperar la capa con exito
274
                        }
275
                }
276
        }
277

    
278
        /**
279
         * Asignar el estado del raster
280
         * @param status
281
         */
282
        public void setStatus(IStatusRaster status){
283
                this.status = status;
284
        }
285

    
286
        /**
287
         * Obtiene el estado del raster
288
         * @return
289
         */
290
        public IStatusRaster getStatus(){
291
                return this.status;
292
        }
293

    
294
        /*
295
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#load()
296
         */
297
        public void load() throws LoadLayerException {
298
                if (isStopped())
299
                        return;
300

    
301
                enableStopped(); // Paramos la capa mientras se hace un load
302

    
303
                String fName = null;
304
                int test = -1;
305
                if (params != null && params instanceof File) {
306
                        fName = ((File) params).getAbsolutePath();
307
                        test = fName.indexOf("ecwp:");
308
                }
309

    
310
                if (test != -1) {
311
                        String urlECW = fName.substring(test + 6);
312
                        fName = "ecwp://" + urlECW;
313
                        System.err.println(test + " " + fName);
314
                }
315

    
316
                try {
317
                        if (params instanceof String[][]) {
318
                                String[][] files = (String[][]) params;
319
                                MultiRasterDataset[][] dt = new MultiRasterDataset[files.length][files[0].length];
320
                                for (int i = 0; i < files.length; i++)
321
                                        for (int j = 0; j < files[i].length; j++)
322
                                                dt[i][j] = MultiRasterDataset.open(getProjection(), files[i][j]);
323
                                dataset = new CompositeDataset(dt);
324
                        } else
325
                                if (params == null || params instanceof File) {
326
                                        if (fName != null)
327
                                                dataset = MultiRasterDataset.open(getProjection(), fName);
328
                                } else
329
                                        dataset = MultiRasterDataset.open(getProjection(), params);
330
                } catch (NotSupportedExtensionException e) {
331
                        if(test == -1 && loadingFromProject) { 
332
                                FLyrRasterSE lyr = tryToSolveError(e, this);
333
                                if(lyr != null)
334
                                        dataset = lyr.getDataSource();
335
                                else
336
                                        throw new LoadLayerException("Formato no valido", e);
337
                        } else
338
                                throw new LoadLayerException("Formato no valido", e);
339
                } catch (MosaicNotValidException e) {
340
                        throw new LoadLayerException("Error en el mosaico", e);
341
                } catch (Exception e) {
342
                        throw new LoadLayerException("No existe la capa.", e);
343
                }
344
                if (dataset != null)
345
                        this.init();
346
        }
347

    
348
        /**
349
         * Acciones de inicializaci?n despu?s de que la fuente de datos
350
         * de la capa est? asignada. El tipo de fuente de datos es variable
351
         * puede ser MultiRasterDataset, CompositeDataset u otras que existan e
352
         * implementen IRasterDatasource.
353
         */
354
        public void init() throws LoadLayerException {
355
                if (dataset == null)
356
                        throw new LoadLayerException("Formato no valido", new IOException());
357
                                
358
                bufferFactory = new BufferFactory(dataset);
359
                render = new Rendering(bufferFactory);
360
                render.addVisualPropertyListener(this);
361
                initFilters();
362

    
363
                //Inicializaci?n del historico de transformaciones
364
                affineTransformList.clear();
365
                affineTransformList.add(this.getAffineTransform());
366

    
367
                try {
368
                        enableOpen();
369
                } catch (NotAvailableStateException e) {
370
                        RasterToolsUtil.messageBoxError("Fallo el estado de open. Closed=" + isClosed() + " Awake=" + isAwake(), this, e);
371
                }
372
        }
373

    
374
        /**
375
         * Obtiene la proyecci?n del fichero.
376
         * @return IProjection
377
         */
378
        public IProjection readProjection() {
379
                try {
380
                        CRS.setCRSFactory(CRSFactory.cp);
381
                        if( dataset == null )
382
                                return null;
383
                        return CRS.convertWktToIProjection(dataset.getWktProjection());
384
                } catch (RasterDriverException e) {
385
                        RasterToolsUtil.messageBoxError("Problemas accediendo a getWktProjection. Driver no inicializado", this, e);
386
                }
387
                return null;
388
        }
389
        
390
        /**
391
         * Crea el objeto renderizador de raster
392
         * @return Rendering
393
         */
394
        public Rendering getRender() {
395
                if (render == null) {
396
                        render = new Rendering(bufferFactory);
397
                        render.addVisualPropertyListener(this);
398
                }
399
                return render;
400
        }
401
        
402
        /**
403
         * Aplica los filtros noData al layer
404
         * @param rasterSE
405
         * @param filterManager
406
         */
407
        public void applyNoData() {
408
                Boolean noDataEnabled = configuration.getValueBoolean("nodata_transparency_enabled", Boolean.FALSE);
409
                if (noDataEnabled.booleanValue() && getDataSource().isNoDataEnabled()) {
410
                        noDataType = RasterLibrary.NODATATYPE_LAYER;
411
                        Double noDataValue = Double.valueOf(getNoDataValue());
412
                        getDataSource().getTransparencyFilesStatus().setNoData(noDataValue.doubleValue());
413
                } else {
414
                        if(getDataSource() != null && getDataSource().getTransparencyFilesStatus() != null)
415
                                getDataSource().getTransparencyFilesStatus().activeNoData(false);
416
                        noDataType = RasterLibrary.NODATATYPE_DISABLED;
417
                }
418
        }
419

    
420
        /**
421
         * Filtros a?adidos por defecto en la pila para visualizaci?n.
422
         */
423
        private void initFilters() {
424
                RasterFilterList filterList = new RasterFilterList();
425
                filterList.addEnvParam("IStatistics", getDataSource().getStatistics());
426
                filterList.addEnvParam("MultiRasterDataset", getDataSource());
427
                
428
                if(getDataSource() == null)
429
                        return;
430
                
431
                getDataSource().resetNoDataValue();
432
                applyNoData();
433
                GridTransparency gridTransparency = new GridTransparency(getDataSource().getTransparencyFilesStatus());
434

    
435
                filterList.setInitDataType(getDataType()[0]);
436
                RasterFilterListManager filterManager = new RasterFilterListManager(filterList);
437

    
438
                // Quitamos la leyenda
439
                lastLegend = null;
440

    
441
                try {
442
                        //Si en la carga del proyecto se carg? una tabla de color asignamos esta
443
                        if(loadedFromProject != null) {
444
                                GridPalette p = new GridPalette(loadedFromProject);
445
                                setLastLegend(p);
446
                                ColorTableListManager ctm = new ColorTableListManager(filterManager);
447
                                ctm.addColorTableFilter(p);
448
                        } else {
449
                                //sino ponemos la tabla asociada al raster
450
                                if (this.getDataSource().getColorTables()[0] != null) {
451
                                        GridPalette p = new GridPalette(getDataSource().getColorTables()[0]);
452
                                        setLastLegend(p);
453
                                        ColorTableListManager ctm = new ColorTableListManager(filterManager);
454
                                        ctm.addColorTableFilter(p);
455
                                } else {
456
                                        //sino hace lo que dice en las preferencias
457
                                        if (getDataType()[0] != IBuffer.TYPE_BYTE) 
458
                                                loadEnhancedOrColorTable(filterManager);
459

    
460
                                }
461
                        }
462
                        loadedFromProject = null;
463

    
464
                        getRender().setFilterList(filterList);
465
                        // Inicializo la transparencia para el render
466
                        getRender().setLastTransparency(gridTransparency);
467
                } catch (FilterTypeException e) {
468
                        //Ha habido un error en la asignaci?n de filtros por los que no se a?ade ninguno.
469
                        RasterToolsUtil.debug("Error a?adiendo filtros en la inicializaci?n de capa " + this.getName() + " Datatype=" + this.getDataType(), null, e);
470
                }
471
        }
472

    
473
        /**
474
         * Mira la configuracion para saber si debe cargar un realce o una tabla
475
         * de color por defecto
476
         * @param filterManager
477
         * @throws FilterTypeException
478
         */
479
        private void loadEnhancedOrColorTable(RasterFilterListManager filterManager) throws FilterTypeException {
480
                String colorTableName = configuration.getValueString("loadlayer_usecolortable", (String) null);
481

    
482
                String palettesPath = FileUtils.getAppHomeDir() + "colortable";
483

    
484
                IStatistics stats = getDataSource().getStatistics();
485

    
486
                if (colorTableName != null) {
487
                        try {
488
                                stats.calcFullStatistics();
489
                                if (getBandCount() == 1) {
490
                                        ArrayList fileList = ColorTableLibraryPersistence.getPaletteFileList(palettesPath);
491
                                        for (int i = 0; i < fileList.size(); i++) {
492
                                                ArrayList paletteItems = new ArrayList();
493
                                                String paletteName = ColorTableLibraryPersistence.loadPalette(palettesPath, (String) fileList.get(i), paletteItems);
494
                                                if (paletteName.equals(colorTableName)) {
495
                                                        if (paletteItems.size() <= 0)
496
                                                                continue;
497

    
498
                                                        ColorTable colorTable = new ColorTable();
499
                                                        colorTable.setName(paletteName);
500
                                                        colorTable.createPaletteFromColorItems(paletteItems, true);
501
                                                        colorTable.setInterpolated(true);
502

    
503
                                                        colorTable.createColorTableInRange(stats.getMinimun(), stats.getMaximun(), true);
504

    
505
                                                        GridPalette p = new GridPalette(colorTable);
506
                                                        setLastLegend(p);
507

    
508
                                                        ColorTableListManager ctm = new ColorTableListManager(filterManager);
509
                                                        ctm.addColorTableFilter(p);
510
                                                        return;
511
                                                }
512
                                        }
513
                                }
514
                        } catch (FileNotOpenException e) {
515
                                // No podemos aplicar el filtro
516
                        } catch (RasterDriverException e) {
517
                                // No podemos aplicar el filtro
518
                        } catch (InterruptedException e) {
519
                                // El usuario ha cancelado el proceso
520
                        }
521
                }
522

    
523
                /*EnhancementListManager elm = new EnhancementListManager(filterManager);
524
                elm.addEnhancedFilter(false, stats, 0.0, getRender().getRenderBands());*/
525
                
526
                EnhancementStretchListManager elm = new EnhancementStretchListManager(filterManager);
527
                try {
528
                        elm.addEnhancedStretchFilter(LinearStretchParams.createStandardParam(getRenderBands(), 0.0, stats, false), 
529
                                                                                stats, 
530
                                                                                getRender().getRenderBands(), 
531
                                                                                false);
532
                } catch (FileNotOpenException e) {
533
                        //No podemos aplicar el filtro
534
                } catch (RasterDriverException e) {
535
                        //No podemos aplicar el filtro
536
                }
537
        }
538

    
539
        /**
540
         * Devuelve si es reproyectable o no la capa
541
         * @return
542
         */
543
        public boolean isReproyectable() {
544
                if (dataset == null)
545
                        return false;
546

    
547
                int nFiles = dataset.getDatasetCount();
548
                for (int i = 0; i < nFiles; i++)
549
                        if (!dataset.getDataset(i)[0].isReproyectable())
550
                                return false;
551
                return true;
552
        }
553
        
554
        /**
555
         * @throws ReadDriverException
556
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
557
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort,
558
         *                 com.iver.utiles.swing.threads.Cancellable)
559
         */
560
        public void draw(BufferedImage image, Graphics2D g, ViewPort vp, Cancellable cancel, double scale) throws ReadDriverException {
561
                this.image = image;
562
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
563
                
564
                task.setEvent(null);
565

    
566
                try {
567
                        if (!isOpen())
568
                                return;
569

    
570
                        enableStopped();
571
                        // callLegendChanged(null);
572

    
573
                        strategy = new RasterDrawStrategy(getMapContext(), this);
574
                        strategy.stackStrategy();
575
                        HashMap tStr = strategy.getStrategy();
576
                        if (tStr != null && 
577
                                tStr.get(this) != null && 
578
                                ((Boolean) (tStr.get(this))).booleanValue() == false) {
579
                                disableStopped();
580
                                return;
581
                        }
582

    
583
                        if (isWithinScale(scale)) {
584
                                if (status != null && firstLoad) {
585
                                        if (mustTileDraw) {
586
                                                Point2D p = vp.getOffset();
587
                                                Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), vp.getImageWidth(), vp.getImageHeight());
588
                                                Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
589
                                                tiles.setAffineTransform((AffineTransform) vp.getAffineTransform().clone());
590
                                                for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
591
                                                        // drawing part
592
                                                        try {
593
                                                                ViewPort vport = tiles.getTileViewPort(vp, tileNr);
594
//                                                                g.setClip(tiles.getClip(tileNr).x, tiles.getClip(tileNr).y, tiles.getClip(tileNr).width - 5, tiles.getClip(tileNr).height);
595
                                                                draw(image, g, vport, cancel);
596
                                                        } catch (RasterDriverException e) {
597
                                                                throw new ReadDriverException("", e);
598
                                                        } catch (InvalidSetViewException e) {
599
                                                                throw new ReadDriverException("Error al asignar la vista en el draw.", e);
600
                                                        } catch (InterruptedException e) {
601
                                                                System.out.println("Se ha cancelado el pintado");
602
//                                                                throw new ReadDriverException("Dibujado interrumpido.", e);
603
                                                        } catch (NoninvertibleTransformException e) {
604
                                                                throw new ReadDriverException("Error en la transformaci?n", e);
605
                                                        }
606
                                                }
607
                                        } else {
608
                                                try {
609
                                                        draw(image, g, vp, cancel);
610
                                                } catch (RasterDriverException e) {
611
                                                        throw new ReadDriverException("", e);
612
                                                } catch (InvalidSetViewException e) {
613
                                                        throw new ReadDriverException("Error al asignar la vista en el draw.", e);
614
                                                } catch (InterruptedException e) {
615
                                                        System.out.println("Se ha cancelado el pintado");
616
//                                                throw new ReadDriverException("Dibujado interrumpido.", e);
617
                                                }
618
                                        }
619
                                        try {
620
                                                status.applyStatus(this);
621
                                        } catch (NotSupportedExtensionException e) {
622
                                                throw new ReadDriverException("Error setting filters from a project.", e);
623
                                        } catch (RasterDriverException e) {
624
                                                throw new ReadDriverException("Error reading file from a project.", e);
625
                                        } catch (FilterTypeException e) {
626
                                                throw new ReadDriverException("Error adding filters.", e);
627
                                        }
628
                                        firstLoad = false;
629
                                }
630

    
631
                                if (mustTileDraw) {
632
                                        Point2D p = vp.getOffset();
633
                                        Rectangle r = new Rectangle((int) p.getX(), (int) p.getY(), vp.getImageWidth(), vp.getImageHeight());
634
                                        Tiling tiles = new Tiling(maxTileDrawWidth, maxTileDrawHeight, r);
635
                                        tiles.setAffineTransform((AffineTransform) vp.getAffineTransform().clone());
636
                                        for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
637
                                                // drawing part
638
                                                try {
639
                                                        ViewPort vport = tiles.getTileViewPort(vp, tileNr);
640
                                                        draw(image, g, vport, cancel);
641
                                                } catch (RasterDriverException e) {
642
                                                        throw new ReadDriverException("", e);
643
                                                } catch (InvalidSetViewException e) {
644
                                                        throw new ReadDriverException("Error al asignar la vista en el draw.", e);
645
                                                } catch (InterruptedException e) {
646
                                                        System.out.println("Se ha cancelado el pintado");
647
//                                                        throw new ReadDriverException("Dibujado interrumpido.", e);
648
                                                } catch (NoninvertibleTransformException e) {
649
                                                        throw new ReadDriverException("Error en la transformaci?n", e);
650
                                                }
651
                                        }
652
                                } else {
653
                                        try {
654
                                                draw(image, g, vp, cancel);
655
                                        } catch (RasterDriverException e) {
656
                                                throw new ReadDriverException("", e);
657
                                        } catch (InvalidSetViewException e) {
658
                                                throw new ReadDriverException("Error al asignar la vista en el draw.", e);
659
                                        } catch (InterruptedException e) {
660
                                                System.out.println("Se ha cancelado el pintado");
661
//                                        throw new ReadDriverException("Dibujado interrumpido.", e);
662
                                        }
663
                                }
664

    
665
                        }
666
                        //callLegendChanged(null);
667
                } finally {
668
                        disableStopped();
669
                        //task.setEvent(null);
670
                }
671
                
672
                /*Runtime r = Runtime.getRuntime();
673
                System.err.println("********************FLyrRaster***************");
674
                System.err.println("Memoria Total: " + (r.totalMemory() / 1024) +"KB");
675
                System.err.println("Memoria Usada: " + ((r.totalMemory() - r.freeMemory()) / 1024) +"KB");
676
                System.err.println("Memoria Libre: " + (r.freeMemory() / 1024) +"KB");
677
                System.err.println("Memoria MaxMemory: " + (r.maxMemory() / 1024) +"KB");
678
                System.err.println("*********************************************");*/
679
        }
680

    
681
        private void draw(BufferedImage image, Graphics2D g, ViewPort vp, Cancellable cancel) throws RasterDriverException, InvalidSetViewException, InterruptedException {
682
                Rectangle2D adjustedExtent = vp.getAdjustedExtent();
683
                if (adjustedExtent == null) return;
684
                Extent e = new Extent(adjustedExtent);
685
                Dimension imgSz = vp.getImageSize();
686
                ViewPortData vp2 = new ViewPortData(vp.getProjection(), e, imgSz );
687
                vp2.setMat(vp.getAffineTransform());
688
                getRender().draw(g, vp2);
689
        }
690

    
691
        /**
692
         * Inserta la proyecci?n.
693
         *
694
         * @param proj Proyecci?n.
695
         */
696
        public void setProjection(IProjection proj) {
697
                super.setProjection(proj);
698
        }
699

    
700
        /*
701
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
702
         */
703
        public Rectangle2D getFullExtent() {
704
                //TODO:DEPURACION Comentamos !isOpen porque getFullExtent de FLayers da una excepci?n ya que siempre espera
705
                //un extent aunque la capa no est? abierta
706
                if(/*!isOpen() || */dataset == null || dataset.getExtent() == null)
707
                        return null;
708
                return dataset.getExtent().toRectangle2D();
709
        }
710

    
711
        /**
712
         * Obtiene el valor del pixel del Image en la posici?n x,y
713
         * @param x Posici?n x
714
         * @param y Posici?n y
715
         * @return valor de pixel
716
         */
717
        public int[] getPixel(int pxx, int pxy) {
718
                int[] argb = { -1, -1, -1, -1 };
719
                if (!isOpen() || (image == null))
720
                        return argb;
721
                if (pxx >= 0 && pxx < image.getWidth() && pxy >= 0 && pxy < image.getHeight()) {
722
                        int value = image.getRGB(pxx, pxy);
723
                        argb[0] = ((value & 0xff000000) >> 24);
724
                        argb[1] = ((value & 0x00ff0000) >> 16);
725
                        argb[2] = ((value & 0x0000ff00) >> 8);
726
                        argb[3] = (value & 0x000000ff);
727
                }
728
                return argb;
729
        }
730

    
731
        /*
732
         * (non-Javadoc)
733
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getMaxX()
734
         */
735
        public double getMaxX() {
736
                if(getFullExtent() != null)
737
                        return getFullExtent().getMaxX();
738
                return -1;
739
        }
740

    
741
        /*
742
         * (non-Javadoc)
743
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getMaxY()
744
         */
745
        public double getMaxY() {
746
                if(getFullExtent() != null)
747
                        return this.getFullExtent().getMaxY();
748
                return -1;
749
        }
750

    
751
        /*
752
         * (non-Javadoc)
753
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getMinX()
754
         */
755
        public double getMinX() {
756
                if(getFullExtent() != null)
757
                        return getFullExtent().getMinX();
758
                return -1;
759
        }
760

    
761
        /*
762
         * (non-Javadoc)
763
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getMinY()
764
         */
765
        public double getMinY() {
766
                if(getFullExtent() != null)
767
                        return getFullExtent().getMinY();
768
                return -1;
769
        }
770

    
771
        /* (non-Javadoc)
772
         * @deprecated. See String getInfo(Point p) throws DriverException
773
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#queryByPoint(java.awt.Point)
774
         */
775
        public String queryByPoint(Point p) {
776
                if (!isOpen())
777
                        return null;
778
                ColorConversion conv = new ColorConversion();
779

    
780
                String data = "<file:" + normalizeAsXMLTag(getName()) + ">\n";
781

    
782
                ArrayList attr = getAttributes();
783
                data += "  <raster\n";
784
                data += "    File=\"" + getFile() + "\"\n";
785
                for (int i = 0; i < attr.size(); i++) {
786
                        Object[] a = (Object[]) attr.get(i);
787

    
788
                        data += "    " + a[0].toString() + "=";
789
                        if (a[1].toString() instanceof String)
790
                                data += "\"" + a[1].toString() + "\"\n";
791
                        else
792
                                data += a[1].toString() + "\n";
793
                }
794
                data += "    Point=\"" + posX + " , " + posY + "\"\n";
795
                data += "    Point_WC=\"" + MathUtils.format(posXWC, 3) + " , " + MathUtils.format(posYWC, 3) + "\"\n";
796
                data += "    RGB=\"" + r + ", " + g + ", " + b + "\"\n";
797
                double[] cmyk = conv.RGBtoCMYK(r & 0xff, g & 0xff, b & 0xff, 1D);
798
                data += "    CMYK=\"" + MathUtils.format(cmyk[0], 4) + ", " + MathUtils.format(cmyk[1], 4) + ", " + MathUtils.format(cmyk[2], 4) + "," + MathUtils.format(cmyk[3], 4) + "\"\n";
799
                double[] hsl = conv.RGBtoHSL(r & 0xff, g & 0xff, b & 0xff);
800
                hsl[0] = (int)(255.0 * hsl[0] / 360.0 + 0.5);
801
                hsl[2] = (int) (hsl[2] * 255. + 0.5);
802
                hsl[1] = (int) (hsl[1] * 255. + 0.5);
803
                data += "    HSL=\"" + MathUtils.format(hsl[0], 4) + ", " + MathUtils.format(hsl[1], 4) + ", " + MathUtils.format(hsl[2], 4) + "\"\n";
804
                data += "  />\n";
805

    
806
                data += "</file:" + normalizeAsXMLTag(getName()) + ">\n";
807
                return data;
808
        }
809

    
810
        /**
811
         * Transforma un punto real a coordenadas pixel indicando la banda que es usada para la
812
         * transformaci?n. Hay que tener en cuenta que es posible que todas las transformaciones no 
813
         * sean iguales en todas la bandas porque puede haber bandas de distinta resoluci?n.
814
         * 
815
         * @param numberBand
816
         * @param pReal
817
         * @return
818
         * @throws ReadDriverException
819
         */
820
        private Point2D transformPoint(int numberBand, Point2D pReal) throws ReadDriverException {
821
                AffineTransform at = this.getDataSource().getAffineTransform(numberBand);
822
                Point2D px = new Point2D.Double();
823
                //px = new Point2D.Double(pReal.getX(), pReal.getY());
824
                try {
825
                        at.inverseTransform(pReal, px);
826
                        return px;
827
                } catch (NoninvertibleTransformException e) {
828
                        throw new ReadDriverException("Error en la transformaci?n del punto", e);
829
                }
830
        }
831
        
832
        /*
833
         * (non-Javadoc)
834
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#getInfo(java.awt.Point, double, com.iver.utiles.swing.threads.Cancellable)
835
         */
836
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadDriverException {
837
                if (!isOpen()) {
838
                        StringXMLItem[] item = new StringXMLItem[1];
839
                        String data = "<file:" + normalizeAsXMLTag(getName()) + ">\n";
840
                        data += "  <raster\n" + "  Layer=\" Not available\"\n" + "  />\n";
841
                        data += "</file:" + normalizeAsXMLTag(getName()) + ">\n";
842
                        item[0] = new StringXMLItem(data, this);
843
                        return item;
844
                }
845

    
846
                Point2D pReal = getMapContext().getViewPort().toMapPoint(p);
847
                Point2D px = new Point2D.Double();
848
                if(        pReal.getX() > this.getMinX() &&
849
                        pReal.getX() < this.getMaxX() &&
850
                        pReal.getY() > this.getMinY() &&
851
                        pReal.getY() < this.getMaxY()) {
852

    
853
                        px = transformPoint(0, pReal);
854
                }
855
                int[] rgb = getPixel((int) p.getX(), (int) p.getY());
856
                ColorConversion conv = new ColorConversion();
857

    
858
                StringXMLItem[] item = new StringXMLItem[1];
859
                String data = "<file:" + normalizeAsXMLTag(getName()) + ">\n";
860

    
861
                data += "  <raster\n";
862
                data += "    View_Point=\"" + p.getX() + " , " + p.getY() + "\"\n";
863
                data += "    World_Point=\"" + MathUtils.format(pReal.getX(), 3) + " , " + MathUtils.format(pReal.getY(), 3) + "\"\n";
864
                if (px == null)
865
                        data += "    Pixel_Point=\"Out\"\n";
866
                else
867
                        data += "    Pixel_Point=\"" + (int) px.getX() + " , " + (int) px.getY() + "\"\n";
868
                if(getDataType()[0] != IBuffer.TYPE_BYTE)
869
                        data += "    RGB=\"" + rgb[1] + "  " + rgb[2] + "  " + rgb[3] + "\"\n";
870
                double[] cmyk = conv.RGBtoCMYK(rgb[1] & 0xff, rgb[2] & 0xff, rgb[3] & 0xff, 1D);
871
                data += "    CMYK=\"" + MathUtils.format(cmyk[0], 4) + ", " + MathUtils.format(cmyk[1], 4) + ", " + MathUtils.format(cmyk[2], 4) + "," + MathUtils.format(cmyk[3], 4) + "\"\n";
872
                double[] hsl = conv.RGBtoHSL(rgb[1] & 0xff, rgb[2] & 0xff, rgb[3] & 0xff);
873
                hsl[0] = (int)(255.0 * hsl[0] / 360.0 + 0.5);
874
                hsl[2] = (int) (hsl[2] * 255. + 0.5);
875
                hsl[1] = (int) (hsl[1] * 255. + 0.5);
876
                data += "    HSL=\"" + MathUtils.format(hsl[0], 4) + ", " + MathUtils.format(hsl[1], 4) + ", " + MathUtils.format(hsl[2], 4) + "\"\n";
877
                data += "    Band_Value=\"";
878
                try {
879
                        if (px != null) {
880
                                if(getDataType()[0] >= 0 && getDataType()[0] <= 3){
881
                                        for(int i = 0; i < getBandCount(); i++) {
882
                                                if(getDataSource().isInside(pReal)) {
883
                                                        Point2D pxAux = transformPoint(i, pReal);
884
                                                        int val = ((Integer)getDataSource().getData((int)pxAux.getX(), (int)pxAux.getY(), i)).intValue();
885
                                                        if(getDataType()[0] == IBuffer.TYPE_BYTE)
886
                                                                data += (val & 0x000000ff) + "  ";
887
                                                        else
888
                                                                data += val + "  ";
889
                                                }
890
                                        }
891
                                }
892
                                if(getDataType()[0] == 4){
893
                                        for(int i = 0; i < getBandCount(); i++) {
894
                                                if(getDataSource().isInside(pReal)) {
895
                                                        Point2D pxAux = transformPoint(i, pReal);
896
                                                        data += ((Float)getDataSource().getData((int)pxAux.getX(), (int)pxAux.getY(), i)).floatValue() + "  ";
897
                                                }
898
                                        }
899
                                }
900
                                if(getDataType()[0] == 5){
901
                                        for(int i = 0; i < getBandCount(); i++) {
902
                                                if(getDataSource().isInside(pReal)) {
903
                                                        Point2D pxAux = transformPoint(i, pReal);
904
                                                        data += ((Double)getDataSource().getData((int)pxAux.getX(), (int)pxAux.getY(), i)).doubleValue() + "  ";
905
                                                }
906
                                        }
907
                                }
908
                        }
909
                } catch (RasterDriverException ex) {
910
                        throw new ReadDriverException("Error en el acceso al dataset", ex);
911
                } catch (InvalidSetViewException ex) {
912
                        throw new ReadDriverException("Error en la asignaci?n de la vista en getData", ex);
913
                } catch (FileNotOpenException ex) {
914
                        throw new ReadDriverException("Fichero no abierto en el dataset", ex);
915
                } catch (InterruptedException e) {
916
                }
917
                data += "\"\n";
918
                data += "  />\n";
919
                data += "</file:" + normalizeAsXMLTag(getName()) + ">\n";
920

    
921
                item[0] = new StringXMLItem(data, this);
922
                return item;
923
        }
924

    
925
        /**
926
         * Filters a string for being suitable as XML Tag, erasing
927
         * all not alphabetic or numeric characters.
928
         * @param s
929
         * @return string normalized
930
         */
931
        private String normalizeAsXMLTag(String s) {
932
                return s.replaceAll("[^a-zA-Z0-9]", "");
933
        }
934

    
935
        /**
936
         * Obtiene atributos a partir de un georasterfile
937
         * @return
938
         */
939
        public ArrayList getAttributes() {
940
                ArrayList attr = new ArrayList();
941
                if(!isOpen())
942
                        return attr;
943
                Object [][] a = {
944
                        {"Filename", dataset.getDataset(0)[0].getFName()},
945
                        {"Filesize", new Long(dataset.getFileSize())},
946
                        {"Width", new Integer((int)dataset.getWidth())},
947
                        {"Height", new Integer((int)dataset.getHeight())},
948
                        {"Bands", new Integer(dataset.getBandCount())}
949
                };
950
                for (int i = 0; i < a.length; i++)
951
                        attr.add(a[i]);
952
                return attr;
953
        }
954

    
955
        /**
956
         * Escribe en el proyecto la capa actual
957
         * @throws XMLException
958
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
959
         */
960
        public XMLEntity getXMLEntity() throws XMLException {
961
                if(isClosed() || isAwake())
962
                        return null;
963

    
964
                return getXMLEntityWithoutChecks();
965
        }
966
        
967
        /**
968
         * This method has been added because a WMS server could be not running
969
         * where the project is loaded, but it doesn't mean that the layer
970
         * can not be loaded.
971
         * @return
972
         * @throws XMLException
973
         */
974
        public XMLEntity getXMLEntityWithoutChecks() throws XMLException {
975
                XMLEntity xml = super.getXMLEntity();
976
                if(getFile() != null){
977
                        xml.putProperty("absolutePath", getFile().getAbsolutePath());
978
                        xml.putProperty("file", pathGenerator.getPath(getFile().getAbsolutePath()));
979
                }
980
                xml.putProperty("driverName", "gvSIG Raster Driver");
981

    
982
                // Si no hay ning?n Status aplicamos el StatusLayerRaster que se usa por defecto
983
                if (status == null)
984
                        status = new StatusLayerRaster();
985
                status.getXMLEntity(xml, true, this);
986

    
987
                return xml;
988
        }
989

    
990
        public void setXMLEntity03(XMLEntity xml) throws XMLException {
991
        }
992

    
993
        /**
994
         * Recupera de disco los datos de la capa.
995
         */
996
        public void setXMLEntity(XMLEntity xml) throws XMLException {
997
                for (int i = 0; i < xml.getPropertyCount(); i++) {
998
                        String key = xml.getPropertyName(i);
999
                        if(key.startsWith("raster.file")) {
1000
                                if(xml.getPropertyValue(i).startsWith(RasterLibrary.getTemporalPath()))
1001
                                        throw new XMLException(new Throwable());
1002
                        }
1003
                }
1004

    
1005
                super.setXMLEntity(xml);
1006
                loadingFromProject = true;
1007
                
1008
                try {
1009
                        String path=pathGenerator.getAbsolutePath((String)xml.getStringProperty("file"));
1010
                        if (path!=null){
1011
                                params = new File(pathGenerator.getAbsolutePath(xml.getStringProperty("file")));
1012
                        }else{
1013
                                params = new File(xml.getStringProperty("absolutePath"));
1014
                        }
1015
                        
1016
                        if(params != null && getName() != null && getName().compareTo("") != 0) {
1017
                                try {
1018
                                        enableAwake();
1019
                                } catch (NotAvailableStateException e) {
1020
                                        RasterToolsUtil.messageBoxError("Fallo el estado de open. Closed=" + isClosed() + " Active=" + isOpen(), this, e);
1021
                                }
1022
                        }
1023
                        if(!super.getFLayerStatus().visible)
1024
                                enableStopped();
1025

    
1026
                        // Para notificar al adapter-driver cual es la proyecci?n.
1027
                        setProjection(super.getProjection());
1028

    
1029
                        //Inicializamos la clase a la que se usa por defecto para
1030
                        //compatibilidad con proyectos antiguos
1031
                        String claseStr = StatusLayerRaster.defaultClass;
1032
                        if (xml.contains("raster.class"))
1033
                                claseStr = xml.getStringProperty("raster.class");
1034

    
1035
                        if (status != null)
1036
                                status.setXMLEntity(xml, this);
1037
                        else {
1038
                                // Cuando cargamos un proyecto
1039

    
1040
                                if (claseStr != null && !claseStr.equals("")) {
1041
                                        try {
1042
                                                Class clase = LayerFactory.getLayerClassForLayerClassName(claseStr);
1043
                                                Constructor constr = clase.getConstructor(null);
1044
                                                status = (IStatusRaster) constr.newInstance(null);
1045
                                                if (status != null) {
1046
                                                        ((StatusLayerRaster)status).setNameClass(claseStr);
1047
                                                        status.setXMLEntity(xml, this);
1048
                                                        filterArguments = status.getFilterArguments();
1049
                                                        
1050
                                                        //Creamos la tabla de color
1051
                                                        ArrayList color = (ArrayList) filterArguments.clone();
1052
                                                        loadedFromProject = ColorTableListManager.createColorTableFromArray(color);
1053
                                                }
1054
                                        } catch (ClassNotFoundException exc) {
1055
                                                throw new XMLException(exc);
1056
                                        } catch (InstantiationException exc) {
1057
                                                throw new XMLException(exc);
1058
                                        } catch (IllegalAccessException exc) {
1059
                                                throw new XMLException(exc);
1060
                                        } catch (NoSuchMethodException exc) {
1061
                                                throw new XMLException(exc);
1062
                                        } catch (InvocationTargetException exc) {
1063
                                                throw new XMLException(exc);
1064
                                        }
1065
                                }
1066
                        }
1067
                        firstLoad = true;
1068
                } catch (NotExistInXMLEntity e) {
1069

    
1070
                }
1071
        }
1072

    
1073
        /* (non-Javadoc)
1074
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort, com.iver.cit.gvsig.fmap.operations.Cancellable)
1075
         */
1076
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet propeties) throws ReadDriverException {
1077

    
1078
                if (!isOpen() || !isVisible() || !isWithinScale(scale))
1079
                        return;
1080

    
1081
                if (!mustTilePrint) {
1082
                        draw(null, g, viewPort, cancel,scale);
1083
                } else {
1084
                        // Para no pedir imagenes demasiado grandes, vamos
1085
                        // a hacer lo mismo que hace EcwFile: chunkear.
1086
                        // Llamamos a drawView con cuadraditos m?s peque?os
1087
                        // del BufferedImage ni caso, cuando se imprime viene con null
1088
                        Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
1089
                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
1090

    
1091
                        //Si es la primera lectura salvamos los valores de m?ximo y m?nimo para la aplicaci?n
1092
                        //de realce si la imagen es de 16 bits.
1093

    
1094
                        //RasterStats stats = getSource().getFilterStack().getStats();
1095
                        //if(stats != null)
1096
                        //stats.history.add(stats.new History(getName(), stats.minBandValue, stats.maxBandValue, stats.secondMinBandValue, stats.secondMaxBandValue));
1097

    
1098

    
1099
                        for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
1100
                                // Parte que dibuja
1101
                                try {
1102
                                        ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
1103
                                        draw(null, g, vp, cancel, scale);
1104
                                } catch (NoninvertibleTransformException e) {
1105
                                        throw new ReadDriverException("Error en la transformaci?n.", e);
1106
                                }
1107
                        }
1108
                        /*if(stats != null){
1109
                                getSource().getFilterStack().getStats().history.clear();
1110
                                stats = getSource().getFilterStack().getStats();
1111
                        }*/
1112
                }
1113
        }
1114

    
1115
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale) throws ReadDriverException {
1116
                if(!isOpen())
1117
                        return;
1118

    
1119
                // Para no pedir imagenes demasiado grandes, vamos
1120
                // a hacer lo mismo que hace EcwFile: chunkear.
1121
                // Llamamos a drawView con cuadraditos m?s peque?os
1122
                // del BufferedImage ni caso, cuando se imprime viene con null
1123

    
1124
                int numW, numH;
1125
                int stepX, stepY;
1126
                int xProv, yProv;
1127
                int A = 1500;
1128
                int H = 1500;
1129
                int altoAux, anchoAux;
1130

    
1131
                AffineTransform mat = (AffineTransform) viewPort.getAffineTransform().clone();
1132

    
1133
                // Vamos a hacerlo en trozos de AxH
1134
                Rectangle r = g.getClipBounds();
1135
                numW = (int) (r.width) / A;
1136
                numH = (int) (r.height) / H;
1137

    
1138
                double[] srcPts = new double[8];
1139
                double[] dstPts = new double[8];
1140

    
1141
                yProv = (int) r.y;
1142
                for (stepY = 0; stepY < numH + 1; stepY++) {
1143
                        if ((yProv + H) > r.getMaxY())
1144
                                altoAux = (int) r.getMaxY() - yProv;
1145
                        else
1146
                                altoAux = H;
1147

    
1148
                        xProv = (int) r.x;
1149
                        for (stepX = 0; stepX < numW + 1; stepX++) {
1150
                                if ((xProv + A) > r.getMaxX())
1151
                                        anchoAux = (int) r.getMaxX() - xProv;
1152
                                else
1153
                                        anchoAux = A;
1154

    
1155
                                //Rectangle newRect = new Rectangle(xProv, yProv, anchoAux, altoAux);
1156

    
1157
                                // Parte que dibuja
1158
                                srcPts[0] = xProv;
1159
                                srcPts[1] = yProv;
1160
                                srcPts[2] = xProv + anchoAux + 1;
1161
                                srcPts[3] = yProv;
1162
                                srcPts[4] = xProv + anchoAux + 1;
1163
                                srcPts[5] = yProv + altoAux + 1;
1164
                                srcPts[6] = xProv;
1165
                                srcPts[7] = yProv + altoAux + 1;
1166

    
1167
                                try {
1168
                                        mat.inverseTransform(srcPts, 0, dstPts, 0, 4);
1169
                                        Rectangle2D.Double rectCuadricula = new Rectangle2D.Double(dstPts[0], dstPts[1], dstPts[2] - dstPts[0], dstPts[5] - dstPts[3]);
1170
                                        // Extent extent = new Extent(rectCuadricula);
1171

    
1172
                                        Dimension tam = new Dimension(anchoAux + 1, altoAux + 1);
1173
                                        ViewPort vp = viewPort.cloneViewPort();
1174
                                        vp.setImageSize(tam);
1175
                                        vp.setExtent(rectCuadricula);
1176
                                        vp.setAffineTransform(mat);
1177
                                        draw(null, g, vp, cancel, scale);
1178

    
1179
                                } catch (NoninvertibleTransformException e) {
1180
                                        throw new ReadDriverException("Error en la transformaci?n.", e);
1181
                                }
1182
                                // Fin parte que dibuja
1183
                                xProv = xProv + A;
1184
                        }
1185
                        yProv = yProv + H;
1186
                }
1187
        }
1188

    
1189
        /**
1190
         * Borra de la lista de listeners el que se pasa como par?metro.
1191
         *
1192
         * @param o LayerListener a borrar.
1193
         *
1194
         * @return True si ha sido correcto el borrado del Listener.
1195
         */
1196
        public boolean removeLayerListener(LayerListener o) {
1197
                if (this.isRemoveRasterFlag()) {
1198
                        try {
1199
                                enableClosed();
1200
                        } catch (NotAvailableStateException e1) {
1201
                                // No se ha podido cambiar el estado de la capa a cerrado
1202
                        }
1203
                }
1204
                
1205
                // Salva a RMF
1206
                if (this.getDataSource() != null) {
1207
                        // Guardamos la GeoReferenciacion de cada dataset
1208
                        try {
1209
                                for (int i = 0; i < getDataSource().getDatasetCount(); i++) {
1210
                                        getDataSource().saveObjectToRmf(i, RasterDataset.class, getDataSource().getDataset(i)[0]);
1211
                                }
1212
                        } catch (RmfSerializerException e) {
1213
                                RasterToolsUtil.messageBoxError("error_salvando_rmf", this, e);
1214
                        }
1215
                }
1216

    
1217
                if (this.isRemoveRasterFlag()) {
1218
                        image = null;
1219
                        String[] files = (String[]) getFileName().clone();
1220
                        if (dataset != null)
1221
                                dataset.close();
1222
                        if (bufferFactory != null)
1223
                                bufferFactory.free();
1224
                        bufferFactory = null;
1225
                        dataset = null;
1226
                        render = null;
1227
                        
1228
                        // System.gc();
1229
                        this.setRemoveRasterFlag(true);
1230
                        
1231
                        for (int i = 0; i < files.length; i++) {
1232
                                File file = new File(files[i]);
1233
                                File dirTemp = RasterLibrary.getTemporalFile();
1234
                                if (dirTemp.compareTo(file.getParentFile()) == 0) {
1235
                                        file.delete();
1236
                                        
1237
                                        // Borramos todos los ficheros que puedan tener relacion con el fichero actual
1238
                                        String basefile = file.getName();
1239
                                        File basepath = file.getParentFile();
1240
                                        int last = basefile.lastIndexOf(".");
1241
                                        if (last != -1)
1242
                                                basefile = basefile.substring(0, last + 1);
1243
                                        File[] list = basepath.listFiles();
1244
                                        for (int j = 0; j < list.length; j++)
1245
                                                if (list[j].getName().startsWith(basefile))
1246
                                                        list[j].delete();
1247
                                }
1248
                        }
1249
                }
1250
                updateDrawVersion();
1251
                return super.layerListeners.remove(o);
1252
        }
1253

    
1254
        /**
1255
         * @return Returns the removeRasterFlag.
1256
         */
1257
        public boolean isRemoveRasterFlag() {
1258
                return removeRasterFlag;
1259
        }
1260

    
1261
        /**
1262
         * Asigna el valor del flag que dice si destruimos la memoria del raster
1263
         * al eliminarlo del TOC o  no.
1264
         * @param removeRasterFlag The removeRasterFlag to set.
1265
         */
1266
        public void setRemoveRasterFlag(boolean removeRasterFlag) {
1267
                this.removeRasterFlag = removeRasterFlag;
1268
        }
1269

    
1270
        /*
1271
         * (non-Javadoc)
1272
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getTocImageIcon()
1273
         */
1274
        public ImageIcon getTocImageIcon() {
1275
                return new ImageIcon(getClass().getResource("images/map_ico_ok.gif"));
1276
        }
1277

    
1278
        /*
1279
         *  (non-Javadoc)
1280
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#getTileSize()
1281
         */
1282
        public int[] getTileSize() {
1283
                int[] size = {maxTileDrawWidth, maxTileDrawHeight};
1284
                return size;
1285
        }
1286

    
1287
        /*
1288
         *  (non-Javadoc)
1289
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#isTiled()
1290
         */
1291
        public boolean isTiled() {
1292
                return mustTileDraw;
1293
        }
1294

    
1295
        /**
1296
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1297
         * @return true si est? georreferenciada y false si no lo est?.
1298
         */
1299
        public boolean isGeoreferenced() {
1300
                return dataset.isGeoreferenced();
1301
        }
1302

    
1303
        /**
1304
         * Get datasource object
1305
         * @return
1306
         */
1307
        public BufferFactory getBufferFactory(){
1308
                return bufferFactory;
1309
        }
1310

    
1311
        /**
1312
         * Obtiene el valor NoData asociado al raster.
1313
         * @return double
1314
         */
1315
        public double getNoDataValue() {
1316
                if (dataset == null)
1317
                        return RasterLibrary.defaultNoDataValue;
1318
                return dataset.getNoDataValue();
1319
        }
1320

    
1321
        /**
1322
         * Asigna el valor no data asociado a la capa
1323
         * @param nd
1324
         */
1325
        public void setNoDataValue(double nd) {
1326
                if (bufferFactory != null)
1327
                        bufferFactory.setNoDataToFill(nd);
1328
                if (dataset != null)
1329
                        dataset.setNoDataValue(nd);
1330
        }
1331

    
1332
        /*
1333
         * (non-Javadoc)
1334
         * @see org.gvsig.fmap.raster.IRasterOperations#getPXHeight()
1335
         */
1336
        public double getPxHeight() {
1337
                return dataset.getHeight();
1338
        }
1339

    
1340
        /*
1341
         * (non-Javadoc)
1342
         * @see org.gvsig.fmap.raster.IRasterOperations#getPxWidth()
1343
         */
1344
        public double getPxWidth() {
1345
                return dataset.getWidth();
1346
        }
1347

    
1348
        /*
1349
         * (non-Javadoc)
1350
         * @see org.gvsig.fmap.raster.IGeoDimension#getWCHeight()
1351
         */
1352
        public double getWCHeight() {
1353
                return getFullExtent().getHeight();
1354
        }
1355

    
1356
        /*
1357
         * (non-Javadoc)
1358
         * @see org.gvsig.fmap.raster.IGeoDimension#getWCWidth()
1359
         */
1360
        public double getWCWidth() {
1361
                return getFullExtent().getWidth();
1362
        }
1363

    
1364
        /*
1365
         * (non-Javadoc)
1366
         * @see org.gvsig.fmap.raster.IRasterFile#getFileSize()
1367
         */
1368
        public long[] getFileSize(){
1369
                int nFiles = dataset.getDatasetCount();
1370
                long[] s = new long[nFiles];
1371
                for (int i = 0; i < nFiles; i++)
1372
                        s[i] = dataset.getDataset(i)[0].getFileSize();
1373
                return s;
1374
        }
1375

    
1376
        /*
1377
         * (non-Javadoc)
1378
         * @see org.gvsig.fmap.raster.IRasterFile#getFileName()
1379
         */
1380
        public String[] getFileName(){
1381
                int nFiles = 0;
1382
                if (dataset != null)
1383
                        nFiles = dataset.getDatasetCount();
1384
                String[] s = new String[nFiles];
1385
                for (int i = 0; i < nFiles; i++)
1386
                        s[i] = dataset.getDataset(i)[0].getFName();
1387
                return s;
1388
        }
1389

    
1390
        /*
1391
         * (non-Javadoc)
1392
         * @see org.gvsig.fmap.raster.IRasterFile#getFileCount()
1393
         */
1394
        public int getFileCount() {
1395
                return (dataset != null) ? dataset.getDatasetCount() : 0;
1396
        }
1397

    
1398
        /*
1399
         * (non-Javadoc)
1400
         * @see org.gvsig.fmap.raster.IRasterFile#getFileFormat()
1401
         */
1402
        public String getFileFormat() {
1403
                String fName = dataset.getDataset(0)[0].getFName();
1404
                int index = fName.lastIndexOf(".") + 1;
1405
                String ext = null;
1406
                if (index > 0)
1407
                        ext = fName.substring(fName.lastIndexOf(".") + 1, fName.length());
1408
                return ext;
1409
        }
1410

    
1411
        /*
1412
         * (non-Javadoc)
1413
         * @see org.gvsig.fmap.raster.IRasterOperations#getBandCount()
1414
         */
1415
        public int getBandCount() {
1416
                return (dataset != null) ? dataset.getBandCount() : 0;
1417
        }
1418

    
1419
        /*
1420
         * (non-Javadoc)
1421
         * @see org.gvsig.fmap.raster.IRasterOperations#getDatatype()
1422
         */
1423
        public int[] getDataType() {
1424
                return dataset.getDataType();
1425
        }
1426

    
1427
        /*
1428
         * (non-Javadoc)
1429
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderTransparency()
1430
         */
1431
        public GridTransparency getRenderTransparency() {
1432
                return getRender().getLastTransparency();
1433
        }
1434

    
1435
        /*
1436
         * (non-Javadoc)
1437
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderFilterList()
1438
         */
1439
        public RasterFilterList getRenderFilterList() {
1440
                return getRender().getFilterList();
1441
        }
1442

    
1443
        /*
1444
         * (non-Javadoc)
1445
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getRenderBands()
1446
         */
1447
        public int[] getRenderBands() {
1448
                return getRender().getRenderBands();
1449
        }
1450

    
1451
        /*
1452
         * (non-Javadoc)
1453
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderBands(int[])
1454
         */
1455
        public void setRenderBands(int[] renderBands) {
1456
                getRender().setRenderBands(renderBands);
1457
        }
1458

    
1459
        /*
1460
         * (non-Javadoc)
1461
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderFilterList(org.gvsig.raster.grid.filter.RasterFilterList)
1462
         */
1463
        public void setRenderFilterList(RasterFilterList filterList) {
1464
                getRender().setFilterList(filterList);
1465
        }
1466

    
1467
        /*
1468
         * (non-Javadoc)
1469
         * @see org.gvsig.raster.hierarchy.IRasterDataset#getDataSource()
1470
         */
1471
        public IRasterDataSource getDataSource() {
1472
                return dataset;
1473
        }
1474

    
1475
        /*
1476
         * (non-Javadoc)
1477
         * @see org.gvsig.fmap.raster.IRasterDataset#addFile(java.lang.String)
1478
         */
1479
        public void addFile(String fileName) throws NotSupportedExtensionException, RasterDriverException {
1480
                if (getRender() != null)
1481
                        bufferFactory.addFile(RasterDataset.open(getProjection(), fileName));
1482
        }
1483

    
1484
        /*
1485
         * (non-Javadoc)
1486
         * @see org.gvsig.fmap.raster.IRasterDataset#delFile(java.lang.String)
1487
         */
1488
        public void delFile(String fileName) {
1489
                if (getRender() != null)
1490
                        bufferFactory.removeFile(fileName);
1491
        }
1492

    
1493
        /*
1494
         * (non-Javadoc)
1495
         * @see org.gvsig.fmap.raster.IRasterDataset#getInfo(java.lang.String)
1496
         */
1497
        public Object getInfo(String key) {
1498
                if (key.equals("DriverName"))
1499
                        return "gvSIG Raster Driver";
1500
                return null;
1501
        }
1502

    
1503
        /*
1504
         * (non-Javadoc)
1505
         * @see org.gvsig.raster.shared.IRasterOperations#getMetadata()
1506
         */
1507
        public DatasetMetadata[] getMetadata() {
1508
                int count = dataset.getDatasetCount();
1509
                DatasetMetadata[] metadata = new DatasetMetadata[count];
1510
                for (int i = 0; i < count; i++) {
1511
                        metadata[i] = dataset.getDataset(i)[0].getMetadata();
1512
                }
1513
                return metadata;
1514
        }
1515

    
1516
        /*
1517
         * (non-Javadoc)
1518
         * @see org.gvsig.raster.shared.IRasterOperations#getBandCountFromDataset()
1519
         */
1520
        public int[] getBandCountFromDataset() {
1521
                int count = dataset.getDatasetCount();
1522
                int[] bands = new int[count];
1523
                for (int i = 0; i < count; i++)
1524
                        bands[i] = dataset.getDataset(i)[0].getBandCount();
1525
                return bands;
1526
        }
1527

    
1528
        /*
1529
         * (non-Javadoc)
1530
         * @see org.gvsig.raster.shared.IRasterOperations#getColourInterpretation(int, int)
1531
         */
1532
        public String getColorInterpretation(int band, int dataset) {
1533
                if (this.dataset.getDataset(dataset)[0].getColorInterpretation().get(band) == null)
1534
                        return "Undefined";
1535
                return this.dataset.getDataset(dataset)[0].getColorInterpretation().get(band);
1536
        }
1537

    
1538
        /*
1539
         * (non-Javadoc)
1540
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getStringProjection()
1541
         */
1542
        public String getWktProjection() throws RasterDriverException {
1543
                return dataset.getWktProjection();
1544
        }
1545

    
1546
        /**
1547
         * Metodo para consultar si una capa puede ser un RGB. Suponemos que es un RGB
1548
         * si el tipo de datos es de tipo byte y su interpretacion de color tiene
1549
         * asignada los tres colores.
1550
         * @return boolean
1551
         */
1552
        public boolean isRGB() {
1553
                if ((dataset == null) || (render == null))
1554
                        return false;
1555

    
1556
// Quitado pq no necesariamente tiene pq tener 3 bandas para ser RGB
1557
//                if (dataset.getBandCount() < 3)
1558
//                        return false;
1559

    
1560
                if (dataset.getDataType()[0] != IBuffer.TYPE_BYTE)
1561
                        return false;
1562

    
1563
                boolean R = false;
1564
                boolean G = false;
1565
                boolean B = false;
1566

    
1567
                int[] renderBands = render.getRenderBands();
1568
                for (int i = 0; i < renderBands.length; i++) {
1569
                        if (renderBands[i] >= 0) {
1570
                                switch (i) {
1571
                                        case 0:
1572
                                                R = true;
1573
                                                break;
1574
                                        case 1:
1575
                                                G = true;
1576
                                                break;
1577
                                        case 2:
1578
                                                B = true;
1579
                                                break;
1580
                                }
1581
                        }
1582
                }
1583

    
1584
                if (R && G && B)
1585
                        return true;
1586

    
1587
                return false;
1588
        }
1589
        
1590
        /**
1591
         * Obtiene el grid de la capa completa. Hay que tener cuidado porque cuando se hace esta
1592
         * petici?n se carga un buffer con todos los datos de la capa. Este buffer puede ser
1593
         * cacheado o no dependiendo del tama?o de esta.
1594
         * @param interpolated true si se solicita un grid interpolado y false si se solicita sin interpolar.
1595
         * @return Grid.
1596
         * @throws InterruptedException
1597
         */
1598
        public Grid getFullGrid(boolean interpolated) throws GridException, InterruptedException {
1599
                BufferFactory bf = getBufferFactory();
1600
                bf.clearDrawableBand();
1601
                bf.setAllDrawableBands();
1602
                try {
1603
                        bf.setAreaOfInterest();
1604
                } catch (RasterDriverException e) {
1605
                        throw new GridException("Error reading buffer");
1606
                }
1607
                return new Grid(bf, interpolated);
1608
        }
1609
        
1610
        /**
1611
         * Obtiene el grid de la capa completa. Esta llamada devuelve un buffer de solo lectura
1612
         * @param interpolated true si se solicita un grid interpolado y false si se solicita sin interpolar.
1613
         * @return Grid.
1614
         * @throws InterruptedException
1615
         */
1616
        public Grid getReadOnlyFullGrid(boolean interpolated) throws GridException, InterruptedException {
1617
                BufferFactory bf = new BufferFactory(dataset.newDataset());
1618
                bf.setReadOnly(true);
1619
                bf.clearDrawableBand();
1620
                bf.setAllDrawableBands();
1621
                try {
1622
                        bf.setAreaOfInterest();
1623
                } catch (RasterDriverException e) {
1624
                        throw new GridException("Error reading buffer");
1625
                }
1626
                return new Grid(bf, interpolated);
1627
        }
1628
        
1629
        /**
1630
         * Obtiene el tama?o de celda de la fuente de datos
1631
         * @return double con el tama?o de celda
1632
         */
1633
        public double getCellSize() {
1634
                return (getDataSource() != null) ? getDataSource().getCellSize() : 1;
1635
        }
1636
        
1637
        /*
1638
         * (non-Javadoc)
1639
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getFullRasterExtent()
1640
         */
1641
        public Extent getFullRasterExtent() {
1642
                if (dataset == null){
1643
                        try {
1644
                                load();
1645
                        } catch (LoadLayerException e) {
1646
                                return null;
1647
                        }
1648
                }
1649
                return this.getDataSource().getExtent();
1650
        }
1651

    
1652

    
1653
        /**
1654
         * Devuelve el fichero asociado a la capa o null si no tiene.
1655
         * @return Fichero.
1656
         */
1657
        public File getFile() {
1658
                return (params instanceof File) ? ((File)params) : null;
1659
        }
1660

    
1661
        /**
1662
         * Consulta si un fichero es aceptado o no para este tipo de capa.
1663
         * @param file Fichero a consultar
1664
         * @return true si es aceptado y false si no lo es.
1665
         */
1666
        public static boolean isFileAccepted(File file) {
1667
                return RasterDataset.fileIsSupported(file.getName());
1668
        }
1669

    
1670
        /*
1671
         * (non-Javadoc)
1672
         * @see org.gvsig.raster.shared.IRasterRendering#existColorTable()
1673
         */
1674
        public boolean existColorTable() {
1675
                return getRender().existColorTable();
1676
        }
1677
        
1678
        /*
1679
         * (non-Javadoc)
1680
         * @see org.gvsig.raster.hierarchy.IRasterRendering#existsAlphaBand()
1681
         */
1682
        public boolean existsAlphaBand() {
1683
                if(getDataSource().getColorInterpretation() != null)
1684
                        return getDataSource().getColorInterpretation().isAlphaBand();
1685
                else 
1686
                        return false;
1687
        }
1688
        
1689
        /*
1690
         * (non-Javadoc)
1691
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getAlphaBandNumber()
1692
         */
1693
        public int getAlphaBandNumber() {
1694
                if(getDataSource().getColorInterpretation() != null)
1695
                        return getDataSource().getColorInterpretation().getBand(DatasetColorInterpretation.ALPHA_BAND);
1696
                return -1;
1697
        }
1698

    
1699
        /**
1700
         * Define la ultima leyenda valida de la capa o se pone a null para que la
1701
         * capa busque una leyenda valida.
1702
         * @param ct
1703
         */
1704
        public void setLastLegend(ColorTable ct) {
1705
                lastLegend = ColorTableLegend.createLegend(ct);
1706
        }
1707

    
1708
        /**
1709
         * Devuelve la Leyenda de la capa.
1710
         * @return Leyenda.
1711
         */
1712
        public ILegend getLegend() {
1713
                if (lastLegend != null)
1714
                        return lastLegend;
1715

    
1716
                return null;
1717
        }
1718

    
1719
        /*
1720
         * (non-Javadoc)
1721
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable#addLegendListener(com.iver.cit.gvsig.fmap.layers.LegendListener)
1722
         */
1723
        public void addLegendListener(LegendListener listener) {
1724
                layerChangeSupport.addLayerListener(listener);
1725
        }
1726

    
1727
        /*
1728
         *  (non-Javadoc)
1729
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable#getShapeType()
1730
         */
1731
        public int getShapeType() throws ReadDriverException {
1732
                return FShape.POLYGON;
1733
        }
1734

    
1735
        /*
1736
         * (non-Javadoc)
1737
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable#removeLegendListener(com.iver.cit.gvsig.fmap.layers.LegendListener)
1738
         */
1739
        public void removeLegendListener(LegendListener listener) {
1740
                layerChangeSupport.removeLayerListener(listener);
1741
        }
1742

    
1743
        /**
1744
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa
1745
         * o fuera de ellos.
1746
         * @param p Punto a calcular
1747
         * @return true si est? dentro de los l?mites y false si est? fuera
1748
         */
1749
        public boolean isInside(Point2D p) {
1750
                 return getDataSource().isInside(p);
1751
        }
1752

    
1753
        /**
1754
         * Recupera del raster la matriz de transformaci?n que lo situa en cualquier parte de la vista
1755
         * @return AffineTransform
1756
         */
1757
        public AffineTransform getAffineTransform(int band) {
1758
                return getDataSource().getAffineTransform(band);
1759
        }
1760
        
1761
        /**
1762
         * Recupera del raster la matriz de transformaci?n que lo situa en cualquier parte de la vista
1763
         * @return AffineTransform
1764
         */
1765
        public AffineTransform getAffineTransform() {
1766
                if(getDataSource() != null)
1767
                        return getDataSource().getAffineTransform(0);
1768
                return null;
1769
        }
1770

    
1771
        /**
1772
         * Asigna al raster la matriz de transformaci?n para situarlo en cualquier parte de la vista
1773
         * @param transf
1774
         */
1775
        public void setAffineTransform(AffineTransform transf) {
1776
                if(transf == null)
1777
                        return;
1778
                affineTransformList.add(transf);
1779
                getDataSource().setAffineTransform(transf);
1780
                updateDrawVersion();
1781
        }
1782

    
1783
        /**
1784
         * Asigna al raster la matriz de transformaci?n para situarlo en cualquier parte de la vista.
1785
         * Esta versi?n no guarda en el historico.
1786
         * @param transf
1787
         */
1788
        public void setAT(AffineTransform transf) {
1789
                getDataSource().setAffineTransform(transf);
1790
                updateDrawVersion();
1791
        }
1792

    
1793
        /**
1794
         * Obtiene la lista de transformaciones que se han ido aplicando al raster.
1795
         * @return Historical. Lista de AffineTransform
1796
         */
1797
        public Historical getAffineTransformHistorical() {
1798
                return this.affineTransformList;
1799
        }
1800
        
1801
        /**
1802
         * Salva la georreferenciaci?n a fichero rmf.
1803
         * @param fName
1804
         * @throws RmfSerializerException 
1805
         */
1806
        public void saveGeoToRmf() throws RmfSerializerException {
1807
                if (!isOpen())
1808
                        return;
1809

    
1810
                // Guardamos la GeoReferenciacion de cada dataset
1811
                for (int i = 0; i < getDataSource().getDatasetCount(); i++)
1812
                        getDataSource().saveObjectToRmf(i, RasterDataset.class, getDataSource().getDataset(i)[0]);
1813
                
1814
                affineTransformList.clear();
1815
                affineTransformList.add(this.getAffineTransform());
1816
        }
1817

    
1818
        /*
1819
         * (non-Javadoc)
1820
         * @see org.gvsig.fmap.raster.layers.IRasterLayerActions#isActionEnabled(int)
1821
         */
1822
        public boolean isActionEnabled(int action) {
1823
                switch (action) {
1824
                        case IRasterLayerActions.BANDS_FILE_LIST:
1825
                                if (existColorTable())
1826
                                        return false;
1827
                                break;
1828
                        case IRasterLayerActions.BANDS_RGB:
1829
                                if (existColorTable())
1830
                                        return false;
1831
                                break;
1832
                        case IRasterLayerActions.REPROJECT:
1833
                                if (!isReproyectable())
1834
                                        return false;
1835
                                break;
1836
                        case IRasterLayerActions.CREATEOVERVIEWS:
1837
                                return overviewsSupport();
1838
                        case IRasterLayerActions.OPACITY:
1839
                        case IRasterLayerActions.TRANSPARENCY:
1840
                        case IRasterLayerActions.BRIGHTNESSCONTRAST:
1841
                        case IRasterLayerActions.ENHANCED:
1842
                        case IRasterLayerActions.PANSHARPENING:
1843
                        case IRasterLayerActions.SELECT_LAYER:
1844
                        case IRasterLayerActions.SAVE_COLORINTERP:
1845
                                return true;
1846
                        case IRasterLayerActions.REMOTE_ACTIONS:
1847
                                return false;
1848
                }
1849
                return true;
1850
        }
1851

    
1852
        /*
1853
         * (non-Javadoc)
1854
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setVisible(boolean)
1855
         */
1856
        public void setVisible(boolean visibility) {
1857
                if(visibility)
1858
                        state.disableStopped();
1859
                else
1860
                        enableStopped();
1861

    
1862
                if(isAwake() || isClosed()) {
1863
                        try {
1864
                                this.load();
1865
                        } catch (LoadLayerException e) {
1866
                                e.printStackTrace();
1867
                        }
1868
                }
1869

    
1870
                /*
1871
                 * Cuando se modifica la visibilidad de una capa raster se hace un updateDrawVersion de todas las
1872
                 * capas raster de ese MapContext. Esto es porque la estrategia utilizada por RasterDrawStrategy hace
1873
                 * que se cacheen en blanco las capas raster que est?n ocultas debajo de otras. Al hacer invisibles las
1874
                 * de arriba la cache que estaba en blanco hace que no se pinte nada. Para evitar esto las marcamos todas
1875
                 * como que han sido modificadas para que se vuelvan a leer.
1876
                 */
1877
                if(getMapContext() != null) {
1878
                        ArrayList listLayers = new ArrayList();
1879
                        listLayers = RasterDrawStrategy.getLayerList(getMapContext().getLayers(), listLayers);
1880
                        for (int i = 0; i < listLayers.size(); i++) {
1881
                                if(listLayers.get(i) instanceof FLyrRasterSE)
1882
                                        ((FLyrRasterSE)listLayers.get(i)).updateDrawVersion();
1883
                        }
1884
                }
1885

    
1886
                super.setVisible(visibility);
1887
        }
1888

    
1889
        /**
1890
         * Consulta la transparencia asignada en la ?ltima renderizaci?n de la capa
1891
         * @return valor de transparencia
1892
         */
1893
        public int getTransparency() {
1894
                try {
1895
                        return getRenderTransparency().getOpacity();
1896
                } catch (NullPointerException e) {
1897
                        return super.getTransparency();
1898
                }
1899
        }
1900

    
1901
        /**
1902
         * Consulta si tiene aplicada alguna transparencia en la ?ltima renderizaci?n
1903
         * o no.
1904
         * @return true si se aplic? alguna transparencia en la ?ltima renderizaci?n.
1905
         */
1906
        public boolean isTransparent() {
1907
                return getRenderTransparency().isTransparencyActive();
1908
        }
1909

    
1910
        /**
1911
         * Asigna la transparencia de la siguiente renderizaci?n
1912
         * @param valor de transparencia
1913
         */
1914
        public void setTransparency(int trans) {
1915
                super.setTransparency(trans);
1916
                try {
1917
                        getRenderTransparency().setOpacity(trans);
1918
                        getRenderTransparency().activeTransparency();
1919
                } catch (NullPointerException e) {
1920
                        //Solo asigna la transparencia a la clase padre y no a la renderizaci?n
1921
                }
1922
        }
1923

    
1924
        /*
1925
         * (non-Javadoc)
1926
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getLastRenderBuffer()
1927
         */
1928
        public IBuffer getLastRenderBuffer() {
1929
                return getRender().getLastRenderBuffer();
1930
        }
1931

    
1932
        /**
1933
         *
1934
         * @return ROIs asociadas a la capa raster.
1935
         */
1936
        public ArrayList getRois() {
1937
                return rois;
1938
        }
1939

    
1940
        /**
1941
         * Establece las ROI asociadas a la capa raster.
1942
         *
1943
         * @param rois ArrayList de ROIs a asociar a la capa raster.
1944
         */
1945
        public void setRois(ArrayList rois) {
1946
                this.rois = rois;
1947
        }
1948

    
1949
        /**
1950
         * Si ya tiene una estrategia de dibujado de raster calculada la devuelve, sino
1951
         * devolver? null.
1952
         * @return TreeMap con la lista de capas a dibujar
1953
         */
1954
        public HashMap getRasterStrategy() {
1955
                if(strategy != null)
1956
                        return strategy.getStrategy();
1957
                return null;
1958
        }
1959
        
1960
        /**
1961
         * Devuelve el tipo de valor de NoData asociado a la capa.
1962
         * Sirve para diferenciar los estados seleccionados por el usuario. Siendo
1963
         * estos '0: Sin Valor NoData', '1: NoData de Capa'(Por defecto) y '2: Personalizado'
1964
         */
1965
        /**
1966
         * @return the noDataType
1967
         */
1968
        public int getNoDataType() {
1969
                return noDataType;
1970
        }
1971

    
1972
        /**
1973
         * @param noDataType the noDataType to set
1974
         */
1975
        public void setNoDataType(int noDataType) {
1976
                this.noDataType = noDataType;
1977
                if (dataset != null)
1978
                        dataset.setNoDataEnabled(noDataType != RasterLibrary.NODATATYPE_DISABLED);
1979
        }
1980

    
1981
        /**
1982
         * @return the configuration
1983
         */
1984
        static public IConfiguration getConfiguration() {
1985
                return configuration;
1986
        }
1987

    
1988
        /**
1989
         * @param configuration the configuration to set
1990
         */
1991
        static public void setConfiguration(IConfiguration configuration) {
1992
                FLyrRasterSE.configuration = configuration;
1993
        }
1994
        
1995
        /*
1996
         * (non-Javadoc)
1997
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#reload()
1998
         */
1999
        public void reload() throws ReloadLayerException {
2000
                try {
2001
                        super.reload();
2002
                        if (getMapContext() == null)
2003
                                return;
2004
                        if (isStopped())
2005
                                disableStopped();
2006
                        load();
2007
                        getMapContext().invalidate();
2008
                } catch (LoadLayerException e) {
2009
                        setAvailable(false);
2010
                        throw new ReloadLayerException(getName(), e);
2011
                }
2012
        }
2013
        
2014
        /**
2015
         * Devuelve si la capa tiene soporte para poder generar overviews
2016
         * @return
2017
         */
2018
        public boolean overviewsSupport() {
2019
                if ((getDataSource() != null) && (getDataSource().overviewsSupport()))
2020
                        return true;
2021

    
2022
                return false;
2023
        }
2024

    
2025
        /**
2026
         * Devuelve si la asignacion de las bandas a renderizar representa una capa
2027
         * en escala de grises
2028
         * @return
2029
         */
2030
        public boolean isRenderingAsGray() {
2031
                int[] renderBands = getRenderBands();
2032
                if ((renderBands != null) && (renderBands.length == 3) && (renderBands[0] >= 0) &&
2033
                                (renderBands[0] == renderBands[1]) && (renderBands[1] == renderBands[2]))
2034
                        return true;
2035
                return false;
2036
        }
2037
        
2038
        /*
2039
         * (non-Javadoc)
2040
         * @see org.gvsig.raster.grid.render.VisualPropertyListener#actionValueChanged(org.gvsig.raster.grid.render.VisualPropertyEvent)
2041
         */
2042
        public void visualPropertyValueChanged(VisualPropertyEvent e) {
2043
                updateDrawVersion();
2044
        }
2045
        
2046
        /*****************************************************/
2047
        //Utils
2048

    
2049
        /**
2050
         * Ajusta las coordenadas especificadas en el par?metro al ?rea m?xima
2051
         * del raster en p?xeles.
2052
         * @param req Punto a ajustar dentro del extener del raster
2053
         */
2054
        public Point2D adjustWorldRequest(Point2D req) {
2055
                Rectangle2D ext = null;
2056

    
2057
                ext = getFullExtent();
2058
                req.setLocation(Math.max(ext.getMinX(), req.getX()), Math.max(ext.getMinY(), req.getY()));
2059
                req.setLocation(Math.min(ext.getMaxX(), req.getX()), Math.min(ext.getMaxY(), req.getY()));
2060
                return req;
2061
        }
2062
        
2063
        /*
2064
         * (non-Javadoc)
2065
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#cloneLayer()
2066
         */
2067
        public FLayer cloneLayer() throws Exception {
2068
                FLyrRasterSE newLayer = FLyrRasterSE.createLayer(this.getName(), params, this.getProjection());
2069
                for (int i = 0; i < dataset.getDatasetCount(); i++) {
2070
                        String name = dataset.getDataset(i)[0].getFName();
2071
                        if (!(dataset instanceof CompositeDataset) && !name.equals(this.getName()) && !isActionEnabled(IRasterLayerActions.REMOTE_ACTIONS))
2072
                                newLayer.addFile(name);
2073
                }
2074
                ArrayList filters = getRender().getFilterList().getStatusCloned();
2075
        
2076
                //Hacemos una copia de las bandas a renderizar
2077
                if(getRenderBands() != null) {
2078
                        int[] rb = new int[getRenderBands().length];
2079
                        for (int i = 0; i < rb.length; i++) 
2080
                                rb[i] = getRenderBands()[i];
2081
                        newLayer.setRenderBands(rb);
2082
                }
2083
                
2084
                //Asignamos el entorno
2085
                if(newLayer.getRender().getFilterList() == null)
2086
                        newLayer.getRender().setFilterList(new RasterFilterList());
2087
                newLayer.getRender().getFilterList().setEnv(getRender().getFilterList().getEnv());        
2088
                newLayer.getRender().getFilterList().setStatus(filters);
2089

    
2090
                // Asignamos los valores noData del original
2091
                newLayer.setNoDataValue(getNoDataValue());
2092
                newLayer.setNoDataType(getNoDataType());
2093
                newLayer.applyNoData();
2094

    
2095
                return newLayer;
2096
        }
2097
        
2098
        /**
2099
         * Gets a layer which the source is a file
2100
         * @return
2101
         */
2102
        public FLayer getFileLayer() {
2103
                try {
2104
                        return cloneLayer();
2105
                } catch (Exception e) {
2106
                }
2107
                return null;
2108
        }
2109
        
2110
        /*****************************************************/
2111

    
2112
        public void disableStopped() {state.disableStopped();}
2113

    
2114
        public void enableAwake() throws NotAvailableStateException {state.enableAwake();}
2115

    
2116
        public void enableClosed() throws NotAvailableStateException {state.enableClosed();}
2117

    
2118
        public void enableOpen() throws NotAvailableStateException {state.enableOpen();}
2119

    
2120
        public void enableStopped() {state.enableStopped();}
2121

    
2122
        public boolean isAwake() {return state.isAwake();}
2123

    
2124
        public boolean isClosed() {return state.isClosed();}
2125

    
2126
        public boolean isOpen() {return state.isOpen();}
2127

    
2128
        public boolean isStopped() {return state.isStopped();}
2129

    
2130
        /**
2131
         * Returns true if exists a process reading data from this layer
2132
         * @return
2133
         */
2134
        public boolean isReadingData() {
2135
                return readingData != null;
2136
        }
2137

    
2138
        /**
2139
         * When a process is using information of this layer this variable will contain
2140
         * the thread ID.
2141
         * @param readingData
2142
         */
2143
        public synchronized void setReadingData(String readingData) {
2144
                this.readingData = readingData;
2145
        }
2146

    
2147
}