Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / MultiRasterDataset.java @ 13328

History | View | Annotate | Download (41.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.dataset;
20

    
21
import java.awt.geom.AffineTransform;
22
import java.awt.geom.Point2D;
23
import java.io.File;
24
import java.io.IOException;
25
import java.util.ArrayList;
26

    
27
import org.cresques.cts.IProjection;
28
import org.gvsig.raster.buffer.RasterBuffer;
29
import org.gvsig.raster.buffer.cache.RasterReadOnlyHugeBuffer;
30
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
31
import org.gvsig.raster.dataset.properties.DatasetListHistogram;
32
import org.gvsig.raster.dataset.properties.DatasetListStatistics;
33
import org.gvsig.raster.datastruct.ColorTable;
34
import org.gvsig.raster.datastruct.Extent;
35
import org.gvsig.raster.datastruct.Histogram;
36
import org.gvsig.raster.datastruct.HistogramException;
37
import org.gvsig.raster.datastruct.Transparency;
38
import org.gvsig.raster.hierarchy.IHistogramable;
39

    
40

    
41
/**
42
 * Clase que representa una imagen de raster georreferenciada formada por varias
43
 * imagenes de disco que tienen la misma extensi?n. Contiene funcionalidades para 
44
 * abrir ficheros, gestionar el extent, pintar el raster sobre un DataImage con 
45
 * su gesti?n de bandas correspondiente.
46
 *  
47
 * @author Nacho Brodin (nachobrodin@gmail.com)
48
 *
49
 */
50
public class MultiRasterDataset implements IRasterDataSource {
51
        
52
        private boolean[]                                        cancel = new boolean[1];
53
        
54
        //File list
55
        private ArrayList                                         files = new ArrayList();
56
        private String                                                name = null;
57
        //Band list
58
        private BandList                                        bandList = new BandList();
59
        protected DatasetListStatistics     stats = null;
60
        protected DatasetListHistogram                histogram = null;
61
        int percent = 0;
62
                        
63
        //TODO: FUNCIONALIDAD: Contructores igual a RasterDataset + String[] nameFiles
64
        public MultiRasterDataset(String name) {
65
                this.name = name;
66
        }
67
        
68
        /**
69
         * Crea un objeto MultiRasterDataset nuevo con los mismos ficheros
70
         * que el actual.
71
         * @return MultiRasterDataset
72
         */
73
        public IRasterDataSource copy() {
74
                try {
75
                        String[] fileList = getNameDatasetStringList(0, 0);
76
                        MultiRasterDataset multiRasterDataset = MultiRasterDataset.open(getDataset(0)[0].getProjection(), fileList[0]);
77
                        for (int j = 1; j < fileList.length; j++)
78
                                multiRasterDataset.addDataset(new String[]{fileList[j]});
79
                        return multiRasterDataset;
80
                } catch (FileNotFoundInListException e) {
81
                        return null;
82
                } catch (NotSupportedExtensionException e) {
83
                        return null;
84
                } catch (RasterDriverException e) {
85
                        return null;
86
                }
87
        }
88
        
89
        /**
90
         * Abre un dataset pasando como par?metros la proyecci?n y un objeto identificador del dataset. Este
91
         * objeto puede ser una ruta a un fichero en disco. En este caso la extensi?n del fichero servir? para 
92
         * buscar el driver que lo gestiona. Si proporcionamos un array de cadenas se tratar?n como la ruta a N ficheros
93
         * de disco. Tambi?n puede ser un buffer de datos en memoria o cualquier otro objeto
94
         * que pueda aceptar un driver.  
95
         * @param proj PRoyecci?n
96
         * @param datasetOpenParam Par?metros al driver
97
         * @return RasterMultiDatset
98
         * @throws NotSupportedExtensionException
99
         * @throws RasterDriverException
100
         */
101
        public static MultiRasterDataset open(IProjection proj, Object datasetOpenParam) throws NotSupportedExtensionException, RasterDriverException{
102
                MultiRasterDataset rmd = new MultiRasterDataset(null);
103
                if(datasetOpenParam instanceof String[]) {
104
                        String[] param = (String[])datasetOpenParam;
105
                        for (int dataset = 0; dataset < param.length; dataset++)
106
                                try {
107
                                        rmd.addDataset(new RasterDataset[]{RasterDataset.open(proj, param[dataset])});
108
                                } catch (FileNotFoundInListException e) {
109
                                        //No lo a?adimos en el dataset pq ya existe
110
                                }         
111
                } else if(datasetOpenParam instanceof IBuffer[]) {
112
                        IBuffer[] param = (IBuffer[])datasetOpenParam;
113
                        for (int dataset = 0; dataset < param.length; dataset++)
114
                                try {
115
                                        rmd.addDataset(new RasterDataset[]{RasterDataset.open(proj, param[dataset])});
116
                                } catch (FileNotFoundInListException e) {
117
                                        //No lo a?adimos en el dataset pq ya existe
118
                                }         
119
                } else {
120
                        RasterDataset rd = RasterDataset.open(proj, datasetOpenParam);
121
                        try {
122
                                rmd.addDataset(new RasterDataset[]{rd});
123
                        } catch (FileNotFoundInListException e) {
124
                                //No lo a?adimos en el dataset pq ya existe
125
                        }
126
                }
127
                return rmd;
128
        }
129
        
130
        /**
131
         * A?ade un fichero a la lista que componen el multi raster. El array solo debe tener un
132
         * elemento ya que solo tiene sentido para este caso con un elemento. ?Ojo!, a?adir m?s elementos
133
         * al array no hace que se a?adan varios datasets a la lista.
134
         * @param f A?ade el elemento 0 a la lista.
135
         */
136
        public void addDataset(RasterDataset[] f)throws FileNotFoundInListException {
137
                if(f.length != 1)
138
                        throw new FileNotFoundInListException("Error in list.");
139
                if(findDataset(f[0]))
140
                        throw new FileNotFoundInListException("The file already is in list.");
141
                files.add(f[0]);
142
                addBands(f[0]);
143
                stats = new DatasetListStatistics(files);
144
        }
145
        
146
        /**
147
         * A?ade un fichero a la lista que componen el multi raster a partir de su nombre. El array solo debe tener un
148
         * elemento ya que solo tiene sentido para este caso con un elemento. ?Ojo!, a?adir m?s elementos
149
         * al array no hace que se a?adan varios datasets a la lista.
150
         * @param f A?ade el elemento 0 a la lista.
151
         */
152
        public void addDataset(String[] fileName)throws FileNotFoundInListException, NotSupportedExtensionException, RasterDriverException {
153
                if(fileName.length != 1)
154
                        throw new FileNotFoundInListException("Error in list.");
155
                if(findDataset(fileName[0]))
156
                        throw new FileNotFoundInListException("The file already is in list.");
157
                RasterDataset f = RasterDataset.open(null, fileName[0]);
158
                files.add(f);
159
                addBands(f);
160
                stats = new DatasetListStatistics(files);
161
        }
162
        
163
        /**
164
         * A?ade el fichero a lista de georrasterfiles y sus bandas a la lista de bandas
165
         * @param grf
166
         */
167
        private void addBands(RasterDataset grf) {
168
                if(grf == null)
169
                        return;
170
                
171
                int dataType = grf.getDataType();
172
                for(int i = 0; i < grf.getBandCount();i++) {
173
                        try {
174
                                Band band = new Band(grf.getFName(), i, dataType);
175
                                bandList.addBand(band, i);
176
                        } catch(BandNotFoundInListException ex) {
177
                                //No a?adimos la banda
178
                        }
179
                }
180
        }
181
        
182
        /**
183
         * Elimina un fichero a la lista a partir de su nombre
184
         * @param fileName        Nombre del fichero a eliminar.
185
         */
186
        public void removeDataset(String fileName) {
187
                for(int i=0;i<files.size();i++) {
188
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName)) {
189
                                files.remove(i);
190
                                bandList.removeBands(fileName);
191
                                return;
192
                        }
193
                }
194
        }
