Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / MultiRasterDataset.java @ 12749

History | View | Annotate | Download (42.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.AffineTransform;
22
import java.awt.geom.Point2D;
23
import java.io.File;
24
import java.io.IOException;
25
import java.util.ArrayList;
26

    
27
import org.cresques.cts.IProjection;
28
import org.gvsig.raster.buffer.RasterBuffer;
29
import org.gvsig.raster.buffer.cache.RasterReadOnlyHugeBuffer;
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.datastruct.ColorTable;
34
import org.gvsig.raster.datastruct.Extent;
35
import org.gvsig.raster.datastruct.Histogram;
36
import org.gvsig.raster.datastruct.HistogramException;
37
import org.gvsig.raster.datastruct.Transparency;
38
import org.gvsig.raster.hierarchy.IHistogramable;
39

    
40

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

    
335
        /**
336
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
337
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
338
         * pixeles de disco. 
339
         * @param x Posici?n X superior izquierda
340
         * @param y Posici?n Y superior izquierda
341
         * @param w Ancho en coordenadas reales
342
         * @param h Alto en coordenadas reales
343
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
344
         * @param bandList
345
         * @return Buffer de datos
346
         */
347
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry) throws InvalidSetViewException {                
348
                Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
349

    
350
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
351
                //por arriba el m?s alto y por abajo el menor y luego restandolos
352
                
353
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(ulx, uly));
354
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(lrx, lry));
355
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
356
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
357
                
358
                //Ajustamos por si nos hemos salido del raster
359
                while(((int)(p1.getX() + width)) > getWidth()[0])
360
                        width --;
361
                while(((int)(p1.getY() + height)) > getHeight()[0])
362
                        height --;
363
                
364
                if(p1.getX() < 0)
365
                        p1.setLocation(0, p1.getY());
366
                if(p1.getY() < 0)
367
                        p1.setLocation(p1.getX(), 0);
368
                if(p2.getX() > getWidth()[0])
369
                        p2.setLocation(getWidth()[0], p2.getY());
370
                if(p1.getY() > getHeight()[0])
371
                        p1.setLocation(p2.getX(), getHeight()[0]);
372
                
373
                int mallocNBands = 0;
374
                if(bandList.getDrawableBands() != null)
375
                        mallocNBands = bandList.getDrawableBands().length;
376
                else
377
                        mallocNBands = bandList.getDrawableBandsCount();
378
                
379
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
380
                
381
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
382
                if(!raster.isBandSwitchable()) {
383
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0).getBandCount(), false);
384
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
385
                                try {
386
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
387
                                } catch (FileNotExistsException e) {
388
                                        //Esto no debe darse ya que se comprueba al hacer el open
389
                                } catch (NotSupportedExtensionException e) {
390
                                        //Esto no debe darse ya que se comprueba al hacer el open
391
                                }
392
                                return rb;
393
                        }
394
                }
395
                                        
396
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
397
                        raster.assignBandToNotValid(iBand);
398
                
399
                //Reservamos memoria para los buffers por dataset
400
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
401
                
402
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor 
403
                //equivalente a los pixeles redondeados.
404
                Point2D wc1 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
405
                Point2D wc2 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
406
                for(int i = 0; i < getDatasetCount(); i++)
407
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), wc2.getX(), wc2.getY(), bandList, bufferDatasets[i]);
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 reales
422
         * @param h Alto en coordenadas reales
423
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
424
         * @param bandList
425
         * @return Buffer de datos
426
         */
427
        public IBuffer getWindowRaster(double ulx, double uly, double w, double h, boolean adjustToExtent) 
428
                throws InvalidSetViewException {
429
                //El incremento o decremento de las X e Y depende de los signos de rotaci?n y escala en la matriz de transformaci?n. Por esto
430
                //tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o y - h 
431
                Extent ext = getExtent();
432
                Point2D pInit = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(0, 0));
433
                Point2D pEnd = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double((int)getWidth()[0], (int)getHeight()[0]));
