Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / RasterMultiDataset.java @ 11396

History | View | Annotate | Download (33.4 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.Point2D;
22
import java.io.File;
23
import java.util.ArrayList;
24

    
25
import org.cresques.cts.IProjection;
26
import org.gvsig.raster.buffer.RasterBuffer;
27
import org.gvsig.raster.buffer.cache.RasterReadOnlyHugeBuffer;
28
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
29
import org.gvsig.raster.dataset.properties.DatasetListHistogram;
30
import org.gvsig.raster.dataset.properties.DatasetListStatistics;
31
import org.gvsig.raster.dataset.properties.DatasetListTransparency;
32
import org.gvsig.raster.dataset.properties.DatasetPalette;
33
import org.gvsig.raster.dataset.properties.DatasetTransparency;
34
import org.gvsig.raster.shared.Extent;
35
import org.gvsig.raster.util.Histogram;
36
import org.gvsig.raster.util.HistogramException;
37
import org.gvsig.raster.util.IHistogramable;
38

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

    
324
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
325
                //por arriba el m?s alto y por abajo el menor y luego restandolos
326
                
327
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(x, y));
328
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(x + w, y - h));
329
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
330
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
331
                
332
                int mallocNBands = 0;
333
                if(bandList.getDrawableArray() != null)
334
                        mallocNBands = bandList.getDrawableArray().length;
335
                else
336
                        bandList.getDrawableBandsCount();
337
                
338
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
339
                
340
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
341
                if(!raster.isBandSwitchable()) {
342
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0).getBandCount(), false);
343
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
344
                                try {
345
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
346
                                } catch (FileNotExistsException e) {
347
                                        //Esto no debe darse ya que se comprueba al hacer el open
348
                                } catch (NotSupportedExtensionException e) {
349
                                        //Esto no debe darse ya que se comprueba al hacer el open
350
                                }
351
                                return rb;
352
                        }
353
                                
354
                }
355
                                        
356
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
357
                        raster.assignBandToNotValid(iBand);
358
                
359
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
360
                //m?s grande y salirse de los l?mites.
361
                if(!adjustToExtent)
362
                         initBufferToNoData(raster, bandList);
363
                
364
                //Reservamos memoria para los buffers por dataset
365
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
366
                for(int i = 0; i < getDatasetCount(); i++)
367
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
368
                        
369
                //Mezclamos los buffers de cada dataset en un solo buffer
370
                mergeBuffers(raster, bufferDatasets, bandList);
371
                                                        
372
                return raster;
373
        }
374
                        
375
        /**
376
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
377
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
378
         * el driver.
379
         * @param minX Valor m?nimo de la X en coordenadas reales
380
         * @param minY Valor m?nimo de la Y en coordenadas reales
381
         * @param maxX Valor m?ximo de la X en coordenadas reales
382
         * @param maxY Valor m?ximo de la Y en coordenadas reales
383
         * @param bufWidth ancho del buffer lde datos
384
         * @param bufHeight alto del buffer de datos
385
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
386
         * @param bandList
387
         * @return Buffer de datos
388
         */
389
        public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, 
