Statistics
| Revision:

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

History | View | Annotate | Download (45.8 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.RasterLibrary;
29
import org.gvsig.raster.buffer.RasterBuffer;
30
import org.gvsig.raster.buffer.cache.RasterReadOnlyBuffer;
31
import org.gvsig.raster.dataset.io.RasterDriverException;
32
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
33
import org.gvsig.raster.dataset.properties.DatasetListHistogram;
34
import org.gvsig.raster.dataset.properties.DatasetListStatistics;
35
import org.gvsig.raster.datastruct.ColorTable;
36
import org.gvsig.raster.datastruct.Extent;
37
import org.gvsig.raster.datastruct.GeoPoint;
38
import org.gvsig.raster.datastruct.Histogram;
39
import org.gvsig.raster.datastruct.HistogramException;
40
import org.gvsig.raster.datastruct.Transparency;
41

    
42
/**
43
 * Clase que representa una imagen de raster georreferenciada formada por varias
44
 * imagenes de disco que tienen la misma extensi?n. Contiene funcionalidades
45
 * para abrir ficheros, gestionar el extent, pintar el raster sobre un DataImage
46
 * con su gesti?n de bandas correspondiente.
47
 * 
48
 * @author Nacho Brodin (nachobrodin@gmail.com)
49
 */
50
public class MultiRasterDataset implements IRasterDataSource {
51
        // File list
52
        private ArrayList               files         = new ArrayList();
53

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

    
357
        /**
358
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
359
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
360
         * pixeles de disco. 
361
         * @param x Posici?n X superior izquierda
362
         * @param y Posici?n Y superior izquierda
363
         * @param w Ancho en coordenadas reales
364
         * @param h Alto en coordenadas reales
365
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
366
         * @param bandList
367
         * @return Buffer de datos
368
         */
369
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry) 
370
                throws InvalidSetViewException, InterruptedException, RasterDriverException {                
371
                //Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
372

    
373
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
374
                //por arriba el m?s alto y por abajo el menor y luego restandolos
375
                
376
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(ulx, uly));
377
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(lrx, lry));
378

    
379
                //Para el valor mayor redondeamos por arriba. Para el valor menor redondeamos por abajo.
380
                double p1X = (p1.getX() > p2.getX()) ? Math.ceil(p1.getX()) : Math.floor(p1.getX());
381
                double p1Y = (p1.getY() > p2.getY()) ? Math.ceil(p1.getY()) : Math.floor(p1.getY());
382
                double p2X = (p2.getX() > p1.getX()) ? Math.ceil(p2.getX()) : Math.floor(p2.getX());
383
                double p2Y = (p2.getY() > p1.getY()) ? Math.ceil(p2.getY()) : Math.floor(p2.getY());
384
                
385
                int width = (int)Math.abs(p1X - p2X); 
386
                int height = (int)Math.abs(p1Y - p2Y);
387
                
388
                //Ajustamos por si nos hemos salido del raster
389
                while(((int)(p1X + width)) > getWidth())
390
                        width --;
391
                while(((int)(p1Y + height)) > getHeight())
392
                        height --;
393
                
394
                if (p1X < 0)
395
                        p1X = 0;
396
                if (p1Y < 0)
397
                        p1Y = 0;
398
                if (p2X > getWidth())
399
                        p2X = getWidth();
400
                if (p2Y > getHeight())
401
                        p2Y = getHeight();
402

    
403
                int mallocNBands = 0;
404
                if(bandList.getDrawableBands() != null)
405
                        mallocNBands = bandList.getDrawableBands().length;
406
                else
407
                        mallocNBands = bandList.getDrawableBandsCount();
408
                
409
                //Buffer ReadOnly
410
                
411
                if(isReadOnly()) {
412
                        RasterBuffer rb = RasterBuffer.getReadOnlyBuffer(getDataType()[0], width, height, getBandCount());
413
                        if(rb instanceof RasterReadOnlyBuffer) {
414
                                try {
415
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, (int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY(), bandList);
416
                                } catch (FileNotExistsException e) {
417
                                        //Esto no debe darse ya que se comprueba al hacer el open.
418
                                        return null;
419
                                } catch (NotSupportedExtensionException e) {
420
                                        //Esto no debe darse ya que se comprueba al hacer el open
421
                                        return null;
422
                                }
423
                                return rb;
424
                        }
425
                }
426
                
427
                //Buffer RW
428
                
429
                IBuffer raster = null;
430
                if(forceToMemory) //Fuerza siempre buffer en memoria
431
                        raster = RasterBuffer.getMemoryBuffer(getDataType()[0], width, height, mallocNBands, false);
432
                else
433
                        raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
434
                                                        
435
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
436
                        raster.assignBandToNotValid(iBand);
437
                
438
                //Reservamos memoria para los buffers por dataset
439
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
440
                
441
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor 
442
                //equivalente a los pixeles redondeados.
