Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataaccess / DataSource.java @ 11067

History | View | Annotate | Download (16.9 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.dataaccess;
20

    
21

    
22
import java.awt.geom.Point2D;
23

    
24
import org.gvsig.raster.dataaccess.buffer.RasterBuffer;
25
import org.gvsig.raster.dataset.FileFoundInListException;
26
import org.gvsig.raster.dataset.IBuffer;
27
import org.gvsig.raster.dataset.NotSupportedExtensionException;
28
import org.gvsig.raster.dataset.RasterDataset;
29
import org.gvsig.raster.dataset.RasterDriverException;
30
import org.gvsig.raster.dataset.RasterMultiDataset;
31
import org.gvsig.raster.dataset.properties.DatasetPalette;
32
import org.gvsig.raster.shared.Extent;
33
import org.gvsig.raster.util.RasterUtilities;
34

    
35
/**
36
 * <P>
37
 * Clase que representa a una rejilla de datos que tiene como fuente
38
 * un RasterMultifile. Tiene m?todos para a?adir nuevos ficheros fuente a la 
39
 * rejilla que podr?n ser consultados como bandas de uno solo. Estos deber?an tener
40
 * la misma extensi?n que el primero introducido.
41
 * </P>
42
 * <P>
43
 * Para la carga del buffer de datos habr? que asigna las bandas que queremos cargar
44
 * de todas las disponibles con addDrawableBands. Despu?s se seleccionar? el ?rea
45
 * que queremos cargar con setAreaOfInterest. Este ?rea se define con coordenadas
46
 * pixel o reales. Finalmente podemos recuperar el buffer con los datos usando la 
47
 * funci?n getRasterBuf.
48
 * </P>
49
 * @author Nacho Brodin (nachobrodin@gmail.com)
50
 *
51
 */
52
public class DataSource implements IQueryableRaster, IWritableRaster  {
53
        
54
        private RasterMultiDataset                 grmf = new RasterMultiDataset(null);
55
        private IBuffer                                        rasterBuf = null;
56
        private int                                                width = 0;
57
        private int                                                height = 0;
58
        private int[]                                         drawableBands = null;
59
        /**
60
         * Extensi?n de los datos del buffer
61
         */
62
        private Extent                                        dataExtent = null;
63
        /**
64
         * Lista de paletas asociadas a las bandas cargadas en el DataSource. Estas son calculadas
65
         * en las funciones que asignan las bandas a dibujar (addDrawableBands)
66
         */
67
        private DatasetPalette[]                        palette = null;
68
        /**
69
         * Activa o desactiva el supersampleo en la carga del buffer.
70
         */
71
        private boolean                                        supersamplingLoadingBuffer = true;
72
        
73
        /**
74
         * Ancho y alto en pixeles del ?ltimo buffer asignado
75
         */
76
        private double                                         nWidth = 0;
77
        private double                                         nHeight = 0;
78
        
79
        /**
80
         * Constructor
81
         */
82
        public DataSource(){}
83
        
84
        /**
85
         * Constructor
86
         * @param grf Lista de geoRasterFile
87
         */
88
        public DataSource(RasterDataset[] grf){
89
                for(int i = 0; i< grf.length; i++)
90
                        addFile(grf[i]);
91
        }
92
        
93
        /**
94
         * Constructor
95
         * @param grf GeoRasterFile
96
         */
97
        public DataSource(RasterDataset grf){
98
                addFile(grf);
99
        }
100
        
101
        /**
102
         * A?ade un GeoRasterFile al Grid
103
         * @param grf GeoRasterFile a a?adir
104
         */
105
        public void addFile(RasterDataset grf){
106
                try{
107
                        grmf.addDataset(grf);
108
                        width = grf.getWidth();
109
                        height = grf.getHeight();
110
                }catch(FileFoundInListException e){
111
                        //El fichero est? en la lista por lo que no lo a?adimos
112
                }
113
        }
114
        
115
        /**
116
         * A?ade un GeoRasterFile al Grid
117
         * @param fileName Nombre del fichero a a?adir
118
         * @throws NotSupportedExtensionException 
119
         * @throws RasterDriverException 
120
         */
121
        public void addFile(String filename) throws NotSupportedExtensionException, RasterDriverException{
122
                try{
123
                        grmf.addDataset(filename);
124
                        width = (int)grmf.getWidth()[0];
125
                        height = (int)grmf.getHeight()[0];
126
                }catch(FileFoundInListException e){
127
                        //El fichero est? en la lista por lo que no lo a?adimos
128
                }
129
        }
130
        
131
        /**
132
         * Elimina un GeoRasterFile del Grid
133
         * @param grf GeoRasterFile a eliminar
134
         */
135
        public void removeFile(RasterDataset grf){
136
                grmf.removeDataset(grf);
137
        }
138
        
139
        /**
140
         * Elimina un GeoRasterFile del Grid
141
         * @param fileName Nombre del fichero a eliminar su GeoRasterFile
142
         */
143
        public void removeFile(String fileName){
144
                grmf.removeDataset(fileName);
145
        }
146
        
147
        /**
148
         * Obtiene el n?mero de ficheros del que est? compuesta la fuente de datos.
149
         * @return
150
         */
151
        public int getFileCount(){
152
                return  grmf.getDatasetCount();
153
        }
154
        
155
        /*
156
         *  (non-Javadoc)
157
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getGeoRasterMultiFile()
158
         */
159
        public RasterMultiDataset getGeoRasterMultiFile(){
160
                return grmf;
161
        }
162
        
163
        /**
164
         * Libera el buffer de memoria
165
         */
166
        public void free(){
167
                rasterBuf = null;
168
                System.gc();
169
        }
170
        
171
        /**
172
         * Resetea la asignaci?n de dibujado de las bandas de la imagen
173
         * sobre el DataImage cuando se hace un update para esta banda.
174
         */
175
        public void clearDrawableBand(){
176
                for(int i = 0; i< grmf.getDatasetCount(); i++)
177
                        grmf.getBands().clearDrawableBand();
178
                palette = null;
179
        }
180
        
181
        /*
182
         *  (non-Javadoc)
183
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#addDrawableBands(int[])
184
         */
185
        public int[] addDrawableBands(int[] drawableBands){
186
                this.drawableBands = drawableBands;
187
                grmf.getBands().setDrawableArray(drawableBands);
188
                
189
                int[] files = new int[drawableBands.length];
190
                palette = new DatasetPalette[drawableBands.length];
191
                
192
                for(int i = 0; i< drawableBands.length; i++){
193
                        if(drawableBands[i] < 0 || drawableBands[i] >= grmf.getBandCount())
194
                                continue;
195
                        grmf.getBands().addDrawableBand(i, drawableBands[i]);
196
                        String fileName = grmf.getBands().getBand(drawableBands[i]).getFileName();
197
                        files[i] = grmf.getBands().getFileNumber(fileName);
198
                        palette[i] = grmf.getPalette(fileName);
199
                }
200
                return files;
201
        }
202

    
203
        /*
204
         *  (non-Javadoc)
205
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAllDrawableBands()
206
         */
207
        public int[] setAllDrawableBands(){
208
                clearDrawableBand();
209
                drawableBands = new int[grmf.getBandCount()];
210
                int[] files = new int[drawableBands.length];
211
                palette = new DatasetPalette[drawableBands.length];
212
                
213
                for(int i = 0; i< grmf.getBandCount(); i++){
214
                        grmf.getBands().addDrawableBand(i, i);
215
                        this.drawableBands[i] = i;
216
                        String fileName = grmf.getBands().getBand(drawableBands[i]).getFileName();
217
                        files[i] = grmf.getBands().getFileNumber(fileName);
218
                        palette[i] = grmf.getPalette(fileName);
219
                }
220
                return files;
221
        }
222

    
223
        /*
224
         *  (non-Javadoc)
225
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getDrawableBands()
226
         */
227
        public int[] getDrawableBands() {
228
                return drawableBands;
229
        }
230
        
231
        /*
232
         *  (non-Javadoc)
233
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest(double, double, double, double)
234
         */
235
        public void setAreaOfInterest(double x, double y, double w, double h, boolean adjustToExtent) throws ArrayIndexOutOfBoundsException{
236
                dataExtent = new Extent(x, y, x + w, y - h);
237
                if(adjustToExtent){
238
                        Extent adjustedDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, grmf.getExtent());
239
                        double newW = w;  
240
                        double newH = h;
241
                        if(!RasterUtilities.compareExtents(dataExtent, adjustedDataExtent)){
242
                                //Si el extent ha sido ajustado entonces tenemos que variar tambi?n al ancho y el alto de la petici?n
243
                                newW = (adjustedDataExtent.width() * w) / dataExtent.width();  
244
                                newH = (adjustedDataExtent.height() * h) / dataExtent.height();
245
                        }
246
                        rasterBuf = grmf.getWindowRaster(adjustedDataExtent.getMin().getX(), adjustedDataExtent.getMax().getY(), newW, newH, adjustToExtent);
247
                }else
248
                        rasterBuf = grmf.getWindowRaster(dataExtent.getMin().getX(), dataExtent.getMax().getY(), w, h, adjustToExtent);
249
        }
250
                
251
        /*
252
         *  (non-Javadoc)
253
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest(double, double, double, double, int, int)
254
         */
255
        public int[] setAreaOfInterest(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, boolean adjustToExtent) throws ArrayIndexOutOfBoundsException{
256
                //TODO: VALIDACI?N: Comprobaci?n de exceso de memoria reservada
257
                dataExtent = new Extent(minX, minY, maxX, maxY);
258
                Extent adjustedDataExtent = new Extent(dataExtent);
259
                if(adjustToExtent)
260
                        adjustedDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, grmf.getExtent());
261

    
262
                minX = adjustedDataExtent.getMin().getX();
263
                minY = adjustedDataExtent.getMin().getY();
264
                maxX = adjustedDataExtent.getMax().getX();
265
                maxY = adjustedDataExtent.getMax().getY();
266
                
267
                //Esta secci?n es para que no supersamplee el driver y pueda hacerse en el cliente
268
                if(!isSupersamplingLoadingBuffer()){
269
                        nWidth = ((adjustedDataExtent.width() * grmf.getDataset(0).getWidth()) / grmf.getDataset(0).getExtent().width());
270
                        nHeight = ((adjustedDataExtent.height() * grmf.getDataset(0).getHeight()) / grmf.getDataset(0).getExtent().height());
271

    
272
                        if(bufWidth > Math.ceil(nWidth) && bufHeight > Math.ceil(nHeight)){                                
273
                                rasterBuf = grmf.getWindowRaster(minX, maxY, Math.abs(maxX - minX), Math.abs(maxY - minY), adjustToExtent);
274
                                int[] step = grmf.calcSteps(minX, maxY, maxX, minY, nWidth, nHeight, bufWidth, bufHeight);
275
                                return step;
276
                        }
277
                }
278
                
279
                rasterBuf = grmf.getWindowRaster(minX, minY, maxX, maxY, bufWidth, bufHeight, adjustToExtent);
280
                return null;
281
        }
