Statistics
| Revision:

root / branches / v10 / libraries / libCq_CMS_praster / src / org / cresques / io / data / Grid.java @ 10953

History | View | Annotate | Download (13 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

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

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

    
299
                return null;
300
        }
301

    
302
        /**
303
         * Obtiene el tipo de datos del grid.
304
         * @return entero que representa el tipo de dato de las celdas del grid.
305
         */
306
        public int getDataType() {
307
                return grmf.getDataType()[0];
308
        }
309

    
310
        /**
311
         * Obtiene la altura del grid.
312
         * @return altura en celdas del grid.
313
         */
314
        public int getHeight() {
315
                return height;
316
        }
317

    
318
        /**
319
         * Obtiene la anchura del grid.
320
         * @return anchura en celdas del grid.
321
         */
322
        public int getWidth() {
323
                return width;
324
        }
325

    
326
        public double getXCellSize() {
327

    
328
                //TODO:remove this
329
                Extent e = grmf.getExtent();
330
                double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
331
                
332
                return dCellsize;
333
                
334
        }
335

    
336
        public double getYCellSize() {
337

    
338
                return 0;
339
        }
340

    
341
        public boolean isNoData(int x, int y, int band) {
342

    
343
                return false;
344
                
345
        }
346
        
347
        public void setNoDataValue(double dNoDataValue){
348
                
349
                //TODO:temporal
350
                m_dNoDataValue = dNoDataValue;
351
        }
352
        
353
        public double getNoDataValue(){
354
                
355
                return m_dNoDataValue;
356
                
357
        }
358

    
359
        public void setDataType(int dt) {
360
                
361
        }
362
        
363
        public int getBandCount(){
364
                if(rasterBuf != null)
365
                        return rasterBuf.getBandCount();
366
                else
367
                        return this.getGeoRasterMultiFile().getBandCount();
368
        }
369

    
370
        /**
371
         * Obtiene el buffer de datos del grid
372
         * @return RasterBuf
373
         */
374
        public RasterBuf getRasterBuf() {
375
                return rasterBuf;
376
        }
377
        
378
        /**
379
         * Obtiene el objeto histograma asociado al grid
380
         * @return
381
         */
382
        public Histogram getHistogram() {
383
                if(histogram == null)
384
                        histogram = new Histogram(this);
385
                
386
                return histogram;
387
        }
388

    
389
        /**
390
         * Obtiene la clase para estadisticas
391
         * @return
392
         */
393
        public Statistic getStatistic() {
394
                return stats;
395
        }
396
        
397
        /**
398
         * Evalua si una coordenada pixel cae dentro de la imagen.
399
         * @param x coordenada pixel X
400
         * @param y coordenada pixel Y
401
         */
402
        public boolean isPixelInGrid(int x, int y){
403
                return (x >= 0 && y >= 0 && x <= getWidth() && y <= getHeight());
404
        }
405
        
406
        /**
407
         * Extent de la fuente de datos
408
         */
409
        public Extent getExtent(){
410
                return grmf.getExtent();
411
        }
412
        
413
        /**
414
         * Extent del grid
415
         */
416
        public Extent getDataExtent(){
417
                return dataExtent;
418
        }
419
}
420