434
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
435
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
436
                double lrx = (((int)(ext.getULX() - wRaster)) == ((int)ext.getLRX())) ? (ulx - w) : (ulx + w);
437
                double lry = (((int)(ext.getULY() - hRaster)) == ((int)ext.getLRY())) ? (uly - h) : (uly + h); 
438
                
439
                Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
440

    
441
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
442
                //por arriba el m?s alto y por abajo el menor y luego restandolos
443
                
444
                Point2D p1 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(ulx, uly));
445
                Point2D p2 = ((RasterDataset)files.get(0)).worldToRaster(new Point2D.Double(lrx, lry));
446
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
447
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
448
                
449
                //Ajustamos por si nos hemos salido del raster
450
                while(((int)(p1.getX() + width)) > getWidth()[0])
451
                        width --;
452
                while(((int)(p1.getY() + height)) > getHeight()[0])
453
                        height --;
454
                
455
                if(p1.getX() < 0)
456
                        p1.setLocation(0, p1.getY());
457
                if(p1.getY() < 0)
458
                        p1.setLocation(p1.getX(), 0);
459
                if(p2.getX() > getWidth()[0])
460
                        p2.setLocation(getWidth()[0], p2.getY());
461
                if(p1.getY() > getHeight()[0])
462
                        p1.setLocation(p2.getX(), getHeight()[0]);
463
                
464
                int mallocNBands = 0;
465
                if(bandList.getDrawableBands() != null)
466
                        mallocNBands = bandList.getDrawableBands().length;
467
                else
468
                        mallocNBands = bandList.getDrawableBandsCount();
469
                
470
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], width, height, mallocNBands, false);
471
                
472
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
473
                if(!raster.isBandSwitchable()) {
474
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], width, height, getDataset(0).getBandCount(), false);
475
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
476
                                try {
477
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
478
                                } catch (FileNotExistsException e) {
479
                                        //Esto no debe darse ya que se comprueba al hacer el open
480
                                } catch (NotSupportedExtensionException e) {
481
                                        //Esto no debe darse ya que se comprueba al hacer el open
482
                                }
483
                                return rb;
484
                        }
485
                                
486
                }
487
                                        
488
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
489
                        raster.assignBandToNotValid(iBand);
490
                
491
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
492
                //m?s grande y salirse de los l?mites.
493
                if(!adjustToExtent)
494
                         initBufferToNoData(raster, bandList);
495
                
496
                //Reservamos memoria para los buffers por dataset
497
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
498
                
499
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor 
500
                //equivalente a los pixeles redondeados.
501
                Point2D wc1 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
502
                Point2D wc2 = ((RasterDataset)files.get(0)).rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
503
                for(int i = 0; i < getDatasetCount(); i++)
504
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), Math.abs(wc2.getX() - wc1.getX()), Math.abs(wc2.getY() - wc1.getY()), bandList, bufferDatasets[i], adjustToExtent);
505
                        //bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
506
                
507
                //Mezclamos los buffers de cada dataset en un solo buffer
508
                mergeBuffers(raster, bufferDatasets, bandList);
509
                                                        
510
                return raster;
511
        }
512
                
513
        /**
514
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
515
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
516
         * el driver.
517
         * @param minX Valor m?nimo de la X en coordenadas reales
518
         * @param minY Valor m?nimo de la Y en coordenadas reales
519
         * @param maxX Valor m?ximo de la X en coordenadas reales
520
         * @param maxY Valor m?ximo de la Y en coordenadas reales
521
         * @param bufWidth ancho del buffer lde datos
522
         * @param bufHeight alto del buffer de datos
523
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
524
         * @param bandList
525
         * @return Buffer de datos
526
         */