282
        
283
        /*
284
         *  (non-Javadoc)
285
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest(int, int, int, int)
286
         */
287
        public void setAreaOfInterest(int x, int y, int w, int h) throws ArrayIndexOutOfBoundsException{
288
                if((x + w) > getWidth() || (y + h) > getHeight())
289
                        throw new ArrayIndexOutOfBoundsException("Out of Image");
290
                dataExtent = new Extent(grmf.rasterToWorld(new Point2D.Double(x, y)), 
291
                                                                grmf.rasterToWorld(new Point2D.Double(x + w, y + h)));
292
                rasterBuf = grmf.getWindowRaster(x, y, w, h);
293
        }
294
        
295
        /*
296
         *  (non-Javadoc)
297
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest()
298
         */
299
        public void setAreaOfInterest(){                
300
                dataExtent = grmf.getExtent();
301
                rasterBuf = grmf.getWindowRaster(0, 0, (int)grmf.getWidth()[0], (int)grmf.getHeight()[0]);
302
        }
303
        
304
        /*
305
         *  (non-Javadoc)
306
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest(int, int, int, int, int, int)
307
         */
308
        public void setAreaOfInterest(int x, int y, int w, int h, int bufWidth, int bufHeight) throws ArrayIndexOutOfBoundsException{
309
                //TODO: VALIDACI?N: Comprobaci?n de exceso de memoria reservada
310
                if(x < 0 || y < 0 || (x + w) > getWidth() || (y + h) > getHeight())
311
                        throw new ArrayIndexOutOfBoundsException("Out of Image");
312
                dataExtent = new Extent(grmf.rasterToWorld(new Point2D.Double(x, y)), 
313
                                                                grmf.rasterToWorld(new Point2D.Double(x + w, y + h)));
314

    
315
                rasterBuf = grmf.getWindowRaster(x, y, w, h, bufWidth, bufHeight);
316
        }
