Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / store / DefaultMultiRasterStore.java @ 162

History | View | Annotate | Download (53.6 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.impl.store;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.Point2D;
26
import java.io.File;
27
import java.util.ArrayList;
28

    
29
import org.cresques.cts.IProjection;
30
import org.gvsig.fmap.dal.DataStoreParameters;
31
import org.gvsig.fmap.dal.coverage.RasterLibrary;
32
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
33
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
34
import org.gvsig.fmap.dal.coverage.datastruct.DatasetBand;
35
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
36
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
37
import org.gvsig.fmap.dal.coverage.exception.BandNotFoundInListException;
38
import org.gvsig.fmap.dal.coverage.exception.FileNotExistsException;
39
import org.gvsig.fmap.dal.coverage.exception.FileNotFoundInListException;
40
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
41
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
42
import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
43
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
44
import org.gvsig.fmap.dal.coverage.exception.OperationNotSupportedException;
45
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
46
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
47
import org.gvsig.fmap.dal.coverage.exception.RmfSerializerException;
48
import org.gvsig.fmap.dal.coverage.store.MultiRasterStore;
49
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
50
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
51
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
52
import org.gvsig.fmap.dal.coverage.store.props.Histogram;
53
import org.gvsig.fmap.dal.coverage.store.props.Metadata;
54
import org.gvsig.fmap.dal.coverage.store.props.SerialInfo;
55
import org.gvsig.fmap.dal.coverage.store.props.Statistics;
56
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
57
import org.gvsig.fmap.dal.exception.InitializeException;
58
import org.gvsig.raster.impl.DefaultRasterManager;
59
import org.gvsig.raster.impl.buffer.cache.RasterReadOnlyBuffer;
60
import org.gvsig.raster.impl.datastruct.BandListImpl;
61
import org.gvsig.raster.impl.datastruct.DatasetBandImpl;
62
import org.gvsig.raster.impl.provider.DefaultRasterProvider;
63
import org.gvsig.raster.impl.provider.RasterProvider;
64
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
65
import org.gvsig.raster.impl.store.properties.DataStoreSerialInfo;
66
import org.gvsig.raster.impl.store.properties.MultiDataStoreHistogram;
67
import org.gvsig.raster.impl.store.properties.MultiDataStoreMetadata;
68
import org.gvsig.raster.impl.store.properties.MultiDataStoreStatistics;
69

    
70
/**
71
 * Clase que representa una imagen de raster georreferenciada formada por varias
72
 * imagenes de disco que tienen la misma extensi?n. Contiene funcionalidades
73
 * para abrir ficheros, gestionar el extent, pintar el raster sobre un DataImage
74
 * con su gesti?n de bandas correspondiente.
75
 *
76
 * @author Nacho Brodin (nachobrodin@gmail.com)
77
 */
78
public class DefaultMultiRasterStore extends AbstractRasterDataStore implements MultiRasterStore {
79
        // File list
80
        private ArrayList<RasterProvider>     providers     = new ArrayList<RasterProvider>();
81

    
82
        // Band list
83
        private BandListImpl                  bandList      = new BandListImpl();
84
        protected MultiDataStoreStatistics    stats         = null;
85
        protected MultiDataStoreHistogram     histogram     = null;
86
        protected MultiDataStoreMetadata      metadata      = null;
87
        /**
88
         * Flag que fuerza al buffer de solo lectura
89
         */
90
        private boolean                       readOnly      = false;
91
        /**
92
         * Flag que fuerza al buffer en memoria
93
         */
94
        private boolean                       forceToMemory = false;
95
        int                                   percent       = 0;
96
        
97

    
98
        //TODO: FUNCIONALIDAD: Contructores igual a RasterDataset + String[] nameFiles
99
        public DefaultMultiRasterStore() {
100
                super();
101
        }
102

    
103
        /**
104
         * Crea un objeto MultiRasterDataset nuevo con los mismos ficheros
105
         * que el actual.
106
         * @return MultiRasterDataset
107
         */
108
        public RasterDataStore newDataStore() {
109
                try {
110
                        String[] fileList = getNameDatasetStringList();
111
                        DefaultMultiRasterStore multiRasterDataset = (DefaultMultiRasterStore)DefaultRasterManager.getInstance().open(fileList[0]);
112
                        for (int j = 1; j < fileList.length; j++)
113
                                multiRasterDataset.addDataStore(new String[] { fileList[j] });
114
                        return multiRasterDataset;
115
                } catch (FileNotFoundInListException e) {
116
                        return null;
117
                } catch (NotSupportedExtensionException e) {
118
                        return null;
119
                } catch (RasterDriverException e) {
120
                        return null;
121
                }
122
        }
123
        
124
        /*
125
         * (non-Javadoc)
126
         * @see org.gvsig.raster.impl.dataset.QueryableRaster#getProviders()
127
         */
128
        public ArrayList<RasterProvider> getProviders() {
129
                return providers;
130
        }
131
        
132
        /*
133
         * (non-Javadoc)
134
         * @see org.gvsig.raster.impl.dataset.QueryableRaster#getProvider(int)
135
         */
136
        public RasterProvider getProvider(int i) {
137
                if(providers == null || 
138
                        providers.size() == 0 || 
139
                        i < 0 || 
140
                        i >= providers.size())
141
                        return null;
142
                return providers.get(i);
143
        }
144
        
145
        /*
146
         * (non-Javadoc)
147
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataSet#getFName()
148
         */
149
        public String getName() {
150
                if(providers != null && providers.size() >= 1)
151
                        return providers.get(0).getFName();
152
                return null;
153
        }
154
        
155
        /*
156
         * (non-Javadoc)
157
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataSet#getFName(int)
158
         */
159
        public String getFName(int i) {
160
                if(providers != null && providers.size() >= (i + 1))
161
                        return providers.get(i).getFName();
162
                return null;
163
        }
164

    
165
        /*
166
         * (non-Javadoc)
167
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataSet#addDataStore(org.gvsig.fmap.dal.coverage.buffer.RasterDataStore)
168
         */
169
        public void addDataStore(RasterDataStore f)throws FileNotFoundInListException, InvalidSourceException {
170
                if(f instanceof DefaultMultiRasterStore) {
171
                        for (int i = 0; i < ((DefaultMultiRasterStore)f).providers.size(); i++) {
172
                                RasterProvider prov = providers.get(i);
173
                                providers.add(prov);
174
                                addBands(prov);
175
                                if(stats == null)
176
                                        stats = new MultiDataStoreStatistics(((QueryableRaster)f).getProviders());
177
                                else
178
                                        stats.addProvider(prov);
179
                        }
180
                }
181
        }
182

    
183
        /*
184
         * (non-Javadoc)
185
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataSet#addDataStore(java.lang.String[])
186
         */
187
        public void addDataStore(RasterProvider provider) {
188
                providers.add(provider);
189
                addBands(provider);
190
                if(stats == null) 
191
                        stats = new MultiDataStoreStatistics(providers);
192
                else
193
                        stats.addProvider(provider);
194
        }
195
        
196
        /*
197
         * (non-Javadoc)
198
         * @see org.gvsig.fmap.dal.coverage.store.MultiRasterStore#addDataStore(java.lang.String[])
199
         */
200
        public void addDataStore(String[] fileName)throws FileNotFoundInListException, NotSupportedExtensionException, RasterDriverException {
201
                if(fileName == null || fileName.length < 1)
202
                        throw new FileNotFoundInListException("Error in list.");
203
                if(findDataset(fileName[0]))
204
                        throw new FileNotFoundInListException("The file already is in list.");
205
                for (int i = 0; i < fileName.length; i++) {
206
                        DefaultRasterProvider ds = DefaultRasterProvider.singleDatasetInstance(fileName[i]);
207
                        addDataStore(ds);
208
                }
209
        }
210
        
211
        /*
212
         * (non-Javadoc)
213
         * @see org.gvsig.fmap.dal.coverage.store.MultiRasterStore#addDataStore(java.lang.String)
214
         */
215
        public void addDataStore(String fileName)throws FileNotFoundInListException, NotSupportedExtensionException, RasterDriverException, OperationNotSupportedException {
216
                addDataStore(new String[]{fileName});
217
        }
218
        
219
        /**
220
         * A?ade el fichero a lista de georrasterfiles y sus bandas a la lista de bandas
221
         * @param grf
222
         */
223
        public void addBands(RasterProvider prov) {
224
                if(prov == null)
225
                        return;
226

    
227
                for(int i = 0; i < prov.getBandCount();i++)
228
                        try {
229
                                int dataType = prov.getDataType()[i];
230
                                DatasetBand band = new DatasetBandImpl(prov.getFName(), i, dataType);
231
                                bandList.addBand(band, i);
232
                        } catch(BandNotFoundInListException ex) {
233
                                //No a?adimos la banda
234
                        }
235
        }
236

    
237
        /*
238
         * (non-Javadoc)
239
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataSet#removeDataStore(java.lang.String)
240
         */
241
        public void removeDataStore(String fileName) {
242
                for(int i = 0; i < providers.size(); i++)
243
                        if(providers.get(i).getFName().equals(fileName)) {
244
                                providers.remove(i);
245
                                bandList.removeBands(fileName);
246
                                return;
247
                        }
248
        }
249

    
250
        /*
251
         * (non-Javadoc)
252
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataSet#removeDataStore(org.gvsig.fmap.dal.coverage.buffer.RasterDataStore)
253
         */
254
        public void removeDataStore(RasterDataStore file) {
255
                for(int i = 0; i < providers.size(); i++)
256
                        if(providers.get(i).getFName().equals(file.getName())) {
257
                                providers.remove(i);
258
                                bandList.removeBands(file.getName());
259
                                return;
260
                        }
261
        }
262

    
263
        /*
264
         * (non-Javadoc)
265
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#getDataStoreCount()
266
         */
267
        public int getDataStoreCount() {
268
                return providers.size();
269
        }
270

    
271
        /**
272
         * Encuentra un fichero en la lista.
273
         * @param file Fichero b?scado.
274
         * @return true si se ha hallado el fichero y false si no se
275
         * ha encontrado
276
         */
277
        public boolean findDataset(RasterDataStore file) {
278
                for(int i = 0; i < providers.size(); i++) {
279
                        RasterProvider prov = providers.get(i);
280
                        if(        prov.getFName().equals(file.getName()))
281
                                return true;
282
                }
283
                return false;
284
        }
285

    
286
        /**
287
         * Encuentra un fichero en la lista.
288
         * @param file Fichero b?scado.
289
         * @return true si se ha hallado el fichero y false si no se
290
         * ha encontrado
291
         */
292
        public boolean findDataset(String fileName) {
293
                for(int i = 0; i < providers.size(); i++)
294
                        if(providers.get(i).getFName().equals(fileName))
295
                                return true;
296
                return false;
297
        }
298

    
299
        /*
300
         * (non-Javadoc)
301
         * @see org.gvsig.fmap.dal.raster.impl.DefaultCoverageStore#close()
302
         */
303
        public void close() {
304
                for(int i = 0; i < providers.size(); i++)
305
                        providers.get(i).close();
306
                providers.clear();
307
                bandList.clear();
308
        }
309

    
310
        /*
311
         * (non-Javadoc)
312
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataSet#getNameDatasetStringList()
313
         */
314
        public String[] getNameDatasetStringList() {
315
                String[] list = new String[providers.size()];
316
                for(int k = 0; k < providers.size(); k++)
317
                        list[k] = providers.get(k).getFName();
318
                return list;
319
        }
320

    
321
        /**
322
         * Inicializa el buffer a valores NoData
323
         * @param raster Buffer a inicializar
324
         * @param bandList Lista de bandas
325
         */
326
        private void initBufferToNoData(Buffer raster, BandList bandList) {
327
                for(int i = 0; i < bandList.getDrawableBandsCount(); i++)
328
                        switch(getDataType()[0]) {
329
                        case Buffer.TYPE_BYTE:raster.assign(i, raster.getByteNoDataValue());break;
330
                        case Buffer.TYPE_SHORT:raster.assign(i, raster.getShortNoDataValue());break;
331
                        case Buffer.TYPE_INT:raster.assign(i, raster.getIntNoDataValue());break;
332
                        case Buffer.TYPE_FLOAT:raster.assign(i, raster.getFloatNoDataValue());break;
333
                        case Buffer.TYPE_DOUBLE:raster.assign(i, raster.getNoDataValue());break;
334
                        }
335
        }
336

    
337
        /**
338
         * A partir de la lista de bandas que dice como cargar el buffer se crean tantos Buffer como ficheros intervienen
339
         * . Cada Buffer corresponde a un dataset del RasterMultiDataset y en ellos se reserva memoria solo para las
340
         * bandas que vayan a ser cargadas. Las otras se asignaran a la banda NotValid.
341
         * @param bl Lista de bandas
342
         * @param width Ancho
343
         * @param height Alto
344
         * @return Lista de buffers en el que cada uno corresponde a un dataset.
345
         */
346
        private Buffer[] mallocBuffersDatasets(BandList bl, int width, int height) {
347
                Buffer[] buffers = new Buffer[getDataStoreCount()];
348
                for(int i = 0; i < getDataStoreCount(); i++) {
349
                        if(forceToMemory)
350
                                buffers[i] =  DefaultRasterManager.getInstance().createMemoryBuffer(getProvider(i).getDataType()[0], width, height, getProvider(i).getBandCount(), false);
351
                        else
352
                                buffers[i] =  DefaultRasterManager.getInstance().createBuffer(getProvider(i).getDataType()[0], width, height, getProvider(i).getBandCount(), false);
353

    
354
                        //Asignamos las bandas de cada fichero que no se pintan a null y las que se pintan se reserva memoria
355
                        String name = getProvider(i).getName();
356
                        for(int j = 0; j < getProvider(i).getBandCount(); j ++)
357
                                if(bl.getBufferBandToDraw(name, j) == null)
358
                                        buffers[i].assignBandToNotValid(j);
359
                                else
360
                                        buffers[i].mallocOneBand(getProvider(i).getDataType()[0], width, height, j);
361
                }
362
                return buffers;
363
        }
364

    
365
        /**
366
         * Mezcla los buffers de los dataset que forman el RasterMultiDataset sobre un solo buffer
367
         * con las directrices que marca la lista de bandas. Esta funci?n es la que realiza el switch
368
         * de las bandas.
369
         * @param b Buffer sobre el que se mezcla
370
         * @param bDataset Buffers que corresponden a los datasets
371
         * @param bandList Objeto que contiene la informaci?n de que bandas de los dataset se escriben sobre
372
         * que banda del buffer.
373
         */
374
        private void mergeBuffers(Buffer b, Buffer[] bDataset, BandList bandList) {
375
                for(int iDataset = 0; iDataset < getDataStoreCount(); iDataset++){ //Ojo! Los datasets est?n en la misma posici?n que se han metido en mallocBuffersDatasets
376
                        String name = getProvider(iDataset).getFName();
377

    
378
                        for(int iBand = 0; iBand < getProvider(iDataset).getBandCount(); iBand ++) {
379
                                int[] posToDraw = bandList.getBufferBandToDraw(name, iBand);
380
                                if(posToDraw != null)
381
                                        for(int i = 0; i < posToDraw.length; i ++)
382
                                                switch(getDataType()[iDataset]) {
383
                                                case Buffer.TYPE_BYTE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
384
                                                case Buffer.TYPE_SHORT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
385
                                                case Buffer.TYPE_INT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
386
                                                case Buffer.TYPE_FLOAT: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
387
                                                case Buffer.TYPE_DOUBLE: b.assignBand(posToDraw[i], bDataset[iDataset].getBand(iBand)); break;
388
                                                }
389
                        }
390
                }
391
        }
392

    
393
        /**
394
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
395
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
396
         * pixeles de disco.
397
         * @param x Posici?n X superior izquierda
398
         * @param y Posici?n Y superior izquierda
399
         * @param w Ancho en coordenadas reales
400
         * @param h Alto en coordenadas reales
401
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
402
         * @param bandList
403
         * @return Buffer de datos
404
         */
405
        public Buffer getWindowRaster(double ulx, double uly, double lrx, double lry)
406
                throws InvalidSetViewException, ProcessInterruptedException, RasterDriverException {
407
                //Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
408

    
409
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
410
                //por arriba el m?s alto y por abajo el menor y luego restandolos
411

    
412
                Point2D p1 = providers.get(0).worldToRaster(new Point2D.Double(ulx, uly));
413
                Point2D p2 = providers.get(0).worldToRaster(new Point2D.Double(lrx, lry));
414

    
415
                //Para el valor mayor redondeamos por arriba. Para el valor menor redondeamos por abajo.
416
                double p1X = (p1.getX() > p2.getX()) ? Math.ceil(p1.getX()) : Math.floor(p1.getX());
417
                double p1Y = (p1.getY() > p2.getY()) ? Math.ceil(p1.getY()) : Math.floor(p1.getY());
418
                double p2X = (p2.getX() > p1.getX()) ? Math.ceil(p2.getX()) : Math.floor(p2.getX());
419
                double p2Y = (p2.getY() > p1.getY()) ? Math.ceil(p2.getY()) : Math.floor(p2.getY());
420

    
421
                int width = (int)Math.abs(p1X - p2X);
422
                int height = (int)Math.abs(p1Y - p2Y);
423

    
424
                //Ajustamos por si nos hemos salido del raster
425
                if(((int)(Math.min(p1X, p2X) + width)) > getWidth())
426
                        width = (int)(getWidth() - Math.min(p1X, p2X));
427
                if(((int)(Math.min(p1Y, p2Y) + height)) > getHeight())
428
                        height = (int)(getHeight() - Math.min(p1Y, p2Y));
429

    
430
                if (p1X < 0)
431
                        p1X = 0;
432
                if (p1Y < 0)
433
                        p1Y = 0;
434
                if (p2X > getWidth())
435
                        p2X = getWidth();
436
                if (p2Y > getHeight())
437
                        p2Y = getHeight();
438

    
439
                int mallocNBands = 0;
440
                if(bandList.getDrawableBands() != null)
441
                        mallocNBands = bandList.getDrawableBands().length;
442
                else
443
                        mallocNBands = bandList.getDrawableBandsCount();
444

    
445
                //Buffer ReadOnly
446

    
447
                if(isReadOnly()) {
448
                        Buffer rb = DefaultRasterManager.getInstance().createReadOnlyBuffer(getDataType()[0], width, height, getBandCount());
449
                        if(rb instanceof RasterReadOnlyBuffer) {
450
                                try {
451
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, (int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY(), bandList);
452
                                } catch (FileNotExistsException e) {
453
                                        //Esto no debe darse ya que se comprueba al hacer el open.
454
                                        return null;
455
                                } catch (NotSupportedExtensionException e) {
456
                                        //Esto no debe darse ya que se comprueba al hacer el open
457
                                        return null;
458
                                }
459
                                return rb;
460
                        }
461
                }
462

    
463
                //Buffer RW
464

    
465
                Buffer raster = null;
466
                if(forceToMemory) //Fuerza siempre buffer en memoria
467
                        raster = DefaultRasterManager.getInstance().createMemoryBuffer(getDataType()[0], width, height, mallocNBands, false);
468
                else
469
                        raster = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], width, height, mallocNBands, false);
470

    
471
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
472
                        raster.assignBandToNotValid(iBand);
473

    
474
                //Reservamos memoria para los buffers por dataset
475
                Buffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
476

    
477
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor
478
                //equivalente a los pixeles redondeados.
479
                Point2D wc1 = providers.get(0).rasterToWorld(new Point2D.Double(p1X, p1Y));
480
                Point2D wc2 = providers.get(0).rasterToWorld(new Point2D.Double(p2X, p2Y));
481
                for(int i = 0; i < getDataStoreCount(); i++)
482
                        bufferDatasets[i] = ((DefaultRasterProvider)providers.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), wc2.getX(), wc2.getY(), bandList, bufferDatasets[i]);