527
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, 
528
                                                                        int bufWidth, int bufHeight, boolean adjustToExtent) throws InvalidSetViewException {
529
                
530
                Point2D p1 = worldToRaster(new Point2D.Double(ulx, uly));
531
                Point2D p2 = worldToRaster(new Point2D.Double(lrx, lry));
532
                if(        ((int)p1.getX()) < 0 || ((int)p2.getX()) > getWidth()[0] ||
533
                                ((int)p2.getY()) > getHeight()[0] || ((int)p2.getY()) < 0)
534
                                throw new InvalidSetViewException("");
535
                
536
                int mallocNBands = 0;
537
                if(bandList.getDrawableBands() != null)
538
                        mallocNBands = bandList.getDrawableBands().length;
539
                else
540
                        mallocNBands = bandList.getDrawableBandsCount();
541
                
542
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
543
                
544
                //TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
545
                //Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
546
                /*if(!raster.isBandSwitchable()) {
547
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
548
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
549
                                try {
550
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), selectedExtent);
551
                                } catch (FileNotExistsException e) {
552
                                        //Esto no debe darse ya que se comprueba al hacer el open
553
                                } catch (NotSupportedExtensionException e) {
554
                                        //Esto no debe darse ya que se comprueba al hacer el open
555
                                }
556
                                return rb;
557
                        }
558
                }*/
559
                        
560
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
561
                        raster.assignBandToNotValid(iBand);
562
                
563
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
564
                //m?s grande y salirse de los l?mites.
565
                if(!adjustToExtent)
566
                         initBufferToNoData(raster, bandList);        
567
                
568
                //Reservamos memoria para los buffers por dataset
569
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
570
                for(int i = 0; i < getDatasetCount(); i++)
571
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(ulx, uly, lrx, lry, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
572
                
573
                //Mezclamos los buffers de cada dataset en un solo buffer
574
                mergeBuffers(raster, bufferDatasets, bandList);
575
                                                        
576
                return raster;
577
        }
578
        
579
        /**
580
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
581
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
582
         * pixeles de disco. 
583
         * @param x Posici?n X superior izquierda
584
         * @param y Posici?n Y superior izquierda
585
         * @param w Ancho en coordenadas pixel
586
         * @param h Alto en coordenadas pixel
587
         * @param bandList
588
         * @return Buffer de datos
589
         */
590
        public IBuffer getWindowRaster(int x, int y, int w, int h) throws InvalidSetViewException {
591
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
592
                        throw new InvalidSetViewException("Out of image");
593
                
594
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
595
                
596
                //Caso en el que un buffer no se puedan conmutar las bandas (t?picamente RasterReadOnlyHugeBuffer)
597
                if(!raster.isBandSwitchable()) {
598
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], w, h, getDataset(0).getBandCount(), false);
599
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
600
                                try {
601
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
602
                                } catch (FileNotExistsException e) {
603
                                        //Esto no debe darse ya que se comprueba al hacer el open
604
                                } catch (NotSupportedExtensionException e) {
605
                                        //Esto no debe darse ya que se comprueba al hacer el open
606
                                }
607
                                return rb;
608
                        }
609
                }
610
                                
611
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
612
                        raster.assignBandToNotValid(iBand);
613
                
614
                //Reservamos memoria para los buffers por dataset
615
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, w, h);
616
                for(int i = 0; i < getDatasetCount(); i++)
617
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i]);
618
                
619
                //Mezclamos los buffers de cada dataset en un solo buffer
620
                mergeBuffers(raster, bufferDatasets, bandList);
621
                                                        
622
                return raster;
623
        }
624
        
625
        /**
626
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
627
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer
628
         * @param x Posici?n X superior izquierda en pixels
629
         * @param y Posici?n Y superior izquierda en pixels
630
         * @param w Ancho en pixels
631
         * @param h Alto en pixels
632
         * @param bufWidth ancho del buffer de datos
633
         * @param bufHeight alto del buffer de datos
634
         * @param bandList
635
         * @return Buffer de datos
636
         */