390
                                                                        int bufWidth, int bufHeight, boolean adjustToExtent) throws InvalidSetViewException {
391
                
392
                if(        minX < ((RasterDataset)files.get(0)).getExtent().minX() || minY < ((RasterDataset)files.get(0)).getExtent().minY() ||
393
                        maxX > ((RasterDataset)files.get(0)).getExtent().maxX() || maxY > ((RasterDataset)files.get(0)).getExtent().maxY())
394
                                throw new InvalidSetViewException("");
395
                
396
                int mallocNBands = 0;
397
                if(bandList.getDrawableArray() != null)
398
                        mallocNBands = bandList.getDrawableArray().length;
399
                else
400
                        bandList.getDrawableBandsCount();
401
                
402
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
403
                
404
                //TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
405
                //Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
406
                /*if(!raster.isBandSwitchable()) {
407
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
408
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
409
                                try {
410
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
411
                                } catch (FileNotExistsException e) {
412
                                        //Esto no debe darse ya que se comprueba al hacer el open
413
                                } catch (NotSupportedExtensionException e) {
414
                                        //Esto no debe darse ya que se comprueba al hacer el open
415
                                }
416
                                return rb;
417
                        }
418
                }*/
419
                        
420
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
421
                        raster.assignBandToNotValid(iBand);
422
                
423
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
424
                //m?s grande y salirse de los l?mites.
425
                if(!adjustToExtent)
426
                         initBufferToNoData(raster, bandList);        
427
                
428
                //Reservamos memoria para los buffers por dataset
429
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
430
                for(int i = 0; i < getDatasetCount(); i++)
431
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(minX, minY, maxX, maxY, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
432
                
433
                //Mezclamos los buffers de cada dataset en un solo buffer
434
                mergeBuffers(raster, bufferDatasets, bandList);
435
                                                        
436
                return raster;
437
        }
438
        
439
        /**
440
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
441
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
442
         * pixeles de disco. 
443
         * @param x Posici?n X superior izquierda
444
         * @param y Posici?n Y superior izquierda
445
         * @param w Ancho en coordenadas pixel
446
         * @param h Alto en coordenadas pixel
447
         * @param bandList
448
         * @return Buffer de datos
449
         */
450
        public IBuffer getWindowRaster(int x, int y, int w, int h) throws InvalidSetViewException {
451
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
452
                        throw new InvalidSetViewException("Out of image");
453
                
454
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
455
                
456
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
457
                if(!raster.isBandSwitchable()) {
458
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], w, h, getDataset(0).getBandCount(), false);
459
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
460
                                try {
461
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
462
                                } catch (FileNotExistsException e) {
463
                                        //Esto no debe darse ya que se comprueba al hacer el open
464
                                } catch (NotSupportedExtensionException e) {
465
                                        //Esto no debe darse ya que se comprueba al hacer el open
466
                                }
467
                                return rb;
468
                        }
469
                }
470
                                
471
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
472
                        raster.assignBandToNotValid(iBand);
473
                
474
                //Reservamos memoria para los buffers por dataset
475
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, w, h);
476
                for(int i = 0; i < getDatasetCount(); i++)
477
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i]);
478
                
479
                //Mezclamos los buffers de cada dataset en un solo buffer
480
                mergeBuffers(raster, bufferDatasets, bandList);
481
                                                        
482
                return raster;
483
        }
484
        
485
        /**
486
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
487
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer
488
         * @param x Posici?n X superior izquierda en pixels
489
         * @param y Posici?n Y superior izquierda en pixels
490
         * @param w Ancho en pixels
491
         * @param h Alto en pixels
492
         * @param bufWidth ancho del buffer de datos
493
         * @param bufHeight alto del buffer de datos
494
         * @param bandList
495
         * @return Buffer de datos
496
         */
497
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight)  
498
                throws InvalidSetViewException {
499
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
500
                        throw new InvalidSetViewException("Out of image");
501
                
502
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
503
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
504
                        raster.assignBandToNotValid(iBand);
505
                
506
                //Reservamos memoria para los buffers por dataset
507
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
508
                
509
                //TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
510
                //Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
511
                /*if(!raster.isBandSwitchable()) {
512
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
513
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
514
                                try {
515
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
516
                                } catch (FileNotExistsException e) {
517
                                        //Esto no debe darse ya que se comprueba al hacer el open
518
                                } catch (NotSupportedExtensionException e) {
519
                                        //Esto no debe darse ya que se comprueba al hacer el open
520
                                }
521
                                return rb;
522
                        }
523
                }*/
524
                                
525
                for(int i = 0; i < getDatasetCount(); i++)
526
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bufWidth, bufHeight, bandList, bufferDatasets[i]);
527
                
528
                //Mezclamos los buffers de cada dataset en un solo buffer
529
                mergeBuffers(raster, bufferDatasets, bandList);
530
                                                        
531
                return raster;
532
        }
533
        
534
        //******************************
535
        //Setters and Getters
536
        //******************************
537
        
538
        /**
539
         * Calcula el tama?o de los ficheros en disco
540
         * @return tama?o en bytes de todos los ficheros de la lista
541
         */
542
        public long getFileSize(){
543
                int len = 0;
544
                for(int i=0;i<files.size();i++){
545
                        if(((RasterDataset)files.get(i)) != null){
546
                                File f = new File(((RasterDataset)files.get(i)).getFName());
547
                                len += f.length();
548
                        }
549
                }
550
                return len;
551
        }
552
        
553
        /**
554
         * Obtiene la altura de la imagen a partir de la primera
555
         * @return altura
556
         */