443
                Point2D wc1 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(p1X, p1Y));
444
                Point2D wc2 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(p2X, p2Y));
445
                for(int i = 0; i < getDatasetCount(); i++)
446
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), wc2.getX(), wc2.getY(), bandList, bufferDatasets[i]);
447
                
448
                //Mezclamos los buffers de cada dataset en un solo buffer
449
                mergeBuffers(raster, bufferDatasets, bandList);
450
                                                        
451
                return raster;
452
        }
453
        
454
        /**
455
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
456
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
457
         * pixeles de disco. 
458
         * @param x Posici?n X superior izquierda
459
         * @param y Posici?n Y superior izquierda
460
         * @param w Ancho en coordenadas reales
461
         * @param h Alto en coordenadas reales
462
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
463
         * @param bandList
464
         * @return Buffer de datos
465
         */
466
        public IBuffer getWindowRaster(double ulx, double uly, double w, double h, boolean adjustToExtent) 
467
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
468
                //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
469
                //tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o y - h 
470
                Extent ext = getExtent();
471
                Point2D pInit = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(0, 0));
472
                Point2D pEnd = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double((int)getWidth(), (int)getHeight()));
473
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
474
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
475
                double lrx = (((int)(ext.getULX() - wRaster)) == ((int)ext.getLRX())) ? (ulx - w) : (ulx + w);
476
                double lry = (((int)(ext.getULY() - hRaster)) == ((int)ext.getLRY())) ? (uly - h) : (uly + h); 
477
                
478
                //Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
479

    
480
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
481
                //por arriba el m?s alto y por abajo el menor y luego restandolos
482
                
483
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(ulx, uly));
484
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(lrx, lry));
485
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
486
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
487
                
488
                //Ajustamos por si nos hemos salido del raster
489
                while(((int)(p1.getX() + width)) > getWidth())
490
                        width --;
491
                while(((int)(p1.getY() + height)) > getHeight())
492
                        height --;
493
                
494
                if (p1.getX() < 0)
495
                        p1.setLocation(0, p1.getY());
496
                if (p1.getY() < 0)
497
                        p1.setLocation(p1.getX(), 0);
498
                if (p2.getX() > getWidth())
499
                        p2.setLocation(getWidth(), p2.getY());
500
                if (p2.getY() > getHeight())
501
                        p2.setLocation(p2.getX(), getHeight());
502
                
503
                int mallocNBands = 0;
504
                if(bandList.getDrawableBands() != null)
505
                        mallocNBands = bandList.getDrawableBands().length;
506
                else
507
                        mallocNBands = bandList.getDrawableBandsCount();
508
                
509
                //Buffer ReadOnly
510
                
511
                if(isReadOnly()) {
512
                        RasterBuffer rb = RasterBuffer.getReadOnlyBuffer(getDataType()[0], width, height, getBandCount());
513
                        if(rb instanceof RasterReadOnlyBuffer) {
514
                                try {
515
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, (int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY(), bandList);
516
                                } catch (FileNotExistsException e) {
517
                                        //Esto no debe darse ya que se comprueba al hacer el open.
518
                                        return null;
519
                                } catch (NotSupportedExtensionException e) {
520
                                        //Esto no debe darse ya que se comprueba al hacer el open
521
                                        return null;
522
                                }
523
                                return rb;
524
                        }
525
                }
526
                
527
                //Buffer RW
528
                
529
                IBuffer raster = null;
530
                if(forceToMemory) //Fuerza siempre buffer en memoria
531
                        raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
532
                else
533
                        raster = RasterBuffer.getMemoryBuffer(getDataType()[0], width, height, mallocNBands, false);
534
                                                        
535
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
536
                        raster.assignBandToNotValid(iBand);
537
                
538
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
539
                //m?s grande y salirse de los l?mites.
540
                if(!adjustToExtent)
541
                         initBufferToNoData(raster, bandList);
542
                
543
                //Reservamos memoria para los buffers por dataset
544
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
545
                
546
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor 
547
                //equivalente a los pixeles redondeados.
548
                Point2D wc1 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
549
                Point2D wc2 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
550
                for(int i = 0; i < getDatasetCount(); i++)
551
                        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);
552
                        //bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
553
                
554
                //Mezclamos los buffers de cada dataset en un solo buffer
555
                mergeBuffers(raster, bufferDatasets, bandList);
556
                                                        
557
                return raster;
558
        }
559
                
560
        /**
561
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
562
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
563
         * el driver.
564
         * @param minX Valor m?nimo de la X en coordenadas reales
565
         * @param minY Valor m?nimo de la Y en coordenadas reales
566
         * @param maxX Valor m?ximo de la X en coordenadas reales
567
         * @param maxY Valor m?ximo de la Y en coordenadas reales
568
         * @param bufWidth ancho del buffer lde datos
569
         * @param bufHeight alto del buffer de datos
570
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
571
         * @param bandList
572
         * @return Buffer de datos
573
         */