483

    
484
                //Mezclamos los buffers de cada dataset en un solo buffer
485
                mergeBuffers(raster, bufferDatasets, bandList);
486

    
487
                for (int i = 0; i < bufferDatasets.length; i++)
488
                        bufferDatasets[i].free();
489

    
490
                return raster;
491
        }
492

    
493
        /**
494
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
495
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
496
         * pixeles de disco.
497
         * @param x Posici?n X superior izquierda
498
         * @param y Posici?n Y superior izquierda
499
         * @param w Ancho en coordenadas reales
500
         * @param h Alto en coordenadas reales
501
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
502
         * @param bandList
503
         * @return Buffer de datos
504
         */
505
        public Buffer getWindowRaster(double ulx, double uly, double w, double h, boolean adjustToExtent)
506
                throws InvalidSetViewException, ProcessInterruptedException, RasterDriverException {
507
                //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
508
                //tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o y - h
509
                Extent ext = getExtent();
510
                Point2D pInit = providers.get(0).rasterToWorld(new Point2D.Double(0, 0));
511
                Point2D pEnd = providers.get(0).rasterToWorld(new Point2D.Double((int)getWidth(), (int)getHeight()));
512
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
513
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
514
                double lrx = (((int)(ext.getULX() - wRaster)) == ((int)ext.getLRX())) ? (ulx - w) : (ulx + w);
515
                double lry = (((int)(ext.getULY() - hRaster)) == ((int)ext.getLRY())) ? (uly - h) : (uly + h);
516

    
517
                //Extent selectedExtent = new Extent(ulx, uly, lrx, lry);
518

    
519
                //Leemos pixels completos aunque el valor obtenido sea decimal. Esto se consigue redondeando
520
                //por arriba el m?s alto y por abajo el menor y luego restandolos
521

    
522
                Point2D p1 = providers.get(0).worldToRaster(new Point2D.Double(ulx, uly));
523
                Point2D p2 = providers.get(0).worldToRaster(new Point2D.Double(lrx, lry));
524
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX()));
525
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
526

    
527
                //Ajustamos por si nos hemos salido del raster