195
        
196
        /**
197
         * Elimina un fichero a la lista
198
         * @param file Fichero a eliminar
199
         */
200
        public void removeDataset(RasterDataset file) {
201
                for(int i=0;i<files.size();i++) {
202
                        if(((RasterDataset)files.get(i)).getFName().equals(file.getFName())) {
203
                                files.remove(i);
204
                                bandList.removeBands(file.getFName());
205
                                return;
206
                        }
207
                }
208
        }
209
                
210
        /**
211
         * Obtiene el n?mero de ficheros en la lista
212
         * @return integer.
213
         */
214
        public int getDatasetCount() {
215
                return files.size();
216
        }
217
        
218
        /**
219
         * Encuentra un fichero en la lista.
220
         * @param file Fichero b?scado.
221
         * @return true si se ha hallado el fichero y false si no se 
222
         * ha encontrado
223
         */
224
        public boolean findDataset(RasterDataset file) {
225
                for(int i = 0;i<files.size();i++) {
226
                        RasterDataset grf = (RasterDataset)files.get(i); 
227
                        if(        grf.getFName().equals(file.getFName()))
228
                                return true;
229
                }
230
                return false;
231
        }
232
        
233
        /**
234
         * Encuentra un fichero en la lista.
235
         * @param file Fichero b?scado.
236
         * @return true si se ha hallado el fichero y false si no se 
237
         * ha encontrado
238
         */
239
        public boolean findDataset(String fileName) {
240
                for(int i = 0;i<files.size();i++) {
241
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
242
                                return true;
243
                }
244
                return false;
245
        }
246
                            
247
        /**
248
         * Cierra la lista de datasets asociados al MultiRasterDataset
249
         */
250
        public void close() {
251
                for(int i = 0; i < files.size(); i++)
252
                        ((RasterDataset)files.get(i)).close();
253
                files.clear();
254
                bandList.clear();
255
        }
256
        
257
        /**
258
         * Obtiene en un array de String la lista de nombres de ficheros. 
259
         * @param i Para un MultiRasterDataset el par?metro es ignorado
260
         * @param j Para un MultiRasterDataset el par?metro es ignorado
261
         * @return lista de nombres de los ficheros del GeoRasterMultiFile
262
         */
263
        public String[] getNameDatasetStringList(int i, int j) {
264
                String[] list = new String[files.size()];
265
                for(int k = 0; k < files.size(); k++)
266
                        list[k] = ((RasterDataset)files.get(k)).getFName();
267
                return list;
268
        }
269
        
270
        /**
271
         * Inicializa el buffer a valores NoData
272
         * @param raster Buffer a inicializar
273
         * @param bandList Lista de bandas
274
         */