637
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight)  
638
                throws InvalidSetViewException {
639
                if(x < 0 || y < 0 || w > ((RasterDataset)files.get(0)).getWidth() || h > ((RasterDataset)files.get(0)).getHeight())
640
                        throw new InvalidSetViewException("Out of image");
641
                                
642
                IBuffer raster = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
643
                        
644
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
645
                        raster.assignBandToNotValid(iBand);
646
                        
647
                //Reservamos memoria para los buffers por dataset
648
                IBuffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
649
                
650
                //TODO: FUNCIONALIDAD: Si la petici?n es muy grande en solo lectura y con resampleo de buffer
651
                //Este caso no deberia darse en una petici?n con resampleo ya que RasterReadOnlyHugeBuffer hace referencia a la imagen en disco
652
                /*if(!raster.isBandSwitchable()) {
653
                        RasterBuffer rb = RasterBuffer.getBuffer(getDataType()[0], bufWidth, bufHeight, getDataset(0).getBandCount(), false);
654
                        if(rb instanceof RasterReadOnlyHugeBuffer) {
655
                                try {
656
                                        ((RasterReadOnlyHugeBuffer)rb).setBufferParams(getDataset(0).getFName(), x, y, x + w, y + h);
657
                                } catch (FileNotExistsException e) {
658
                                        //Esto no debe darse ya que se comprueba al hacer el open
659
                                } catch (NotSupportedExtensionException e) {
660
                                        //Esto no debe darse ya que se comprueba al hacer el open
661
                                }
662
                                return rb;
663
                        }
664
                }*/
665
                        
666
                for(int i = 0; i < getDatasetCount(); i++)
667
                        bufferDatasets[i] = ((RasterDataset)files.get(i)).getWindowRaster(x, y, w, h, bufWidth, bufHeight, bandList, bufferDatasets[i]);
668

    
669
                //Mezclamos los buffers de cada dataset en un solo buffer
670
                mergeBuffers(raster, bufferDatasets, bandList);
671
                                                        
672
                return raster;
673
        }
674
        
675
        //******************************
676
        //Setters and Getters
677
        //******************************
678
        
679
        /**
680
         * Calcula el tama?o de los ficheros en disco
681
         * @return tama?o en bytes de todos los ficheros de la lista
682
         */
683
        public long getFileSize(){
684
                int len = 0;
685
                for(int i=0;i<files.size();i++){
686
                        if(((RasterDataset)files.get(i)) != null){
687
                                File f = new File(((RasterDataset)files.get(i)).getFName());
688
                                len += f.length();
689
                        }
690
                }
691
                return len;
692
        }
693
        
694
        /**
695
         * Obtiene la altura de la imagen a partir de la primera
696
         * @return altura
697
         */
698
        public double[] getHeight() {
699
                double[] lenghts = new double[getDatasetCount()];
700
                for(int i = 0; i < getDatasetCount(); i++)
701
                        if(((RasterDataset)files.get(i)) != null)
702
                                lenghts[i] = ((RasterDataset)files.get(i)).getHeight();
703
                return lenghts;
704
        }
705

    
706
        /**
707
         * Obtiene la anchura de la imagen a partir de la primera
708
         * @return anchura
709
         */
710
        public double[] getWidth() {
711
                double[] lenghts = new double[getDatasetCount()];
712
                for(int i = 0; i < getDatasetCount(); i++)
713
                        if(((RasterDataset)files.get(i)) != null)
714
                                lenghts[i] = ((RasterDataset)files.get(i)).getWidth();
715
                return lenghts;        
716
        }
717
        
718
        /**
719
         * Obtiene el n?mero de bandas del fichero
720
         * @return
721
         */
722
        public int getBandCount(){
723
                return bandList.getBandCount();
724
        }
725

    
726
        /**
727
         * Obtiene el tipo de dato por banda
728
         * @return tipo de dato por banda
729
         */
730
        public int[] getDataType() {
731
                int[] dt = new int[getDatasetCount()];
732
                for(int i=0;i<files.size();i++)
733
                        dt[i] = ((RasterDataset)files.get(i)).getDataType();
734
                                
735
            if(dt.length == 0)
736
                    return null;
737
            else
738
                    return dt;
739
        }
740
        
741
        /**
742
         * Obtiene fichero de la posici?n i.
743
         * @param i Posici?n del fichero a obtener.
744
         * @return GeoRasterFileDataset.
745
         */
746
        public RasterDataset getDataset(int i){
747
                return (RasterDataset)files.get(i);
748
        }
749
        
