Statistics
| Revision:

root / trunk / extensions / extRasterTools-SE / src / org / gvsig / fmap / raster / layers / FLyrRasterSE.java @ 33213

History | View | Annotate | Download (65.4 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

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

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

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

    
170
        static {
171
                 RasterLibrary.wakeUp();
172
                 //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.
173
                 FLyrRasterSE.addSolveErrorForLayer(NotSupportedExtensionException.class, new FileNotFoundSolve());
174
        }
175

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

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

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

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

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

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

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

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

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

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

    
298
                enableStopped(); // Paramos la capa mientras se hace un load
299

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

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

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

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

    
360
                //Inicializaci?n del historico de transformaciones
361
                affineTransformList.clear();
362
                affineTransformList.add(this.getAffineTransform());
363

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

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

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

    
432
                filterList.setInitDataType(getDataType()[0]);
433
                RasterFilterListManager filterManager = new RasterFilterListManager(filterList);
434

    
435
                // Quitamos la leyenda
436
                lastLegend = null;
437

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

    
457
                                }
458
                        }
459
                        loadedFromProject = null;
460

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

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

    
479
                String palettesPath = FileUtils.getAppHomeDir() + "colortable";
480

    
481
                IStatistics stats = getDataSource().getStatistics();
482

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

    
495
                                                        ColorTable colorTable = new ColorTable();
496
                                                        colorTable.setName(paletteName);
497
                                                        colorTable.createPaletteFromColorItems(paletteItems, true);
498
                                                        colorTable.setInterpolated(true);
499

    
500
                                                        colorTable.createColorTableInRange(stats.getMinimun(), stats.getMaximun(), true);
501

    
502
                                                        GridPalette p = new GridPalette(colorTable);
503
                                                        setLastLegend(p);
504

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

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

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

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

    
563
                try {
564
                        if (!isOpen())
565
                                return;
566

    
567
                        enableStopped();
568
                        // callLegendChanged(null);
569

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
803
                data += "</file:" + normalizeAsXMLTag(getName()) + ">\n";
804
                return data;
805
        }
806

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

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

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

    
855
                StringXMLItem[] item = new StringXMLItem[1];
856
                String data = "<file:" + normalizeAsXMLTag(getName()) + ">\n";
857

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

    
913
                item[0] = new StringXMLItem(data, this);
914
                return item;
915
        }
916

    
917
        /**
918
         * Filters a string for being suitable as XML Tag, erasing
919
         * all not alphabetic or numeric characters.
920
         * @param s
921
         * @return string normalized
922
         */
923
        private String normalizeAsXMLTag(String s) {
924
                return s.replaceAll("[^a-zA-Z0-9]", "");
925
        }
926

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

    
947
        /**
948
         * Escribe en el proyecto la capa actual
949
         * @throws XMLException
950
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
951
         */
952
        public XMLEntity getXMLEntity() throws XMLException {
953
                if(isClosed() || isAwake())
954
                        return null;
955

    
956
                return getXMLEntityWithoutChecks();
957
        }
958
        
959
        /**
960
         * This method has been added because a WMS server could be not running
961
         * where the project is loaded, but it doesn't mean that the layer
962
         * can not be loaded.
963
         * @return
964
         * @throws XMLException
965
         */
966
        public XMLEntity getXMLEntityWithoutChecks() throws XMLException {
967
                XMLEntity xml = super.getXMLEntity();
968
                if(getFile() != null)
969
                        xml.putProperty("file", getFile());
970
                xml.putProperty("driverName", "gvSIG Raster Driver");
971

    
972
                // Si no hay ning?n Status aplicamos el StatusLayerRaster que se usa por defecto
973
                if (status == null)
974
                        status = new StatusLayerRaster();
975
                status.getXMLEntity(xml, true, this);
976

    
977
                return xml;
978
        }
979

    
980
        public void setXMLEntity03(XMLEntity xml) throws XMLException {
981
        }
982

    
983
        /**
984
         * Recupera de disco los datos de la capa.
985
         */
986
        public void setXMLEntity(XMLEntity xml) throws XMLException {
987
                for (int i = 0; i < xml.getPropertyCount(); i++) {
988
                        String key = xml.getPropertyName(i);
989
                        if(key.startsWith("raster.file")) {
990
                                if(xml.getPropertyValue(i).startsWith(RasterLibrary.getTemporalPath()))
991
                                        throw new XMLException(new Throwable());
992
                        }
993
                }
994

    
995
                super.setXMLEntity(xml);
996
                loadingFromProject = true;
997
                
998
                try {
999
                        params = new File(xml.getStringProperty("file"));
1000

    
1001
                        if(params != null && getName() != null && getName().compareTo("") != 0) {
1002
                                try {
1003
                                        enableAwake();
1004
                                } catch (NotAvailableStateException e) {
1005
                                        RasterToolsUtil.messageBoxError("Fallo el estado de open. Closed=" + isClosed() + " Active=" + isOpen(), this, e);
1006
                                }
1007
                        }
1008
                        if(!super.getFLayerStatus().visible)
1009
                                enableStopped();
1010

    
1011
                        // Para notificar al adapter-driver cual es la proyecci?n.
1012
                        setProjection(super.getProjection());
1013

    
1014
                        //Inicializamos la clase a la que se usa por defecto para
1015
                        //compatibilidad con proyectos antiguos
1016
                        String claseStr = StatusLayerRaster.defaultClass;
1017
                        if (xml.contains("raster.class"))
1018
                                claseStr = xml.getStringProperty("raster.class");
1019

    
1020
                        if (status != null)
1021
                                status.setXMLEntity(xml, this);
1022
                        else {
1023
                                // Cuando cargamos un proyecto
1024

    
1025
                                if (claseStr != null && !claseStr.equals("")) {
1026
                                        try {
1027
                                                Class clase = LayerFactory.getLayerClassForLayerClassName(claseStr);
1028
                                                Constructor constr = clase.getConstructor(null);
1029
                                                status = (IStatusRaster) constr.newInstance(null);
1030
                                                if (status != null) {
1031
                                                        ((StatusLayerRaster)status).setNameClass(claseStr);
1032
                                                        status.setXMLEntity(xml, this);
1033
                                                        filterArguments = status.getFilterArguments();
1034
                                                        
1035
                                                        //Creamos la tabla de color
1036
                                                        ArrayList color = (ArrayList) filterArguments.clone();
1037
                                                        loadedFromProject = ColorTableListManager.createColorTableFromArray(color);
1038
                                                }
1039
                                        } catch (ClassNotFoundException exc) {
1040
                                                throw new XMLException(exc);
1041
                                        } catch (InstantiationException exc) {
1042
                                                throw new XMLException(exc);
1043
                                        } catch (IllegalAccessException exc) {
1044
                                                throw new XMLException(exc);
1045
                                        } catch (NoSuchMethodException exc) {
1046
                                                throw new XMLException(exc);
1047
                                        } catch (InvocationTargetException exc) {
1048
                                                throw new XMLException(exc);
1049
                                        }
1050
                                }
1051
                        }
1052
                        firstLoad = true;
1053
                } catch (NotExistInXMLEntity e) {
1054

    
1055
                }
1056
        }