275
        private void initBufferToNoData(IBuffer raster, BandList bandList) {
276
                for(int i = 0; i < bandList.getDrawableBandsCount(); i++) {
277
                        switch(getDataType()[0]) {
278
                        case IBuffer.TYPE_BYTE:raster.assign(i, raster.getByteNoDataValue());break;
279
                        case IBuffer.TYPE_SHORT:raster.assign(i, raster.getShortNoDataValue());break;
280
                        case IBuffer.TYPE_INT:raster.assign(i, raster.getIntNoDataValue());break;
281
                        case IBuffer.TYPE_FLOAT:raster.assign(i, raster.getFloatNoDataValue());break;
282
                        case IBuffer.TYPE_DOUBLE:raster.assign(i, raster.getNoDataValue());break;
283
                        }
284
                }        
285
        }
286
        
287
        /**
288
         * A partir de la lista de bandas que dice como cargar el buffer se crean tantos IBuffer como ficheros intervienen
289
         * . Cada IBuffer corresponde a un dataset del RasterMultiDataset y en ellos se reserva memoria solo para las
290
         * bandas que vayan a ser cargadas. Las otras se asignaran a la banda NotValid.
291
         * @param bl Lista de bandas
292
         * @param width Ancho
293
         * @param height Alto
294
         * @return Lista de buffers en el que cada uno corresponde a un dataset.
295
         */
296
        private IBuffer[] mallocBuffersDatasets(BandList bl, int width, int height) {
297
                IBuffer[] buffers = new IBuffer[getDatasetCount()];
298
                for(int i = 0; i < getDatasetCount(); i++) {
299
                        buffers[i] =  RasterBuffer.getBuffer(getDataset(i)[0].getDataType(), width, height, getDataset(i)[0].getBandCount(), false);
300
                        
301
                        //Asignamos las bandas de cada fichero que no se pintan a null y las que se pintan se reserva memoria
302
                        String name = getDataset(i)[0].getFName();
303
                        for(int j = 0; j < getDataset(i)[0].getBandCount(); j ++) {
304
                                if(bl.getBufferBandToDraw(name, j) == null)
305
                                        buffers[i].assignBandToNotValid(j);
306
                                else
307
                                        buffers[i].mallocOneBand(getDataset(i)[0].getDataType(), width, height, j);
308
                        }
309
                }
310
                return buffers;
311
        }
312
        
313
        /**
314
         * Mezcla los buffers de los dataset que forman el RasterMultiDataset sobre un solo buffer
315
         * con las directrices que marca la lista de bandas. Esta funci?n es la que realiza el switch 
316
         * de las bandas.
317
         * @param b Buffer sobre el que se mezcla
318
         * @param bDataset Buffers que corresponden a los datasets
319
         * @param bandList Objeto que contiene la informaci?n de que bandas de los dataset se escriben sobre
320
         * que banda del buffer.
321
         */
322
        private void mergeBuffers(IBuffer b, IBuffer[] bDataset, BandList bandList) {
323
                for(int iDataset = 0; iDataset < getDatasetCount(); iDataset++){ //Ojo! Los datasets est?n en la misma posici?n que se han metido en mallocBuffersDatasets
324
                        String name = getDataset(iDataset)[0].getFName();
325
                                                
326
                        for(int iBand = 0; iBand < getDataset(iDataset)[0].getBandCount(); iBand ++) {
327
                                int[] posToDraw = bandList.getBufferBandToDraw(name, iBand);
328
                                if(posToDraw != null) {
329
                                        for(int i = 0; i < posToDraw.length; i ++) {
330
                                                switch(getDataType()[iDataset]) {
331
                                                case IBuffer.TYPE_BYTE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
332
                                                case IBuffer.TYPE_SHORT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
333
                                                case IBuffer.TYPE_INT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
334
                                                case IBuffer.TYPE_FLOAT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
335
                                                case IBuffer.TYPE_DOUBLE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
336
                                                }
337
                                        }
338
                                }
339
                        }
340
                }
341
        }
342

    
343
        /**
344
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
345
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
346
         * pixeles de disco. 
347
         * @param x Posici?n X superior izquierda
348
         * @param y Posici?n Y superior izquierda
349
         * @param w Ancho en coordenadas reales
350
         * @param h Alto en coordenadas reales
351
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
352
         * @param bandList
353
         * @return Buffer de datos
354
         */
355
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry) throws InvalidSetViewException {                
356
                Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
357

    
358
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
359
                //por arriba el m?s alto y por abajo el menor y luego restandolos
360
                
361
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(ulx, uly));
362
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(lrx, lry));
363
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
364
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
365
                
366
                //Ajustamos por si nos hemos salido del raster
367
                while(((int)(p1.getX() + width)) > getWidth()[0])
368
                        width --;
369
                while(((int)(p1.getY() + height)) > getHeight()[0])
370
                        height --;
371
                
372
                if(p1.getX() < 0)
373
                        p1.setLocation(0, p1.getY());
374
                if(p1.getY() < 0)
375
                        p1.setLocation(p1.getX(), 0);
376
                if(p2.getX() > getWidth()[0])
377
                        p2.setLocation(getWidth()[0], p2.getY());
378
                if(p1.getY() > getHeight()[0])
379
                        p1.setLocation(p2.getX(), getHeight()[0]);
380
                
381
                int mallocNBands = 0;
382
                if(bandList.getDrawableBands() != null)
383
                        mallocNBands = bandList.getDrawableBands().length;
384
                else
385
                        mallocNBands = bandList.getDrawableBandsCount();
386
                
387
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
388
                