557
        public double[] getHeight() {
558
                double[] lenghts = new double[getDatasetCount()];
559
                for(int i = 0; i < getDatasetCount(); i++)
560
                        if(((RasterDataset)files.get(i)) != null)
561
                                lenghts[i] = ((RasterDataset)files.get(i)).getHeight();
562
                return lenghts;
563
        }
564

    
565
        /**
566
         * Obtiene la anchura de la imagen a partir de la primera
567
         * @return anchura
568
         */
569
        public double[] getWidth() {
570
                double[] lenghts = new double[getDatasetCount()];
571
                for(int i = 0; i < getDatasetCount(); i++)
572
                        if(((RasterDataset)files.get(i)) != null)
573
                                lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
574
                return lenghts;        
575
        }
576
        
577
        /**
578
         * Obtiene el n?mero de bandas del fichero
579
         * @return
580
         */
581
        public int getBandCount(){
582
                return bandList.getBandCount();
583
        }
584

    
585
        /**
586
         * Obtiene el tipo de dato por banda
587
         * @return tipo de dato por banda
588
         */
589
        public int[] getDataType() {
590
                int[] dt = new int[getDatasetCount()];
591
                for(int i=0;i<files.size();i++)
592
                        dt[i] = ((RasterDataset)files.get(i)).getDataType();
593
                                
594
            if(dt.length == 0)
595
                    return null;
596
            else
597
                    return dt;
598
        }
599
        
600
        /**
601
         * Obtiene fichero de la posici?n i.
602
         * @param i Posici?n del fichero a obtener.
603
         * @return GeoRasterFileDataset.
604
         */
605
        public RasterDataset getDataset(int i){
606
                return (RasterDataset)files.get(i);
607
        }
608
        
609
        /**
610
         * Obtiene fichero de nombre fileName.
611
         * @param i Posici?n del fichero a obtener.
612
         * @return GeoRasterFile.
613
         */
614
        public RasterDataset getDataset(String fileName){
615
                for(int i=0;i<files.size();i++){
616
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
617
                                return (RasterDataset)files.get(i); 
618
                }
619
                return null;                
620
        }
621
        
622
        /**
623
         * Asigna el nombre al GeoRasterMultiFile
624
         * @param name Nombre del GeoRasterMultiFile
625
         */
626
        public void setName(String name){
627
                this.name = name;
628
        }
629
        
630
        /**
631
         * Obtiene la lista de bandas
632
         * @return BandList
633
         */
634
        public BandList getBands(){
635
                return bandList;
636
        }
637
        
638
        /**
639
         * Obtiene la coordenada X m?nima de toda la lista
640
         * @return Coordenada X m?nima
641
         */
642
        public double getMinX(){
643
                double minx = Double.MAX_VALUE;
644
                for(int i = 0; i < files.size(); i++){
645
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
646
                        if(aux < minx)
647
                                minx = aux;
648
                }
649
                return minx;
650
        }
651
        
652
        /**
653
         * Obtiene la coordenada Y m?nima de toda la lista
654
         * @return Coordenada Y m?nima
655
         */
656
        public double getMinY(){
657
                double miny = Double.MAX_VALUE;
658
                for(int i = 0; i < files.size(); i++){
659
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
660
                        if(aux < miny)
661
                                miny = aux;
662
                }
663
                return miny;
664
        }
665
        
666
        /**
667
         * Obtiene la coordenada Y m?xima de toda la lista
668
         * @return Coordenada Y m?xima
669
         */
670
        public double getMaxX(){
671
                double maxx = Double.NEGATIVE_INFINITY;
672
                for(int i = 0; i < files.size(); i++){
673
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
674
                        if(aux > maxx)
675
                                maxx = aux;
676
                }
677
                return maxx;
678
        }
679

    
680
        /**
681
         * Obtiene la coordenada Y m?xima de toda la lista
682
         * @return Coordenada Y m?xima
683
         */
684
        public double getMaxY(){
685
                double maxy = Double.NEGATIVE_INFINITY;
686
                for(int i = 0; i < files.size(); i++){
687
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
688
                        if(aux > maxy)
689
                                maxy = aux;
690
                }
691
                return maxy;
692
        }
693
        
694
        /**
695
         * Obtiene el extent del multi fichero. Este corresponde al primer
696
         * GeoRasterFile de la lista.
697
         * @return Extent
698
         */
699
        public Extent getExtent(){
700
                if(files.size() == 0)
701
                        return null;
702
                else
703
                        return ((RasterDataset)files.get(0)).getExtent();
704
        }
705
        