1057

    
1058
        /* (non-Javadoc)
1059
         * @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)
1060
         */
1061
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet propeties) throws ReadDriverException {
1062

    
1063
                if (!isOpen() || !isVisible() || !isWithinScale(scale))
1064
                        return;
1065

    
1066
                if (!mustTilePrint) {
1067
                        draw(null, g, viewPort, cancel,scale);
1068
                } else {
1069
                        // Para no pedir imagenes demasiado grandes, vamos
1070
                        // a hacer lo mismo que hace EcwFile: chunkear.
1071
                        // Llamamos a drawView con cuadraditos m?s peque?os
1072
                        // del BufferedImage ni caso, cuando se imprime viene con null
1073
                        Tiling tiles = new Tiling(maxTilePrintWidth, maxTilePrintHeight, g.getClipBounds());
1074
                        tiles.setAffineTransform((AffineTransform) viewPort.getAffineTransform().clone());
1075

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

    
1079
                        //RasterStats stats = getSource().getFilterStack().getStats();
1080
                        //if(stats != null)
1081
                        //stats.history.add(stats.new History(getName(), stats.minBandValue, stats.maxBandValue, stats.secondMinBandValue, stats.secondMaxBandValue));
1082

    
1083

    
1084
                        for (int tileNr = 0; tileNr < tiles.getNumTiles(); tileNr++) {
1085
                                // Parte que dibuja
1086
                                try {
1087
                                        ViewPort vp = tiles.getTileViewPort(viewPort, tileNr);
1088
                                        draw(null, g, vp, cancel, scale);
1089
                                } catch (NoninvertibleTransformException e) {
1090
                                        throw new ReadDriverException("Error en la transformaci?n.", e);
1091
                                }
1092
                        }
1093
                        /*if(stats != null){
1094
                                getSource().getFilterStack().getStats().history.clear();
1095
                                stats = getSource().getFilterStack().getStats();
1096
                        }*/
1097
                }
1098
        }
1099

    
1100
        public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale) throws ReadDriverException {
1101
                if(!isOpen())
1102
                        return;
1103

    
1104
                // Para no pedir imagenes demasiado grandes, vamos
1105
                // a hacer lo mismo que hace EcwFile: chunkear.
1106
                // Llamamos a drawView con cuadraditos m?s peque?os
1107
                // del BufferedImage ni caso, cuando se imprime viene con null
1108

    
1109
                int numW, numH;
1110
                int stepX, stepY;
1111
                int xProv, yProv;
1112
                int A = 1500;
1113
                int H = 1500;
1114
                int altoAux, anchoAux;
1115

    
1116
                AffineTransform mat = (AffineTransform) viewPort.getAffineTransform().clone();
1117

    
1118
                // Vamos a hacerlo en trozos de AxH
1119
                Rectangle r = g.getClipBounds();
1120
                numW = (int) (r.width) / A;
1121
                numH = (int) (r.height) / H;
1122

    
1123
                double[] srcPts = new double[8];
1124
                double[] dstPts = new double[8];
1125

    
1126
                yProv = (int) r.y;
1127
                for (stepY = 0; stepY < numH + 1; stepY++) {
1128
                        if ((yProv + H) > r.getMaxY())
1129
                                altoAux = (int) r.getMaxY() - yProv;
1130
                        else
1131
                                altoAux = H;
1132

    
1133
                        xProv = (int) r.x;
1134
                        for (stepX = 0; stepX < numW + 1; stepX++) {
1135
                                if ((xProv + A) > r.getMaxX())
1136
                                        anchoAux = (int) r.getMaxX() - xProv;
1137
                                else
1138
                                        anchoAux = A;
1139

    
1140
                                //Rectangle newRect = new Rectangle(xProv, yProv, anchoAux, altoAux);
1141

    
1142
                                // Parte que dibuja
1143
                                srcPts[0] = xProv;
1144
                                srcPts[1] = yProv;
1145
                                srcPts[2] = xProv + anchoAux + 1;
1146
                                srcPts[3] = yProv;
1147
                                srcPts[4] = xProv + anchoAux + 1;
1148
                                srcPts[5] = yProv + altoAux + 1;
1149
                                srcPts[6] = xProv;
1150
                                srcPts[7] = yProv + altoAux + 1;
1151

    
1152
                                try {
1153
                                        mat.inverseTransform(srcPts, 0, dstPts, 0, 4);
1154
                                        Rectangle2D.Double rectCuadricula = new Rectangle2D.Double(dstPts[0], dstPts[1], dstPts[2] - dstPts[0], dstPts[5] - dstPts[3]);
1155
                                        // Extent extent = new Extent(rectCuadricula);
1156

    
1157
                                        Dimension tam = new Dimension(anchoAux + 1, altoAux + 1);
1158
                                        ViewPort vp = viewPort.cloneViewPort();
1159
                                        vp.setImageSize(tam);
1160
                                        vp.setExtent(rectCuadricula);
1161
                                        vp.setAffineTransform(mat);
1162
                                        draw(null, g, vp, cancel, scale);
1163

    
1164
                                } catch (NoninvertibleTransformException e) {
1165
                                        throw new ReadDriverException("Error en la transformaci?n.", e);
1166
                                }
1167
                                // Fin parte que dibuja
1168
                                xProv = xProv + A;
1169
                        }
1170
                        yProv = yProv + H;
1171
                }
1172
        }