528
                if(((int)(p1.getX() + width)) > getWidth())
529
                        width = (int)(getWidth() - p1.getX());
530
                if(((int)(p1.getY() + height)) > getHeight())
531
                        height = (int)(getHeight() - p1.getY());
532

    
533
                if (p1.getX() < 0)
534
                        p1.setLocation(0, p1.getY());
535
                if (p1.getY() < 0)
536
                        p1.setLocation(p1.getX(), 0);
537
                if (p2.getX() > getWidth())
538
                        p2.setLocation(getWidth(), p2.getY());
539
                if (p2.getY() > getHeight())
540
                        p2.setLocation(p2.getX(), getHeight());
541

    
542
                int mallocNBands = 0;
543
                if(bandList.getDrawableBands() != null)
544
                        mallocNBands = bandList.getDrawableBands().length;
545
                else
546
                        mallocNBands = bandList.getDrawableBandsCount();
547

    
548
                //Buffer ReadOnly
549

    
550
                if(isReadOnly()) {
551
                        Buffer rb = DefaultRasterManager.getInstance().createReadOnlyBuffer(getDataType()[0], width, height, getBandCount());
552
                        if(rb instanceof RasterReadOnlyBuffer) {
553
                                try {
554
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, (int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY(), bandList);
555
                                } catch (FileNotExistsException e) {
556
                                        //Esto no debe darse ya que se comprueba al hacer el open.
557
                                        return null;
558
                                } catch (NotSupportedExtensionException e) {
559
                                        //Esto no debe darse ya que se comprueba al hacer el open
560
                                        return null;
561
                                }
562
                                return rb;
563
                        }
564
                }
565

    
566
                //Buffer RW
567

    
568
                Buffer raster = null;
569
                if(forceToMemory) //Fuerza siempre buffer en memoria
570
                        raster = DefaultRasterManager.getInstance().createMemoryBuffer(getDataType()[0], width, height, mallocNBands, false);
571
                else
572
                        raster = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], width, height, mallocNBands, false);
573

    
574
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
575
                        raster.assignBandToNotValid(iBand);
576

    
577
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
578
                //m?s grande y salirse de los l?mites.
579
                if(!adjustToExtent)
580
                         initBufferToNoData(raster, bandList);
581

    
582
                //Reservamos memoria para los buffers por dataset
583
                Buffer[] bufferDatasets = mallocBuffersDatasets(bandList, width, height);
584

    
585
                //Si hemos redondeado los pixeles de la petici?n (p1 y p2) por arriba y por abajo deberemos calcular un extent mayor