706
        /**
707
     * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el 
708
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
709
     * pero para un raster rotado ser? igual al extent del raster como si no 
710
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
711
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
712
     * aplicado.
713
     * @return Extent
714
     */
715
    public Extent getExtentForRequest() {
716
        return ((RasterDataset)files.get(0)).getExtentForRequest();
717
    }
718
        
719
        /**
720
         * Obtiene las coordenadas del fichero worldFile (o cabecera del raster) asociado 
721
         * o el RMF en caso de que existan. Si la imagen no est? georreferenciada tendr?
722
         * las coordenadas pixel de la misma 
723
         * @return Array de seis valores:
724
         *         <TABLE BORDER="1">
725
         *         <TR><TD><B>0:</B></TD><TD>Valor X de la esquina superior izquierda.</TD></TR>
726
         *         <TR><TD><B>1:</B></TD><TD>Tama?o de pixel en X.</TD></TR>
727
         *         <TR><TD><B>2:</B></TD><TD>Shearing en X.</TD></TR>
728
         *         <TR><TD><B>3:</B></TD><TD>Valor Y de la esquina superior izquierda.</TD></TR>
729
         *         <TR><TD><B>4:</B></TD><TD>Shearing en Y.</TD></TR>
730
         *         <TR><TD><B>5:</B></TD><TD>Tama?o de pixel en Y.</TD></TR>
731
         *         </TABLE>
732
         */
733
        public double[] getCoordsGeoTransformFile(){
734
                return ((RasterDataset)files.get(0)).getTransform();
735
        }
736
        
737
        /**
738
         * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
739
         * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
740
         * que se hayan aplicado sobre el/los dataset.
741
         * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
742
         * solicitada.
743
         */
744
        public Extent getLastSelectedView(){
745
                return ((RasterDataset)files.get(0)).getView();
746
        }
747
        
748
        /**
749
         * Obtiene el tama?o de pixel.
750
         * @return array de dos elementos, tama?o de pixel en X y en Y.
751
         */
752
        public double[] getPixelSize(){
753
                double[] at = ((RasterDataset)files.get(0)).getTransform();
754
                return new double[]{at[1], at[5]};
755
        }
756
        
757
        /**
758
         * Obtiene el estado de transparencia a partir de los estados de transparencia de todos
759
         * los ficheros que lo componen. Si varios de los ficheros que lo componen tienen banda de 
760
         * transparencia estas tendr?n que ser mezcladas sobre una banda de transparencia ?nica.
761
         * @return Objeto FileTransparency con el estado de transparencia
762
         */
763
        public DatasetListTransparency getTransparencyFilesStatus(){
764
                DatasetListTransparency out = null;
765
                for(int i = 0; i < files.size(); i++){
766
                        DatasetTransparency tfs = ((RasterDataset)files.get(i)).getTransparencyDatasetStatus();
767
                        if(tfs != null){
768
                                if(out == null)
769
                                        out = new DatasetListTransparency(tfs);
770
                                else
771
                                        out.merge(tfs);
772
                        }
773
                }
774
                return out;
775
        }
776
        
777
        /**
778
         * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
779
         * @param i Posici?n del raster
780
         * @return Paleta asociada a este o null si no tiene
781
         */
782
        public DatasetPalette getPalette(int i){
783
                if(i >= files.size())
784
                        return null;
785
                return ((RasterDataset)files.get(i)).getPalette();
786
        }
787
        
788
        /**
789
         * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
790
         * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
791
         * para ese fichero no hay paletas asociadas.
792
         */
793
        public DatasetPalette[] getPalettes(){
794
                if(files.size() <= 0)
795
                        return null;
796
                DatasetPalette[] list = new DatasetPalette[files.size()];
797
                for(int i = 0; i < files.size(); i++)
798
                        list[i] = ((RasterDataset)files.get(i)).getPalette();
799
                return list;
800
        }
801
        
802
        /**
803
         * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro. 
804
         * @param fileName Nombre del fichero
805
         * @return Paleta o null si no la tiene
806
         */
807
        public DatasetPalette getPalette(String fileName){
808
                for(int i = 0; i < files.size(); i++){
809
                        if(((RasterDataset)files.get(i)).getFName().indexOf(fileName) == 0)
810
                                return ((RasterDataset)files.get(i)).getPalette();
811
                }
812
                return null;
813
        }
814
        
815
        /**
816
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
817
         * @param pt Punto a transformar
818
         * @return punto transformado en coordenadas del mundo
819
         */