317
        
318
        /**
319
         * Ajusta el ?rea del grid a un ancho y un alto dado en pixeles. Este ajuste se har? 
320
         * en relaci?n a un m?todo de interpolaci?n definido en el par?metro.
321
         * @param w Ancho de la nueva imagen.
322
         * @param h Alto de la nueva imagen.
323
         * @param interpolation M?todo de interpolaci?n que se usar? en el ajuste.
324
         * @param bands Bandas que se desea en el nuevo RasterBuf ajustado. Si este par?metro es null
325
         * se usar?n todas las bandas de la imagen.
326
         */
327
        public void setAdjustedWindow(int w, int h, int interpolationMethod, int[] bands){
328
                if(w == width && h == height)
329
                        return;
330
                switch(interpolationMethod){
331
                case IQueryableRaster.INTERPOLATION_NearestNeighbour:
332
                                rasterBuf = ((RasterBuffer)rasterBuf).adjustRasterNearestNeighbourInterpolation(w, h, bands);
333
                                break;
334
                case IQueryableRaster.INTERPOLATION_Bilinear:
335
                                System.out.println("Method not implemented yet");
336
                                break;
337
                case IQueryableRaster.INTERPOLATION_InverseDistance:
338
                                System.out.println("Method not implemented yet");
339
                                break;
340
                case IQueryableRaster.INTERPOLATION_BicubicSpline:
341
                                System.out.println("Method not implemented yet");
342
                                break;
343
                case IQueryableRaster.INTERPOLATION_BSpline:
344
                                System.out.println("Method not implemented yet");
345
                                break;
346
                }
347
                //width = rasterBuf.getWidth();
348
                //height = rasterBuf.getHeight();
349
        }