750
        /**
751
         * Obtiene fichero de nombre fileName.
752
         * @param i Posici?n del fichero a obtener.
753
         * @return GeoRasterFile.
754
         */
755
        public RasterDataset getDataset(String fileName){
756
                for(int i=0;i<files.size();i++){
757
                        if(((RasterDataset)files.get(i)).getFName().equals(fileName))
758
                                return (RasterDataset)files.get(i); 
759
                }
760
                return null;                
761
        }
762
        
763
        /**
764
         * Asigna el nombre al GeoRasterMultiFile
765
         * @param name Nombre del GeoRasterMultiFile
766
         */
767
        public void setName(String name){
768
                this.name = name;
769
        }
770
        
771
        /**
772
         * Obtiene la lista de bandas
773
         * @return BandList
774
         */
775
        public BandList getBands(){
776
                return bandList;
777
        }
778
        
779
        /**
780
         * Obtiene la coordenada X m?nima de toda la lista
781
         * @return Coordenada X m?nima
782
         */
783
        public double getMinX(){
784
                double minx = Double.MAX_VALUE;
785
                for(int i = 0; i < files.size(); i++){
786
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getX();
787
                        if(aux < minx)
788
                                minx = aux;
789
                }
790
                return minx;
791
        }
792
        
793
        /**
794
         * Obtiene la coordenada Y m?nima de toda la lista
795
         * @return Coordenada Y m?nima
796
         */
797
        public double getMinY(){
798
                double miny = Double.MAX_VALUE;
799
                for(int i = 0; i < files.size(); i++){
800
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
801
                        if(aux < miny)
802
                                miny = aux;
803
                }
804
                return miny;
805
        }
806
        
807
        /**
808
         * Obtiene la coordenada Y m?xima de toda la lista
809
         * @return Coordenada Y m?xima
810
         */
811
        public double getMaxX(){
812
                double maxx = Double.NEGATIVE_INFINITY;
813
                for(int i = 0; i < files.size(); i++){
814
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
815
                        if(aux > maxx)
816
                                maxx = aux;
817
                }
818
                return maxx;
819
        }
820

    
821
        /**
822
         * Obtiene la coordenada Y m?xima de toda la lista
823
         * @return Coordenada Y m?xima
824
         */
825
        public double getMaxY(){
826
                double maxy = Double.NEGATIVE_INFINITY;
827
                for(int i = 0; i < files.size(); i++){
828
                        double aux = ((RasterDataset)files.get(i)).getExtent().getMin().getY();
829
                        if(aux > maxy)
830
                                maxy = aux;
831
                }
832
                return maxy;
833
        }
834
        
835
        /**
836
         * Obtiene el extent del multi fichero. Este corresponde al primer
837
         * GeoRasterFile de la lista.
838
         * @return Extent
839
         */
840
        public Extent getExtent(){
841
                if(files.size() == 0)
842
                        return null;
843
                else
844
                        return ((RasterDataset)files.get(0)).getExtent();
845
        }
846
        
847
        /**
848
     * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el 
849
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
850
     * pero para un raster rotado ser? igual al extent del raster como si no 
851
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
852
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
853
     * aplicado.
854
     * @return Extent
855
     */
856
    public Extent getExtentForRequest() {
857
        return ((RasterDataset)files.get(0)).getExtentWithoutRot();
858
    }
859
        
860
        /**
861
         * Obtiene las coordenadas del fichero worldFile (o cabecera del raster) asociado 
862
         * o el RMF en caso de que existan. Si la imagen no est? georreferenciada tendr?
863
         * las coordenadas pixel de la misma 
864
         * @return Array de seis valores:
865
         *         <TABLE BORDER="1">
866
         *         <TR><TD><B>0:</B></TD><TD>Valor X de la esquina superior izquierda.</TD></TR>
867
         *         <TR><TD><B>1:</B></TD><TD>Tama?o de pixel en X.</TD></TR>
868
         *         <TR><TD><B>2:</B></TD><TD>Shearing en X.</TD></TR>
869
         *         <TR><TD><B>3:</B></TD><TD>Valor Y de la esquina superior izquierda.</TD></TR>
870
         *         <TR><TD><B>4:</B></TD><TD>Shearing en Y.</TD></TR>
871
         *         <TR><TD><B>5:</B></TD><TD>Tama?o de pixel en Y.</TD></TR>
872
         *         </TABLE>
873
         */
