Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / RasterMultiDataset.java @ 11079

History | View | Annotate | Download (32 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.lang.reflect.Constructor;
24
import java.lang.reflect.InvocationTargetException;
25
import java.util.ArrayList;
26

    
27
import org.cresques.cts.IProjection;
28
import org.gvsig.raster.buffer.RasterBuffer;
29
import org.gvsig.raster.dataset.io.GdalDriver;
30
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
31
import org.gvsig.raster.dataset.properties.DatasetListHistogram;
32
import org.gvsig.raster.dataset.properties.DatasetListStatistics;
33
import org.gvsig.raster.dataset.properties.DatasetListTransparency;
34
import org.gvsig.raster.dataset.properties.DatasetPalette;
35
import org.gvsig.raster.dataset.properties.DatasetTransparency;
36
import org.gvsig.raster.shared.Extent;
37
import org.gvsig.raster.util.DataClassList;
38
import org.gvsig.raster.util.Histogram;
39
import org.gvsig.raster.util.HistogramException;
40
import org.gvsig.raster.util.IHistogramable;
41
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
42
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
43
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
44

    
45

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

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

    
511
        /**
512
         * Obtiene la anchura de la imagen a partir de la primera
513
         * @return anchura
514
         */
515
        public double[] getWidth() {
516
                double[] lenghts = new double[getDatasetCount()];
517
                for(int i = 0; i < getDatasetCount(); i++)
518
                        if(((RasterDataset)files.get(i)) != null)
519
                                lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
520
                return lenghts;        
521
        }
522
        
523
        /**
524
         * Obtiene el n?mero de bandas del fichero
525
         * @return
526
         */
527
        public int getBandCount(){
528
                return bandList.getBandCount();
529
        }
530

    
531
        /**
532
         * Obtiene el tipo de dato por banda
533
         * @return tipo de dato por banda
534
         */
535
        public int[] getDataType() {
536
                int[] dt = new int[getDatasetCount()];
537
                for(int i=0;i<files.size();i++)
538
                        dt[i] = ((RasterDataset)files.get(i)).getDataType();
539
                                
540
            if(dt.length == 0)
541
                    return null;
542
            else
543
                    return dt;
544
        }
545
        
546
        /**
547
         * Obtiene fichero de la posici?n i.
548
         * @param i Posici?n del fichero a obtener.
549
         * @return GeoRasterFileDataset.
550
         */
551
        public RasterDataset getDataset(int i){
552
                return (RasterDataset)files.get(i);
553
        }
554
        
555
        /**
556
         * Obtiene fichero de nombre fileName.
557
         * @param i Posici?n del fichero a obtener.
558
         * @return GeoRasterFile.
559
         */
560
        public RasterDataset getDataset(String fileName){
561
                for(int i=0;i<files.size();i++){
562
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
563
                                return (RasterDataset)files.get(i); 
564
                }
565
                return null;                
566
        }
567
        
568
        /**
569
         * Asigna el nombre al GeoRasterMultiFile
570
         * @param name Nombre del GeoRasterMultiFile
571
         */
572
        public void setName(String name){
573
                this.name = name;
574
        }
575
        
576
        /**
577
         * Obtiene la lista de bandas
578
         * @return BandList
579
         */
580
        public BandList getBands(){
581
                return bandList;
582
        }
583
        
584
        /**
585
         * Obtiene la coordenada X m?nima de toda la lista
586
         * @return Coordenada X m?nima
587
         */
588
        public double getMinX(){
589
                double minx = Double.MAX_VALUE;
590
                for(int i = 0; i < files.size(); i++){
591
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
592
                        if(aux < minx)
593
                                minx = aux;
594
                }
595
                return minx;
596
        }
597
        
598
        /**
599
         * Obtiene la coordenada Y m?nima de toda la lista
600
         * @return Coordenada Y m?nima
601
         */
602
        public double getMinY(){
603
                double miny = Double.MAX_VALUE;
604
                for(int i = 0; i < files.size(); i++){
605
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
606
                        if(aux < miny)
607
                                miny = aux;
608
                }
609
                return miny;
610
        }
611
        
612
        /**
613
         * Obtiene la coordenada Y m?xima de toda la lista
614
         * @return Coordenada Y m?xima
615
         */
616
        public double getMaxX(){
617
                double maxx = Double.MIN_VALUE;
618
                for(int i = 0; i < files.size(); i++){
619
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
620
                        if(aux > maxx)
621
                                maxx = aux;
622
                }
623
                return maxx;
624
        }
625

    
626
        /**
627
         * Obtiene la coordenada Y m?xima de toda la lista
628
         * @return Coordenada Y m?xima
629
         */
630
        public double getMaxY(){
631
                double maxy = Double.MIN_VALUE;
632
                for(int i = 0; i < files.size(); i++){
633
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
634
                        if(aux > maxy)
635
                                maxy = aux;
636
                }
637
                return maxy;
638
        }
639
        
640
        /**
641
         * Obtiene el extent del multi fichero. Este corresponde al primer
642
         * GeoRasterFile de la lista.
643
         * @return Extent
644
         */
645
        public Extent getExtent(){
646
                if(files.size() == 0)
647
                        return null;
648
                else
649
                        return ((RasterDataset)files.get(0)).getExtent();
650
        }
651
        
652
        /**
653
     * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el 
654
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
655
     * pero para un raster rotado ser? igual al extent del raster como si no 
656
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
657
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
658
     * aplicado.
659
     * @return Extent
660
     */
661
    public Extent getExtentForRequest() {
662
        return ((RasterDataset)files.get(0)).getExtentForRequest();
663
    }
664
        
665
        /**
666
         * Obtiene las coordenadas del fichero worldFile (o cabecera del raster) asociado 
667
         * o el RMF en caso de que existan. Si la imagen no est? georreferenciada tendr?
668
         * las coordenadas pixel de la misma 
669
         * @return Array de seis valores:
670
         *         <TABLE BORDER="1">
671
         *         <TR><TD><B>0:</B></TD><TD>Valor X de la esquina superior izquierda.</TD></TR>
672
         *         <TR><TD><B>1:</B></TD><TD>Tama?o de pixel en X.</TD></TR>
673
         *         <TR><TD><B>2:</B></TD><TD>Shearing en X.</TD></TR>
674
         *         <TR><TD><B>3:</B></TD><TD>Valor Y de la esquina superior izquierda.</TD></TR>
675
         *         <TR><TD><B>4:</B></TD><TD>Shearing en Y.</TD></TR>
676
         *         <TR><TD><B>5:</B></TD><TD>Tama?o de pixel en Y.</TD></TR>
677
         *         </TABLE>
678
         */
679
        public double[] getCoordsGeoTransformFile(){
680
                return ((RasterDataset)files.get(0)).getTransform();
681
        }
682
        
683
        /**
684
         * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
685
         * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
686
         * que se hayan aplicado sobre el/los dataset.
687
         * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
688
         * solicitada.
689
         */
690
        public Extent getLastSelectedView(){
691
                return ((RasterDataset)files.get(0)).getView();
692
        }
693
        
694
        /**
695
         * Obtiene el tama?o de pixel.
696
         * @return array de dos elementos, tama?o de pixel en X y en Y.
697
         */
698
        public double[] getPixelSize(){
699
                double[] at = ((RasterDataset)files.get(0)).getTransform();
700
                return new double[]{at[1], at[5]};
701
        }
702
        
703
        /**
704
         * Obtiene el estado de transparencia a partir de los estados de transparencia de todos
705
         * los ficheros que lo componen. Si varios de los ficheros que lo componen tienen banda de 
706
         * transparencia estas tendr?n que ser mezcladas sobre una banda de transparencia ?nica.
707
         * @return Objeto FileTransparency con el estado de transparencia
708
         */
709
        public DatasetListTransparency getTransparencyFilesStatus(){
710
                DatasetListTransparency out = null;
711
                for(int i = 0; i < files.size(); i++){
712
                        DatasetTransparency tfs = ((RasterDataset)files.get(i)).getTransparencyDatasetStatus();
713
                        if(tfs != null){
714
                                if(out == null)
715
                                        out = new DatasetListTransparency(tfs);
716
                                else
717
                                        out.merge(tfs);
718
                        }
719
                }
720
                return out;
721
        }
722
        
723
        /**
724
         * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
725
         * @param i Posici?n del raster
726
         * @return Paleta asociada a este o null si no tiene
727
         */
728
        public DatasetPalette getPalette(int i){
729
                if(i >= files.size())
730
                        return null;
731
                return ((RasterDataset)files.get(i)).getPalette();
732
        }
733
        
734
        /**
735
         * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
736
         * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
737
         * para ese fichero no hay paletas asociadas.
738
         */
739
        public DatasetPalette[] getPalettes(){
740
                if(files.size() <= 0)
741
                        return null;
742
                DatasetPalette[] list = new DatasetPalette[files.size()];
743
                for(int i = 0; i < files.size(); i++)
744
                        list[i] = ((RasterDataset)files.get(i)).getPalette();
745
                return list;
746
        }
747
        
748
        /**
749
         * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro. 
750
         * @param fileName Nombre del fichero
751
         * @return Paleta o null si no la tiene
752
         */
753
        public DatasetPalette getPalette(String fileName){
754
                for(int i = 0; i < files.size(); i++){
755
                        if(((RasterDataset)files.get(i)).getFName().indexOf(fileName) == 0)
756
                                return ((RasterDataset)files.get(i)).getPalette();
757
                }
758
                return null;
759
        }
760
        
761
        /**
762
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
763
         * @param pt Punto a transformar
764
         * @return punto transformado en coordenadas del mundo
765
         */
766
        public Point2D rasterToWorld(Point2D pt) {
767
                return ((RasterDataset)files.get(0)).rasterToWorld(pt);
768
        }
769
        
770
        /**
771
         * Convierte un punto desde del mundo a coordenadas pixel.
772
         * @param pt Punto a transformar
773
         * @return punto transformado en coordenadas pixel
774
         */
775
        public Point2D worldToRaster(Point2D pt) {
776
                return ((RasterDataset)files.get(0)).worldToRaster(pt);
777
        }
778
        
779
        /**
780
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
781
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
782
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
783
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
784
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
785
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
786
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
787
         * el driver autom?ticamente.
788
         * @param dWorldTLX Coordenada real X superior izquierda
789
         * @param dWorldTLY Coordenada real Y superior izquierda
790
         * @param nWidth Ancho del raster
791
         * @param nHeight Alto del raster
792
         * @param bufWidth Ancho del buffer
793
         * @param bufHeight Alto del buffer
794
         * @return Array de dos elementos con el desplazamiento en X e Y. 
795
         */
796
        public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
797
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
798
                return ((RasterDataset)files.get(0)).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
799
        }