574
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, int bufWidth, int bufHeight, boolean adjustToExtent) 
575
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
576
                
577
                Point2D p1 = worldToRaster(new Point2D.Double(ulx, uly));
578
                Point2D p2 = worldToRaster(new Point2D.Double(lrx, lry));
579
                if(        ((int)p1.getX()) < 0 || ((int)p2.getX()) > getWidth() ||
580
                                ((int)p2.getY()) > getHeight() || ((int)p2.getY()) < 0)
581
                                throw new InvalidSetViewException("");
582
                
583
                int mallocNBands = 0;
584
                if(bandList.getDrawableBands() != null)
585
                        mallocNBands = bandList.getDrawableBands().length;
586
                else
587
                        mallocNBands = bandList.getDrawableBandsCount();
588
                
589
                //Buffer ReadOnly
590
                
591
                if(isReadOnly()) {
592
                        RasterBuffer rb = RasterBuffer.getReadOnlyBuffer(getDataType()[0], bufWidth, bufHeight, getBandCount());
593
                        if(rb instanceof RasterReadOnlyBuffer) {
594
                                try {
595
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, (int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY(), bandList);
596
                                } catch (FileNotExistsException e) {
597
                                        //Esto no debe darse ya que se comprueba al hacer el open.
598
                                        return null;
599
                                } catch (NotSupportedExtensionException e) {
600
                                        //Esto no debe darse ya que se comprueba al hacer el open
601
                                        return null;
602
                                }
603
                                return rb;
604
                        }
605
                }
606
                
607
                //Buffer RW
608
                
609
                IBuffer raster = null;
610
                if(forceToMemory) //Fuerza siempre buffer en memoria
611
                        raster = RasterBuffer.getMemoryBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
612
                else
613
                        raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
614
                                        
615
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
616
                        raster.assignBandToNotValid(iBand);
617
                
618
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
619
                //m?s grande y salirse de los l?mites.
620
                if(!adjustToExtent)
621
                         initBufferToNoData(raster, bandList);        
622
                
623
                //Reservamos memoria para los buffers por dataset
624
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
625
                for(int i = 0; i < getDatasetCount(); i++)
626
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(ulx, uly, lrx, lry, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
627
                
628
                //Mezclamos los buffers de cada dataset en un solo buffer
629
                mergeBuffers(raster, bufferDatasets, bandList);
630
                                                        
631
                return raster;
632
        }
633
        
634
        /**
635
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
636
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
637
         * pixeles de disco. 
638
         * @param x Posici?n X superior izquierda
639
         * @param y Posici?n Y superior izquierda
640
         * @param w Ancho en coordenadas pixel
641
         * @param h Alto en coordenadas pixel
642
         * @param bandList
643
         * @return Buffer de datos
644
         */
645
        public IBuffer getWindowRaster(int x, int y, int w, int h) 
646
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
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
                //Buffer ReadOnly
651
                
652
                if(isReadOnly()) {
653
                        RasterBuffer rb = RasterBuffer.getReadOnlyBuffer(getDataType()[0], w, h, getBandCount());
654
                        if(rb instanceof RasterReadOnlyBuffer) {
655
                                try {
656
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, x, y, x + w, y + h, bandList);
657
                                } catch (FileNotExistsException e) {
658
                                        //Esto no debe darse ya que se comprueba al hacer el open.
659
                                        return null;
660
                                } catch (NotSupportedExtensionException e) {
661
                                        //Esto no debe darse ya que se comprueba al hacer el open
662
                                        return null;
663
                                }
664
                                return rb;
665
                        }
666
                }
667
                
668
                //Buffer RW
669
                
670
                IBuffer raster = null;
671
                if(forceToMemory) //Fuerza siempre buffer en memoria
672
                        raster = RasterBuffer.getMemoryBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
673
                else
674
                        raster = RasterBuffer.getBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
675
                
676
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
677
                        raster.assignBandToNotValid(iBand);
678
                
679
                //Reservamos memoria para los buffers por dataset
680
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, w, h);
681
                for(int i = 0; i < getDatasetCount(); i++)
682
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i]);
683
                
684
                //Mezclamos los buffers de cada dataset en un solo buffer
685
                mergeBuffers(raster, bufferDatasets, bandList);
686
                                                        
687
                return raster;
688
        }
689
        
690
        /**
691
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
692
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer
693
         * @param x Posici?n X superior izquierda en pixels
694
         * @param y Posici?n Y superior izquierda en pixels
695
         * @param w Ancho en pixels
696
         * @param h Alto en pixels
697
         * @param bufWidth ancho del buffer de datos
698
         * @param bufHeight alto del buffer de datos
699
         * @param bandList
700
         * @return Buffer de datos
701
         */