874
        public AffineTransform getCoordsGeoTransformFile(){
875
                return ((RasterDataset)files.get(0)).getAffineTransform();
876
        }
877
        
878
        /**
879
         * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
880
         * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
881
         * que se hayan aplicado sobre el/los dataset.
882
         * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
883
         * solicitada.
884
         */
885
        public Extent getLastSelectedView(){
886
                return ((RasterDataset)files.get(0)).getView();
887
        }
888
                
889
        /**
890
         * Obtiene el estado de transparencia a partir de los estados de transparencia de todos
891
         * los ficheros que lo componen. Si varios de los ficheros que lo componen tienen banda de 
892
         * transparencia estas tendr?n que ser mezcladas sobre una banda de transparencia ?nica.
893
         * @return Objeto FileTransparency con el estado de transparencia
894
         */
895
        public Transparency getTransparencyFilesStatus() {
896
                if(files.size() <= 0)
897
                        return null;
898
                Transparency t = ((RasterDataset)files.get(0)).getTransparencyDatasetStatus();
899
                for(int i = 1; i < files.size(); i++) {
900
                        Transparency t1 = ((RasterDataset)files.get(i)).getTransparencyDatasetStatus();
901
                        t.merge(t1);
902
                }
903
                return t;
904
        }
905
        
906
        /**
907
         * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
908
         * @param i Posici?n del raster
909
         * @return Paleta asociada a este o null si no tiene
910
         */
911
        public ColorTable getColorTable(int i){
912
                if(i >= files.size())
913
                        return null;
914
                return ((RasterDataset)files.get(i)).getColorTable();
915
        }
916
        
917
        /**
918
         * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
919
         * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
920
         * para ese fichero no hay paletas asociadas.
921
         */
922
        public ColorTable[] getColorTables(){
923
                if(files.size() <= 0)
924
                        return null;
925
                ColorTable[] list = new ColorTable[files.size()];
926
                for(int i = 0; i < files.size(); i++)
927
                        list[i] = ((RasterDataset)files.get(i)).getColorTable();
928
                return list;
929
        }
930
        
931
        /**
932
         * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro. 
933
         * @param fileName Nombre del fichero
934
         * @return Paleta o null si no la tiene
935
         */
936
        public ColorTable getColorTable(String fileName){
937
                for(int i = 0; i < files.size(); i++){
938
                        if(((RasterDataset)files.get(i)).getFName().indexOf(fileName) == 0)
939
                                return ((RasterDataset)files.get(i)).getColorTable();
940
                }
941
                return null;
942
        }
943
        
944
        /**
945
         * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
946
         * @param pt Punto a transformar
947
         * @return punto transformado en coordenadas del mundo
948
         */
949
        public Point2D rasterToWorld(Point2D pt) {
950
                return ((RasterDataset)files.get(0)).rasterToWorld(pt);
951
        }
952
        
953
        /**
954
         * Convierte un punto desde del mundo a coordenadas pixel.
955
         * @param pt Punto a transformar
956
         * @return punto transformado en coordenadas pixel
957
         */
958
        public Point2D worldToRaster(Point2D pt) {
959
                return ((RasterDataset)files.get(0)).worldToRaster(pt);
960
        }
961
        
962
        /**
963
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
964
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
965
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
966
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
967
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
968
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
969
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
970
         * el driver autom?ticamente.
971
         * @param dWorldTLX Coordenada real X superior izquierda
972
         * @param dWorldTLY Coordenada real Y superior izquierda
973
         * @param nWidth Ancho del raster
974
         * @param nHeight Alto del raster
975
         * @param bufWidth Ancho del buffer
976
         * @param bufHeight Alto del buffer
977
         * @return Array de dos elementos con el desplazamiento en X e Y. 
978
         */