350
                
351
        /**
352
         * Obtiene el tipo de datos del grid.
353
         * @return entero que representa el tipo de dato de las celdas del grid.
354
         */
355
        public int getDataType() {
356
                return grmf.getDataType()[0];
357
        }
358

    
359
        /**
360
         * Obtiene la altura del grid.
361
         * @return altura en celdas del grid.
362
         */
363
        public int getHeight() {
364
                return height;
365
        }
366

    
367
        /**
368
         * Obtiene la anchura del grid.
369
         * @return anchura en celdas del grid.
370
         */
371
        public int getWidth() {
372
                return width;
373
        }
374

    
375
        /*
376
         *  (non-Javadoc)
377
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getXCellSize()
378
         */
379
        public double getXCellSize() {
380

    
381
                Extent e = grmf.getExtent();
382
                double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
383
                
384
                return dCellsize;
385
                
386
        }
387

    
388
        /*
389
         *  (non-Javadoc)
390
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getYCellSize()
391
         */
392
        public double getYCellSize() {
393

    
394
                return 0;
395
        }
396

    
397
        /*
398
         *  (non-Javadoc)
399
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#isNoData(int, int, int)
400
         */
401
        public boolean isNoData(int x, int y, int band) {
402

    
403
                return false;
404
                
405
        }
406
        
407
        public void setNoDataValue(double dNoDataValue){
408
                if(rasterBuf instanceof RasterBuffer)
409
                        ((RasterBuffer)rasterBuf).setNoDataValue(dNoDataValue);
410
        }
411
        