702
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight)  
703
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
704
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
705
                        throw new InvalidSetViewException("Out of image");
706
                
707
                //Buffer ReadOnly
708
                
709
                if(isReadOnly()) {
710
                        RasterBuffer rb = RasterBuffer.getReadOnlyBuffer(getDataType()[0], bufWidth, bufHeight, getBandCount());
711
                        if(rb instanceof RasterReadOnlyBuffer) {
712
                                try {
713
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, x, y, x + w, y + h, bandList);
714
                                } catch (FileNotExistsException e) {
715
                                        //Esto no debe darse ya que se comprueba al hacer el open.
716
                                        return null;
717
                                } catch (NotSupportedExtensionException e) {
718
                                        //Esto no debe darse ya que se comprueba al hacer el open
719
                                        return null;
720
                                }
721
                                return rb;
722
                        }
723
                }
724
                
725
                IBuffer raster = null;
726
                if(forceToMemory) //Fuerza siempre buffer en memoria
727
                        raster = RasterBuffer.getMemoryBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
728
                else
729
                        raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
730
                        
731
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
732
                        raster.assignBandToNotValid(iBand);
733
                        
734
                //Reservamos memoria para los buffers por dataset
735
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
736
                                        
737
                for(int i = 0; i < getDatasetCount(); i++)
738
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bufWidth, bufHeight, bandList, bufferDatasets[i]);
739

    
740
                //Mezclamos los buffers de cada dataset en un solo buffer
741
                mergeBuffers(raster, bufferDatasets, bandList);
742
                                                        
743
                return raster;
744
        }
745
        
746
        //******************************
747
        //Setters and Getters
748
        //******************************
749
        
750
        /**
751
         * Calcula el tama?o de los ficheros en disco
752
         * @return tama?o en bytes de todos los ficheros de la lista
753
         */
754
        public long getFileSize() {
755
                int len = 0;
756
                for(int i = 0; i < files.size();i++) {
757
                        if(((RasterDataset)files.get(i)) != null) {
758
                                File f = new File(((RasterDataset)files.get(i)).getFName());
759
                                len += f.length();
760
                        }
761
                }
762
                return len;
763
        }
764
        
765
        /*
766
         * (non-Javadoc)
767
         * @see org.gvsig.raster.dataset.IRasterDataSource#getHeight()
768
         */
769
        public double getHeight() {
770
                double[] lenghts = new double[getDatasetCount()];
771
                for(int i = 0; i < getDatasetCount(); i++)
772
                        if(((RasterDataset)files.get(i)) != null)
773
                                lenghts[i] = ((RasterDataset)files.get(i)).getHeight();
774
                return lenghts[0];
775
        }
776

    
777
        /*
778
         * (non-Javadoc)
779
         * @see org.gvsig.raster.dataset.IRasterDataSource#getWidth()
780
         */
781
        public double getWidth() {
782
                double[] lenghts = new double[getDatasetCount()];
783
                for(int i = 0; i < getDatasetCount(); i++)
784
                        if(((RasterDataset)files.get(i)) != null)
785
                                lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
786
                return lenghts[0];        
787
        }
788
        
789
        /*
790
         * (non-Javadoc)
791
         * @see org.gvsig.raster.dataset.IRasterDataSource#getCellSize()
792
         */
793
        public double getCellSize() {
794
                try {
795
                        Extent e = getExtent();
796
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
797
                        return dCellsize;
798
                } catch (NullPointerException e) {
799
                        return 1;
800
                }
801
        }
802
        
803
        /*
804
         * (non-Javadoc)
805
         * @see org.gvsig.raster.dataset.IRasterDataSource#getBandCount()
806
         */
807
        public int getBandCount() {
808
                return bandList.getBandCount();
809
        }
810

    
811
        /*
812
         * (non-Javadoc)
813
         * @see org.gvsig.raster.dataset.IRasterDataSource#getDataType()
814
         */
815
        public int[] getDataType() {
816
                int[] dt = new int[getBandCount()];
817

    
818
                if (dt.length == 0)
819
                        return null;
820

    
821
                int k = 0;
822
                for(int i = 0; i < files.size(); i++) {
823
                        int[] types = ((RasterDataset)files.get(i)).getDataType();
824
                        for (int j = 0; j < types.length; j++) {
825
                                dt[k] = types[j];
826
                                k ++;
827
                        }
828
                }
829
                                
830
                return dt;
831
        }
832
        
833
        /**
834
         * Obtiene fichero de la posici?n i. En un MultiRasterDataset el array devuelto ser? de 
835
         * un solo elemento por lo que solo tendr? sentido la posici?n 0.
836
         * @param i Posici?n del fichero a obtener.
837
         * @return GeoRasterFileDataset.
838
         */
839
        public RasterDataset[] getDataset(int i) {
840
                return new RasterDataset[]{(RasterDataset)files.get(i)};
841
        }
842
        