820
        public Point2D rasterToWorld(Point2D pt) {
821
                return ((RasterDataset)files.get(0)).rasterToWorld(pt);
822
        }
823
        
824
        /**
825
         * Convierte un punto desde del mundo a coordenadas pixel.
826
         * @param pt Punto a transformar
827
         * @return punto transformado en coordenadas pixel
828
         */
829
        public Point2D worldToRaster(Point2D pt) {
830
                return ((RasterDataset)files.get(0)).worldToRaster(pt);
831
        }
832
        
833
        /**
834
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
835
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
836
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
837
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
838
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
839
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
840
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
841
         * el driver autom?ticamente.
842
         * @param dWorldTLX Coordenada real X superior izquierda
843
         * @param dWorldTLY Coordenada real Y superior izquierda
844
         * @param nWidth Ancho del raster
845
         * @param nHeight Alto del raster
846
         * @param bufWidth Ancho del buffer
847
         * @param bufHeight Alto del buffer
848
         * @return Array de dos elementos con el desplazamiento en X e Y. 
849
         */
850
        public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
851
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
852
                return ((RasterDataset)files.get(0)).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
853
        }
854
        
855
        /**
856
         * Obtiene el objeto con las estadisticas
857
         * @return MultiFileStatistics
858
         */
859
        public DatasetListStatistics getStatistics(){
860
                return stats;
861
        }
862
        
863
        /**
864
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
865
         * @return true si est? georreferenciada y false si no lo est?.
866
         */
867
        public boolean isGeoreferenced() {
868
                for(int i = 0; i < files.size(); i++){
869
                        if(((RasterDataset)files.get(i)).isGeoreferenced())
870
                                return true;
871
                }
872
                return false;
873
        }
874

    
875
        //TODO: TEST: Probar getData para multifichero
876
        /**
877
         * Obtiene el valor del raster en la coordenada que se le pasa.
878
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
879
         * raster.
880
         * @param x        coordenada X
881
         * @param y coordenada Y
882
         * @return
883
         */
884
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
885
                String file = bandList.getBand(band).getFileName();
886
                for(int i = 0; i < files.size(); i++){
887
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
888
                                return ((RasterDataset)files.get(i)).getData(x, y, band); 
889
                }
890
                return null;
891
        }
892
                
893
        /**
894
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
895
         * color por banda para el dataset seleccionado
896
         * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
897
         * @return DatasetColorInterpretation
898
         */
899
        public DatasetColorInterpretation getColorInterpretation(int dataset){
900
                return ((RasterDataset)files.get(dataset)).getColorInterpretation();
901
        }
902
        
903
        /**
904
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
905
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
906
         * dataset.
907
         * @return Proyecci?n en formato cadena
908
         * @throws RasterDriverException
909
         */
910
        public String getStringProjection() throws RasterDriverException{
911
                return ((RasterDataset)files.get(0)).getStringProjection();
912
        }
913

    
914
        /*
915
         * (non-Javadoc)
916
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
917
         */
918
        public Histogram getHistogram() throws HistogramException {
919
                if (histogram == null)
920
                        histogram = new DatasetListHistogram(this);
921
                
922
                try {
923
                        Histogram tmpHist = histogram.getHistogram();
924
                        return tmpHist;
925
                } catch (FileNotOpenException e) {
926
                        throw new HistogramException("FileNotOpenException");
927
                } catch (RasterDriverException e) {
928
                        throw new HistogramException("RasterDriverException");
929
                }
930
        }
931

    
932
        /*
933
         * (non-Javadoc)
934
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
935
         */
936
        public int getPercent() {
937
                if (histogram != null) return histogram.getPercent();
938
                return 0;
939
        }
940
        
941
        
942
        /*
943
         * (non-Javadoc)
944
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
945
         */
946
        public void resetPercent() {
947
                if (histogram != null) histogram.resetPercent();
948
        }
949

    
950
        /*
951
         * (non-Javadoc)
952
         * @see org.gvsig.raster.util.ICancellable#isCanceled()
953
         */
954
        public boolean isCanceled() {
955
                if (histogram != null) return histogram.isCanceled();
956
                return false;
957
        }
958

    
959
        /*
960
         * (non-Javadoc)
961
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
962
         */
963
        public void setCanceled(boolean value) {
964
                if (histogram != null) histogram.setCanceled(value);
965
        }
966
}