Statistics
| Revision:

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

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

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

    
554
                //Mezclamos los buffers de cada dataset en un solo buffer
555
                mergeBuffers(raster, bufferDatasets, bandList);
556
                                                        
557
                return raster;
558
        }
559
        
560
        //******************************
561
        //Setters and Getters
562
        //******************************
563
        
564
        /**
565
         * Calcula el tama?o de los ficheros en disco
566
         * @return tama?o en bytes de todos los ficheros de la lista
567
         */
568
        public long getFileSize(){
569
                int len = 0;
570
                for(int i=0;i<files.size();i++){
571
                        if(((RasterDataset)files.get(i)) != null){
572
                                File f = new File(((RasterDataset)files.get(i)).getFName());
573
                                len += f.length();
574
                        }
575
                }
576
                return len;
577
        }
578
        
579
        /**
580
         * Obtiene la altura de la imagen a partir de la primera
581
         * @return altura
582
         */
583
        public double[] getHeight() {
584
                double[] lenghts = new double[getDatasetCount()];
585
                for(int i = 0; i < getDatasetCount(); i++)
586
                        if(((RasterDataset)files.get(i)) != null)
587
                                lenghts[i] = ((RasterDataset)files.get(i)).getHeight();
588
                return lenghts;
589
        }
590

    
591
        /**
592
         * Obtiene la anchura de la imagen a partir de la primera
593
         * @return anchura
594
         */
595
        public double[] getWidth() {
596
                double[] lenghts = new double[getDatasetCount()];
597
                for(int i = 0; i < getDatasetCount(); i++)
598
                        if(((RasterDataset)files.get(i)) != null)
599
                                lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
600
                return lenghts;        
601
        }
602
        
603
        /**
604
         * Obtiene el n?mero de bandas del fichero
605
         * @return
606
         */
607
        public int getBandCount(){
608
                return bandList.getBandCount();
609
        }
610

    
611
        /**
612
         * Obtiene el tipo de dato por banda
613
         * @return tipo de dato por banda
614
         */
615
        public int[] getDataType() {
616
                int[] dt = new int[getDatasetCount()];
617
                for(int i=0;i<files.size();i++)
618
                        dt[i] = ((RasterDataset)files.get(i)).getDataType();
619
                                
620
            if(dt.length == 0)
621
                    return null;
622
            else
623
                    return dt;
624
        }
625
        
626
        /**
627
         * Obtiene fichero de la posici?n i.
628
         * @param i Posici?n del fichero a obtener.
629
         * @return GeoRasterFileDataset.
630
         */
631
        public RasterDataset getDataset(int i){
632
                return (RasterDataset)files.get(i);
633
        }
634
        
635
        /**
636
         * Obtiene fichero de nombre fileName.
637
         * @param i Posici?n del fichero a obtener.
638
         * @return GeoRasterFile.
639
         */
640
        public RasterDataset getDataset(String fileName){
641
                for(int i=0;i<files.size();i++){
642
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
643
                                return (RasterDataset)files.get(i); 
644
                }
645
                return null;                
646
        }
647
        
648
        /**
649
         * Asigna el nombre al GeoRasterMultiFile
650
         * @param name Nombre del GeoRasterMultiFile
651
         */
652
        public void setName(String name){
653
                this.name = name;
654
        }
655
        
656
        /**
657
         * Obtiene la lista de bandas
658
         * @return BandList
659
         */
660
        public BandList getBands(){
661
                return bandList;
662
        }
663
        
664
        /**
665
         * Obtiene la coordenada X m?nima de toda la lista
666
         * @return Coordenada X m?nima
667
         */
668
        public double getMinX(){
669
                double minx = Double.MAX_VALUE;
670
                for(int i = 0; i < files.size(); i++){
671
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
672
                        if(aux < minx)
673
                                minx = aux;
674
                }
675
                return minx;
676
        }
677
        
678
        /**
679
         * Obtiene la coordenada Y m?nima de toda la lista
680
         * @return Coordenada Y m?nima
681
         */
682
        public double getMinY(){
683
                double miny = Double.MAX_VALUE;
684
                for(int i = 0; i < files.size(); i++){
685
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
686
                        if(aux < miny)
687
                                miny = aux;
688
                }
689
                return miny;
690
        }
691
        
692
        /**
693
         * Obtiene la coordenada Y m?xima de toda la lista
694
         * @return Coordenada Y m?xima
695
         */
696
        public double getMaxX(){
697
                double maxx = Double.NEGATIVE_INFINITY;
698
                for(int i = 0; i < files.size(); i++){
699
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
700
                        if(aux > maxx)
701
                                maxx = aux;
702
                }
703
                return maxx;
704
        }
705

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

    
901
        //TODO: TEST: Probar getData para multifichero
902
        /**
903
         * Obtiene el valor del raster en la coordenada que se le pasa.
904
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
905
         * raster.
906
         * @param x        coordenada X
907
         * @param y coordenada Y
908
         * @return
909
         */
910
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
911
                String file = bandList.getBand(band).getFileName();
912
                for(int i = 0; i < files.size(); i++){
913
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
914
                                return ((RasterDataset)files.get(i)).getData(x, y, band); 
915
                }
916
                return null;
917
        }
918
                
919
        /**
920
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
921
         * color por banda para el dataset seleccionado
922
         * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
923
         * @return DatasetColorInterpretation
924
         */
925
        public DatasetColorInterpretation getColorInterpretation(int dataset){
926
                return ((RasterDataset)files.get(dataset)).getColorInterpretation();
927
        }
928
        
929
        /**
930
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
931
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
932
         * dataset.
933
         * @return Proyecci?n en formato cadena
934
         * @throws RasterDriverException
935
         */
936
        public String getStringProjection() throws RasterDriverException{
937
                return ((RasterDataset)files.get(0)).getStringProjection();
938
        }
939

    
940
        /*
941
         * (non-Javadoc)
942
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
943
         */
944
        public Histogram getHistogram() throws HistogramException {
945
                if (histogram == null)
946
                        histogram = new DatasetListHistogram(this);
947
                
948
                try {
949
                        Histogram tmpHist = histogram.getHistogram();
950
                        return tmpHist;
951
                } catch (FileNotOpenException e) {
952
                        throw new HistogramException("FileNotOpenException");
953
                } catch (RasterDriverException e) {
954
                        throw new HistogramException("RasterDriverException");
955
                }
956
        }
957

    
958
        /*
959
         * (non-Javadoc)
960
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
961
         */
962
        public int getPercent() {
963
                if (histogram != null) return histogram.getPercent();
964
                return 0;
965
        }
966
        
967
        
968
        /*
969
         * (non-Javadoc)
970
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
971
         */
972
        public void resetPercent() {
973
                if (histogram != null) histogram.resetPercent();
974
        }
975

    
976
        /*
977
         * (non-Javadoc)
978
         * @see org.gvsig.raster.util.ICancellable#isCanceled()
979
         */
980
        public boolean isCanceled(int process) {
981
                if(process == CANCEL_HISTOGRAM) {
982
                        if (histogram != null) 
983
                                return histogram.isCanceled(0);
984
                }
985
                return false;
986
        }
987

    
988
        /*
989
         * (non-Javadoc)
990
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
991
         */
992
        public void setCanceled(boolean value, int process) {
993
                if(process == CANCEL_HISTOGRAM || process == 0) 
994
                        if (histogram != null) 
995
                                histogram.setCanceled(value, 0);
996
                        
997
        }
998
}