843
        /**
844
         * Obtiene fichero de nombre fileName.
845
         * @param i Posici?n del fichero a obtener.
846
         * @return GeoRasterFile.
847
         */
848
        public RasterDataset getDataset(String fileName) {
849
                for(int i=0;i<files.size();i++){
850
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
851
                                return (RasterDataset)files.get(i); 
852
                }
853
                return null;                
854
        }
855
                
856
        /**
857
         * Obtiene la lista de bandas
858
         * @return BandList
859
         */
860
        public BandList getBands() {
861
                return bandList;
862
        }
863
        
864
        /**
865
         * Obtiene la coordenada X m?nima de toda la lista
866
         * @return Coordenada X m?nima
867
         */
868
        public double getMinX() {
869
                double minx = Double.MAX_VALUE;
870
                for(int i = 0; i < files.size(); i++) {
871
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
872
                        if(aux < minx)
873
                                minx = aux;
874
                }
875
                return minx;
876
        }
877
        
878
        /**
879
         * Obtiene la coordenada Y m?nima de toda la lista
880
         * @return Coordenada Y m?nima
881
         */
882
        public double getMinY() {
883
                double miny = Double.MAX_VALUE;
884
                for(int i = 0; i < files.size(); i++) {
885
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
886
                        if(aux < miny)
887
                                miny = aux;
888
                }
889
                return miny;
890
        }
891
        
892
        /**
893
         * Obtiene la coordenada Y m?xima de toda la lista
894
         * @return Coordenada Y m?xima
895
         */
896
        public double getMaxX() {
897
                double maxx = Double.NEGATIVE_INFINITY;
898
                for(int i = 0; i < files.size(); i++) {
899
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
900
                        if(aux > maxx)
901
                                maxx = aux;
902
                }
903
                return maxx;
904
        }
905

    
906
        /**
907
         * Obtiene la coordenada Y m?xima de toda la lista
908
         * @return Coordenada Y m?xima
909
         */
910
        public double getMaxY() {
911
                double maxy = Double.NEGATIVE_INFINITY;
912
                for(int i = 0; i < files.size(); i++) {
913
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
914
                        if(aux > maxy)
915
                                maxy = aux;
916
                }
917
                return maxy;
918
        }
919

    
920
        /*
921
         * (non-Javadoc)
922
         * @see org.gvsig.raster.dataset.IRasterDataSource#getNoDataValue()
923
         */
924
        public double getNoDataValue() {
925
                if (files.isEmpty())
926
                        return RasterLibrary.defaultNoDataValue;
927

    
928
                return ((RasterDataset) files.get(0)).getNoDataValue();
929
        }
930

    
931
        /*
932
         * (non-Javadoc)
933
         * @see org.gvsig.raster.dataset.IRasterDataSource#isNoDataEnabled()
934
         */
935
        public boolean isNoDataEnabled() {
936
                if (files.isEmpty())
937
                        return false;
938

    
939
                return ((RasterDataset) files.get(0)).isNoDataEnabled();
940
        }
941

    
942
        /*
943
         * (non-Javadoc)
944
         * @see org.gvsig.raster.dataset.IRasterDataSource#resetNoDataValue()
945
         */
946
        public void resetNoDataValue() {
947
                for (int i = 0; i < files.size(); i++)
948
                        ((RasterDataset) files.get(i)).resetNoDataValue();
949
        }
950

    
951
        /*
952
         * (non-Javadoc)
953
         * @see org.gvsig.raster.dataset.IRasterDataSource#setNoDataValue(double)
954
         */
955
        public void setNoDataValue(double value) {
956
                for (int i = 0; i < files.size(); i++)
957
                        ((RasterDataset) files.get(i)).setNoDataValue(value);
958
        }
959

    
960
        /*
961
         * (non-Javadoc)
962
         * @see org.gvsig.raster.dataset.IRasterDataSource#setNoDataEnabled(boolean)
963
         */
964
        public void setNoDataEnabled(boolean enabled) {
965
                for (int i = 0; i < files.size(); i++)
966
                        ((RasterDataset) files.get(i)).setNoDataEnabled(enabled);
967
        }
968

    
969
        /**
970
         * Obtiene el extent del multi fichero. Este corresponde al primer
971
         * GeoRasterFile de la lista.
972
         * @return Extent
973
         */
974
        public Extent getExtent() {
975
                if(files.size() == 0)
976
                        return null;
977
                else
978
                        return ((RasterDataset)files.get(0)).getExtent();
979
        }
980
        
981
        /**
982
                 * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el 
983
                 * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
984
                 * pero para un raster rotado ser? igual al extent del raster como si no 
985
                 * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
986
                 * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
987
                 * aplicado.
988
                 * @return Extent
989
                 */
990
                public Extent getExtentForRequest() {
991
                                return ((RasterDataset)files.get(0)).getExtentWithoutRot();
992
                }