412
        public double getNoDataValue(){
413
                if(rasterBuf instanceof RasterBuffer)
414
                        return ((RasterBuffer)rasterBuf).getNoDataValue();
415
                return 0D;
416
        }
417

    
418
        /*
419
         *  (non-Javadoc)
420
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setDataType(int)
421
         */
422
        public void setDataType(int dt) {
423
                
424
        }
425
        
426
        /*
427
         *  (non-Javadoc)
428
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getBandCount()
429
         */
430
        public int getBandCount(){
431
                if(rasterBuf != null)
432
                        return rasterBuf.getBandCount();
433
                else
434
                        return this.getGeoRasterMultiFile().getBandCount();
435
        }
436

    
437
        /**
438
         * Obtiene el buffer de datos del grid
439
         * @return RasterBuf
440
         */
441
        public IBuffer getRasterBuf() {
442
                return rasterBuf;
443
        }
444
                
445
        /**
446
         * Evalua si una coordenada pixel cae dentro de la imagen.
447
         * @param x coordenada pixel X
448
         * @param y coordenada pixel Y
449
         */
450
        public boolean isPixelInGrid(int x, int y){
451
                return (x >= 0 && y >= 0 && x <= getWidth() && y <= getHeight());
452
        }
453
        
454
        /**
455
         * Extent de todo el raster asociado a la fuente de datos.
456
         */
457
        public Extent getExtent(){
458
                return grmf.getExtent();
459
        }
460

    
461
        /*
462
         *  (non-Javadoc)
463
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getData(int, int, int, int)
464
         */
465
        public RasterBuffer getData(int x, int y, int w, int h) {
466
                return null;
467
        }
468

    
469
        /*
470
         *  (non-Javadoc)
471
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getCoordsGeoTransformFile()
472
         */
473
        public double[] getCoordsGeoTransformFile() {
474
                return grmf.getCoordsGeoTransformFile();                
475
        }
476
        
477
        /*
478
         *  (non-Javadoc)
479
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getLastSelectedView()
480
         */
481
        public Extent getLastSelectedView(){
482
                return grmf.getLastSelectedView();
483
        }
484
                
485
        /**
486
         * Obtiene el extent correspondiente a los datos cargados en el buffer
487
         * @return Extent
488
         */
489
        public Extent getDataExtent() {
490
                return dataExtent;
491
        }
492
        
493
        /*
494
         * (non-Javadoc)
495
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getPalettes()
496
         */
497
        public DatasetPalette[] getPalettes(){
498
                return palette;
499
        }
500
        
501
        /**
502
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
503
         * @return true si est? georreferenciada y false si no lo est?.
504
         */
505
        public boolean isGeoreferenced() {
506
                return grmf.isGeoreferenced();
507
        }
508

    
509
        /**
510
         * Consulta el flag de supersampleo en la carga del buffer.
511
         * <P> 
512
         * Si este flag es false 
513
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la 
514
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos 
515
         * en el ?rea.
516
         * </P>
517
         * <P> 
518
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe 
519
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta 
520
         * variable es true el buffer lo generar? de 500x400.
521
         * </P>
522
         *  
523
         * @return true si el supersampleo en la carga del buffer est? activado y false si no lo est?.
524
         */
525
        public boolean isSupersamplingLoadingBuffer() {
526
                return supersamplingLoadingBuffer;
527
        }
528

    
529
        /**
530
         * Activa o desactiva el supersampling en la carga del buffer.
531
         * <P> 
532
         * Si este flag es false 
533
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la 
534
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos 
535
         * en el ?rea.
536
         * </P>
537
         * <P> 
538
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe 
539
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta 
540
         * variable es true el buffer lo generar? de 500x400.
541
         * </P> 
542
         *
543
         * @param supersamplingLoadingBuffer true o false para activar o desactivar el supersampling en la 
544
         * carga del buffer.
545
         */
546
        public void setSupersamplingLoadingBuffer(boolean supersamplingLoadingBuffer) {
547
                this.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
548
        }
549
        
550
        public double getNHeight() {
551
                return nHeight;
552
        }
553

    
554
        public double getNWidth() {
555
                return nWidth;
556
        }
557

    
558
}
559