389
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
390
                if(!raster.isBandSwitchable()) {
391
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0)[0].getBandCount(), false);
392
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
393
                                try {
394
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0)[0].getFName(), selectedExtent);
395
                                } catch (FileNotExistsException e) {
396
                                        //Esto no debe darse ya que se comprueba al hacer el open
397
                                } catch (NotSupportedExtensionException e) {
398
                                        //Esto no debe darse ya que se comprueba al hacer el open
399
                                }
400
                                return rb;
401
                        }
402
                }
403
                                        
404
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
405
                        raster.assignBandToNotValid(iBand);
406
                
407
                //Reservamos memoria para los buffers por dataset
408
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
409
                
410
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor 
411
                //equivalente a los pixeles redondeados.
412
                Point2D wc1 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
413
                Point2D wc2 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
414
                for(int i = 0; i < getDatasetCount(); i++)
415
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), wc2.getX(), wc2.getY(), bandList, bufferDatasets[i]);
416
                
417
                //Mezclamos los buffers de cada dataset en un solo buffer
418
                mergeBuffers(raster, bufferDatasets, bandList);
419
                                                        
420
                return raster;
421
        }
422
        
423
        /**
424
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
425
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
426
         * pixeles de disco. 
427
         * @param x Posici?n X superior izquierda
428
         * @param y Posici?n Y superior izquierda
429
         * @param w Ancho en coordenadas reales
430
         * @param h Alto en coordenadas reales
431
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
432
         * @param bandList
433
         * @return Buffer de datos
434
         */
435
        public IBuffer getWindowRaster(double ulx, double uly, double w, double h, boolean adjustToExtent) 
436
                throws InvalidSetViewException {
437
                //El incremento o decremento de las X e Y depende de los signos de rotaci?n y escala en la matriz de transformaci?n. Por esto
438
                //tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o y - h 
439
                Extent ext = getExtent();
440
                Point2D pInit = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(0, 0));
441
                Point2D pEnd = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double((int)getWidth()[0], (int)getHeight()[0]));
442
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
443
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
444
                double lrx = (((int)(ext.getULX() - wRaster)) == ((int)ext.getLRX())) ? (ulx - w) : (ulx + w);
445
                double lry = (((int)(ext.getULY() - hRaster)) == ((int)ext.getLRY())) ? (uly - h) : (uly + h); 
446
                
447
                Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
448

    
449
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
450
                //por arriba el m?s alto y por abajo el menor y luego restandolos
451
                
452
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(ulx, uly));
453
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(lrx, lry));
454
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
455
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
456
                
457
                //Ajustamos por si nos hemos salido del raster
458
                while(((int)(p1.getX() + width)) > getWidth()[0])
459
                        width --;
460
                while(((int)(p1.getY() + height)) > getHeight()[0])
461
                        height --;
462
                
463
                if(p1.getX() < 0)
464
                        p1.setLocation(0, p1.getY());
465
                if(p1.getY() < 0)
466
                        p1.setLocation(p1.getX(), 0);
467
                if(p2.getX() > getWidth()[0])
468
                        p2.setLocation(getWidth()[0], p2.getY());
469
                if(p1.getY() > getHeight()[0])
470
                        p1.setLocation(p2.getX(), getHeight()[0]);
471
                
472
                int mallocNBands = 0;
473
                if(bandList.getDrawableBands() != null)
474
                        mallocNBands = bandList.getDrawableBands().length;
475
                else
476
                        mallocNBands = bandList.getDrawableBandsCount();
477
                
478
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
479
                
480
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
481
                if(!raster.isBandSwitchable()) {
482
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0)[0].getBandCount(), false);
483
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
484
                                try {
485
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0)[0].getFName(), selectedExtent);
486
                                } catch (FileNotExistsException e) {
487
                                        //Esto no debe darse ya que se comprueba al hacer el open
488
                                } catch (NotSupportedExtensionException e) {
489
                                        //Esto no debe darse ya que se comprueba al hacer el open
490
                                }
491
                                return rb;
492
                        }
493
                                
494
                }
495
                                        
496
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
497
                        raster.assignBandToNotValid(iBand);
498
                
499
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
500
                //m?s grande y salirse de los l?mites.
501
                if(!adjustToExtent)
502
                         initBufferToNoData(raster, bandList);
503
                
504
                //Reservamos memoria para los buffers por dataset
505
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
506
                
507
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor 
508
                //equivalente a los pixeles redondeados.
509
                Point2D wc1 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
510
                Point2D wc2 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
511
                for(int i = 0; i < getDatasetCount(); i++)
512
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), Math.abs(wc2.getX() - wc1.getX()), Math.abs(wc2.getY() - wc1.getY()), bandList, bufferDatasets[i], adjustToExtent);
513
                        //bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
514
                
515
                //Mezclamos los buffers de cada dataset en un solo buffer
516
                mergeBuffers(raster, bufferDatasets, bandList);
517
                                                        
518
                return raster;
519
        }
520
                
521
        /**
522
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
523
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
524
         * el driver.
525
         * @param minX Valor m?nimo de la X en coordenadas reales
526
         * @param minY Valor m?nimo de la Y en coordenadas reales
527
         * @param maxX Valor m?ximo de la X en coordenadas reales
528
         * @param maxY Valor m?ximo de la Y en coordenadas reales
529
         * @param bufWidth ancho del buffer lde datos
530
         * @param bufHeight alto del buffer de datos
531
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
532
         * @param bandList
533
         * @return Buffer de datos
534
         */