1173

    
1174
        /**
1175
         * Borra de la lista de listeners el que se pasa como par?metro.
1176
         *
1177
         * @param o LayerListener a borrar.
1178
         *
1179
         * @return True si ha sido correcto el borrado del Listener.
1180
         */
1181
        public boolean removeLayerListener(LayerListener o) {
1182
                if (this.isRemoveRasterFlag()) {
1183
                        try {
1184
                                enableClosed();
1185
                        } catch (NotAvailableStateException e1) {
1186
                                // No se ha podido cambiar el estado de la capa a cerrado
1187
                        }
1188
                }
1189
                
1190
                // Salva a RMF
1191
                if (this.getDataSource() != null) {
1192
                        // Guardamos la GeoReferenciacion de cada dataset
1193
                        try {
1194
                                for (int i = 0; i < getDataSource().getDatasetCount(); i++) {
1195
                                        getDataSource().saveObjectToRmf(i, RasterDataset.class, getDataSource().getDataset(i)[0]);
1196
                                }
1197
                        } catch (RmfSerializerException e) {
1198
                                RasterToolsUtil.messageBoxError("error_salvando_rmf", this, e);
1199
                        }
1200
                }
1201

    
1202
                if (this.isRemoveRasterFlag()) {
1203
                        image = null;
1204
                        String[] files = (String[]) getFileName().clone();
1205
                        if (dataset != null)
1206
                                dataset.close();
1207
                        if (bufferFactory != null)
1208
                                bufferFactory.free();
1209
                        bufferFactory = null;
1210
                        dataset = null;
1211
                        render = null;
1212
                        
1213
                        // System.gc();
1214
                        this.setRemoveRasterFlag(true);
1215
                        
1216
                        for (int i = 0; i < files.length; i++) {
1217
                                File file = new File(files[i]);
1218
                                File dirTemp = RasterLibrary.getTemporalFile();
1219
                                if (dirTemp.compareTo(file.getParentFile()) == 0) {
1220
                                        file.delete();
1221
                                        
1222
                                        // Borramos todos los ficheros que puedan tener relacion con el fichero actual
1223
                                        String basefile = file.getName();
1224
                                        File basepath = file.getParentFile();
1225
                                        int last = basefile.lastIndexOf(".");
1226
                                        if (last != -1)
1227
                                                basefile = basefile.substring(0, last + 1);
1228
                                        File[] list = basepath.listFiles();
1229
                                        for (int j = 0; j < list.length; j++)
1230
                                                if (list[j].getName().startsWith(basefile))
1231
                                                        list[j].delete();
1232
                                }
1233
                        }
1234
                }
1235
                updateDrawVersion();
1236
                return super.layerListeners.remove(o);
1237
        }
1238

    
1239
        /**
1240
         * @return Returns the removeRasterFlag.
1241
         */
1242
        public boolean isRemoveRasterFlag() {
1243
                return removeRasterFlag;
1244
        }
1245

    
1246
        /**
1247
         * Asigna el valor del flag que dice si destruimos la memoria del raster
1248
         * al eliminarlo del TOC o  no.
1249
         * @param removeRasterFlag The removeRasterFlag to set.
1250
         */
1251
        public void setRemoveRasterFlag(boolean removeRasterFlag) {
1252
                this.removeRasterFlag = removeRasterFlag;
1253
        }
1254

    
1255
        /*
1256
         * (non-Javadoc)
1257
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getTocImageIcon()
1258
         */
1259
        public ImageIcon getTocImageIcon() {
1260
                return new ImageIcon(getClass().getResource("images/map_ico_ok.gif"));
1261
        }
1262

    
1263
        /*
1264
         *  (non-Javadoc)
1265
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#getTileSize()
1266
         */
1267
        public int[] getTileSize() {
1268
                int[] size = {maxTileDrawWidth, maxTileDrawHeight};
1269
                return size;
1270
        }
1271

    
1272
        /*
1273
         *  (non-Javadoc)
1274
         * @see com.iver.cit.gvsig.fmap.layers.RasterOperations#isTiled()
1275
         */
1276
        public boolean isTiled() {
1277
                return mustTileDraw;
1278
        }
1279

    
1280
        /**
1281
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1282
         * @return true si est? georreferenciada y false si no lo est?.
1283
         */
1284
        public boolean isGeoreferenced() {
1285
                return dataset.isGeoreferenced();
1286
        }