979
        public int[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
980
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
981
                return ((RasterDataset)files.get(0)).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
982
        }
983
        
984
        /**
985
         * Obtiene el objeto con las estadisticas
986
         * @return MultiFileStatistics
987
         */
988
        public DatasetListStatistics getStatistics(){
989
                return stats;
990
        }
991
        
992
        /**
993
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
994
         * @return true si est? georreferenciada y false si no lo est?.
995
         */
996
        public boolean isGeoreferenced() {
997
                for(int i = 0; i < files.size(); i++){
998
                        if(((RasterDataset)files.get(i)).isGeoreferenced())
999
                                return true;
1000
                }
1001
                return false;
1002
        }
1003

    
1004
        //TODO: TEST: Probar getData para multifichero
1005
        /**
1006
         * Obtiene el valor del raster en la coordenada que se le pasa.
1007
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
1008
         * raster.
1009
         * @param x        coordenada X
1010
         * @param y coordenada Y
1011
         * @return
1012
         */
1013
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException{
1014
                String file = bandList.getBand(band).getFileName();
1015
                for(int i = 0; i < files.size(); i++){
1016
                        if(((RasterDataset)files.get(i)).getFName().equals(file))
1017
                                return ((RasterDataset)files.get(i)).getData(x, y, band); 
1018
                }
1019
                return null;
1020
        }
1021
                
1022
        /**
1023
         * Obtiene el objeto que contiene que contiene la interpretaci?n de 
1024
         * color por banda para el dataset seleccionado
1025
         * @param dataset Dataset del que se necesesita la informaci?n de color dentro del RasterMultiDataset
1026
         * @return DatasetColorInterpretation
1027
         */
1028
        public DatasetColorInterpretation getColorInterpretation(int dataset){
1029
                return ((RasterDataset)files.get(dataset)).getColorInterpretation();
1030
        }
1031
        
1032
        /**
1033
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del 
1034
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
1035
         * dataset.
1036
         * @return Proyecci?n en formato cadena
1037
         * @throws RasterDriverException
1038
         */
1039
        public String getWktProjection() throws RasterDriverException{
1040
                return ((RasterDataset)files.get(0)).getWktProjection();
1041
        }
1042

    
1043
        /*
1044
         * (non-Javadoc)
1045
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
1046
         */
1047
        public Histogram getHistogram() throws HistogramException {
1048
                if (histogram == null)
1049
                        histogram = new DatasetListHistogram(this);
1050
                
1051
                try {
1052
                        Histogram tmpHist = histogram.getHistogram();
1053
                        return tmpHist;
1054
                } catch (FileNotOpenException e) {
1055
                        throw new HistogramException("FileNotOpenException");
1056
                } catch (RasterDriverException e) {
1057
                        throw new HistogramException("RasterDriverException");
1058
                }
1059
        }
1060

    
1061
        /*
1062
         * (non-Javadoc)
1063
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
1064
         */
1065
        public int getPercent() {
1066
                if (histogram != null) return histogram.getPercent();
1067
                return 0;
1068
        }
1069
        
1070
        
1071
        /*
1072
         * (non-Javadoc)
1073
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
1074
         */
1075
        public void resetPercent() {
1076
                if (histogram != null) histogram.resetPercent();
1077
        }
1078

    
1079
        /*
1080
         * (non-Javadoc)
1081
         * @see org.gvsig.raster.util.ICancellable#isCanceled()
1082
         */
1083
        public boolean isCanceled(int process) {
1084
                if(process == CANCEL_HISTOGRAM) {
1085
                        if (histogram != null) 
1086
                                return histogram.isCanceled(0);
1087
                }
1088
                return false;
1089
        }
1090

    
1091
        /*
1092
         * (non-Javadoc)
1093
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean)
1094
         */
1095
        public void setCanceled(boolean value, int process) {
1096
                if(process == CANCEL_HISTOGRAM || process == 0) 
1097
                        if (histogram != null) 
1098
                                histogram.setCanceled(value, 0);
1099
                        
1100
        }