535
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, 
536
                                                                        int bufWidth, int bufHeight, boolean adjustToExtent) throws InvalidSetViewException {
537
                
538
                Point2D p1 = worldToRaster(new Point2D.Double(ulx, uly));
539
                Point2D p2 = worldToRaster(new Point2D.Double(lrx, lry));
540
                if(        ((int)p1.getX()) < 0 || ((int)p2.getX()) > getWidth()[0] ||
541
                                ((int)p2.getY()) > getHeight()[0] || ((int)p2.getY()) < 0)
542
                                throw new InvalidSetViewException("");
543
                
544
                int mallocNBands = 0;
545
                if(bandList.getDrawableBands() != null)
546
                        mallocNBands = bandList.getDrawableBands().length;
547
                else
548
                        mallocNBands = bandList.getDrawableBandsCount();
549
                
550
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
551
                
552
                //TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
553
                //Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
554
                /*if(!raster.isBandSwitchable()) {
555
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
556
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
557
                                try {
558
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
559
                                } catch (FileNotExistsException e) {
560
                                        //Esto no debe darse ya que se comprueba al hacer el open
561
                                } catch (NotSupportedExtensionException e) {
562
                                        //Esto no debe darse ya que se comprueba al hacer el open
563
                                }
564
                                return rb;
565
                        }
566
                }*/
567
                        
568
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
569
                        raster.assignBandToNotValid(iBand);
570
                
571
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
572
                //m?s grande y salirse de los l?mites.
573
                if(!adjustToExtent)
574
                         initBufferToNoData(raster, bandList);        
575
                
576
                //Reservamos memoria para los buffers por dataset
577
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
578
                for(int i = 0; i < getDatasetCount(); i++)
579
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(ulx, uly, lrx, lry, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
580
                
581
                //Mezclamos los buffers de cada dataset en un solo buffer
582
                mergeBuffers(raster, bufferDatasets, bandList);
583
                                                        
584
                return raster;
585
        }
586
        
587
        /**
588
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
589
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
590
         * pixeles de disco. 
591
         * @param x Posici?n X superior izquierda
592
         * @param y Posici?n Y superior izquierda
593
         * @param w Ancho en coordenadas pixel
594
         * @param h Alto en coordenadas pixel
595
         * @param bandList
596
         * @return Buffer de datos
597
         */
598
        public IBuffer getWindowRaster(int x, int y, int w, int h) throws InvalidSetViewException {
599
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
600
                        throw new InvalidSetViewException("Out of image");
601
                
602
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
603
                
604
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
605
                if(!raster.isBandSwitchable()) {
606
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], w, h, getDataset(0)[0].getBandCount(), false);
607
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
608
                                try {
609
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0)[0].getFName(), x, y, x + w, y + h);
610
                                } catch (FileNotExistsException e) {
611
                                        //Esto no debe darse ya que se comprueba al hacer el open
612
                                } catch (NotSupportedExtensionException e) {
613
                                        //Esto no debe darse ya que se comprueba al hacer el open
614
                                }
615
                                return rb;
616
                        }
617
                }
618
                                
619
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
620
                        raster.assignBandToNotValid(iBand);
621
                
622
                //Reservamos memoria para los buffers por dataset
623
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, w, h);
624
                for(int i = 0; i < getDatasetCount(); i++)
625
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i]);
626
                
627
                //Mezclamos los buffers de cada dataset en un solo buffer
628
                mergeBuffers(raster, bufferDatasets, bandList);
629
                                                        
630
                return raster;
631
        }
632
        
633
        /**
634
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
635
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer
636
         * @param x Posici?n X superior izquierda en pixels
637
         * @param y Posici?n Y superior izquierda en pixels
638
         * @param w Ancho en pixels
639
         * @param h Alto en pixels
640
         * @param bufWidth ancho del buffer de datos
641
         * @param bufHeight alto del buffer de datos
642
         * @param bandList
643
         * @return Buffer de datos
644
         */
645
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight)  
646
                throws InvalidSetViewException {
647
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
648
                        throw new InvalidSetViewException("Out of image");
649
                                
650
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
651
                        
652
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
653
                        raster.assignBandToNotValid(iBand);
654
                        
655
                //Reservamos memoria para los buffers por dataset
656
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
657
                
658
                //TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
659
                //Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
660
                /*if(!raster.isBandSwitchable()) {
661
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
662
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
663
                                try {
664
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
665
                                } catch (FileNotExistsException e) {
666
                                        //Esto no debe darse ya que se comprueba al hacer el open
667
                                } catch (NotSupportedExtensionException e) {
668
                                        //Esto no debe darse ya que se comprueba al hacer el open
669
                                }
670
                                return rb;
671
                        }
672
                }*/
673
                        
674
                for(int i = 0; i < getDatasetCount(); i++)
675
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bufWidth, bufHeight, bandList, bufferDatasets[i]);
676

    
677
                //Mezclamos los buffers de cada dataset en un solo buffer
678
                mergeBuffers(raster, bufferDatasets, bandList);
679
                                                        
680
                return raster;
681
        }
682
        
683
        //******************************
684
        //Setters and Getters
685
        //******************************
686
        
687
        /**
688
         * Calcula el tama?o de los ficheros en disco
689
         * @return tama?o en bytes de todos los ficheros de la lista
690
         */
691
        public long getFileSize() {
692
                int len = 0;
693
                for(int i = 0; i < files.size();i++) {
694
                        if(((RasterDataset)files.get(i)) != null) {
695
                                File f = new File(((RasterDataset)files.get(i)).getFName());
696
                                len += f.length();
697
                        }
698
                }
699
                return len;
700
        }
701
        
702
        /**
703
         * Obtiene la altura de la imagen a partir de la primera
704
         * @return altura
705
         */