993
        
994
        /*
995
         * (non-Javadoc)
996
         * @see org.gvsig.raster.dataset.IRasterDataSource#getLastSelectedView()
997
         */
998
        public Extent getLastSelectedView(){
999
                return ((RasterDataset)files.get(0)).getView();
1000
        }
1001
                
1002
        /*
1003
         * (non-Javadoc)
1004
         * @see org.gvsig.raster.dataset.IRasterDataSource#getTransparencyFilesStatus()
1005
         */
1006
        public Transparency getTransparencyFilesStatus() {
1007
                if(files.size() <= 0)
1008
                        return null;
1009
                Transparency t = ((RasterDataset)files.get(0)).getTransparencyDatasetStatus();
1010
                for(int i = 1; i < files.size(); i++) {
1011
                        Transparency t1 = ((RasterDataset)files.get(i)).getTransparencyDatasetStatus();
1012
                        t.merge(t1);
1013
                }
1014
                return t;
1015
        }
1016
        
1017
        /**
1018
         * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
1019
         * @param i Posici?n del raster
1020
         * @return Paleta asociada a este o null si no tiene
1021
         */
1022
        public ColorTable getColorTable(int i){
1023
                if(i >= files.size())
1024
                        return null;
1025
                return ((RasterDataset)files.get(i)).getColorTable();
1026
        }
1027
        
1028
        /**
1029
         * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
1030
         * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
1031
         * para ese fichero no hay paletas asociadas.
1032
         */
1033
        public ColorTable[] getColorTables(){
1034
                if(files.size() <= 0)
1035
                        return null;
1036
                ColorTable[] list = new ColorTable[files.size()];
1037
                for(int i = 0; i < files.size(); i++)
1038
                        list[i] = ((RasterDataset)files.get(i)).getColorTable();
1039
                return list;
1040
        }
1041
        
1042
        /**
1043
         * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro. 
1044
         * @param fileName Nombre del fichero
1045
         * @return Paleta o null si no la tiene
1046
         */
1047
        public ColorTable getColorTable(String fileName){
1048
                for(int i = 0; i < files.size(); i++){
1049
                        if(((RasterDataset)files.get(i)).getFName().indexOf(fileName) == 0)
1050
                                return ((RasterDataset)files.get(i)).getColorTable();
1051
                }
1052
                return null;
1053
        }
1054
        
1055
        /*
1056
         * (non-Javadoc)
1057
         * @see org.gvsig.raster.dataset.IRasterDataSource#rasterToWorld(java.awt.geom.Point2D)
1058
         */
1059
        public Point2D rasterToWorld(Point2D pt) {
1060
                return ((RasterDataset)files.get(0)).rasterToWorld(pt);
1061
        }
1062
        
1063
        /*
1064
         * (non-Javadoc)
1065
         * @see org.gvsig.raster.dataset.IRasterDataSource#worldToRaster(java.awt.geom.Point2D)
1066
         */
1067
        public Point2D worldToRaster(Point2D pt) {
1068
                return ((RasterDataset)files.get(0)).worldToRaster(pt);
1069
        }
1070
        
1071
        /*
1072
         * (non-Javadoc)
1073
         * @see org.gvsig.raster.dataset.IRasterDataSource#calcSteps(double, double, double, double, double, double, int, int)
1074
         */
1075
        public double[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
1076
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
1077
                return ((RasterDataset)files.get(0)).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
1078
        }
1079
        
1080
        /**
1081
         * Obtiene el objeto con las estadisticas
1082
         * @return MultiFileStatistics
1083
         */
1084
        public DatasetListStatistics getStatistics(){
1085
                return stats;
1086
        }
1087
        
1088
        /*
1089
         * (non-Javadoc)
1090
         * @see org.gvsig.raster.dataset.IRasterDataSource#isGeoreferenced()
1091
         */
1092
        public boolean isGeoreferenced() {
1093
                for(int i = 0; i < files.size(); i++){
1094
                        if(((RasterDataset)files.get(i)).isGeoreferenced())
1095
                                return true;
1096
                }
1097
                return false;
1098
        }
1099
        
1100
        /**
1101
         * Obtiene el tama?o de pixel en X
1102
         * @return tama?o de pixel en X
1103
         */
1104
        public double getPixelSizeX() {
1105
                return ((RasterDataset)files.get(0)).getPixelSizeX();
1106
        }
1107
        
1108
        /**
1109
         * Obtiene el tama?o de pixel en Y
1110
         * @return tama?o de pixel en Y
1111
         */
1112
        public double getPixelSizeY() {
1113
                return ((RasterDataset)files.get(0)).getPixelSizeY();
1114
        }
1115

    
1116
        //TODO: TEST: Probar getData para multifichero
1117

    
1118
        /*
1119
         * (non-Javadoc)
1120
         * @see org.gvsig.raster.dataset.IRasterDataSource#getData(int, int, int)
1121
         */
