Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / BufferFactory.java @ 11074

History | View | Annotate | Download (17.3 KB)

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

    
21

    
22
import java.awt.geom.Point2D;
23

    
24
import org.gvsig.raster.dataset.FileFoundInListException;
25
import org.gvsig.raster.dataset.FileNotOpenException;
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.DataClassList;
34
import org.gvsig.raster.util.Histogram;
35
import org.gvsig.raster.util.RasterUtilities;
36

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

    
215
        /*
216
         *  (non-Javadoc)
217
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAllDrawableBands()
218
         */
219
        public int[] setAllDrawableBands() {
220
                clearDrawableBand();
221
                drawableBands = new int[mDataset.getBandCount()];
222
                int[] files = new int[drawableBands.length];
223
                palette = new DatasetPalette[drawableBands.length];
224
                
225
                for(int i = 0; i< mDataset.getBandCount(); i++) {
226
                        mDataset.getBands().addDrawableBand(i, i);
227
                        this.drawableBands[i] = i;
228
                        String fileName = mDataset.getBands().getBand(drawableBands[i]).getFileName();
229
                        files[i] = mDataset.getBands().getFileNumber(fileName);
230
                        palette[i] = mDataset.getPalette(fileName);
231
                }
232
                return files;
233
        }
234

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

    
274
                minX = adjustedDataExtent.getMin().getX();
275
                minY = adjustedDataExtent.getMin().getY();
276
                maxX = adjustedDataExtent.getMax().getX();
277
                maxY = adjustedDataExtent.getMax().getY();
278
                
279
                //Esta secci?n es para que no supersamplee el driver y pueda hacerse en el cliente
280
                if(!isSupersamplingLoadingBuffer()) {
281
                        nWidth = ((adjustedDataExtent.width() * mDataset.getDataset(0).getWidth()) / mDataset.getDataset(0).getExtent().width());
282
                        nHeight = ((adjustedDataExtent.height() * mDataset.getDataset(0).getHeight()) / mDataset.getDataset(0).getExtent().height());
283

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

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

    
371
        /**
372
         * Obtiene la altura del grid.
373
         * @return altura en celdas del grid.
374
         */
375
        public int getHeight() {
376
                return height;
377
        }
378

    
379
        /**
380
         * Obtiene la anchura del grid.
381
         * @return anchura en celdas del grid.
382
         */
383
        public int getWidth() {
384
                return width;
385
        }
386

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

    
393
                Extent e = mDataset.getExtent();
394
                double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
395
                
396
                return dCellsize;
397
                
398
        }
399

    
400
        /*
401
         *  (non-Javadoc)
402
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getYCellSize()
403
         */
404
        public double getYCellSize() {
405

    
406
                return 0;
407
        }
408

    
409
        /*
410
         *  (non-Javadoc)
411
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#isNoData(int, int, int)
412
         */
413
        public boolean isNoData(int x, int y, int band) {
414

    
415
                return false;
416
                
417
        }
418
        
419
        public void setNoDataValue(double dNoDataValue) {
420
                if(rasterBuf instanceof RasterBuffer)
421
                        ((RasterBuffer)rasterBuf).setNoDataValue(dNoDataValue);
422
        }
423
        
424
        public double getNoDataValue() {
425
                if(rasterBuf instanceof RasterBuffer)
426
                        return ((RasterBuffer)rasterBuf).getNoDataValue();
427
                return 0D;
428
        }
429

    
430
        /*
431
         *  (non-Javadoc)
432
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setDataType(int)
433
         */
434
        public void setDataType(int dt) {
435
                
436
        }
437
        
438
        /*
439
         *  (non-Javadoc)
440
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getBandCount()
441
         */
442
        public int getBandCount() {
443
                if(rasterBuf != null)
444
                        return rasterBuf.getBandCount();
445
                else
446
                        return this.getGeoRasterMultiFile().getBandCount();
447
        }
448

    
449
        /**
450
         * Obtiene el buffer de datos del grid
451
         * @return RasterBuf
452
         */
453
        public IBuffer getRasterBuf() {
454
                return rasterBuf;
455
        }
456
                
457
        /**
458
         * Evalua si una coordenada pixel cae dentro de la imagen.
459
         * @param x coordenada pixel X
460
         * @param y coordenada pixel Y
461
         */
462
        public boolean isPixelInGrid(int x, int y) {
463
                return (x >= 0 && y >= 0 && x <= getWidth() && y <= getHeight());
464
        }
465
        
466
        /**
467
         * Extent de todo el raster asociado a la fuente de datos.
468
         */
469
        public Extent getExtent() {
470
                return mDataset.getExtent();
471
        }
472

    
473
        /*
474
         *  (non-Javadoc)
475
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getData(int, int, int, int)
476
         */
477
        public RasterBuffer getData(int x, int y, int w, int h) {
478
                return null;
479
        }
480

    
481
        /*
482
         *  (non-Javadoc)
483
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getCoordsGeoTransformFile()
484
         */
485
        public double[] getCoordsGeoTransformFile() {
486
                return mDataset.getCoordsGeoTransformFile();                
487
        }
488
        
489
        /*
490
         *  (non-Javadoc)
491
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getLastSelectedView()
492
         */
493
        public Extent getLastSelectedView() {
494
                return mDataset.getLastSelectedView();
495
        }
496
                
497
        /**
498
         * Obtiene el extent correspondiente a los datos cargados en el buffer
499
         * @return Extent
500
         */
501
        public Extent getDataExtent() {
502
                return dataExtent;
503
        }
504
        
505
        /*
506
         * (non-Javadoc)
507
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#getPalettes()
508
         */
509
        public DatasetPalette[] getPalettes() {
510
                return palette;
511
        }
512
        
513
        /**
514
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
515
         * @return true si est? georreferenciada y false si no lo est?.
516
         */
517
        public boolean isGeoreferenced() {
518
                return mDataset.isGeoreferenced();
519
        }
520

    
521
        /**
522
         * Consulta el flag de supersampleo en la carga del buffer.
523
         * <P> 
524
         * Si este flag es false 
525
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la 
526
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos 
527
         * en el ?rea.
528
         * </P>
529
         * <P> 
530
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe 
531
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta 
532
         * variable es true el buffer lo generar? de 500x400.
533
         * </P>
534
         *  
535
         * @return true si el supersampleo en la carga del buffer est? activado y false si no lo est?.
536
         */
537
        public boolean isSupersamplingLoadingBuffer() {
538
                return supersamplingLoadingBuffer;
539
        }
540

    
541
        /**
542
         * Activa o desactiva el supersampling en la carga del buffer.
543
         * <P> 
544
         * Si este flag es false 
545
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la 
546
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos 
547
         * en el ?rea.
548
         * </P>
549
         * <P> 
550
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe 
551
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta 
552
         * variable es true el buffer lo generar? de 500x400.
553
         * </P> 
554
         *
555
         * @param supersamplingLoadingBuffer true o false para activar o desactivar el supersampling en la 
556
         * carga del buffer.
557
         */
558
        public void setSupersamplingLoadingBuffer(boolean supersamplingLoadingBuffer) {
559
                this.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
560
        }
561
        
562
        public double getNHeight() {
563
                return nHeight;
564
        }
565

    
566
        public double getNWidth() {
567
                return nWidth;
568
        }
569

    
570
}
571