706
        public double[] getHeight() {
707
                double[] lenghts = new double[getDatasetCount()];
708
                for(int i = 0; i < getDatasetCount(); i++)
709
                        if(((RasterDataset)files.get(i)) != null)
710
                                lenghts[i] = ((RasterDataset)files.get(i)).getHeight();
711
                return lenghts;
712
        }
713

    
714
        /**
715
         * Obtiene la anchura de la imagen a partir de la primera
716
         * @return anchura
717
         */
718
        public double[] getWidth() {
719
                double[] lenghts = new double[getDatasetCount()];
720
                for(int i = 0; i < getDatasetCount(); i++)
721
                        if(((RasterDataset)files.get(i)) != null)
722
                                lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
723
                return lenghts;        
724
        }
725
        
726
        /**
727
         * Obtiene el n?mero de bandas del fichero
728
         * @return
729
         */
730
        public int getBandCount() {
731
                return bandList.getBandCount();
732
        }
733

    
734
        /*
735
         * (non-Javadoc)
736
         * @see org.gvsig.raster.dataset.IRasterDataSource#getDataType()
737
         */
738
        public int[] getDataType() {
739
                int[] dt = new int[getDatasetCount()];
740
                for(int i=0;i<files.size();i++)
741
                        dt[i] = ((RasterDataset)files.get(i)).getDataType();
742
                                
743
            if(dt.length == 0)
744
                    return null;
745
            else
746
                    return dt;
747
        }
748
        
749
        /**
750
         * Obtiene fichero de la posici?n i. En un MultiRasterDataset el array devuelto ser? de 
751
         * un solo elemento por lo que solo tendr? sentido la posici?n 0.
752
         * @param i Posici?n del fichero a obtener.
753
         * @return GeoRasterFileDataset.
754
         */
755
        public RasterDataset[] getDataset(int i) {
756
                return new RasterDataset[]{(RasterDataset)files.get(i)};
757
        }
758
        
759
        /**
760
         * Obtiene fichero de nombre fileName.
761
         * @param i Posici?n del fichero a obtener.
762
         * @return GeoRasterFile.
763
         */
764
        public RasterDataset getDataset(String fileName) {
765
                for(int i=0;i<files.size();i++){
766
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
767
                                return (RasterDataset)files.get(i); 
768
                }
769
                return null;                
770
        }
771
        
772
        /**
773
         * Asigna el nombre al GeoRasterMultiFile
774
         * @param name Nombre del GeoRasterMultiFile
775
         */
776
        public void setName(String name) {
777
                this.name = name;
778
        }
779
        
780
        /**
781
         * Obtiene la lista de bandas
782
         * @return BandList
783
         */
784
        public BandList getBands() {
785
                return bandList;
786
        }
787
        
788
        /**
789
         * Obtiene la coordenada X m?nima de toda la lista
790
         * @return Coordenada X m?nima
791
         */
792
        public double getMinX() {
793
                double minx = Double.MAX_VALUE;
794
                for(int i = 0; i < files.size(); i++) {
795
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
796
                        if(aux < minx)
797
                                minx = aux;
798
                }
799
                return minx;
800
        }
801
        
802
        /**
803
         * Obtiene la coordenada Y m?nima de toda la lista
804
         * @return Coordenada Y m?nima
805
         */
806
        public double getMinY() {
807
                double miny = Double.MAX_VALUE;
808
                for(int i = 0; i < files.size(); i++) {
809
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
810
                        if(aux < miny)
811
                                miny = aux;
812
                }
813
                return miny;
814
        }
815
        
816
        /**
817
         * Obtiene la coordenada Y m?xima de toda la lista
818
         * @return Coordenada Y m?xima
819
         */
820
        public double getMaxX() {
821
                double maxx = Double.NEGATIVE_INFINITY;
822
                for(int i = 0; i < files.size(); i++) {
823
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
824
                        if(aux > maxx)
825
                                maxx = aux;
826
                }
827
                return maxx;
828
        }
829

    
830
        /**
831
         * Obtiene la coordenada Y m?xima de toda la lista
832
         * @return Coordenada Y m?xima
833
         */
834
        public double getMaxY() {
835
                double maxy = Double.NEGATIVE_INFINITY;
836
                for(int i = 0; i < files.size(); i++) {
837
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
838
                        if(aux > maxy)
839
                                maxy = aux;
840
                }
841
                return maxy;
842
        }
843
        
844
        /**
845
         * Obtiene el extent del multi fichero. Este corresponde al primer
846
         * GeoRasterFile de la lista.
847
         * @return Extent
848
         */
849
        public Extent getExtent() {
850
                if(files.size() == 0)
851
                        return null;
852
                else
853
                        return ((RasterDataset)files.get(0)).getExtent();
854
        }
855
        
856
        /**
857
     * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el 
858
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
859
     * pero para un raster rotado ser? igual al extent del raster como si no 
860
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
861
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
862
     * aplicado.
863
     * @return Extent
864
     */
865
    public Extent getExtentForRequest() {
866
        return ((RasterDataset)files.get(0)).getExtentWithoutRot();
867
    }
868
        