800
        
801
        /**
802
         * Obtiene el objeto con las estadisticas
803
         * @return MultiFileStatistics
804
         */
805
        public DatasetListStatistics getStatistics(){
806
                return stats;
807
        }
808
        
809
        /**
810
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
811
         * @return true si est? georreferenciada y false si no lo est?.
812
         */
813
        public boolean isGeoreferenced() {
814
                for(int i = 0; i < files.size(); i++){
815
                        if(((RasterDataset)files.get(i)).isGeoreferenced())
816
                                return true;
817
                }
818
                return false;
819
        }
820

    
821
        //TODO: TEST: Probar getData para multifichero
822
        /**
823
         * Obtiene el valor del raster en la coordenada que se le pasa.
824
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
825
         * raster.
826
         * @param x        coordenada X
827
         * @param y coordenada Y
828
         * @return
829
         */
830
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
831
                String file = bandList.getBand(band).getFileName();
832
                for(int i = 0; i < files.size(); i++){
833
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
834
                                return ((RasterDataset)files.get(i)).getData(x, y, band); 
835
                }
836
                return null;
837
        }
838
        
839
        /**
840
         * Obtiene el histograma. 
841
         * 
842
         * @return Histograma
843
         */
844
        public Histogram getHistogram(DataClassList classes)throws FileNotOpenException, RasterDriverException{
845
                if (histogram == null)
846
                        histogram = new DatasetListHistogram(this);
847
                histogram.setClasses(classes);
848
                return histogram.getHistogram();
849
        }