1122
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
1123
                String file = bandList.getBand(band).getFileName(); 
1124
                int[] posList = bandList.getBandPositionList();
1125
                for(int i = 0; i < files.size(); i++){
1126
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
1127
                                return ((RasterDataset)files.get(i)).getData(x, y, posList[band]); 
1128
                }
1129
                return null;
1130
        }
1131
                
1132
        /**
1133
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
1134
         * color por banda para el dataset seleccionado
1135
         * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
1136
         * @return DatasetColorInterpretation
1137
         */
1138
        public DatasetColorInterpretation getColorInterpretation(int dataset){
1139
                return ((RasterDataset)files.get(dataset)).getColorInterpretation();
1140
        }
1141
        
1142
        /**
1143
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
1144
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
1145
         * dataset.
1146
         * @return Proyecci?n en formato cadena
1147
         * @throws RasterDriverException
1148
         */
1149
        public String getWktProjection() throws RasterDriverException {
1150
                return ((RasterDataset)files.get(0)).getWktProjection();
1151
        }
1152

    
1153
        /*
1154
         * (non-Javadoc)
1155
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
1156
         */
1157
        public Histogram getHistogram() throws HistogramException, InterruptedException {
1158
                if (histogram == null)
1159
                        histogram = new DatasetListHistogram(this);
1160
                
1161
                try {
1162
                        Histogram tmpHist = histogram.getHistogram();
1163
                        return tmpHist;
1164
                } catch (FileNotOpenException e) {
1165
                        throw new HistogramException("FileNotOpenException");
1166
                } catch (RasterDriverException e) {
1167
                        throw new HistogramException("RasterDriverException");
1168
                }
1169
        }
1170

    
1171
        /*
1172
         * (non-Javadoc)
1173
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
1174
         */
1175
        public int getPercent() {
1176
                if (histogram != null) 
1177
                        return histogram.getPercent();
1178
                return 0;
1179
        }
1180
        
1181
        /*
1182
         * (non-Javadoc)
1183
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
1184
         */
1185
        public void resetPercent() {
1186
                if (histogram != null) histogram.resetPercent();
1187
        }
1188
        
1189
        /**
1190
         * Escribe sobre el rmf todos los cambios que haya para salvar, es decir, para cada
1191
         * Objeto registrado en el manager volcar? su contenido al fichero rmf.
1192
         * @throws IOException
1193
         */
1194
        public void saveRmfModification() throws IOException {
1195
                for (int i = 0; i < files.size(); i++) 
1196
                        ((RasterDataset)files.get(i)).saveRmfModification();
1197
        }
1198
        
1199
        /**
1200
         * Salva la georreferenciaci?n a fichero rmf.
1201
         * @param fName
1202
         * @throws IOException  
1203
         */
1204
        public void saveGeoToRmf() throws IOException {
1205
                for (int i = 0; i < files.size(); i++) 
1206
                        ((RasterDataset)files.get(i)).saveGeoToRmf();
1207
        }
1208
        
1209
        /**
1210
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa 
1211
         * o fuera de ellos.
1212
         * @param p Punto a calcular
1213
         * @return true si est? dentro de los l?mites y false si est? fuera
1214
         */
1215
        public boolean isInside(Point2D p) {
1216
                if(getDataset(0) != null)
1217
                        return getDataset(0)[0].isInside(p);
1218
                return false;
1219
        }
1220
        
1221
        /**
1222
         * Devuelve la transformaci?n leida en la carga del raster 
1223
         * @return AffineTransform
1224
         */
1225
        public AffineTransform getOwnAffineTransform() {
1226
                if(getDataset(0) != null)
1227
                        return getDataset(0)[0].ownTransformation;
1228
                return null;
1229
        }
1230
        
1231
        /*
1232
         * (non-Javadoc)
1233
         * @see org.gvsig.raster.dataset.IRasterDataSource#getAffineTransform()
1234
         */
1235
        public AffineTransform getAffineTransform(){
1236
                if(getDataset(0) != null)
1237
                        return getDataset(0)[0].getAffineTransform();
1238
                return null;
1239
        }
1240
        
1241
        /*
1242
         * (non-Javadoc)
1243
         * @see org.gvsig.raster.dataset.IRasterDataSource#setAffineTransform(java.awt.geom.AffineTransform)
1244
         */
1245
        public void setAffineTransform(AffineTransform transf){
1246
                for (int i = 0; i < getDatasetCount(); i++) 
1247
                        this.getDataset(i)[0].setAffineTransform(transf);        
1248
        }
1249
        