869
        /**
870
         * Obtiene las coordenadas del fichero worldFile (o cabecera del raster) asociado 
871
         * o el RMF en caso de que existan. Si la imagen no est? georreferenciada tendr?
872
         * las coordenadas pixel de la misma 
873
         * @return Array de seis valores:
874
         *         <TABLE BORDER="1">
875
         *         <TR><TD><B>0:</B></TD><TD>Valor X de la esquina superior izquierda.</TD></TR>
876
         *         <TR><TD><B>1:</B></TD><TD>Tama?o de pixel en X.</TD></TR>
877
         *         <TR><TD><B>2:</B></TD><TD>Shearing en X.</TD></TR>
878
         *         <TR><TD><B>3:</B></TD><TD>Valor Y de la esquina superior izquierda.</TD></TR>
879
         *         <TR><TD><B>4:</B></TD><TD>Shearing en Y.</TD></TR>
880
         *         <TR><TD><B>5:</B></TD><TD>Tama?o de pixel en Y.</TD></TR>
881
         *         </TABLE>
882
         */
883
        /*public AffineTransform getCoordsGeoTransformFile(){
884
                return ((RasterDataset)files.get(0)).getAffineTransform();
885
        }*/
886
        
887
        /*
888
         * (non-Javadoc)
889
         * @see org.gvsig.raster.dataset.IRasterDataSource#getLastSelectedView()
890
         */
891
        public Extent getLastSelectedView(){
892
                return ((RasterDataset)files.get(0)).getView();
893
        }
894
                
895
        /*
896
         * (non-Javadoc)
897
         * @see org.gvsig.raster.dataset.IRasterDataSource#getTransparencyFilesStatus()
898
         */
899
        public Transparency getTransparencyFilesStatus() {
900
                if(files.size() <= 0)
901
                        return null;
902
                Transparency t = ((RasterDataset)files.get(0)).getTransparencyDatasetStatus();
903
                for(int i = 1; i < files.size(); i++) {
904
                        Transparency t1 = ((RasterDataset)files.get(i)).getTransparencyDatasetStatus();
905
                        t.merge(t1);
906
                }
907
                return t;
908
        }
909
        
910
        /**
911
         * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
912
         * @param i Posici?n del raster
913
         * @return Paleta asociada a este o null si no tiene
914
         */
915
        public ColorTable getColorTable(int i){
916
                if(i >= files.size())
917
                        return null;
918
                return ((RasterDataset)files.get(i)).getColorTable();
919
        }
920
        
921
        /**
922
         * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
923
         * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
924
         * para ese fichero no hay paletas asociadas.
925
         */
926
        public ColorTable[] getColorTables(){
927
                if(files.size() <= 0)
928
                        return null;
929
                ColorTable[] list = new ColorTable[files.size()];
930
                for(int i = 0; i < files.size(); i++)
931
                        list[i] = ((RasterDataset)files.get(i)).getColorTable();
932
                return list;
933
        }
934
        
935
        /**
936
         * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro. 
937
         * @param fileName Nombre del fichero
938
         * @return Paleta o null si no la tiene
939
         */
940
        public ColorTable getColorTable(String fileName){
941
                for(int i = 0; i < files.size(); i++){
942
                        if(((RasterDataset)files.get(i)).getFName().indexOf(fileName) == 0)
943
                                return ((RasterDataset)files.get(i)).getColorTable();
944
                }
945
                return null;
946
        }
947
        
948
        /*
949
         * (non-Javadoc)
950
         * @see org.gvsig.raster.dataset.IRasterDataSource#rasterToWorld(java.awt.geom.Point2D)
951
         */
952
        public Point2D rasterToWorld(Point2D pt) {
953
                return ((RasterDataset)files.get(0)).rasterToWorld(pt);
954
        }
955
        
956
        /*
957
         * (non-Javadoc)
958
         * @see org.gvsig.raster.dataset.IRasterDataSource#worldToRaster(java.awt.geom.Point2D)
959
         */
960
        public Point2D worldToRaster(Point2D pt) {
961
                return ((RasterDataset)files.get(0)).worldToRaster(pt);
962
        }
963
        
964
        /*
965
         * (non-Javadoc)
966
         * @see org.gvsig.raster.dataset.IRasterDataSource#calcSteps(double, double, double, double, double, double, int, int)
967
         */
968
        public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
969
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
970
                return ((RasterDataset)files.get(0)).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
971
        }
972
        
973
        /**
974
         * Obtiene el objeto con las estadisticas
975
         * @return MultiFileStatistics
976
         */
977
        public DatasetListStatistics getStatistics(){
978
                return stats;
979
        }
980
        
981
        /*
982
         * (non-Javadoc)
983
         * @see org.gvsig.raster.dataset.IRasterDataSource#isGeoreferenced()
984
         */
985
        public boolean isGeoreferenced() {
986
                for(int i = 0; i < files.size(); i++){
987
                        if(((RasterDataset)files.get(i)).isGeoreferenced())
988
                                return true;
989
                }
990
                return false;
991
        }
992

    
993
        //TODO: TEST: Probar getData para multifichero
994

    
995
        /*
996
         * (non-Javadoc)
997
         * @see org.gvsig.raster.dataset.IRasterDataSource#getData(int, int, int)
998
         */
999
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
1000
                String file = bandList.getBand(band).getFileName();
1001
                for(int i = 0; i < files.size(); i++){
1002
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
1003
                                return ((RasterDataset)files.get(i)).getData(x, y, band); 
1004
                }
1005
                return null;
1006
        }
1007
                
1008
        /**
1009
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
1010
         * color por banda para el dataset seleccionado
1011
         * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
1012
         * @return DatasetColorInterpretation
1013
         */
1014
        public DatasetColorInterpretation getColorInterpretation(int dataset){
1015
                return ((RasterDataset)files.get(dataset)).getColorInterpretation();
1016
        }
