Statistics
| Revision:

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

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

    
341
                return null;
342
        }
343

    
344
        /**
345
         * Obtiene el tipo de datos del grid.
346
         * @return entero que representa el tipo de dato de las celdas del grid.
347
         */
348
        public int getDataType() {
349
                return grmf.getDataType()[0];
350
        }
351

    
352
        /**
353
         * Obtiene la altura del grid.
354
         * @return altura en celdas del grid.
355
         */
356
        public int getHeight() {
357
                return height;
358
        }
359

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

    
368
        public double getXCellSize() {
369

    
370
                //TODO:remove this
371
                Extent e = grmf.getExtent();
372
                double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
373
                
374
                return dCellsize;
375
                
376
        }
377

    
378
        public double getYCellSize() {
379

    
380
                return 0;
381
        }
382

    
383
        public boolean isNoData(int x, int y, int band) {
384

    
385
                return false;
386
                
387
        }
388
        
389
        public void setNoDataValue(double dNoDataValue){
390
                
391
                //TODO:temporal
392
                m_dNoDataValue = dNoDataValue;
393
        }
394
        
395
        public double getNoDataValue(){
396
                
397
                return m_dNoDataValue;
398
                
399
        }
400

    
401
        public void setDataType(int dt) {
402
                
403
        }
404
        
405
        public int getBandCount(){
406
                if(rasterBuf != null)
407
                        return rasterBuf.getBandCount();
408
                else
409
                        return this.getGeoRasterMultiFile().getBandCount();
410
        }
411

    
412
        /**
413
         * Obtiene el buffer de datos del grid
414
         * @return RasterBuf
415
         */
416
        public RasterBuf getRasterBuf() {
417
                return rasterBuf;
418
        }
419
        
420
        /**
421
         * Obtiene el objeto histograma asociado al grid
422
         * @return
423
         */
424
        public Histogram getHistogram() {
425
                if(histogram == null)
426
                        histogram = new Histogram(this);
427
                
428
                return histogram;
429
        }
430

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