Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / MultiRasterDataset.java @ 20119

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

    
56
        //Band list
57
        private BandList                                        bandList = new BandList();
58
        protected DatasetListStatistics     stats = null;
59
        protected DatasetListHistogram                histogram = null;
60
        /**
61
         * Flag que fuerza al buffer de solo lectura
62
         */
63
        private boolean                     readOnly = false;
64
        /**
65
         * Flag que fuerza al buffer en memoria
66
         */
67
        private boolean                     forceToMemory = false;
68
        int percent = 0;
69
                        
70
        //TODO: FUNCIONALIDAD: Contructores igual a RasterDataset + String[] nameFiles
71
        public MultiRasterDataset() {
72

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

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

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

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

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

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

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

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

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

    
820
                if (dt.length == 0)
821
                        return null;
822

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

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

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

    
930
                return ((RasterDataset) files.get(0)).getNoDataValue();
931
        }
932

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

    
941
                return ((RasterDataset) files.get(0)).isNoDataEnabled();
942
        }
943

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

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

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

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

    
1118
        //TODO: TEST: Probar getData para multifichero
1119

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

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

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

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

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

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

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

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

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