1017
        
1018
        /**
1019
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
1020
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
1021
         * dataset.
1022
         * @return Proyecci?n en formato cadena
1023
         * @throws RasterDriverException
1024
         */
1025
        public String getWktProjection() throws RasterDriverException {
1026
                return ((RasterDataset)files.get(0)).getWktProjection();
1027
        }
1028

    
1029
        /*
1030
         * (non-Javadoc)
1031
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
1032
         */
1033
        public Histogram getHistogram() throws HistogramException {
1034
                if (histogram == null)
1035
                        histogram = new DatasetListHistogram(this);
1036
                
1037
                try {
1038
                        Histogram tmpHist = histogram.getHistogram();
1039
                        return tmpHist;
1040
                } catch (FileNotOpenException e) {
1041
                        throw new HistogramException("FileNotOpenException");
1042
                } catch (RasterDriverException e) {
1043
                        throw new HistogramException("RasterDriverException");
1044
                }
1045
        }
1046

    
1047
        /*
1048
         * (non-Javadoc)
1049
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
1050
         */
1051
        public int getPercent() {
1052
                if (histogram != null) return histogram.getPercent();
1053
                return 0;
1054
        }
1055
        
1056
        
1057
        /*
1058
         * (non-Javadoc)
1059
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
1060
         */
1061
        public void resetPercent() {
1062
                if (histogram != null) histogram.resetPercent();
1063
        }
1064

    
1065
        /*
1066
         * (non-Javadoc)
1067
         * @see org.gvsig.raster.util.ICancellable#isCanceled()
1068
         */
1069
        public boolean isCanceled(int process) {
1070
                if(process == CANCEL_HISTOGRAM) {
1071
                        if (histogram != null) 
1072
                                return histogram.isCanceled(0);
1073
                }
1074
                return false;
1075
        }
1076

    
1077
        /*
1078
         * (non-Javadoc)
1079
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
1080
         */
1081
        public void setCanceled(boolean value, int process) {
1082
                if(process == CANCEL_HISTOGRAM || process == 0) 
1083
                        if (histogram != null) 
1084
                                histogram.setCanceled(value, 0);
1085
                        
1086
        }
1087
        
1088
        /**
1089
         * Escribe sobre el rmf todos los cambios que haya para salvar, es decir, para cada
1090
         * Objeto registrado en el manager volcar? su contenido al fichero rmf.
1091
         * @throws IOException
1092
         */
1093
        public void saveRmfModification() throws IOException {
1094
                for (int i = 0; i < files.size(); i++) 
1095
                        ((RasterDataset)files.get(i)).saveRmfModification();
1096
        }
1097
        
1098
        /**
1099
         * Salva la georreferenciaci?n a fichero rmf.
1100
         * @param fName
1101
         * @throws IOException  
1102
         */
1103
        public void saveGeoToRmf() throws IOException {
1104
                for (int i = 0; i < files.size(); i++) 
1105
                        ((RasterDataset)files.get(i)).saveGeoToRmf();
1106
        }
1107
        
1108
        /**
1109
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa 
1110
         * o fuera de ellos.
1111
         * @param p Punto a calcular
1112
         * @return true si est? dentro de los l?mites y false si est? fuera
1113
         */
1114
        public boolean isInside(Point2D p) {
1115
                if(getDataset(0) != null)
1116
                        return getDataset(0)[0].isInside(p);
1117
                return false;
1118
        }
1119
        
1120
        /*
1121
         * (non-Javadoc)
1122
         * @see org.gvsig.raster.dataset.IRasterDataSource#getAffineTransform()
1123
         */
1124
        public AffineTransform getAffineTransform(){
1125
                if(getDataset(0) != null)
1126
                        return getDataset(0)[0].getAffineTransform();
1127
                return null;
1128
        }
1129
        
1130
        /*
1131
         * (non-Javadoc)
1132
         * @see org.gvsig.raster.dataset.IRasterDataSource#setAffineTransform(java.awt.geom.AffineTransform)
1133
         */
1134
        public void setAffineTransform(AffineTransform transf){
1135
                for (int i = 0; i < getDatasetCount(); i++) {
1136
                        this.getDataset(i)[0].setAffineTransform(transf);        
1137
                }
1138
        }
1139
        
1140
        /**
1141
         * Obtiene la matriz de transformaci?n del propio raster. Esta matriz es la encargada
1142
         * de convertir las coordenadas de la petici?n en coordenadas a las que se pide a la libreria.
1143
         * En gdal, por ejemplo, se piden las coordenadas a la libreria en coordenadas pixel por lo que
1144
         * esta matriz tendr? la georreferenciaci?n asociada en el worldfile o cabecera. Otras librerias como
1145
         * ermapper la petici?n a la libreria se hace en coordenadas geograficas que son las mismas en las
1146
         * que pide el usuario de gvSIG por lo que esta matriz en este caso se inicializa con la identidad. 
1147
         * @return
1148
         */
1149
        public AffineTransform getOwnTransformation() {
1150
                if(getDataset(0) != null)
1151
                        return getDataset(0)[0].getOwnTransformation();
1152
                return new AffineTransform();
1153
        } 
1154

    
1155
        /*
1156
         * (non-Javadoc)
1157
         * @see org.gvsig.raster.dataset.IRasterDataSource#isRotated()
1158
         */
1159
        public boolean isRotated() {
1160
                if(getDataset(0) != null)
1161
                        return getDataset(0)[0].isRotated();
1162
                return false;
1163
        }
1164
}