586
                //equivalente a los pixeles redondeados.
587
                Point2D wc1 = providers.get(0).rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
588
                Point2D wc2 = providers.get(0).rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
589
                for(int i = 0; i < getDataStoreCount(); i++)
590
                        bufferDatasets[i] = ((DefaultRasterProvider)providers.get(i)).getWindowRaster(wc1.getX(), wc1.getY(), Math.abs(wc2.getX() - wc1.getX()), Math.abs(wc2.getY() - wc1.getY()), bandList, bufferDatasets[i], adjustToExtent);
591
                        //bufferDatasets[i] = ((RasterDataStore)files.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i], adjustToExtent);
592

    
593
                //Mezclamos los buffers de cada dataset en un solo buffer
594
                mergeBuffers(raster, bufferDatasets, bandList);
595

    
596
                for (int i = 0; i < bufferDatasets.length; i++)
597
                        bufferDatasets[i].free();
598

    
599
                return raster;
600
        }
601

    
602
        /**
603
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
604
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer. Esta operaci?n la gestiona
605
         * el driver.
606
         * @param minX Valor m?nimo de la X en coordenadas reales
607
         * @param minY Valor m?nimo de la Y en coordenadas reales
608
         * @param maxX Valor m?ximo de la X en coordenadas reales
609
         * @param maxY Valor m?ximo de la Y en coordenadas reales
610
         * @param bufWidth ancho del buffer lde datos
611
         * @param bufHeight alto del buffer de datos
612
         * @param adjustToExtent Flag que dice si el extent solicitado debe ajustarse al extent del raster o no.
613
         * @param bandList
614
         * @return Buffer de datos
615
         */
616
        public Buffer getWindowRaster(double ulx, double uly, double lrx, double lry, int bufWidth, int bufHeight, boolean adjustToExtent)
617
                throws InvalidSetViewException, ProcessInterruptedException, RasterDriverException {
618

    
619
                Point2D p1 = worldToRaster(new Point2D.Double(ulx, uly));
620
                Point2D p2 = worldToRaster(new Point2D.Double(lrx, lry));
621
                
622
                if(p1.getX() > p2.getX())
623
                        p1.setLocation(p1.getX() - 1, p1.getY());
624
                else
625
                        p2.setLocation(p2.getX() - 1, p2.getY());
626
                
627
                if(p1.getY() > p2.getY())
628
                        p1.setLocation(p1.getX(), p1.getY() - 1);
629
                else
630
                        p2.setLocation(p2.getX(), p2.getY() - 1);
631
                
632
                if(        ((int)p1.getX()) < 0 || ((int)p2.getX()) > getWidth() ||
633
                                ((int)p2.getY()) > getHeight() || ((int)p2.getY()) < 0)
634
                                throw new InvalidSetViewException("");
635

    
636
                int mallocNBands = 0;
637
                if(bandList.getDrawableBands() != null)
638
                        mallocNBands = bandList.getDrawableBands().length;
639
                else
640
                        mallocNBands = bandList.getDrawableBandsCount();
641

    
642
                //Buffer ReadOnly
643

    
644
                if(isReadOnly()) {
645
                        Buffer rb = DefaultRasterManager.getInstance().createReadOnlyBuffer(getDataType()[0], bufWidth, bufHeight, getBandCount());
646
                        if(rb instanceof RasterReadOnlyBuffer) {
647
                                try {
648
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, (int)p1.getX(), (int)p1.getY(), (int)p2.getX(), (int)p2.getY(), bandList);
649
                                } catch (FileNotExistsException e) {
650
                                        //Esto no debe darse ya que se comprueba al hacer el open.
651
                                        return null;
652
                                } catch (NotSupportedExtensionException e) {
653
                                        //Esto no debe darse ya que se comprueba al hacer el open
654
                                        return null;
655
                                }
656
                                return rb;
657
                        }
658
                }
659

    
660
                //Buffer RW
661

    
662
                Buffer raster = null;
663
                if(forceToMemory) //Fuerza siempre buffer en memoria
664
                        raster = DefaultRasterManager.getInstance().createMemoryBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
665
                else
666
                        raster = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], bufWidth, bufHeight, mallocNBands, false);
667

    
668
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
669
                        raster.assignBandToNotValid(iBand);
670

    
671
                //Si no vamos a ajustar el extent al raster inicializamos el buffer a noData ya que este puede ser
672
                //m?s grande y salirse de los l?mites.
673
                if(!adjustToExtent)
674
                         initBufferToNoData(raster, bandList);
675

    
676
                //Reservamos memoria para los buffers por dataset
677
                Buffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
678
                for(int i = 0; i < getDataStoreCount(); i++)
679
                        bufferDatasets[i] = ((DefaultRasterProvider)providers.get(i)).getWindowRaster(ulx, uly, lrx, lry, bufWidth, bufHeight, bandList, bufferDatasets[i], adjustToExtent);
680

    
681
                //Mezclamos los buffers de cada dataset en un solo buffer
682
                mergeBuffers(raster, bufferDatasets, bandList);
683

    
684
                for (int i = 0; i < bufferDatasets.length; i++)
685
                        bufferDatasets[i].free();
686

    
687
                return raster;
688
        }
689

    
690
        /**
691
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
692
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
693
         * pixeles de disco.
694
         * @param x Posici?n X superior izquierda
695
         * @param y Posici?n Y superior izquierda
696
         * @param w Ancho en coordenadas pixel
697
         * @param h Alto en coordenadas pixel
698
         * @param bandList
699
         * @return Buffer de datos
700
         */
701
        public Buffer getWindowRaster(int x, int y, int w, int h)
702
                throws InvalidSetViewException, ProcessInterruptedException, RasterDriverException {
703
                if(x < 0 || y < 0 || w > providers.get(0).getWidth() || h > providers.get(0).getHeight())
704
                        throw new InvalidSetViewException("Out of image");
705

    
706
                //Buffer ReadOnly
707

    
708
                if(isReadOnly()) {
709
                        Buffer rb = DefaultRasterManager.getInstance().createReadOnlyBuffer(getDataType()[0], w, h, getBandCount());
710
                        if(rb instanceof RasterReadOnlyBuffer) {
711
                                try {
712
                                        ((RasterReadOnlyBuffer)rb).setBufferParams(this, x, y, x + w, y + h, bandList);
713
                                } catch (FileNotExistsException e) {
714
                                        //Esto no debe darse ya que se comprueba al hacer el open.
715
                                        return null;
716
                                } catch (NotSupportedExtensionException e) {
717
                                        //Esto no debe darse ya que se comprueba al hacer el open
718
                                        return null;
719
                                }
720
                                return rb;
721
                        }
722
                }
723

    
724
                //Buffer RW
725

    
726
                Buffer raster = null;
727
                if(forceToMemory) //Fuerza siempre buffer en memoria
728
                        raster = DefaultRasterManager.getInstance().createMemoryBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
729
                else
730
                        raster = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], w, h, bandList.getDrawableBandsCount(), false);
731

    
732
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
733
                        raster.assignBandToNotValid(iBand);
734

    
735
                //Reservamos memoria para los buffers por dataset
736
                Buffer[] bufferDatasets = mallocBuffersDatasets(bandList, w, h);
737
                for(int i = 0; i < getDataStoreCount(); i++)
738
                        bufferDatasets[i] = ((DefaultRasterProvider)providers.get(i)).getWindowRaster(x, y, w, h, bandList, bufferDatasets[i]);
739

    
740
                //Mezclamos los buffers de cada dataset en un solo buffer
741
                mergeBuffers(raster, bufferDatasets, bandList);
742

    
743
                for (int i = 0; i < bufferDatasets.length; i++)
744
                        bufferDatasets[i].free();
745

    
746
                return raster;
747
        }
748

    
749
        /**
750
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales.
751
         * Aplica supersampleo o subsampleo en funci?n del tama?o del buffer
752
         * @param x Posici?n X superior izquierda en pixels
753
         * @param y Posici?n Y superior izquierda en pixels
754
         * @param w Ancho en pixels
755
         * @param h Alto en pixels
756
         * @param bufWidth ancho del buffer de datos
757
         * @param bufHeight alto del buffer de datos
758
         * @param bandList
759
         * @return Buffer de datos
760
         */