1250
        /**
1251
         * Obtiene la matriz de transformaci?n del propio raster. Esta matriz es la encargada
1252
         * de convertir las coordenadas de la petici?n en coordenadas a las que se pide a la libreria.
1253
         * En gdal, por ejemplo, se piden las coordenadas a la libreria en coordenadas pixel por lo que
1254
         * esta matriz tendr? la georreferenciaci?n asociada en el worldfile o cabecera. Otras librerias como
1255
         * ermapper la petici?n a la libreria se hace en coordenadas geograficas que son las mismas en las
1256
         * que pide el usuario de gvSIG por lo que esta matriz en este caso se inicializa con la identidad. 
1257
         * @return
1258
         */
1259
        public AffineTransform getOwnTransformation() {
1260
                if(getDataset(0) != null)
1261
                        return getDataset(0)[0].getOwnTransformation();
1262
                return new AffineTransform();
1263
        } 
1264

    
1265
        /*
1266
         * (non-Javadoc)
1267
         * @see org.gvsig.raster.dataset.IRasterDataSource#isRotated()
1268
         */
1269
        public boolean isRotated() {
1270
                if(getDataset(0) != null)
1271
                        return getDataset(0)[0].isRotated();
1272
                return false;
1273
        }
1274
        
1275
        /*
1276
         * (non-Javadoc)
1277
         * @see org.gvsig.raster.dataset.IRasterDataSource#setDrawableBands(int[])
1278
         */
1279
        public void setDrawableBands(int[] db) {
1280
                getBands().setDrawableBands(db);
1281
        }
1282
        
1283
        /*
1284
         * (non-Javadoc)
1285
         * @see org.gvsig.raster.dataset.IRasterDataSource#clearDrawableBands()
1286
         */
1287
        public void clearDrawableBands() {
1288
                getBands().clearDrawableBands();
1289
        }
1290
        
1291
        /*
1292
         * (non-Javadoc)
1293
         * @see org.gvsig.raster.dataset.IRasterDataSource#addDrawableBand(int, int)
1294
         */
1295
        public void addDrawableBand(int posRasterBuf, int imageBand) {
1296
                getBands().addDrawableBand(posRasterBuf, imageBand);
1297
        }
1298

    
1299
        /*
1300
         * (non-Javadoc)
1301
         * @see org.gvsig.raster.dataset.IRasterDataSource#isReadOnly()
1302
         */
1303
        public boolean isReadOnly() {
1304
                return readOnly;
1305
        }
1306

    
1307
        /*
1308
         * (non-Javadoc)
1309
         * @see org.gvsig.raster.dataset.IRasterDataSource#setReadOnly(boolean)
1310
         */
1311
        public void setReadOnly(boolean readOnly) {
1312
                this.readOnly = readOnly;
1313
                if(readOnly)
1314
                        this.forceToMemory = false;
1315
        }
1316
        
1317
        /*
1318
         * (non-Javadoc)
1319
         * @see org.gvsig.raster.dataset.IRasterDataSource#setMemoryBuffer(boolean)
1320
         */
1321
        public void setMemoryBuffer(boolean memory) {
1322
                this.forceToMemory = memory;
1323
                if(memory)
1324
                        this.readOnly = false;
1325
        }
1326

    
1327
        /*
1328
         * (non-Javadoc)
1329
         * @see org.gvsig.raster.dataset.IRasterDataSource#isMemoryBuffer()
1330
         */
1331
        public boolean isMemoryBuffer() {
1332
                return forceToMemory;
1333
        }
1334
        
1335
        /*
1336
         * (non-Javadoc)
1337
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewCount(int)
1338
         */
1339
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
1340
                if(band >= getBandCount())
1341
                        throw new BandAccessException("Wrong band");
1342
                String fileName = getBands().getBand(band).getFileName();
1343
                RasterDataset dataset = getDataset(fileName);
1344
                return dataset.getOverviewCount(0);
1345
        }
1346
        
1347
        /*
1348
         * (non-Javadoc)
1349
         * @see org.gvsig.raster.dataset.IRasterDataSource#overviewsSupport()
1350
         */
1351
        public boolean overviewsSupport() {
1352
                return getDataset(0)[0].overviewsSupport();
1353
        }
1354

    
1355
        /*
1356
         * (non-Javadoc)
1357
         * @see org.gvsig.raster.dataset.IRasterDataSource#loadGeoPointsFromRmf()
1358
         */
1359
        public GeoPoint[] loadGeoPointsFromRmf() throws IOException {
1360
                return getDataset(0)[0].loadGeoPointsFromRmf();        
1361
        }
1362

    
1363
        /*
1364
         * (non-Javadoc)
1365
         * @see org.gvsig.raster.dataset.IRasterDataSource#saveGeoPointsToRmf(org.gvsig.raster.datastruct.GeoPoint[])
1366
         */
1367
        public void saveGeoPointsToRmf(GeoPoint[] geoPoints) throws IOException {
1368
                for (int i = 0; i < getDatasetCount(); i++) 
1369
                        getDataset(i)[0].saveGeoPointsToRmf(geoPoints);
1370
        }
1371
}