1287

    
1288
        /**
1289
         * Get datasource object
1290
         * @return
1291
         */
1292
        public BufferFactory getBufferFactory(){
1293
                return bufferFactory;
1294
        }
1295

    
1296
        /**
1297
         * Obtiene el valor NoData asociado al raster.
1298
         * @return double
1299
         */
1300
        public double getNoDataValue() {
1301
                if (dataset == null)
1302
                        return RasterLibrary.defaultNoDataValue;
1303
                return dataset.getNoDataValue();
1304
        }
1305

    
1306
        /**
1307
         * Asigna el valor no data asociado a la capa
1308
         * @param nd
1309
         */
1310
        public void setNoDataValue(double nd) {
1311
                if (bufferFactory != null)
1312
                        bufferFactory.setNoDataToFill(nd);
1313
                if (dataset != null)
1314
                        dataset.setNoDataValue(nd);
1315
        }
1316

    
1317
        /*
1318
         * (non-Javadoc)
1319
         * @see org.gvsig.fmap.raster.IRasterOperations#getPXHeight()
1320
         */
1321
        public double getPxHeight() {
1322
                return dataset.getHeight();
1323
        }
1324

    
1325
        /*
1326
         * (non-Javadoc)
1327
         * @see org.gvsig.fmap.raster.IRasterOperations#getPxWidth()
1328
         */
1329
        public double getPxWidth() {
1330
                return dataset.getWidth();
1331
        }
1332

    
1333
        /*
1334
         * (non-Javadoc)
1335
         * @see org.gvsig.fmap.raster.IGeoDimension#getWCHeight()
1336
         */
1337
        public double getWCHeight() {
1338
                return getFullExtent().getHeight();
1339
        }
1340

    
1341
        /*
1342
         * (non-Javadoc)
1343
         * @see org.gvsig.fmap.raster.IGeoDimension#getWCWidth()
1344
         */
1345
        public double getWCWidth() {
1346
                return getFullExtent().getWidth();
1347
        }
1348

    
1349
        /*
1350
         * (non-Javadoc)
1351
         * @see org.gvsig.fmap.raster.IRasterFile#getFileSize()
1352
         */
1353
        public long[] getFileSize(){
1354
                int nFiles = dataset.getDatasetCount();
1355
                long[] s = new long[nFiles];
1356
                for (int i = 0; i < nFiles; i++)
1357
                        s[i] = dataset.getDataset(i)[0].getFileSize();
1358
                return s;
1359
        }
1360

    
1361
        /*
1362
         * (non-Javadoc)
1363
         * @see org.gvsig.fmap.raster.IRasterFile#getFileName()
1364
         */
1365
        public String[] getFileName(){
1366
                int nFiles = 0;
1367
                if (dataset != null)
1368
                        nFiles = dataset.getDatasetCount();
1369
                String[] s = new String[nFiles];
1370
                for (int i = 0; i < nFiles; i++)
1371
                        s[i] = dataset.getDataset(i)[0].getFName();
1372
                return s;
1373
        }
1374

    
1375
        /*
1376
         * (non-Javadoc)
1377
         * @see org.gvsig.fmap.raster.IRasterFile#getFileCount()
1378
         */
1379
        public int getFileCount() {
1380
                return (dataset != null) ? dataset.getDatasetCount() : 0;
1381
        }
1382

    
1383
        /*
1384
         * (non-Javadoc)
1385
         * @see org.gvsig.fmap.raster.IRasterFile#getFileFormat()
1386
         */
1387
        public String getFileFormat() {
1388
                String fName = dataset.getDataset(0)[0].getFName();
1389
                int index = fName.lastIndexOf(".") + 1;
1390
                String ext = null;
1391
                if (index > 0)
1392
                        ext = fName.substring(fName.lastIndexOf(".") + 1, fName.length());
1393
                return ext;
1394
        }
1395

    
1396
        /*
1397
         * (non-Javadoc)
1398
         * @see org.gvsig.fmap.raster.IRasterOperations#getBandCount()
1399
         */
1400
        public int getBandCount() {
1401
                return (dataset != null) ? dataset.getBandCount() : 0;
1402
        }
1403

    
1404
        /*
1405
         * (non-Javadoc)
1406
         * @see org.gvsig.fmap.raster.IRasterOperations#getDatatype()
1407
         */
1408
        public int[] getDataType() {
1409
                return dataset.getDataType();
1410
        }
1411

    
1412
        /*
1413
         * (non-Javadoc)
1414
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderTransparency()
1415
         */
1416
        public GridTransparency getRenderTransparency() {
1417
                return getRender().getLastTransparency();
1418
        }
1419

    
1420
        /*
1421
         * (non-Javadoc)
1422
         * @see org.gvsig.fmap.raster.IRasterRendering#getRenderFilterList()
1423
         */
1424
        public RasterFilterList getRenderFilterList() {
1425
                return getRender().getFilterList();
1426
        }
1427

    
1428
        /*
1429
         * (non-Javadoc)
1430
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getRenderBands()
1431
         */
1432
        public int[] getRenderBands() {
1433
                return getRender().getRenderBands();
1434
        }
1435

    
1436
        /*
1437
         * (non-Javadoc)
1438
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderBands(int[])
1439
         */
1440
        public void setRenderBands(int[] renderBands) {
1441
                getRender().setRenderBands(renderBands);
1442
        }
1443

    
1444
        /*
1445
         * (non-Javadoc)
1446
         * @see org.gvsig.raster.hierarchy.IRasterRendering#setRenderFilterList(org.gvsig.raster.grid.filter.RasterFilterList)
1447
         */
1448
        public void setRenderFilterList(RasterFilterList filterList) {
1449
                getRender().setFilterList(filterList);
1450
        }