761
        public Buffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight)
762
                throws InvalidSetViewException, ProcessInterruptedException, RasterDriverException {
763
                if(x < 0 || y < 0 || w > providers.get(0).getWidth() || h > providers.get(0).getHeight())
764
                        throw new InvalidSetViewException("Out of image");
765

    
766
                //Buffer ReadOnly
767

    
768
                if(isReadOnly()) {
769
                        Buffer rb = DefaultRasterManager.getInstance().createReadOnlyBuffer(getDataType()[0], bufWidth, bufHeight, getBandCount());
770
                        if(rb instanceof RasterReadOnlyBuffer) {
771
                                try {
772
                                        ((RasterReadOnlyBuffer)rb).setBufferParams((QueryableRaster)this, x, y, x + w, y + h, bandList);
773
                                } catch (FileNotExistsException e) {
774
                                        //Esto no debe darse ya que se comprueba al hacer el open.
775
                                        return null;
776
                                } catch (NotSupportedExtensionException e) {
777
                                        //Esto no debe darse ya que se comprueba al hacer el open
778
                                        return null;
779
                                }
780
                                return rb;
781
                        }
782
                }
783

    
784
                Buffer raster = null;
785
                if(forceToMemory) //Fuerza siempre buffer en memoria
786
                        raster = DefaultRasterManager.getInstance().createMemoryBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
787
                else
788
                        raster = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], bufWidth, bufHeight, bandList.getDrawableBandsCount(), false);
789

    
790
                for(int iBand = 0; iBand < raster.getBandCount(); iBand ++)
791
                        raster.assignBandToNotValid(iBand);
792

    
793
                //Reservamos memoria para los buffers por dataset
794
                Buffer[] bufferDatasets = mallocBuffersDatasets(bandList, bufWidth, bufHeight);
795

    
796
                for(int i = 0; i < getDataStoreCount(); i++)
797
                        bufferDatasets[i] = ((DefaultRasterProvider)providers.get(i)).getWindowRaster(x, y, w, h, bufWidth, bufHeight, bandList, bufferDatasets[i]);
798

    
799
                //Mezclamos los buffers de cada dataset en un solo buffer
800
                mergeBuffers(raster, bufferDatasets, bandList);
801

    
802
                for (int i = 0; i < bufferDatasets.length; i++)
803
                        bufferDatasets[i].free();
804

    
805
                return raster;
806
        }
807

    
808
        //******************************
809
        //Setters and Getters
810
        //******************************
811

    
812
        /**
813
         * Calcula el tama?o de los ficheros en disco
814
         * @return tama?o en bytes de todos los ficheros de la lista
815
         */
816
        public long getFileSize() {
817
                int len = 0;
818
                for(int i = 0; i < providers.size();i++)
819
                        if(providers.get(i) != null) {
820
                                File f = new File(providers.get(i).getFName());
821
                                len += f.length();
822
                        }
823
                return len;
824
        }
825

    
826
        /*
827
         * (non-Javadoc)
828
         * @see org.gvsig.raster.dataset.IRasterDataSource#getHeight()
829
         */
830
        public double getHeight() {
831
                double[] lenghts = new double[getDataStoreCount()];
832
                for(int i = 0; i < getDataStoreCount(); i++)
833
                        if(providers.get(i) != null)
834
                                lenghts[i] = providers.get(i).getHeight();
835
                return lenghts[0];
836
        }
837

    
838
        /*
839
         * (non-Javadoc)
840
         * @see org.gvsig.raster.dataset.IRasterDataSource#getWidth()
841
         */
842
        public double getWidth() {
843
                double[] lenghts = new double[getDataStoreCount()];
844
                for(int i = 0; i < getDataStoreCount(); i++)
845
                        if(providers.get(i) != null)
846
                                lenghts[i] = providers.get(i).getWidth();
847
                return lenghts[0];
848
        }
849

    
850
        /*
851
         * (non-Javadoc)
852
         * @see org.gvsig.raster.dataset.IRasterDataSource#getCellSize()
853
         */
854
        public double getCellSize() {
855
                try {
856
                        Extent e = getExtent();
857
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getWidth();
858
                        return dCellsize;
859
                } catch (NullPointerException e) {
860
                        return 1;
861
                }
862
        }
863

    
864
        /*
865
         * (non-Javadoc)
866
         * @see org.gvsig.raster.dataset.IRasterDataSource#getBandCount()
867
         */
868
        public int getBandCount() {
869
                return bandList.getBandCount();
870
        }
871

    
872
        /*
873
         * (non-Javadoc)
874
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getDataType()
875
         */
876
        public int[] getDataType() {
877
                int[] dt = new int[getBandCount()];
878

    
879
                if (dt.length == 0)
880
                        return null;
881

    
882
                int k = 0;
883
                for(int i = 0; i < providers.size(); i++) {
884
                        int[] types = providers.get(i).getDataType();
885
                        for (int j = 0; j < types.length; j++) {
886
                                dt[k] = types[j];
887
                                k ++;
888
                        }
889
                }
890

    
891
                return dt;
892
        }
893

    
894
        /**
895
         * Obtiene fichero de la posici?n i. En un MultiRasterDataStore el array devuelto ser? de
896
         * un solo elemento por lo que solo tendr? sentido la posici?n 0.
897
         * @param i Posici?n del fichero a obtener.
898
         * @return GeoRasterFileDataset.
899
         */
900
        public RasterDataStore getDataStore(int i) {
901
                try {
902
                        DefaultMultiRasterStore store = new DefaultMultiRasterStore();
903
                        store.addDataStore(providers.get(i));
904
                        store.intializePhase1(null, (DataStoreParameters)providers.get(i).getDataParameters());
905
                        return store;
906
                } catch (ArrayIndexOutOfBoundsException e) {
907
                        return null;
908
                } catch (InitializeException e) {
909
                        return null;
910
                }
911
        }
912

    
913
        /**
914
         * Obtiene fichero de nombre fileName.
915
         * @param i Posici?n del fichero a obtener.
916
         * @return GeoRasterFile.
917
         */
918
        public RasterDataStore getDataStore(String fileName) {
919
                DefaultMultiRasterStore store = new DefaultMultiRasterStore();
920
                boolean exists = false;
921
                for(int i = 0; i < providers.size(); i++) {
922
                        if(providers.get(i).getFName().equals(fileName)) {
923
                                store.addDataStore(providers.get(i));
924
                                store.addBands(providers.get(i));
925
                                exists = true;
926
                        }
927
                }
928
                if(exists)
929
                        return store;
930
                else
931
                        return null;
932
        }
933

    
934
        /**
935
         * Obtiene la lista de bandas
936
         * @return BandList
937
         */
938
        public BandList getBands() {
939
                return bandList;
940
        }
941

    
942
        /**
943
         * Obtiene la coordenada X m?nima de toda la lista
944
         * @return Coordenada X m?nima
945
         */
946
        public double getMinX() {
947
                double minx = Double.MAX_VALUE;
948
                for(int i = 0; i < providers.size(); i++) {
949
                        double aux = providers.get(i).getExtent().getMin().getX();
950
                        if(aux < minx)
951
                                minx = aux;
952
                }
953
                return minx;
954
        }
955

    
956
        /**
957
         * Obtiene la coordenada Y m?nima de toda la lista
958
         * @return Coordenada Y m?nima
959
         */
960
        public double getMinY() {
961
                double miny = Double.MAX_VALUE;
962
                for(int i = 0; i < providers.size(); i++) {
963
                        double aux = providers.get(i).getExtent().getMin().getY();
964
                        if(aux < miny)
965
                                miny = aux;
966
                }
967
                return miny;
968
        }
969

    
970
        /**
971
         * Obtiene la coordenada Y m?xima de toda la lista
972
         * @return Coordenada Y m?xima
973
         */
974
        public double getMaxX() {
975
                double maxx = Double.NEGATIVE_INFINITY;
976
                for(int i = 0; i < providers.size(); i++) {
977
                        double aux = providers.get(i).getExtent().getMin().getY();
978
                        if(aux > maxx)
979
                                maxx = aux;
980
                }
981
                return maxx;
982
        }
983

    
984
        /**
985
         * Obtiene la coordenada Y m?xima de toda la lista
986
         * @return Coordenada Y m?xima
987
         */
