Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / grid / GridInterpolated.java @ 11076

History | View | Annotate | Download (11.6 KB)

1
/*******************************************************************************
2
    GridWrapperInterpolated
3
    Copyright (C) Victor Olaya
4
    
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (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.grid;
20

    
21
import org.gvsig.raster.buffer.BufferFactory;
22
import org.gvsig.raster.buffer.IQueryableRaster;
23
import org.gvsig.raster.buffer.RasterBuffer;
24

    
25
/**
26
 * A grid wrapper that performs interpolation to calculate
27
 * cell values. This should be used when the window extent
28
 * does not 'fit' into the structure (coordinates and cellsize)
29
 * of the grid.
30
 * 
31
 * @author Victor Olaya
32
 */
33

    
34
public class GridInterpolated extends GridReader{
35

    
36
        public static final int INTERPOLATION_NearestNeighbour = IQueryableRaster.INTERPOLATION_NearestNeighbour;
37
        public static final int INTERPOLATION_Bilinear = IQueryableRaster.INTERPOLATION_Bilinear;
38
        public static final int INTERPOLATION_InverseDistance = IQueryableRaster.INTERPOLATION_InverseDistance;
39
        public static final int INTERPOLATION_BicubicSpline = IQueryableRaster.INTERPOLATION_BicubicSpline;
40
        public static final int INTERPOLATION_BSpline = IQueryableRaster.INTERPOLATION_BSpline;
41
        
42
        double m_dXMin , m_dYMax; //coordinates of the layer, not the window
43
        double m_dCellSize; //cellsize of the layer, not the window
44
        int m_iInterpolationMethod = INTERPOLATION_BSpline;
45

    
46
        /**
47
         * Crea un objeto lector a partir de un buffer de datos y el extent de la extensi?n
48
         * completa y de la ventana accedida.
49
         * @param rb Buffer de datos
50
         * @param layerExtent extent de la capa completa
51
         * @param windowExtent Extent
52
         * @param bands N?mero de bandas del origen
53
         */
54
        public GridInterpolated(        RasterBuffer rb, 
55
                                                                GridExtent layerExtent,
56
                                                                GridExtent windowExtent,
57
                                                                int[] bands){
58
                super(rb, layerExtent, windowExtent, bands);
59
                m_dXMin = layerExtent.minX();
60
                m_dYMax = layerExtent.maxY();
61
                
62
                m_dCellSize = layerExtent.getCellSize();
63
        }
64
        
65
        /**
66
         * Crea un objeto lector a partir de una fuente de datos y el extent de la extensi?n
67
         * completa y de la ventana accedida.
68
         * @param ds Fuente de datos
69
         * @param layerExtent extent de la capa completa
70
         * @param windowExtent Extent
71
         * @param bands N?mero de bandas del origen
72
         */
73
        public GridInterpolated(        BufferFactory ds, 
74
                                                                GridExtent layerExtent,
75
                                                                GridExtent windowExtent,
76
                                                                int[] bands){
77
                super(ds, layerExtent, windowExtent, bands);
78
                init();
79
        }
80
        
81
        /**
82
         * Inicializaci?n de la fuente de datos y carga del buffer.
83
         */
84
        private void init(){
85
                m_dXMin = dataSource.getExtent().minX();
86
                m_dYMax = dataSource.getExtent().maxY();
87
                
88
                m_dCellSize = dataSource.getXCellSize();
89
                
90
                dataSource.addDrawableBands(bands);
91
        }
92
                
93
        /**
94
         * Asigna el m?todo de interpolaci?n 
95
         * @param iMethod
96
         */
97
        public void setInterpolationMethod(int iMethod){
98
                m_iInterpolationMethod = iMethod;
99
        }
100

    
101
        /*
102
         *  (non-Javadoc)
103
         * @see org.gvsig.fmap.grid.GridReader#getCellValueAsByte(int, int)
104
         */
105
        public byte getCellValueAsByte(int x, int y) {
106
                return (byte) _getValueAt(x, y);
107
        }
108
        
109
        /*
110
         *  (non-Javadoc)
111
         * @see org.gvsig.fmap.grid.GridReader#getCellValueAsShort(int, int)
112
         */
113
        public short getCellValueAsShort(int x, int y) {
114
                return (short) _getValueAt(x, y);
115
        }
116
        
117
        /*
118
         *  (non-Javadoc)
119
         * @see org.gvsig.fmap.grid.GridReader#getCellValueAsInt(int, int)
120
         */
121
        public int getCellValueAsInt(int x, int y) {                
122
                return (int) _getValueAt(x, y);
123
        }
124

    
125
        /*
126
         *  (non-Javadoc)
127
         * @see org.gvsig.fmap.grid.GridReader#getCellValueAsFloat(int, int)
128
         */
129
        public float getCellValueAsFloat(int x, int y) {
130
                return (float) _getValueAt(x, y);
131
        }
132
        
133
        /*
134
         *  (non-Javadoc)
135
         * @see org.gvsig.fmap.grid.GridReader#getCellValueAsDouble(int, int)
136
         */
137
        public double getCellValueAsDouble(int x, int y) {
138
                return _getValueAt(x, y);
139
        }
140
        
141
        private double _getValueAt(int x, int y){
142
                double dX = windowExtent.minX() + windowExtent.getCellSize() * (x + 0.5);
143
                double dY = windowExtent.maxY() - windowExtent.getCellSize() * (y + 0.5);
144
                
145
                return getValueAt(dX, dY);
146
        }
147

    
148
        private double getValueAt(double xPosition, double yPosition){
149
                int        x, y;
150
                double        dx, dy;
151
                double dValue;
152

    
153
                x        = (int) Math.floor(xPosition = (xPosition - m_dXMin) / m_dCellSize);
154
                y        = (int)Math.floor(yPosition        = (m_dYMax - yPosition ) / m_dCellSize);
155
                
156
                dValue = _getCellValueInLayerCoords(x,y);
157
                
158
                if(        !isNoDataValue(dValue) ){
159

    
160
                        dx        = xPosition - x;
161
                        dy        = yPosition - y;
162

    
163
                        switch( m_iInterpolationMethod ){
164
                        case INTERPOLATION_NearestNeighbour:
165
                                dValue = _getValueNearestNeighbour (x, y, dx, dy);
166
                                break;
167

    
168
                        case INTERPOLATION_Bilinear:
169
                                dValue        = _getValueBiLinear (x, y, dx, dy);
170
                                break;
171

    
172
                        case INTERPOLATION_InverseDistance:
173
                                dValue        = _getValueInverseDistance(x, y, dx, dy);
174
                                break;
175

    
176
                        case INTERPOLATION_BicubicSpline:
177
                                dValue        = _getValueBiCubicSpline (x, y, dx, dy);
178
                                break;
179

    
180
                        case INTERPOLATION_BSpline:
181
                                dValue        = _getValueBSpline (x, y, dx, dy);
182
                                break;
183
                        }
184
                }
185
                else{
186
                        dValue = getNoDataValue();
187
                }
188

    
189
                return dValue;
190
        }
191

    
192
        private double _getValueNearestNeighbour(int x, int y, double dx, double dy){
193
                x        += (int)(0.5 + dx);
194
                y        += (int)(0.5 + dy);
195

    
196
                return _getCellValueInLayerCoords(x, y);
197
        }
198

    
199
        private  double _getValueBiLinear(int x, int y, double dx, double dy){
200
                double        z = 0.0, n = 0.0, d;
201
                double dValue;
202
                
203
                dValue = _getCellValueInLayerCoords(x, y);
204
                if (!isNoDataValue(dValue)){
205
                         d = (1.0 - dx) * (1.0 - dy);
206
                         z += d * dValue; 
207
                         n += d;
208
                }
209
                
210
                dValue = _getCellValueInLayerCoords(x + 1, y);
211
                if (!isNoDataValue(dValue)){
212
                         d = (dx) * (1.0 - dy);
213
                         z += d * dValue; 
214
                         n += d;
215
                }
216
                
217
                dValue = _getCellValueInLayerCoords(x, y + 1);
218
                if (!isNoDataValue(dValue)){
219
                         d = (1.0 - dx) * (dy);
220
                         z += d * dValue; 
221
                         n += d;
222
                }
223
                
224
                dValue = _getCellValueInLayerCoords(x + 1, y + 1);
225
                if (!isNoDataValue(dValue)){
226
                         d = (dx) * (dy);
227
                         z += d * dValue; 
228
                         n += d;
229
                }
230

    
231
                if( n > 0.0 ){
232
                        return( z / n );
233
                }
234

    
235
                return( getNoDataValue() );
236
        }
237

    
238
        private double _getValueInverseDistance(int x, int y, double dx, double dy){
239
                double        z = 0.0, n = 0.0, d;
240
                double dValue;
241
                
242
                if( dx > 0.0 || dy > 0.0 ){
243

    
244
                        dValue = _getCellValueInLayerCoords(x, y);
245
                        if (!isNoDataValue(dValue)){
246
                                d = 1.0 / Math.sqrt(dx*dx + dy*dy); 
247
                                z += d * dValue; 
248
                                n += d;
249
                        }
250
                        
251
                        dValue = _getCellValueInLayerCoords(x + 1, y);
252
                        if (!isNoDataValue(dValue)){
253
                                d = 1.0 / Math.sqrt((1.0-dx)*(1.0-dx) + dy*dy); 
254
                                z += d * dValue; 
255
                                n += d;
256
                        }
257
                        
258
                        dValue = _getCellValueInLayerCoords(x, y + 1);
259
                        if (!isNoDataValue(dValue)){
260
                                d = 1.0 / Math.sqrt(dx*dx + (1.0-dy)*(1.0-dy)); 
261
                                z += d * dValue; 
262
                                n += d;
263
                        }
264
                        
265
                        dValue = _getCellValueInLayerCoords(x + 1, y + 1);
266
                        if (!isNoDataValue(dValue)){
267
                                d = 1.0 / Math.sqrt((1.0-dx)*(1.0-dx) + (1.0-dy)*(1.0-dy)); 
268
                                z += d * dValue; 
269
                                n += d;
270
                        }
271

    
272
                        if( n > 0.0 ){
273
                                return( z / n );
274
                        }
275
                }else
276
                        return( _getCellValueInLayerCoords(x, y) );
277
                
278
                return( getNoDataValue());
279
        }
280

    
281
        private double _getValueBiCubicSpline(int x, int y, double dx, double dy){
282
                int                i;
283
                double        a0, a2, a3, b1, b2, b3, c[], z_xy[][];
284

    
285
                c = new double[4];
286
                z_xy = new double[4][4];
287
                
288
                if( _get4x4Submatrix(x, y, z_xy) ){
289
                        
290
                        for(i=0; i<4; i++){
291
                                a0                = z_xy[0][i] - z_xy[1][i];
292
                                a2                = z_xy[2][i] - z_xy[1][i];
293
                                a3                = z_xy[3][i] - z_xy[1][i];
294

    
295
                                b1                = -a0 / 3.0 + a2       - a3 / 6.0;
296
                                b2                =  a0 / 2.0 + a2 / 2.0;
297
                                b3                = -a0 / 6.0 - a2 / 2.0 + a3 / 6.0;
298

    
299
                                c[i]        = z_xy[1][i] + b1 * dx + b2 * dx*dx + b3 * dx*dx*dx;
300
                        }
301

    
302
                        a0                = c[0] - c[1];
303
                        a2                = c[2] - c[1];
304
                        a3                = c[3] - c[1];
305

    
306
                        b1                = -a0 / 3.0 + a2       - a3 / 6.0;
307
                        b2                =  a0 / 2.0 + a2 / 2.0;
308
                        b3                = -a0 / 6.0 - a2 / 2.0 + a3 / 6.0;
309

    
310
                        return( c[1] + b1 * dy + b2 * dy*dy + b3 * dy*dy*dy );
311
                }
312

    
313
                return( _getValueBiLinear(x, y, dx, dy) );
314
        }
315

    
316
        private double _getValueBSpline(int x, int y, double dx, double dy){
317
                int                i, ix, iy;
318
                double        z, px, py, Rx[], Ry[], z_xy[][];
319
                
320
                Rx = new double[4];
321
                Ry = new double[4];
322
                z_xy = new double [4][4];
323

    
324
                if( _get4x4Submatrix(x, y, z_xy) ){
325
                        for(i=0, px=-1.0-dx, py=-1.0-dy; i<4; i++, px++, py++){
326
                                Rx[i]        = 0.0;
327
                                Ry[i]        = 0.0;
328

    
329
                                if( (z = px + 2.0) > 0.0 )
330
                                        Rx[i]        +=        z*z*z;
331
                                if( (z = px + 1.0) > 0.0 )
332
                                        Rx[i]        += -4.0 * z*z*z;
333
                                if( (z = px + 0.0) > 0.0 )
334
                                        Rx[i]        +=  6.0 * z*z*z;
335
                                if( (z = px - 1.0) > 0.0 )
336
                                        Rx[i]        += -4.0 * z*z*z;
337
                                if( (z = py + 2.0) > 0.0 )
338
                                        Ry[i]        +=        z*z*z;
339
                                if( (z = py + 1.0) > 0.0 )
340
                                        Ry[i]        += -4.0 * z*z*z;
341
                                if( (z = py + 0.0) > 0.0 )
342
                                        Ry[i]        +=  6.0 * z*z*z;
343
                                if( (z = py - 1.0) > 0.0 )
344
                                        Ry[i]        += -4.0 * z*z*z;
345

    
346
                                Rx[i]        /= 6.0;
347
                                Ry[i]        /= 6.0;
348
                        }
349

    
350
                        for(iy=0, z=0.0; iy<4; iy++){
351
                                for(ix=0; ix<4; ix++){
352
                                        z        += z_xy[ix][iy] * Rx[ix] * Ry[iy];
353
                                }
354
                        }
355

    
356
                        return( z );
357
                }
358
                return( _getValueBiLinear(x, y, dx, dy) );
359
        }
360

    
361
        private boolean _get4x4Submatrix(int x, int y, double z_xy[][]){
362
                int        ix, iy, px, py;
363
                double dValue;
364

    
365
                for(iy=0, py=y-1; iy<4; iy++, py++){
366
                        for(ix=0, px=x-1; ix<4; ix++, px++){
367
                                dValue = _getCellValueInLayerCoords(px, py);
368
                                if (isNoDataValue(dValue)){
369
                                        return false;
370
                                }
371
                                else{
372
                                        z_xy[ix][iy] = dValue;
373
                                }
374
                        }
375
                }
376
                return( true );
377
        }
378

    
379
        private double _getCellValueInLayerCoords(int x, int y){
380
                int w = 0, h = 0;
381
                int pX = 0, pY = 0;
382
                if(dataSource != null){ 
383
                        w = dataSource.getWidth();
384
                        h = dataSource.getHeight();
385
                        dataSource.setAreaOfInterest(x, y, 1, 1);
386
                        pX = 1; 
387
                        pY = 1;
388
                }else{
389
                        w = rasterBuf.getWidth();
390
                        h = rasterBuf.getHeight();
391
                        pX = x;
392
                        pY = y;
393
                }
394
        
395
                if ( x >= 0 && y >= 0 && x < w && y < h){
396
                        if (dataType == RasterBuffer.TYPE_DOUBLE) {
397
                                return rasterBuf.getElemDouble(pY, pX, bandToOperate);
398
                        } else if (dataType == RasterBuffer.TYPE_INT) {
399
                                return (double) rasterBuf.getElemInt(pY, pX, bandToOperate);
400
                        } else if (dataType == RasterBuffer.TYPE_FLOAT) {
401
                                return (double) rasterBuf.getElemFloat(pY, pX, bandToOperate);
402
                        } else if (dataType == RasterBuffer.TYPE_BYTE) {
403
                                return (double) rasterBuf.getElemByte(pY, pX, bandToOperate);
404
                        } else if ((dataType == RasterBuffer.TYPE_SHORT) | (dataType == RasterBuffer.TYPE_USHORT)) {
405
                                return (double) rasterBuf.getElemShort(pY, pX, bandToOperate);
406
                        }
407
                }
408
                return getNoDataValue();
409
        }
410

    
411
        public byte[] getBandsValuesAsByte(int x, int y) {
412
                //TODO: FUNCIONALIDAD: getBandsValuesAsByte:Obtener los valores interpolados en todas las bandas
413
                return null;
414
        }
415

    
416
        public short[] getBandsValuesAsShort(int x, int y) {
417
                //TODO: FUNCIONALIDAD: getBandsValuesAsShort:Obtener los valores interpolados en todas las bandas
418
                return null;
419
        }
420

    
421
        public int[] getBandsValuesAsInt(int x, int y) {
422
                //TODO: FUNCIONALIDAD: getBandsValuesAsInt:Obtener los valores interpolados en todas las bandas
423
                return null;
424
        }
425

    
426
        public float[] getBandsValuesAsFloat(int x, int y) {
427
                //TODO: FUNCIONALIDAD: getBandsValuesAsFloat:Obtener los valores interpolados en todas las bandas
428
                return null;
429
        }
430

    
431
        public double[] getBandsValuesAsDouble(int x, int y) {
432
                //TODO: FUNCIONALIDAD: getBandsValuesAsDouble:Obtener los valores interpolados en todas las bandas
433
                return null;
434
        }
435
}