Statistics
| Revision:

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

History | View | Annotate | Download (34.3 KB)

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

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

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

    
39

    
40
/**
41
 * Clase que representa una imagen de raster georreferenciada formada por varias
42
 * imagenes de disco que tienen la misma extensi?n. Contiene funcionalidades para 
43
 * abrir ficheros, gestionar el extent, pintar el raster sobre un DataImage con 
44
 * su gesti?n de bandas correspondiente.
45
 *  
46
 * @author Nacho Brodin (nachobrodin@gmail.com)
47
 *
48
 */
49
public class RasterMultiDataset implements IHistogramable {
50
        
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 RasterMultiDataset(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 RasterMultiDataset copyDataset() {
74
                try {
75
                        String[] fileList = getNameDatasetStringList();
76
                        RasterMultiDataset multiRasterDataset = RasterMultiDataset.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 RasterMultiDataset open(IProjection proj, Object datasetOpenParam) throws NotSupportedExtensionException, RasterDriverException{
102
                RasterMultiDataset rmd = new RasterMultiDataset(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
                        System.out.println("");                
316
                        System.out.println("4*............................");
317
                        bandList.show();
318
                        
319
                        for(int iBand = 0; iBand < getDataset(iDataset).getBandCount(); iBand ++) {
320
                                int[] posToDraw = bandList.getBufferBandToDraw(name, iBand);
321
                                if(posToDraw != null) {
322
                                        for(int i = 0; i < posToDraw.length; i ++) {
323
                                                switch(getDataType()[iDataset]) {
324
                                                case IBuffer.TYPE_BYTE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
325
                                                case IBuffer.TYPE_SHORT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
326
                                                case IBuffer.TYPE_INT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
327
                                                case IBuffer.TYPE_FLOAT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
328
                                                case IBuffer.TYPE_DOUBLE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
329
                                                }
330
                                        }
331
                                }
332
                        }
333
                }
334
        }
335
        
336
        /**
337
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
338
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
339
         * pixeles de disco. 
340
         * @param x Posici?n X superior izquierda
341
         * @param y Posici?n Y superior izquierda
342
         * @param w Ancho en coordenadas reales
343
         * @param h Alto en coordenadas reales
344
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
345
         * @param bandList
346
         * @return Buffer de datos
347
         */
348
        public IBuffer getWindowRaster(double x, double y, double w, double h, boolean adjustToExtent) 
349
                throws InvalidSetViewException {
350
                
351
                Extent selectedExtent = new Extent(x, y, x + w, y - h);
352

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

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

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

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

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

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

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

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

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

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