988
        public double getMaxY() {
989
                double maxy = Double.NEGATIVE_INFINITY;
990
                for(int i = 0; i < providers.size(); i++) {
991
                        double aux = providers.get(i).getExtent().getMin().getY();
992
                        if(aux > maxy)
993
                                maxy = aux;
994
                }
995
                return maxy;
996
        }
997

    
998
        /*
999
         * (non-Javadoc)
1000
         * @see org.gvsig.raster.dataset.IRasterDataSource#getNoDataValue()
1001
         */
1002
        public double getNoDataValue() {
1003
                if (providers.isEmpty())
1004
                        return RasterLibrary.defaultNoDataValue;
1005

    
1006
                return providers.get(0).getNoDataValue();
1007
        }
1008

    
1009
        /*
1010
         * (non-Javadoc)
1011
         * @see org.gvsig.raster.dataset.IRasterDataSource#isNoDataEnabled()
1012
         */
1013
        public boolean isNoDataEnabled() {
1014
                if (providers.isEmpty())
1015
                        return false;
1016

    
1017
                return providers.get(0).isNoDataEnabled();
1018
        }
1019

    
1020
        /*
1021
         * (non-Javadoc)
1022
         * @see org.gvsig.raster.dataset.IRasterDataSource#resetNoDataValue()
1023
         */
1024
        public void resetNoDataValue() {
1025
                for (int i = 0; i < providers.size(); i++)
1026
                        providers.get(i).resetNoDataValue();
1027
        }
1028

    
1029
        /*
1030
         * (non-Javadoc)
1031
         * @see org.gvsig.raster.dataset.IRasterDataSource#setNoDataValue(double)
1032
         */
1033
        public void setNoDataValue(double value) {
1034
                for (int i = 0; i < providers.size(); i++)
1035
                        providers.get(i).setNoDataValue(value);
1036
        }
1037

    
1038
        /*
1039
         * (non-Javadoc)
1040
         * @see org.gvsig.raster.dataset.IRasterDataSource#setNoDataEnabled(boolean)
1041
         */
1042
        public void setNoDataEnabled(boolean enabled) {
1043
                for (int i = 0; i < providers.size(); i++)
1044
                        providers.get(i).setNoDataEnabled(enabled);
1045
        }
1046

    
1047
        /**
1048
         * Obtiene el extent del multi fichero. Este corresponde al primer
1049
         * GeoRasterFile de la lista.
1050
         * @return Extent
1051
         */
1052
        public Extent getExtent() {
1053
                if(providers.size() == 0)
1054
                        return null;
1055
                else
1056
                        return providers.get(0).getExtent();
1057
        }
1058

    
1059
        /**
1060
         * Este es el extent sobre el que se ajusta una petici?n para que esta no exceda el
1061
         * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
1062
         * pero para un raster rotado ser? igual al extent del raster como si no
1063
         * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
1064
         * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
1065
         * aplicado.
1066
         * @return Extent
1067
         */
1068
        public Extent getExtentForRequest() {
1069
                return providers.get(0).getExtentWithoutRot();
1070
        }
1071

    
1072
        /*
1073
         * (non-Javadoc)
1074
         * @see org.gvsig.raster.dataset.IRasterDataSource#getLastSelectedView()
1075
         */
1076
        public Extent getLastSelectedView(){
1077
                return providers.get(0).getView();
1078
        }
1079

    
1080
        /*
1081
         * (non-Javadoc)
1082
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#getTransparencyFilesStatus()
1083
         */
1084
        public Transparency getTransparencyFilesStatus() {
1085
                if(providers.size() <= 0)
1086
                        return null;
1087
                Transparency t = providers.get(0).getTransparency();
1088
                for(int i = 1; i < providers.size(); i++) {
1089
                        Transparency t1 = providers.get(i).getTransparency();
1090
                        t.merge(t1);
1091
                }
1092
                return t;
1093
        }
1094

    
1095
        /**
1096
         * Obtiene la paleta correspondiente a uno de los ficheros que forman el GeoMultiRasterFile
1097
         * @param i Posici?n del raster
1098
         * @return Paleta asociada a este o null si no tiene
1099
         */
1100
        public ColorTable getColorTable(int i){
1101
                if(i >= providers.size())
1102
                        return null;
1103
                return providers.get(i).getColorTable();
1104
        }
1105

    
1106
        /**
1107
         * Obtiene la lista de paletas correspondiente a todos los ficheros que forman el GeoMultiRasterFile
1108
         * @return Paleta asociada a este o null si no tiene. Una posici?n null en el array tambi?n indica que
1109
         * para ese fichero no hay paletas asociadas.
1110
         */
1111
        public ColorTable[] getColorTables(){
1112
                if(providers.size() <= 0)
1113
                        return null;
1114
                ColorTable[] list = new ColorTable[providers.size()];
1115
                for(int i = 0; i < providers.size(); i++)
1116
                        list[i] = providers.get(i).getColorTable();
1117
                return list;
1118
        }
1119

    
1120
        /**
1121
         * Obtiene la paleta correspondiente al nombre del fichero pasado por par?metro.
1122
         * @param fileName Nombre del fichero
1123
         * @return Paleta o null si no la tiene
1124
         */
1125
        public ColorTable getColorTable(String fileName){
1126
                for(int i = 0; i < providers.size(); i++)
1127
                        if(providers.get(i).getFName().indexOf(fileName) == 0)
1128
                                return providers.get(i).getColorTable();
1129
                return null;
1130
        }
1131

    
1132
        /*
1133
         * (non-Javadoc)
1134
         * @see org.gvsig.raster.dataset.IRasterDataSource#rasterToWorld(java.awt.geom.Point2D)
1135
         */
1136
        public Point2D rasterToWorld(Point2D pt) {
1137
                return providers.get(0).rasterToWorld(pt);
1138
        }
1139

    
1140
        /*
1141
         * (non-Javadoc)
1142
         * @see org.gvsig.raster.dataset.IRasterDataSource#worldToRaster(java.awt.geom.Point2D)
1143
         */
1144
        public Point2D worldToRaster(Point2D pt) {
1145
                return providers.get(0).worldToRaster(pt);
1146
        }
1147

    
1148
        /*
1149
         * (non-Javadoc)
1150
         * @see org.gvsig.raster.dataset.IRasterDataSource#calcSteps(double, double, double, double, double, double, int, int)
1151
         */
1152
        public double[] calcSteps(double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
1153
                        double nWidth, double nHeight, int bufWidth, int bufHeight){
1154
                return providers.get(0).calcSteps(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, bufWidth, bufHeight);
1155
        }
1156

    
1157
        /*
1158
         * (non-Javadoc)
1159
         * @see org.gvsig.raster.dataset.IRasterDataSource#isGeoreferenced()
1160
         */
1161
        public boolean isGeoreferenced() {
1162
                for(int i = 0; i < providers.size(); i++)
1163
                        if(providers.get(i).isGeoreferenced())
1164
                                return true;
1165
                return false;
1166
        }
1167

    
1168
        /*
1169
         * (non-Javadoc)
1170
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getPixelSizeX()
1171
         */
1172
        public double getPixelSizeX() {
1173
                return providers.get(0).getPixelSizeX();
1174
        }
1175

    
1176
        /*
1177
         * (non-Javadoc)
1178
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getPixelSizeY()
1179
         */
1180
        public double getPixelSizeY() {
1181
                return providers.get(0).getPixelSizeY();
1182
        }
1183

    
1184
        /*
1185
         * (non-Javadoc)
1186
         * @see org.gvsig.raster.dataset.IRasterDataSource#getData(int, int, int)
1187
         */
1188
        public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
1189
                String file = bandList.getBand(band).getFileName();
1190
                int[] posList = bandList.getBandPositionList();
1191
                for(int i = 0; i < providers.size(); i++)
1192
                        if(providers.get(i).getFName().equals(file))
1193
                                return providers.get(i).getData(x, y, posList[band]);
1194
                return null;
1195
        }
1196

    
1197
        /**
1198
         * Obtiene la proyecci?n asociada al dataset. Como todos los dataset del
1199
         * multiDataset deben tener la misma proyecci?n obtenemos esta del primer
1200
         * dataset.
1201
         * @return Proyecci?n en formato cadena
1202
         * @throws RasterDriverException
1203
         */