1451

    
1452
        /*
1453
         * (non-Javadoc)
1454
         * @see org.gvsig.raster.hierarchy.IRasterDataset#getDataSource()
1455
         */
1456
        public IRasterDataSource getDataSource() {
1457
                return dataset;
1458
        }
1459

    
1460
        /*
1461
         * (non-Javadoc)
1462
         * @see org.gvsig.fmap.raster.IRasterDataset#addFile(java.lang.String)
1463
         */
1464
        public void addFile(String fileName) throws NotSupportedExtensionException, RasterDriverException {
1465
                if (getRender() != null)
1466
                        bufferFactory.addFile(RasterDataset.open(getProjection(), fileName));
1467
        }
1468

    
1469
        /*
1470
         * (non-Javadoc)
1471
         * @see org.gvsig.fmap.raster.IRasterDataset#delFile(java.lang.String)
1472
         */
1473
        public void delFile(String fileName) {
1474
                if (getRender() != null)
1475
                        bufferFactory.removeFile(fileName);
1476
        }
1477

    
1478
        /*
1479
         * (non-Javadoc)
1480
         * @see org.gvsig.fmap.raster.IRasterDataset#getInfo(java.lang.String)
1481
         */
1482
        public Object getInfo(String key) {
1483
                if (key.equals("DriverName"))
1484
                        return "gvSIG Raster Driver";
1485
                return null;
1486
        }
1487

    
1488
        /*
1489
         * (non-Javadoc)
1490
         * @see org.gvsig.raster.shared.IRasterOperations#getMetadata()
1491
         */
1492
        public DatasetMetadata[] getMetadata() {
1493
                int count = dataset.getDatasetCount();
1494
                DatasetMetadata[] metadata = new DatasetMetadata[count];
1495
                for (int i = 0; i < count; i++) {
1496
                        metadata[i] = dataset.getDataset(i)[0].getMetadata();
1497
                }
1498
                return metadata;
1499
        }
1500

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

    
1513
        /*
1514
         * (non-Javadoc)
1515
         * @see org.gvsig.raster.shared.IRasterOperations#getColourInterpretation(int, int)
1516
         */
1517
        public String getColorInterpretation(int band, int dataset) {
1518
                if (this.dataset.getDataset(dataset)[0].getColorInterpretation().get(band) == null)
1519
                        return "Undefined";
1520
                return this.dataset.getDataset(dataset)[0].getColorInterpretation().get(band);
1521
        }
1522

    
1523
        /*
1524
         * (non-Javadoc)
1525
         * @see org.gvsig.raster.shared.IRasterGeoOperations#getStringProjection()
1526
         */
1527
        public String getWktProjection() throws RasterDriverException {
1528
                return dataset.getWktProjection();
1529
        }
1530

    
1531
        /**
1532
         * Metodo para consultar si una capa puede ser un RGB. Suponemos que es un RGB
1533
         * si el tipo de datos es de tipo byte y su interpretacion de color tiene
1534
         * asignada los tres colores.
1535
         * @return boolean
1536
         */