1101
        
1102
        /**
1103
         * Escribe sobre el rmf todos los cambios que haya para salvar, es decir, para cada
1104
         * Objeto registrado en el manager volcar? su contenido al fichero rmf.
1105
         * @throws IOException
1106
         */
1107
        public void saveRmfModification() throws IOException {
1108
                for (int i = 0; i < files.size(); i++) 
1109
                        ((RasterDataset)files.get(i)).saveRmfModification();
1110
        }
1111
        
1112
        /**
1113
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa 
1114
         * o fuera de ellos.
1115
         * @param p Punto a calcular
1116
         * @return true si est? dentro de los l?mites y false si est? fuera
1117
         */
1118
        public boolean isInside(Point2D p) {
1119
                if(getDataset(0) != null)
1120
                        return getDataset(0).isInside(p);
1121
                return false;
1122
        }
1123
        
1124
        /**
1125
         * Recupera del raster la matriz de transformaci?n que lo situa en cualquier parte de la vista
1126
         * @return AffineTransform
1127
         */
1128
        public AffineTransform getAffineTransform(){
1129
                if(getDataset(0) != null)
1130
                        return getDataset(0).getAffineTransform();
1131
                return null;
1132
        }
1133
        
1134
        /**
1135
         * Asigna al raster la matriz de transformaci?n para situarlo en cualquier parte de la vista
1136
         * @param transf
1137
         */
1138
        public void setAffineTransform(AffineTransform transf){
1139
                for (int i = 0; i < getDatasetCount(); i++) {
1140
                        this.getDataset(i).setAffineTransform(transf);        
1141
                }
1142
        }
1143
        
1144
        /**
1145
         * Obtiene la matriz de transformaci?n del propio raster. Esta matriz es la encargada
1146
         * de convertir las coordenadas de la petici?n en coordenadas a las que se pide a la libreria.
1147
         * En gdal, por ejemplo, se piden las coordenadas a la libreria en coordenadas pixel por lo que
1148
         * esta matriz tendr? la georreferenciaci?n asociada en el worldfile o cabecera. Otras librerias como
1149
         * ermapper la petici?n a la libreria se hace en coordenadas geograficas que son las mismas en las
1150
         * que pide el usuario de gvSIG por lo que esta matriz en este caso se inicializa con la identidad. 
1151
         * @return
1152
         */
1153
        public AffineTransform getOwnTransformation() {
1154
                if(getDataset(0) != null)
1155
                        return getDataset(0).getOwnTransformation();
1156
                return new AffineTransform();
1157
        } 
1158
        
1159
        /**
1160
         * Obtiene las coordenadas reales de las esquinas del raster. En un raster sin rotaci?n esta llamada no es
1161
         * necesaria ya que es suficiente con el Extent pero cuando introducimos rotaci?n las coordenadas de las
1162
         * 4 esquinas son diferentes entre si.
1163
         * @return Point2D[] Lista de cuatro puntos que corresponden a las esquinas superior izquieda, superior derecha,
1164
         * inferior derecha e inferior inquierda respectivamente.
1165
         */
1166
        public Point2D[] getCorners() {
1167
                if(getDataset(0) != null)
1168
                        return getDataset(0).getCorners();
1169
                return null;
1170
        }
1171
        
1172
        /**
1173
         * Obtiene el Extent correspondiente a los valores m?ximos y m?nimos del raster. Este es equivalente a getExtent
1174
         * en un raster sin rotaci?n pero varia en un raster rotado.
1175
         * @return Extent
1176
         */
1177
        public Extent getLimits() {
1178
                if(getDataset(0) != null)
1179
                        return getDataset(0).getLimits();
1180
                return null;
1181
        }
1182
        
1183
        /**
1184
         * Consulta de si un raster tiene rotaci?n o no.
1185
         * @return true si tiene rotaci?n y false si no la tiene.
1186
         */
1187
        public boolean isRotated() {
1188
                if(getDataset(0) != null)
1189
                        return getDataset(0).isRotated();
1190
                return false;
1191
        }
1192
}