1204
        public String getWktProjection() throws RasterDriverException {
1205
                return providers.get(0).getWktProjection();
1206
        }
1207

    
1208
        /*
1209
         * (non-Javadoc)
1210
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
1211
         */
1212
        public int getPercent() {
1213
                if (histogram != null)
1214
                        return histogram.getPercent();
1215
                return 0;
1216
        }
1217

    
1218
        /*
1219
         * (non-Javadoc)
1220
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
1221
         */
1222
        public void resetPercent() {
1223
                if (histogram != null) histogram.resetPercent();
1224
        }
1225

    
1226
        /**
1227
         * Metodo que obtiene si un punto cae dentro de los l?mites de la capa
1228
         * o fuera de ellos.
1229
         * @param p Punto a calcular
1230
         * @return true si est? dentro de los l?mites y false si est? fuera
1231
         */
1232
        public boolean isInside(Point2D p) {
1233
                if(getProvider(0) != null)
1234
                        return getProvider(0).isInside(p);
1235
                return false;
1236
        }
1237
        
1238
        /*
1239
         * (non-Javadoc)
1240
         * @see org.gvsig.raster.impl.dataset.QueryableRaster#getDataset()
1241
         */
1242
        public RasterDataStore getDataStore() {
1243
                return this;
1244
        }
1245

    
1246
        /*
1247
         * (non-Javadoc)
1248
         * @see org.gvsig.raster.dataset.IRasterDataSource#getAffineTransform()
1249
         */
1250
        public AffineTransform getAffineTransform(int band){
1251
                if(band < 0 || band > (getBandCount() - 1))
1252
                        return null;
1253
                int[] providerBand = getProviderFromBandNumber(band);
1254
                if(providerBand != null)
1255
                        return providers.get(providerBand[0]).getAffineTransform();
1256
                return null;
1257
        }
1258

    
1259
        /**
1260
         * Obtiene el n?mero de dataset para un n?mero de banda y la posici?n de la banda dentro de
1261
         * ese dataset.
1262
         * @param bandNumber N?mero de banda
1263
         * @return Dataset que corresponde a la banda pedida y n?mero de banda dentro del dataset (dataset, banda)
1264
         */
1265
        public int[] getProviderFromBandNumber(int bandNumber) {
1266
                int cont = 0;
1267
                for (int i = 0; i < getDataStoreCount(); i++) {
1268
                        RasterProvider provider = providers.get(i);
1269
                        cont += provider.getBandCount();
1270
                        if(cont > bandNumber) {
1271
                                int lastBands = (cont - provider.getBandCount()); //Suma de las bandas de todos los datasets anteriores.
1272
                                return new int[]{i, (bandNumber - lastBands)};
1273
                        }
1274
                }
1275
                return null;
1276
        }
1277

    
1278
        /*
1279
         * (non-Javadoc)
1280
         * @see org.gvsig.raster.dataset.IRasterDataSource#setAffineTransform(java.awt.geom.AffineTransform)
1281
         */
1282
        public void setAffineTransform(AffineTransform transf){
1283
                for (int i = 0; i < getDataStoreCount(); i++)
1284
                        this.getProvider(i).setAffineTransform(transf);
1285
        }
1286

    
1287
        /**
1288
         * Obtiene la matriz de transformaci?n del propio raster. Esta matriz es la encargada
1289
         * de convertir las coordenadas de la petici?n en coordenadas a las que se pide a la libreria.
1290
         * En gdal, por ejemplo, se piden las coordenadas a la libreria en coordenadas pixel por lo que
1291
         * esta matriz tendr? la georreferenciaci?n asociada en el worldfile o cabecera. Otras librerias como
1292
         * ermapper la petici?n a la libreria se hace en coordenadas geograficas que son las mismas en las
1293
         * que pide el usuario de gvSIG por lo que esta matriz en este caso se inicializa con la identidad.
1294
         * @return
1295
         */
1296
        public AffineTransform getOwnTransformation() {
1297
                if(providers != null && providers.size() > 0)
1298
                        return providers.get(0).getOwnAffineTransform();
1299
                return new AffineTransform();
1300
        }
1301

    
1302
        /*
1303
         * (non-Javadoc)
1304
         * @see org.gvsig.raster.dataset.IRasterDataSource#isRotated()
1305
         */
1306
        public boolean isRotated() {
1307
                if(providers != null && providers.size() > 0)
1308
                        return providers.get(0).isRotated();
1309
                return false;
1310
        }
1311

    
1312
        /*
1313
         * (non-Javadoc)
1314
         * @see org.gvsig.raster.dataset.IRasterDataSource#setDrawableBands(int[])
1315
         */
1316
        public void setDrawableBands(int[] db) {
1317
                getBands().setDrawableBands(db);
1318
        }
1319
        
1320
        /*
1321
         * (non-Javadoc)
1322
         * @see org.gvsig.raster.impl.dataset.QueryableRaster#getDrawableBands()
1323
         */
1324
        public int[] getDrawableBands() {
1325
                return getBands().getDrawableBands();
1326
        }
1327

    
1328
        /*
1329
         * (non-Javadoc)
1330
         * @see org.gvsig.raster.impl.dataset.QueryableRaster#clearDrawableBands()
1331
         */
1332
        public void clearDrawableBands() {
1333
                getBands().clearDrawableBands();
1334
        }
1335

    
1336
        /*
1337
         * (non-Javadoc)
1338
         * @see org.gvsig.raster.impl.dataset.QueryableRaster#addDrawableBand(int, int)
1339
         */
1340
        public void addDrawableBand(int posRasterBuf, int imageBand) {
1341
                getBands().addDrawableBand(posRasterBuf, imageBand);
1342
        }
1343

    
1344
        /*
1345
         * (non-Javadoc)
1346
         * @see org.gvsig.raster.dataset.IRasterDataSource#isReadOnly()
1347
         */
1348
        public boolean isReadOnly() {
1349
                return readOnly;
1350
        }
1351

    
1352
        /*
1353
         * (non-Javadoc)
1354
         * @see org.gvsig.raster.dataset.IRasterDataSource#setReadOnly(boolean)
1355
         */
1356
        public void setReadOnly(boolean readOnly) {
1357
                this.readOnly = readOnly;
1358
                if(readOnly)
1359
                        this.forceToMemory = false;
1360
        }
1361

    
1362
        /*
1363
         * (non-Javadoc)
1364
         * @see org.gvsig.raster.dataset.IRasterDataSource#setMemoryBuffer(boolean)
1365
         */
1366
        public void setMemoryBuffer(boolean memory) {
1367
                this.forceToMemory = memory;
1368
                if(memory)
1369
                        this.readOnly = false;
1370
        }
1371

    
1372
        /*
1373
         * (non-Javadoc)
1374
         * @see org.gvsig.raster.dataset.IRasterDataSource#isMemoryBuffer()
1375
         */
1376
        public boolean isMemoryBuffer() {
1377
                return forceToMemory;
1378
        }
1379
        
1380
        /*
1381
         * (non-Javadoc)
1382
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#getOverviewWidth(int, int)
1383
         */
1384
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
1385
                int[] providerBand = getProviderFromBandNumber(band);
1386
                RasterProvider prov = getProvider(providerBand[0]);
1387
                return prov.getOverviewWidth(providerBand[1], overview);
1388
        }
1389

    
1390
        /*
1391
         * (non-Javadoc)
1392
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#getOverviewHeight(int, int)
1393
         */
1394
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
1395
                int[] providerBand = getProviderFromBandNumber(band);
1396
                RasterProvider prov = getProvider(providerBand[0]);
1397
                return prov.getOverviewHeight(providerBand[1], overview);
1398
        }
1399

    
1400
        /*
1401
         * (non-Javadoc)
1402
         * @see org.gvsig.raster.dataset.RasterDataStore#getOverviewCount(int)
1403
         */
1404
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
1405
                if(band >= getBandCount())
1406
                        throw new BandAccessException("Wrong band");
1407
                String fileName = getBands().getBand(band).getFileName();
1408
                RasterDataStore store = getDataStore(fileName);
1409
                RasterProvider prov = ((DefaultMultiRasterStore)store).getProvider(0);
