Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1015 / libraries / libCq_CMS_praster / src / org / cresques / io / data / Grid.java @ 13679

History | View | Annotate | Download (14.7 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.cresques.io.data;
20

    
21
import java.awt.geom.Point2D;
22

    
23
import org.cresques.io.GeoRasterFile;
24
import org.cresques.io.datastruct.Histogram;
25
import org.cresques.io.datastruct.Statistic;
26
import org.cresques.io.exceptions.FileFoundInListException;
27
import org.cresques.px.Extent;
28
import org.cresques.px.PxRaster;
29
import org.cresques.util.Utilities;
30
import org.cresques.filter.IRaster;
31

    
32
public class Grid implements IQueryableRaster, IWritableRaster  {
33
        
34
        private GeoRasterMultiFile                 grmf = new GeoRasterMultiFile(null);
35
        private RasterBuf                                rasterBuf = null;
36
        private Histogram                                histogram = null;
37
        private PxRaster                                pxRaster = null;
38
        private Statistic                                stats = null;
39
        protected int                                        width = 0;
40
        protected int                                        height = 0;
41
        protected Extent                                dataExtent = null;
42
        
43
        private double m_dNoDataValue = -99999; //TODO:temporal
44
        
45
        /**
46
         * Constructor
47
         */
48
        public Grid(){}
49
        
50
        /**
51
         * Constructor
52
         * @param grf Lista de geoRasterFile
53
         */
54
        public Grid(GeoRasterFile[] grf){
55
                for(int i = 0; i< grf.length; i++)
56
                        addFile(grf[i]);
57
        }
58
        
59
        /**
60
         * Constructor
61
         * @param grf GeoRasterFile
62
         */
63
        public Grid(GeoRasterFile grf){
64
                addFile(grf);
65
        }
66

    
67
        /**
68
         * Asigna el renderizador para el calculo de histogramas a partir 
69
         * de la visualizaci?n.
70
         * @param pxR Renderizador.
71
         */
72
        public void addRenderizer(PxRaster pxR){
73
                this.pxRaster = pxR;
74
                this.stats = pxR.stats;
75
                this.getHistogram().addRenderizer(pxR);
76
        }
77
        
78
        /**
79
         * Asigna el RasterBuffer
80
         * @param rb
81
         */
82
        public void setRasterBuf(RasterBuf rb) {
83
                this.rasterBuf = rb;
84
        }
85
        
86
        /**
87
         * A?ade un GeoRasterFile al Grid
88
         * @param grf GeoRasterFile a a?adir
89
         */
90
        public void addFile(GeoRasterFile grf){
91
                try{
92
                        grmf.addFile(grf);
93
                        width = grf.getWidth();
94
                        height = grf.getHeight();
95
                }catch(FileFoundInListException e){
96
                        //El fichero est? en la lista por lo que no lo a?adimos
97
                }
98
        }
99
        
100
        /**
101
         * Elimina un GeoRasterFile del Grid
102
         * @param grf GeoRasterFile a eliminar
103
         */
104
        public void removeFile(GeoRasterFile grf){
105
                grmf.removeFile(grf);
106
        }
107
        
108
        /**
109
         * Obtiene la estructura que contiene la lista de ficheros del Grid
110
         * @return GeoRasterMultiFile
111
         */
112
        public GeoRasterMultiFile getGeoRasterMultiFile(){
113
                return grmf;
114
        }
115
        
116
        /**
117
         * Libera el buffer de memoria
118
         */
119
        public void free(){
120
                rasterBuf = null;
121
                System.gc();
122
        }
123
        
124
        /**
125
         * Resetea la asignaci?n de dibujado de las bandas de la imagen
126
         * sobre el DataImage cuando se hace un update para esta banda.
127
         */
128
        public void clearDrawableBand(){
129
                for(int i = 0; i< grmf.getFileCount(); i++)
130
                        grmf.getBands().clearDrawableBand();
131
        }
132
        
133
        /**
134
         * Para este GeoRasterFile asigna que bandas se pintaran
135
         * sobre el RasterBuf cuando se haga un update. Cada posici?n del vector es una banda
136
         * del rasterBuf y el contenido de esa posici?n es la banda de la imagen que se dibujar?
137
         * sobre ese RasterBuf.
138
         * @param drawableBands        .
139
         */
140
        public void addDrawableBands(int[] drawableBands){
141
                for(int i = 0; i< drawableBands.length; i++)
142
                        grmf.getBands().addDrawableBand(i, drawableBands[i]);                                
143
        }
144
        
145
        /**
146
         * Asigna el ?rea de interes en coordenadas del mundo real. Si las coordenadas exceden del tama?o de la imagen
147
         * estas coordenadas son ajustadas el extent.
148
         * @param x Coordenada X, esquina superior izquierda
149
         * @param y Coordenada Y, esquina superior izquierda
150
         * @param w Ancho del ?rea 
151
         * @param h Alto del ?rea
152
         * @throws ArrayIndexOutOfBoundsException
153
         */
154
        public void setAreaOfInterest(double x, double y, double w, double h) throws ArrayIndexOutOfBoundsException{
155
                dataExtent = new Extent(x, y, x + w, y - h);
156
                Extent fitExtent = Utilities.calculateAdjustedView(dataExtent, grmf.getExtent());
157
                
158
                rasterBuf = grmf.getWindowRaster(fitExtent.minX(), fitExtent.maxY(), fitExtent.width(), fitExtent.height());
159
                
160
                if(!Utilities.isInside(dataExtent, fitExtent)){
161
                        double distWcX = Math.abs(fitExtent.getMin().getX() - dataExtent.getMin().getX());
162
                        double distWcY = Math.abs(fitExtent.getMax().getY() - dataExtent.getMax().getY());
163
                        double mtsPixelX = grmf.getExtent().width() / grmf.getWidth();
164
                        double mtsPixelY = grmf.getExtent().width() / grmf.getWidth(); 
165
                        double pxX = distWcX / mtsPixelX;
166
                        double pxY =  distWcY / mtsPixelY;
167
                        
168
                        double wPx = dataExtent.width() / mtsPixelX;
169
                        double hPx = dataExtent.height() / mtsPixelY;
170
                        
171
                        RasterBuf buf = new RasterBuf(rasterBuf.getDataType(), (int)wPx, (int)hPx, rasterBuf.getBandCount(), true);
172
                        buf.setToNoData();
173
                        
174
                        for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
175
                                for (int row = 0; row < rasterBuf.getHeight(); row++) 
176
                                        for (int col = 0; col < rasterBuf.getWidth(); col++) 
177
                                                buf.setElemByte((int)(row + pxY), (int)(col + pxX), 
178
                                                                                iBand, 
179
                                                                                rasterBuf.getElemByte(row, col, iBand));
180
                        rasterBuf = buf;
181
                }
182
        }
183
        
184
        /**
185
         * Asigna el ?rea de interes en coordenadas pixel. Si las coordenadas exceden del tama?o de la imagen
186
         * lanza una excepci?n.
187
         * @param x Coordenada X, esquina superior izquierda
188
         * @param y Coordenada Y, esquina superior izquierda
189
         * @param w Ancho del ?rea 
190
         * @param h Alto del ?rea
191
         * @throws ArrayIndexOutOfBoundsException
192
         */
193
        public void setAreaOfInterest(int x, int y, int w, int h) throws ArrayIndexOutOfBoundsException{
194
                if((x + w) > getWidth() || (y + h) > getHeight())
195
                        throw new ArrayIndexOutOfBoundsException("Out of Image");
196
                
197
                Point2D begin = grmf.rasterToWorld(new Point2D.Double(x, y));
198
                Point2D end = grmf.rasterToWorld(new Point2D.Double(x + w, y + h));
199
                if(begin != null && end != null)
200
                        dataExtent = new Extent(begin, end);
201
                
202
                rasterBuf = grmf.getWindowRaster(x, y, w, h);
203
                //width = rasterBuf.getWidth();
204
                //height = rasterBuf.getHeight();
205
        }
206
        
207
        /*
208
         *  (non-Javadoc)
209
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest(double, double, double, double, int, int)
210
         */
211
        public int[] setAreaOfInterest(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight) throws ArrayIndexOutOfBoundsException{
212
                //TODO: VALIDACI?N: Comprobaci?n de exceso de memoria reservada
213
                dataExtent = new Extent(minX, minY, maxX, maxY);
214
                Extent fitExtent = Utilities.calculateAdjustedView(dataExtent, grmf.getExtent());
215
                
216
                //Caso en que la extensi?n pedida SI se sale fuera del ?rea del raster
217
                //El pixel a medias entre NoData y datos se pone NoData
218
                if(Utilities.isOutside(dataExtent, grmf.getExtent())) {
219
                        double error = 0.01;
220
                        //Upper Left
221
                        double distWcX = Math.abs(fitExtent.getMin().getX() - dataExtent.getMin().getX());
222
                        distWcX = (distWcX > error) ? distWcX : 0;
223
                        double distWcY = Math.abs(fitExtent.getMax().getY() - dataExtent.getMax().getY());
224
                        distWcY = (distWcY > error) ? distWcY : 0;
225
                        //Pixel inicial del buffer donde se empieza a dibujar. Redondeamos por arriba pq lo que sobra se pone NoData
226
                        double initPxX = Math.ceil((distWcX * bufWidth) / (Math.abs(maxX - minX))); 
227
                        double initPxY = Math.ceil((distWcY * bufHeight) / (Math.abs(maxY - minY)));
228
                        //Obtenemos la coordenada real para el pixel inicial
229
                        double wcXInit = (minX < grmf.getExtent().minX()) ? grmf.getExtent().minX() : minX;
230
                        double wcYInit = (maxY > grmf.getExtent().maxY()) ? grmf.getExtent().maxY() : maxY;
231
                        
232
                        //Lower Right
233
                        distWcX = Math.abs(fitExtent.getMax().getX() - dataExtent.getMin().getX());
234
                        distWcX = (distWcX > error) ? distWcX : 0;
235
                        distWcY = Math.abs(fitExtent.getMin().getY() - dataExtent.getMax().getY());
236
                        distWcY = (distWcY > error) ? distWcY : 0;
237
                        //Pixel final del buffer donde se dibuja. Redondeamos por abajo pq lo que sobra se pone NoData
238
                        double endPxX = Math.floor((distWcX * bufWidth) / (Math.abs(maxX - minX))); 
239
                        double endPxY = Math.floor((distWcY * bufHeight) / (Math.abs(maxY - minY)));
240
                        //Obtenemos la coordenada real para el pixel
241
                        double wcXEnd = (maxX > grmf.getExtent().maxX()) ? grmf.getExtent().maxX() : maxX;
242
                        double wcYEnd = (minY < grmf.getExtent().minY()) ? grmf.getExtent().minY() : minY;
243
                        
244
                        int copyX = (int)Math.abs(endPxX - initPxX);
245
                        int copyY = (int)Math.abs(endPxY - initPxY);
246
                        
247
                        rasterBuf = grmf.getWindowRaster(wcXInit, wcYEnd, wcXEnd, wcYInit, copyX, copyY);
248
                        RasterBuf buf = new RasterBuf(rasterBuf.getDataType(), bufWidth, bufHeight, rasterBuf.getBandCount(), true);
249
                        buf.setNoDataValue(m_dNoDataValue);
250
                        buf.setToNoData();
251
                        
252
                        switch(rasterBuf.getDataType()) {
253
                          case IRaster.TYPE_BYTE:
254
                                  for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
255
                                                for (int row = 0; row < copyY; row++) 
256
                                                        for (int col = 0; col < copyX; col++) 
257
                                                                buf.setElemByte((int)(row + initPxY), (int)(col + initPxX), 
258
                                                                                                iBand, 
259
                                                                                                rasterBuf.getElemByte(row, col, iBand));
260
                                    break;
261
                          case IRaster.TYPE_SHORT:
262
                          case IRaster.TYPE_USHORT:
263
                                  for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
264
                                                for (int row = 0; row < copyY; row++) 
265
                                                        for (int col = 0; col < copyX; col++) 
266
                                                                buf.setElemShort((int)(row + initPxY), (int)(col + initPxX), 
267
                                                                                                iBand, 
268
                                                                                                rasterBuf.getElemShort(row, col, iBand));
269
                                    break;
270
                          case IRaster.TYPE_INT:
271
                                  for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
272
                                                for (int row = 0; row < copyY; row++) 
273
                                                        for (int col = 0; col < copyX; col++) 
274
                                                                buf.setElemInt((int)(row + initPxY), (int)(col + initPxX), 
275
                                                                                                iBand, 
276
                                                                                                rasterBuf.getElemInt(row, col, iBand));
277
                                    break;
278
                          case IRaster.TYPE_FLOAT:
279
                                  for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
280
                                                for (int row = 0; row < copyY; row++) 
281
                                                        for (int col = 0; col < copyX; col++) 
282
                                                                buf.setElemFloat((int)(row + initPxY), (int)(col + initPxX), 
283
                                                                                                iBand, 
284
                                                                                                rasterBuf.getElemFloat(row, col, iBand));
285
                                    break;
286
                          case IRaster.TYPE_DOUBLE:
287
                                for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
288
                                        for (int row = 0; row < copyY; row++) 
289
                                                for (int col = 0; col < copyX; col++) 
290
                                                        buf.setElemDouble((int)(row + initPxY), (int)(col + initPxX), 
291
                                                                                        iBand, 
292
                                                                                        rasterBuf.getElemDouble(row, col, iBand));
293
                            break;
294
                        }
295
                        rasterBuf = buf;
296
                        return null;
297
                        
298
                }
299
                
300
                //Caso en que la extensi?n pedida NO se sale fuera del ?rea del raster
301
                rasterBuf = grmf.getWindowRaster(fitExtent.minX(), fitExtent.minY(), fitExtent.maxX(), fitExtent.maxY(), bufWidth, bufHeight);
302
                return null;
303
        }
304
        
305
        /*
306
         *  (non-Javadoc)
307
         * @see org.gvsig.fmap.dataaccess.IQueryableRaster#setAreaOfInterest(double, double, double, double)
308
         */
309
        public void setAreaOfInterestWithNoData(double x, double y, double w, double h) throws ArrayIndexOutOfBoundsException{
310
                dataExtent = new Extent(x, y, x + w, y - h);
311
                rasterBuf = grmf.getWindowRasterWithNoData(dataExtent.getMin().getX(), dataExtent.getMax().getY(), w, h);
312
        }
313
                
314
        /**
315
         * Ajusta el ?rea del grid a un ancho y un alto dado en pixeles. Este ajuste se har? 
316
         * en relaci?n a un m?todo de interpolaci?n definido en el par?metro.
317
         * @param w Ancho de la nueva imagen.
318
         * @param h Alto de la nueva imagen.
319
         * @param interpolation M?todo de interpolaci?n que se usar? en el ajuste.
320
         * @param bands Bandas que se desea en el nuevo RasterBuf ajustado. Si este par?metro es null
321
         * se usar?n todas las bandas de la imagen.
322
         */
323
        public void setAdjustedWindow(int w, int h, int interpolationMethod, int[] bands){
324
                if(w == width && h == height)
325
                        return;
326
                switch(interpolationMethod){
327
                case IQueryableRaster.INTERPOLATION_NearestNeighbour:
328
                                rasterBuf = rasterBuf.adjustRasterNearestNeighbour(w, h, bands);
329
                                break;
330
                case IQueryableRaster.INTERPOLATION_Bilinear:
331
                                System.out.println("Method not implemented yet");
332
                                break;
333
                case IQueryableRaster.INTERPOLATION_InverseDistance:
334
                                System.out.println("Method not implemented yet");
335
                                break;
336
                case IQueryableRaster.INTERPOLATION_BicubicSpline:
337
                                System.out.println("Method not implemented yet");
338
                                break;
339
                case IQueryableRaster.INTERPOLATION_BSpline:
340
                                System.out.println("Method not implemented yet");
341
                                break;
342
                }
343
                //width = rasterBuf.getWidth();
344
                //height = rasterBuf.getHeight();
345
        }
346
        
347
        public RasterBuf getData(int x, int y, int w, int h) {
348

    
349
                return null;
350
        }
351

    
352
        /**
353
         * Obtiene el tipo de datos del grid.
354
         * @return entero que representa el tipo de dato de las celdas del grid.
355
         */
356
        public int getDataType() {
357
                return grmf.getDataType()[0];
358
        }
359

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

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

    
376
        public double getXCellSize() {
377

    
378
                //TODO:remove this
379
                Extent e = grmf.getExtent();
380
                double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
381
                
382
                return dCellsize;
383
                
384
        }
385

    
386
        public double getYCellSize() {
387

    
388
                return 0;
389
        }
390

    
391
        public boolean isNoData(int x, int y, int band) {
392

    
393
                return false;
394
                
395
        }
396
        
397
        public void setNoDataValue(double dNoDataValue){
398
                
399
                //TODO:temporal
400
                m_dNoDataValue = dNoDataValue;
401
        }
402
        
403
        public double getNoDataValue(){
404
                
405
                return m_dNoDataValue;
406
                
407
        }
408

    
409
        public void setDataType(int dt) {
410
                
411
        }
412
        
413
        public int getBandCount(){
414
                if(rasterBuf != null)
415
                        return rasterBuf.getBandCount();
416
                else
417
                        return this.getGeoRasterMultiFile().getBandCount();
418
        }
419

    
420
        /**
421
         * Obtiene el buffer de datos del grid
422
         * @return RasterBuf
423
         */
424
        public RasterBuf getRasterBuf() {
425
                return rasterBuf;
426
        }
427
        
428
        /**
429
         * Obtiene el objeto histograma asociado al grid
430
         * @return
431
         */
432
        public Histogram getHistogram() {
433
                if(histogram == null)
434
                        histogram = new Histogram(this);
435
                
436
                return histogram;
437
        }
438

    
439
        /**
440
         * Obtiene la clase para estadisticas
441
         * @return
442
         */
443
        public Statistic getStatistic() {
444
                return stats;
445
        }
446
        
447
        /**
448
         * Evalua si una coordenada pixel cae dentro de la imagen.
449
         * @param x coordenada pixel X
450
         * @param y coordenada pixel Y
451
         */
452
        public boolean isPixelInGrid(int x, int y){
453
                return (x >= 0 && y >= 0 && x <= getWidth() && y <= getHeight());
454
        }
455
        
456
        /**
457
         * Extent de la fuente de datos
458
         */
459
        public Extent getExtent(){
460
                return grmf.getExtent();
461
        }
462
        
463
        /**
464
         * Extent del grid
465
         */
466
        public Extent getDataExtent(){
467
                return dataExtent;
468
        }
469
}
470