1537
        public boolean isRGB() {
1538
                if ((dataset == null) || (render == null))
1539
                        return false;
1540

    
1541
// Quitado pq no necesariamente tiene pq tener 3 bandas para ser RGB
1542
//                if (dataset.getBandCount() < 3)
1543
//                        return false;
1544

    
1545
                if (dataset.getDataType()[0] != IBuffer.TYPE_BYTE)
1546
                        return false;
1547

    
1548
                boolean R = false;
1549
                boolean G = false;
1550
                boolean B = false;
1551

    
1552
                int[] renderBands = render.getRenderBands();
1553
                for (int i = 0; i < renderBands.length; i++) {
1554
                        if (renderBands[i] >= 0) {
1555
                                switch (i) {
1556
                                        case 0:
1557
                                                R = true;
1558
                                                break;
1559
                                        case 1:
1560
                                                G = true;
1561
                                                break;
1562
                                        case 2:
1563
                                                B = true;
1564
                                                break;
1565
                                }
1566
                        }
1567
                }
1568

    
1569
                if (R && G && B)
1570
                        return true;
1571

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

    
1637

    
1638
        /**
1639
         * Devuelve el fichero asociado a la capa o null si no tiene.
1640
         * @return Fichero.
1641
         */
1642
        public File getFile() {
1643
                return (params instanceof File) ? ((File)params) : null;
1644
        }
1645

    
1646
        /**
1647
         * Consulta si un fichero es aceptado o no para este tipo de capa.
1648
         * @param file Fichero a consultar
1649
         * @return true si es aceptado y false si no lo es.
1650
         */
1651
        public static boolean isFileAccepted(File file) {
1652
                return RasterDataset.fileIsSupported(file.getName());
1653
        }
1654

    
1655
        /*
1656
         * (non-Javadoc)
1657
         * @see org.gvsig.raster.shared.IRasterRendering#existColorTable()
1658
         */
1659
        public boolean existColorTable() {
1660
                return getRender().existColorTable();
1661
        }
1662
        
1663
        /*
1664
         * (non-Javadoc)
1665
         * @see org.gvsig.raster.hierarchy.IRasterRendering#existsAlphaBand()
1666
         */
1667
        public boolean existsAlphaBand() {
1668
                if(getDataSource().getColorInterpretation() != null)
1669
                        return getDataSource().getColorInterpretation().isAlphaBand();
1670
                else 
1671
                        return false;
1672
        }
1673
        
1674
        /*
1675
         * (non-Javadoc)
1676
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getAlphaBandNumber()
1677
         */
1678
        public int getAlphaBandNumber() {
1679
                if(getDataSource().getColorInterpretation() != null)
1680
                        return getDataSource().getColorInterpretation().getBand(DatasetColorInterpretation.ALPHA_BAND);
1681
                return -1;
1682
        }
1683

    
1684
        /**
1685
         * Define la ultima leyenda valida de la capa o se pone a null para que la
1686
         * capa busque una leyenda valida.
1687
         * @param ct
1688
         */
1689
        public void setLastLegend(ColorTable ct) {
1690
                lastLegend = ColorTableLegend.createLegend(ct);
1691
        }
1692

    
1693
        /**
1694
         * Devuelve la Leyenda de la capa.
1695
         * @return Leyenda.
1696
         */
1697
        public ILegend getLegend() {
1698
                if (lastLegend != null)
1699
                        return lastLegend;
1700

    
1701
                return null;
1702
        }
1703

    
1704
        /*
1705
         * (non-Javadoc)
1706
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable#addLegendListener(com.iver.cit.gvsig.fmap.layers.LegendListener)
1707
         */
1708
        public void addLegendListener(LegendListener listener) {
1709
                layerChangeSupport.addLayerListener(listener);
1710
        }
1711

    
1712
        /*
1713
         *  (non-Javadoc)
1714
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable#getShapeType()
1715
         */
1716
        public int getShapeType() throws ReadDriverException {
1717
                return FShape.POLYGON;
1718
        }
1719

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

    
1728
        /**
1729
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa
1730
         * o fuera de ellos.
1731
         * @param p Punto a calcular
1732
         * @return true si est? dentro de los l?mites y false si est? fuera
1733
         */
1734
        public boolean isInside(Point2D p) {
1735
                 return getDataSource().isInside(p);
1736
        }
1737

    
1738
        /**
1739
         * Recupera del raster la matriz de transformaci?n que lo situa en cualquier parte de la vista
1740
         * @return AffineTransform
1741
         */
1742
        public AffineTransform getAffineTransform(int band) {
1743
                return getDataSource().getAffineTransform(band);
1744
        }
1745
        
1746
        /**
1747
         * Recupera del raster la matriz de transformaci?n que lo situa en cualquier parte de la vista
1748
         * @return AffineTransform
1749
         */
1750
        public AffineTransform getAffineTransform() {
1751
                if(getDataSource() != null)
1752
                        return getDataSource().getAffineTransform(0);
1753
                return null;
1754
        }
1755

    
1756
        /**
1757
         * Asigna al raster la matriz de transformaci?n para situarlo en cualquier parte de la vista
1758
         * @param transf
1759
         */
1760
        public void setAffineTransform(AffineTransform transf) {
1761
                if(transf == null)
1762
                        return;
1763
                affineTransformList.add(transf);
1764
                getDataSource().setAffineTransform(transf);
1765
                updateDrawVersion();
1766
        }
1767

    
1768
        /**
1769
         * Asigna al raster la matriz de transformaci?n para situarlo en cualquier parte de la vista.
1770
         * Esta versi?n no guarda en el historico.
1771
         * @param transf
1772
         */
1773
        public void setAT(AffineTransform transf) {
1774
                getDataSource().setAffineTransform(transf);
1775
                updateDrawVersion();
1776
        }
1777

    
1778
        /**
1779
         * Obtiene la lista de transformaciones que se han ido aplicando al raster.
1780
         * @return Historical. Lista de AffineTransform
1781
         */
1782
        public Historical getAffineTransformHistorical() {
1783
                return this.affineTransformList;
1784
        }
1785
        
1786
        /**
1787
         * Salva la georreferenciaci?n a fichero rmf.
1788
         * @param fName
1789
         * @throws RmfSerializerException 
1790
         */
1791
        public void saveGeoToRmf() throws RmfSerializerException {
1792
                if (!isOpen())
1793
                        return;
1794

    
1795
                // Guardamos la GeoReferenciacion de cada dataset
1796
                for (int i = 0; i < getDataSource().getDatasetCount(); i++)
1797
                        getDataSource().saveObjectToRmf(i, RasterDataset.class, getDataSource().getDataset(i)[0]);
1798
                
1799
                affineTransformList.clear();
1800
                affineTransformList.add(this.getAffineTransform());
1801
        }
1802

    
1803
        /*
1804
         * (non-Javadoc)
1805
         * @see org.gvsig.fmap.raster.layers.IRasterLayerActions#isActionEnabled(int)
1806
         */
1807
        public boolean isActionEnabled(int action) {
1808
                switch (action) {
1809
                        case IRasterLayerActions.BANDS_FILE_LIST:
1810
                                if (existColorTable())
1811
                                        return false;
1812
                                break;
1813
                        case IRasterLayerActions.BANDS_RGB:
1814
                                if (existColorTable())
1815
                                        return false;
1816
                                break;
1817
                        case IRasterLayerActions.REPROJECT:
1818
                                if (!isReproyectable())
1819
                                        return false;
1820
                                break;
1821
                        case IRasterLayerActions.CREATEOVERVIEWS:
1822
                                return overviewsSupport();
1823
                        case IRasterLayerActions.OPACITY:
1824
                        case IRasterLayerActions.TRANSPARENCY:
1825
                        case IRasterLayerActions.BRIGHTNESSCONTRAST:
1826
                        case IRasterLayerActions.ENHANCED:
1827
                        case IRasterLayerActions.PANSHARPENING:
1828
                        case IRasterLayerActions.SELECT_LAYER:
1829
                        case IRasterLayerActions.SAVE_COLORINTERP:
1830
                                return true;
1831
                        case IRasterLayerActions.REMOTE_ACTIONS:
1832
                                return false;
1833
                }
1834
                return true;
1835
        }
1836

    
1837
        /*
1838
         * (non-Javadoc)
1839
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setVisible(boolean)
1840
         */
1841
        public void setVisible(boolean visibility) {
1842
                if(visibility)
1843
                        state.disableStopped();
1844
                else
1845
                        enableStopped();
1846

    
1847
                if(isAwake() || isClosed()) {
1848
                        try {
1849
                                this.load();
1850
                        } catch (LoadLayerException e) {
1851
                                e.printStackTrace();
1852
                        }
1853
                }
1854

    
1855
                /*
1856
                 * Cuando se modifica la visibilidad de una capa raster se hace un updateDrawVersion de todas las
1857
                 * capas raster de ese MapContext. Esto es porque la estrategia utilizada por RasterDrawStrategy hace
1858
                 * que se cacheen en blanco las capas raster que est?n ocultas debajo de otras. Al hacer invisibles las
1859
                 * de arriba la cache que estaba en blanco hace que no se pinte nada. Para evitar esto las marcamos todas
1860
                 * como que han sido modificadas para que se vuelvan a leer.
1861
                 */
1862
                if(getMapContext() != null) {
1863
                        ArrayList listLayers = new ArrayList();
1864
                        listLayers = RasterDrawStrategy.getLayerList(getMapContext().getLayers(), listLayers);
1865
                        for (int i = 0; i < listLayers.size(); i++) {
1866
                                if(listLayers.get(i) instanceof FLyrRasterSE)
1867
                                        ((FLyrRasterSE)listLayers.get(i)).updateDrawVersion();
1868
                        }
1869
                }
1870

    
1871
                super.setVisible(visibility);
1872
        }
1873

    
1874
        /**
1875
         * Consulta la transparencia asignada en la ?ltima renderizaci?n de la capa
1876
         * @return valor de transparencia
1877
         */
1878
        public int getTransparency() {
1879
                try {
1880
                        return getRenderTransparency().getOpacity();
1881
                } catch (NullPointerException e) {
1882
                        return super.getTransparency();
1883
                }
1884
        }
1885

    
1886
        /**
1887
         * Consulta si tiene aplicada alguna transparencia en la ?ltima renderizaci?n
1888
         * o no.
1889
         * @return true si se aplic? alguna transparencia en la ?ltima renderizaci?n.
1890
         */
1891
        public boolean isTransparent() {
1892
                return getRenderTransparency().isTransparencyActive();
1893
        }
1894

    
1895
        /**
1896
         * Asigna la transparencia de la siguiente renderizaci?n
1897
         * @param valor de transparencia
1898
         */
1899
        public void setTransparency(int trans) {
1900
                super.setTransparency(trans);
1901
                try {
1902
                        getRenderTransparency().setOpacity(trans);
1903
                        getRenderTransparency().activeTransparency();
1904
                } catch (NullPointerException e) {
1905
                        //Solo asigna la transparencia a la clase padre y no a la renderizaci?n
1906
                }
1907
        }
1908

    
1909
        /*
1910
         * (non-Javadoc)
1911
         * @see org.gvsig.raster.hierarchy.IRasterRendering#getLastRenderBuffer()
1912
         */
1913
        public IBuffer getLastRenderBuffer() {
1914
                return getRender().getLastRenderBuffer();
1915
        }
1916

    
1917
        /**
1918
         *
1919
         * @return ROIs asociadas a la capa raster.
1920
         */
1921
        public ArrayList getRois() {
1922
                return rois;
1923
        }
1924

    
1925
        /**
1926
         * Establece las ROI asociadas a la capa raster.
1927
         *
1928
         * @param rois ArrayList de ROIs a asociar a la capa raster.
1929
         */
1930
        public void setRois(ArrayList rois) {
1931
                this.rois = rois;
1932
        }
1933

    
1934
        /**
1935
         * Si ya tiene una estrategia de dibujado de raster calculada la devuelve, sino
1936
         * devolver? null.
1937
         * @return TreeMap con la lista de capas a dibujar
1938
         */
1939
        public HashMap getRasterStrategy() {
1940
                if(strategy != null)
1941
                        return strategy.getStrategy();
1942
                return null;
1943
        }
1944
        
1945
        /**
1946
         * Devuelve el tipo de valor de NoData asociado a la capa.
1947
         * Sirve para diferenciar los estados seleccionados por el usuario. Siendo
1948
         * estos '0: Sin Valor NoData', '1: NoData de Capa'(Por defecto) y '2: Personalizado'
1949
         */
1950
        /**
1951
         * @return the noDataType
1952
         */
1953
        public int getNoDataType() {
1954
                return noDataType;
1955
        }
1956

    
1957
        /**
1958
         * @param noDataType the noDataType to set
1959
         */
1960
        public void setNoDataType(int noDataType) {
1961
                this.noDataType = noDataType;
1962
                if (dataset != null)
1963
                        dataset.setNoDataEnabled(noDataType != RasterLibrary.NODATATYPE_DISABLED);
1964
        }
1965

    
1966
        /**
1967
         * @return the configuration
1968
         */
1969
        static public IConfiguration getConfiguration() {
1970
                return configuration;
1971
        }
1972

    
1973
        /**
1974
         * @param configuration the configuration to set
1975
         */
1976
        static public void setConfiguration(IConfiguration configuration) {
1977
                FLyrRasterSE.configuration = configuration;
1978
        }
1979
        
1980
        /*
1981
         * (non-Javadoc)
1982
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#reload()
1983
         */
1984
        public void reload() throws ReloadLayerException {
1985
                try {
1986
                        super.reload();
1987
                        if (getMapContext() == null)
1988
                                return;
1989
                        if (isStopped())
1990
                                disableStopped();
1991
                        load();
1992
                        getMapContext().invalidate();
1993
                } catch (LoadLayerException e) {
1994
                        setAvailable(false);
1995
                        throw new ReloadLayerException(getName(), e);
1996
                }
1997
        }
1998
        
1999
        /**
2000
         * Devuelve si la capa tiene soporte para poder generar overviews
2001
         * @return
2002
         */
2003
        public boolean overviewsSupport() {
2004
                if ((getDataSource() != null) && (getDataSource().overviewsSupport()))
2005
                        return true;
2006

    
2007
                return false;
2008
        }
2009

    
2010
        /**
2011
         * Devuelve si la asignacion de las bandas a renderizar representa una capa
2012
         * en escala de grises
2013
         * @return
2014
         */
2015
        public boolean isRenderingAsGray() {
2016
                int[] renderBands = getRenderBands();
2017
                if ((renderBands != null) && (renderBands.length == 3) && (renderBands[0] >= 0) &&
2018
                                (renderBands[0] == renderBands[1]) && (renderBands[1] == renderBands[2]))
2019
                        return true;
2020
                return false;
2021
        }
2022
        
2023
        /*
2024
         * (non-Javadoc)
2025
         * @see org.gvsig.raster.grid.render.VisualPropertyListener#actionValueChanged(org.gvsig.raster.grid.render.VisualPropertyEvent)
2026
         */
2027
        public void visualPropertyValueChanged(VisualPropertyEvent e) {
2028
                updateDrawVersion();
2029
        }
2030
        
2031
        /*****************************************************/
2032
        //Utils
2033

    
2034
        /**
2035
         * Ajusta las coordenadas especificadas en el par?metro al ?rea m?xima
2036
         * del raster en p?xeles.
2037
         * @param req Punto a ajustar dentro del extener del raster
2038
         */
2039
        public Point2D adjustWorldRequest(Point2D req) {
2040
                Rectangle2D ext = null;
2041

    
2042
                ext = getFullExtent();
2043
                req.setLocation(Math.max(ext.getMinX(), req.getX()), Math.max(ext.getMinY(), req.getY()));
2044
                req.setLocation(Math.min(ext.getMaxX(), req.getX()), Math.min(ext.getMaxY(), req.getY()));
2045
                return req;
2046
        }
2047
        
2048
        /*
2049
         * (non-Javadoc)
2050
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#cloneLayer()
2051
         */
2052
        public FLayer cloneLayer() throws Exception {
2053
                FLyrRasterSE newLayer = FLyrRasterSE.createLayer(this.getName(), params, this.getProjection());
2054
                for (int i = 0; i < dataset.getDatasetCount(); i++) {
2055
                        String name = dataset.getDataset(i)[0].getFName();
2056
                        if (!(dataset instanceof CompositeDataset) && !name.equals(this.getName()) && !isActionEnabled(IRasterLayerActions.REMOTE_ACTIONS))
2057
                                newLayer.addFile(name);
2058
                }
2059
                ArrayList filters = getRender().getFilterList().getStatusCloned();
2060
        
2061
                //Hacemos una copia de las bandas a renderizar
2062
                if(getRenderBands() != null) {
2063
                        int[] rb = new int[getRenderBands().length];
2064
                        for (int i = 0; i < rb.length; i++) 
2065
                                rb[i] = getRenderBands()[i];
2066
                        newLayer.setRenderBands(rb);
2067
                }
2068
                
2069
                //Asignamos el entorno
2070
                if(newLayer.getRender().getFilterList() == null)
2071
                        newLayer.getRender().setFilterList(new RasterFilterList());
2072
                newLayer.getRender().getFilterList().setEnv(getRender().getFilterList().getEnv());        
2073
                newLayer.getRender().getFilterList().setStatus(filters);
2074

    
2075
                // Asignamos los valores noData del original
2076
                newLayer.setNoDataValue(getNoDataValue());
2077
                newLayer.setNoDataType(getNoDataType());
2078
                newLayer.applyNoData();
2079

    
2080
                return newLayer;
2081
        }
2082
        
2083
        /**
2084
         * Gets a layer which the source is a file
2085
         * @return
2086
         */
2087
        public FLayer getFileLayer() {
2088
                try {
2089
                        return cloneLayer();
2090
                } catch (Exception e) {
2091
                }
2092
                return null;
2093
        }
2094
        
2095
        /*****************************************************/
2096

    
2097
        public void disableStopped() {state.disableStopped();}
2098

    
2099
        public void enableAwake() throws NotAvailableStateException {state.enableAwake();}
2100

    
2101
        public void enableClosed() throws NotAvailableStateException {state.enableClosed();}
2102

    
2103
        public void enableOpen() throws NotAvailableStateException {state.enableOpen();}
2104

    
2105
        public void enableStopped() {state.enableStopped();}
2106

    
2107
        public boolean isAwake() {return state.isAwake();}
2108

    
2109
        public boolean isClosed() {return state.isClosed();}
2110

    
2111
        public boolean isOpen() {return state.isOpen();}
2112

    
2113
        public boolean isStopped() {return state.isStopped();}
2114

    
2115
        /**
2116
         * Returns true if exists a process reading data from this layer
2117
         * @return
2118
         */
2119
        public boolean isReadingData() {
2120
                return readingData != null;
2121
        }
2122

    
2123
        /**
2124
         * When a process is using information of this layer this variable will contain
2125
         * the thread ID.
2126
         * @param readingData
2127
         */
2128
        public synchronized void setReadingData(String readingData) {
2129
                this.readingData = readingData;
2130
        }
2131

    
2132
}