1410
                return prov.getOverviewCount(0);
1411
        }
1412

    
1413
        /*
1414
         * (non-Javadoc)
1415
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#overviewsSupport()
1416
         */
1417
        public boolean overviewsSupport() {
1418
                return getProvider(0).overviewsSupport();
1419
        }
1420
        
1421
        /*
1422
         * (non-Javadoc)
1423
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#saveGeoreferencingToRmf()
1424
         */
1425
        public void saveGeoreferencingToRmf() throws RmfSerializerException {
1426
                for (int i = 0; i < providers.size(); i++) {
1427
                        providers.get(i).saveObjectToRmf(DefaultRasterProvider.class, providers.get(i));
1428
                }
1429
        }
1430
        
1431
        /*
1432
         * (non-Javadoc)
1433
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#saveSerialInfoToRmf(org.gvsig.fmap.dal.coverage.store.props.SerialInfo)
1434
         */
1435
        public void saveSerialInfoToRmf(SerialInfo serialInfo) throws RmfSerializerException {
1436
                for (int i = 0; i < providers.size(); i++) {
1437
                        providers.get(i).saveObjectToRmf(DataStoreSerialInfo.class, serialInfo);
1438
                }
1439
        }
1440
        
1441
        /*
1442
         * (non-Javadoc)
1443
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#loadSerialInfoFromRmf(org.gvsig.fmap.dal.coverage.store.props.SerialInfo)
1444
         */
1445
        public boolean loadSerialInfoFromRmf(SerialInfo serialInfo) {
1446
                for (int i = 0; i < providers.size(); i++) {
1447
                        try {
1448
                                providers.get(i).loadObjectFromRmf(DataStoreSerialInfo.class, serialInfo);
1449
                                return true;
1450
                        } catch (RmfSerializerException e) {
1451
                                //Prueba hasta que alguno tiene la informaci?n
1452
                        }
1453
                }
1454
                return false;
1455
        }
1456

    
1457
        /*
1458
         * (non-Javadoc)
1459
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getView()
1460
         */
1461
        public Extent getView() {
1462
                if(providers.size() >= 1)
1463
                        return providers.get(0).getView();
1464
                return null;
1465
        }
1466
        
1467
        /*
1468
         * (non-Javadoc)
1469
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getExtentWithoutRot()
1470
         */
1471
        public Extent getExtentWithoutRot() {
1472
                if(providers.size() >= 1)
1473
                        return providers.get(0).getExtentWithoutRot();
1474
                return null;
1475
        }
1476
        
1477
        /*
1478
         * (non-Javadoc)
1479
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getOwnAffineTransform()
1480
         */
1481
        public AffineTransform getOwnAffineTransform() {
1482
                if(providers.size() >= 1)
1483
                        return providers.get(0).getOwnAffineTransform();
1484
                return null;
1485
        }
1486
        
1487
        /*
1488
         * (non-Javadoc)
1489
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getAffineTransform()
1490
         */
1491
        public AffineTransform getAffineTransform() {
1492
                if(providers.size() >= 1)
1493
                        return providers.get(0).getAffineTransform();
1494
                return null;
1495
        }
1496
        
1497
        /*
1498
         * (non-Javadoc)
1499
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getProjection()
1500
         */
1501
        public IProjection getProjection() {
1502
                if(providers.size() >= 1)
1503
                        return providers.get(0).getProjection();
1504
                return null;
1505
        }
1506
        
1507
        /**
1508
         * Obtiene el objeto con las estadisticas
1509
         * @return MultiFileStatistics
1510
         */
1511
        public Statistics getStatistics() {
1512
                if(stats == null)
1513
                        stats = new MultiDataStoreStatistics(providers);
1514
                return stats;
1515
        }
1516
        
1517
        /*
1518
         * (non-Javadoc)
1519
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
1520
         */
1521
        public Histogram getHistogram() {
1522
                if (histogram == null)
1523
                        histogram = new MultiDataStoreHistogram(this);
1524
                return histogram;
1525
        }
1526
        
1527
        /*
1528
         * (non-Javadoc)
1529
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getMetadata()
1530
         */
1531
        public Metadata getMetadata() {
1532
                if(metadata == null) {
1533
                        int[] bands = new int[providers.size()];
1534
                        for (int i = 0; i < bands.length; i++) 
1535
                                bands[i] = providers.get(i).getBandCount();
1536
                        metadata = new MultiDataStoreMetadata(bands);
1537
                }
1538
                return metadata;
1539
        }
1540
        
1541
        /*
1542
         * (non-Javadoc)
1543
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getColorTable()
1544
         */
1545
        public ColorTable getColorTable() {
1546
                //Solo tiene sentido si tiene un fichero y ese fichero tiene una sola banda
1547
                if(providers.size() == 1)
1548
                        return providers.get(0).getColorTable();
1549
                return null;
1550
        }
1551
        
1552
        /*
1553
         * (non-Javadoc)
1554
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getTransparency()
1555
         */
1556
        public Transparency getTransparency() {
1557
                if(providers.size() >= 1)
1558
                        return providers.get(0).getTransparency();
1559
                return null;
1560
        }
1561
        
1562
        /*
1563
         * (non-Javadoc)
1564
         * @see org.gvsig.fmap.dal.coverage.dataset.RasterDataStore#getColorInterpretation()
1565
         */
1566
        public ColorInterpretation getColorInterpretation() {
1567
                DataStoreColorInterpretation ci = new DataStoreColorInterpretation();
1568
                for (int i = 0; i < providers.size(); i++)
1569
                        ci.addColorInterpretation(providers.get(i).getColorInterpretation());
1570
                return ci;
1571
        }
1572
        
1573
        /*
1574
         * (non-Javadoc)
1575
         * @see org.gvsig.fmap.dal.coverage.dataset.MultiRasterDataStore#getColorInterpretation(int)
1576
         */
1577
        public ColorInterpretation getColorInterpretation(int file) {
1578
                try {
1579
                        return providers.get(file).getColorInterpretation();
1580
                } catch (ArrayIndexOutOfBoundsException e) {
1581
                        return null;
1582
                }
1583
        }
1584

    
1585
        /*
1586
         * (non-Javadoc)
1587
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#isReproyectable()
1588
         */
1589
        public boolean isReproyectable() {
1590
                boolean is = true; 
1591
                for (int i = 0; i < providers.size(); i++) {
1592
                        if(!providers.get(i).isReproyectable())
1593
                                is = false;
1594
                }
1595
                return is;
1596
        }
1597
        
1598
        /*
1599
         * (non-Javadoc)
1600
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1601
         */
1602
        public String getMetadataName() {
1603
                if(providers.size() != 0)
1604
                        return providers.get(0).getName();
1605
                return null;
1606
        }
1607
        
1608
        /*
1609
         * (non-Javadoc)
1610
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#cloneDataStore()
1611
         */
1612
        public RasterDataStore cloneDataStore() {
1613
                DefaultMultiRasterStore ds = new DefaultMultiRasterStore();
1614
                
1615
                int[] bands = new int[providers.size()];
1616
                for (int i = 0; i < bands.length; i++) 
1617
                        bands[i] = providers.get(i).getBandCount();
1618
                ds.metadata = new MultiDataStoreMetadata(bands);
1619
                
1620
                for (int i = 0; i < providers.size(); i++) {
1621
                        RasterProvider prov = providers.get(i).cloneProvider();
1622
                        ds.providers.add(prov);
1623
                        ds.metadata.add(providers.get(i).getMetadata());
1624
                }
1625
                ds.bandList = (BandListImpl)bandList.clone();
1626
                ds.stats = new MultiDataStoreStatistics(ds.providers);
1627
                ds.histogram = new MultiDataStoreHistogram(ds);
1628
                return ds;
1629
        }
1630
        
1631
        /*
1632
         * (non-Javadoc)
1633
         * @see org.gvsig.fmap.dal.coverage.store.RasterDataStore#isOpen()
1634
         */
1635
        public boolean isOpen() {
1636
                if(providers == null || providers.size() == 0)
1637
                        return false;
1638
                for (int i = 0; i < providers.size(); i++) {
1639
                        if(!providers.get(i).isOpen())
1640
                                return false;
1641
                }
1642
                return true;
1643
        }
1644
}