850
        
851
        /**
852
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
853
         * color por banda para el dataset seleccionado
854
         * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
855
         * @return DatasetColorInterpretation
856
         */
857
        public DatasetColorInterpretation getColorInterpretation(int dataset){
858
                return ((RasterDataset)files.get(dataset)).getColorInterpretation();
859
        }
860
        
861
        /**
862
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
863
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
864
         * dataset.
865
         * @return Proyecci?n en formato cadena
866
         * @throws RasterDriverException
867
         */
868
        public String getStringProjection() throws RasterDriverException{
869
                return ((RasterDataset)files.get(0)).getStringProjection();
870
        }
871

    
872
        /*
873
         * (non-Javadoc)
874
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
875
         */
876
        public Histogram getHistogram() throws HistogramException {
877
                if(histogram == null)
878
                        histogram = new DatasetListHistogram(this);
879
                
880
                try {
881
                        Histogram tmp = histogram.getHistogram();
882
                        return tmp;
883
                } catch (FileNotOpenException e) {
884
                        throw new HistogramException("FileNotOpenException");
885
                } catch (RasterDriverException e) {
886
                        throw new HistogramException("RasterDriverException");
887
                }
888
        }
889
        
890
        /*
891
         * (non-Javadoc)
892
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogramUsingClasses(org.gvsig.raster.shared.DataClassList)
893
         */
894
        public Histogram getHistogramUsingClasses(DataClassList classes)throws HistogramException {
895
                if(histogram == null)
896
                        histogram = new DatasetListHistogram(this);
897
                histogram.setClasses(classes);
898
                try {
899
                        return histogram.getHistogram();
900
                } catch (FileNotOpenException e) {
901
                        throw new HistogramException("FileNotOpenException");
902
                } catch (RasterDriverException e) {
903
                        throw new HistogramException("RasterDriverException");
904
                }
905
        }
906

    
907
        /*
908
         * (non-Javadoc)
909
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
910
         */
911
        public int getPercent() {
912
                if (histogram != null) return histogram.getPercent();
913
                return 0;
914
        }
915
        
916
        
917
        /*
918
         * (non-Javadoc)
919
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
920
         */
921
        public void resetPercent() {
922
                if (histogram != null) histogram.resetPercent();
923
        }
924

    
925
        /*
926
         * (non-Javadoc)
927
         * @see org.gvsig.raster.util.ICancellable#isCanceled()
928
         */
929
        public boolean isCanceled() {
930
                if (histogram != null) return histogram.isCanceled();
931
                return false;
932
        }
933

    
934
        /*
935
         * (non-Javadoc)
936
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
937
         */
938
        public void setCanceled(boolean value) {
939
                if (histogram != null) histogram.setCanceled(value);
940
        }
941
}