Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libRaster / src / org / gvsig / raster / dataset / MultiRasterDataset.java @ 29786

History | View | Annotate | Download (46.2 KB)

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

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

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

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

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

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

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

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

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

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

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

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

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

    
816
                if (dt.length == 0)
817
                        return null;
818

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

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

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

    
926
                return ((RasterDataset) files.get(0)).getNoDataValue();
927
        }
928

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

    
937
                return ((RasterDataset) files.get(0)).isNoDataEnabled();
938
        }
939

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

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

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

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

    
1114
        //TODO: TEST: Probar getData para multifichero
1115

    
1116
        /*
1117
         * (non-Javadoc)
1118
         * @see org.gvsig.raster.dataset.IRasterDataSource#getData(int, int, int)
1119
         */
1120
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
1121
                String file = bandList.getBand(band).getFileName(); 
1122
                int[] posList = bandList.getBandPositionList();
1123
                for(int i = 0; i < files.size(); i++){
1124
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
1125
                                return ((RasterDataset)files.get(i)).getData(x, y, posList[band]); 
1126
                }
1127
                return null;
1128
        }
1129
                
1130
        /**
1131
         * Obtiene el objeto que contiene la interpretaci?n de color del MultiRasterDataset
1132
         * @return DatasetColorInterpretation
1133
         */
1134
        public DatasetColorInterpretation getColorInterpretation(){
1135
                DatasetColorInterpretation ci = new DatasetColorInterpretation();
1136
                for (int i = 0; i < files.size(); i++) {
1137
                        ci.addColorInterpretation(((RasterDataset) files.get(i)).getColorInterpretation());
1138
                }
1139
                return ci;
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
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa 
1191
         * o fuera de ellos.
1192
         * @param p Punto a calcular
1193
         * @return true si est? dentro de los l?mites y false si est? fuera
1194
         */
1195
        public boolean isInside(Point2D p) {
1196
                if(getDataset(0) != null)
1197
                        return getDataset(0)[0].isInside(p);
1198
                return false;
1199
        }
1200
        
1201
        /**
1202
         * Devuelve la transformaci?n leida en la carga del raster 
1203
         * @return AffineTransform
1204
         */
1205
        public AffineTransform getOwnAffineTransform() {
1206
                if(getDataset(0) != null)
1207
                        return getDataset(0)[0].ownTransformation;
1208
                return null;
1209
        }
1210
        
1211
        /*
1212
         * (non-Javadoc)
1213
         * @see org.gvsig.raster.dataset.IRasterDataSource#getAffineTransform()
1214
         */
1215
        public AffineTransform getAffineTransform(int band){
1216
                if(band < 0 || band > (getBandCount() - 1))
1217
                        return null;
1218
                int[] datasetBand = getDatasetFromBandNumber(band);
1219
                if(datasetBand != null && getDataset(datasetBand[0]) != null)
1220
                        return getDataset(datasetBand[0])[0].getAffineTransform();
1221
                return null;
1222
        }
1223
        
1224
        /**
1225
         * Obtiene el n?mero de dataset para un n?mero de banda y la posici?n de la banda dentro de 
1226
         * ese dataset.
1227
         * @param bandNumber N?mero de banda
1228
         * @return Dataset que corresponde a la banda pedida y n?mero de banda dentro del dataset (dataset, banda)
1229
         */
1230
        private int[] getDatasetFromBandNumber(int bandNumber) {
1231
                int cont = 0;
1232
                for (int i = 0; i < getDatasetCount(); i++) {
1233
                        cont += getDataset(i)[0].getBandCount();
1234
                        if(cont > bandNumber) {
1235
                                int lastBands = (cont - getDataset(i)[0].getBandCount()); //Suma de las bandas de todos los datasets anteriores.
1236
                                return new int[]{i, (bandNumber - lastBands)};
1237
                        }
1238
                }
1239
                return null;
1240
        }
1241
        
1242
        /*
1243
         * (non-Javadoc)
1244
         * @see org.gvsig.raster.dataset.IRasterDataSource#setAffineTransform(java.awt.geom.AffineTransform)
1245
         */
1246
        public void setAffineTransform(AffineTransform transf){
1247
                for (int i = 0; i < getDatasetCount(); i++) 
1248
                        this.getDataset(i)[0].setAffineTransform(transf);        
1249
        }
1250
        
1251
        /**
1252
         * Obtiene la matriz de transformaci?n del propio raster. Esta matriz es la encargada
1253
         * de convertir las coordenadas de la petici?n en coordenadas a las que se pide a la libreria.
1254
         * En gdal, por ejemplo, se piden las coordenadas a la libreria en coordenadas pixel por lo que
1255
         * esta matriz tendr? la georreferenciaci?n asociada en el worldfile o cabecera. Otras librerias como
1256
         * ermapper la petici?n a la libreria se hace en coordenadas geograficas que son las mismas en las
1257
         * que pide el usuario de gvSIG por lo que esta matriz en este caso se inicializa con la identidad. 
1258
         * @return
1259
         */
1260
        public AffineTransform getOwnTransformation() {
1261
                if(getDataset(0) != null)
1262
                        return getDataset(0)[0].getOwnTransformation();
1263
                return new AffineTransform();
1264
        } 
1265

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

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

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

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

    
1356
        /*
1357
         * (non-Javadoc)
1358
         * @see org.gvsig.raster.dataset.IRasterDataSource#saveObjectToRMF(int, java.lang.Class, java.lang.Object)
1359
         */
1360
        public void saveObjectToRmf(int file, Class class1, Object value) throws RmfSerializerException {
1361
                ((RasterDataset) files.get(file)).saveObjectToRmf(class1, value);
1362
        }
1363

    
1364
        /*
1365
         * (non-Javadoc)
1366
         * @see org.gvsig.raster.dataset.IRasterDataSource#loadObjectFromRMF(java.lang.Class, java.lang.Object)
1367
         */
1368
        public Object loadObjectFromRmf(Class class1, Object value) throws RmfSerializerException {
1369
                return ((RasterDataset) files.get(0)).loadObjectFromRmf(class1, value);
1370
        }
1371
}