Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / grid / Grid.java @ 11200

History | View | Annotate | Download (33.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.gvsig.raster.grid;
20

    
21
import java.awt.image.DataBuffer;
22
import java.io.IOException;
23
import java.util.Arrays;
24

    
25
import org.gvsig.raster.buffer.BufferFactory;
26
import org.gvsig.raster.buffer.RasterBuffer;
27
import org.gvsig.raster.buffer.RasterBufferInvalidAccessException;
28
import org.gvsig.raster.buffer.RasterBufferInvalidException;
29
import org.gvsig.raster.dataset.IBuffer;
30
import org.gvsig.raster.dataset.properties.DatasetListTransparency;
31
import org.gvsig.raster.grid.filter.RasterFilterList;
32

    
33
/**
34
 * Clase que representa una rejilla de datos raster. Este tipo de grid tiene el interfaz necesario
35
 * de acceso a la informaci?n raster para aplicaciones de analisis raster. Contiene m?todos de acceso al
36
 * dato tanto en lectura como en escritura y encapsula operaciones entre grids. Adem?s contiene
37
 * objetos que contienen las caracter?sticas asociadas a ese grid. Sobre un grid pueden
38
 * aplicarse tambi?n operaciones de filtrado.
39
 * 
40
 * Podemos crear un Grid de cinco formas distitas:
41
 * <UL>
42
 * <LI>A partir de una fuente de datos (cargada en el constructor). Se har? una petici?n del extent pasado por par?metro con las bandas seleccionadas por par?metro.</LI>
43
 * <LI>A partir de un extensi?n de capa, una extensi?n de vista, un tipo de dato y un n?mero de datos
44
 * crea un Grid vacio util para escritura.</LI>
45
 * <LI>A partir de una fuente de datos (cargados). Datasource se usa como buffer de datos cargados y se selecciona si queremos el reader interpolado.</LI>
46
 * <LI>A partir de una fuente de datos (cargada en el constructor). Se har? una petici?n del extent completo de la fuente con las bandas seleccionadas por par?metro.</LI>
47
 * <LI>A partir de una fuente de datos (cargada en el constructor). Se har? una petici?n del extent completo de la fuente con todas las bandas disponibles.</LI>
48
 * </UL>
49
 * 
50
 * @author Victor Olaya (volaya@ya.com)
51
 * @author Nacho Brodin (nachobrodin@gmail.com)
52
 */
53
public class Grid implements IQueryableGrid, IWritableGrid{
54

    
55
        //TODO: ARQUITECTURA: Estos tipos de datos no deben ser necesarios. Existiendo IBuffer se tendr?an que usar esos Hay que convertir, antes de eliminarlos, el uso de estos a los de IBuffer 
56
        public static final int                 RASTER_DATA_TYPE_FLOAT = DataBuffer.TYPE_FLOAT;
57
        public static final int                 RASTER_DATA_TYPE_DOUBLE = DataBuffer.TYPE_DOUBLE;
58
        public static final int                 RASTER_DATA_TYPE_INT = DataBuffer.TYPE_INT;
59
        public static final int                 RASTER_DATA_TYPE_SHORT = DataBuffer.TYPE_SHORT;
60
        public static final int                 RASTER_DATA_TYPE_BYTE = DataBuffer.TYPE_BYTE;
61
        
62
    public final static double                 DEG_45_IN_RAD = Math.PI / 180. * 45.;
63
    public final static double                 DEG_90_IN_RAD = Math.PI / 180. * 90.;
64
    public final static double                 DEG_180_IN_RAD = Math.PI ;
65
    public final static double                 DEG_270_IN_RAD = Math.PI / 180. * 270.;
66
    public final static double                 DEG_360_IN_RAD = Math.PI * 2.;
67
    
68
        /* neighbor's address*/                        /* N  NE   E  SE   S  SW   W  NW */
69
        private final static int                 m_iOffsetX []=        {  0,  1,  1,  1,  0, -1, -1, -1};
70
        private final static int                m_iOffsetY []=        {  1,  1,  0, -1, -1, -1,  0,  1};
71
        
72
        private double                                         m_dDist[];
73
        public double                                         _2DX, _6DX, _DX_2, _4DX_2;
74
                        
75
        private int[]                                         bands = null;
76
        private int                                         dataType = IBuffer.TYPE_UNDEFINED;
77

    
78
        private RasterBuffer                        rasterBuf = null;
79
        private GridReader                                 reader = null;
80
        private GridWriter                                 writer = null;
81
        private GridExtent                                 windowExtent = null;
82
        private GridExtent                                 layerExtent = null;
83
        private GridStatistic                        statistic = null;
84
        private GridTransparency                transparency = null;
85
        private GridPalette[]                        palette = null;
86
        private RasterFilterList                filterList = null;
87

    
88
        
89

    
90
        /**
91
         * Crea un grid a partir de un BufferFactory. Usa el extent de la fuente de datos como
92
         * extent completo y el extent pasado como par?metro como extensi?n de ventana. El buffer de
93
         * la fuente de datos no tiene porque estar cargado ya que de esto se encarga el reader.
94
         * @param dataSource Fuente de datos
95
         * @param bands n?mero de bandas requeridas
96
         * @param windowExtent Extensi?n de la ventana. Si este par?metro es null se usar? el 
97
         * mismo que el de la capa.
98
         */
99
        public Grid(BufferFactory dataSource, int[] bands, GridExtent windowExtent)
100
                        throws RasterBufferInvalidException{
101
                layerExtent = new GridExtent(dataSource.getExtent(), dataSource.getXCellSize());
102
                dataType = dataSource.getDataType();
103
                this.bands = bands;
104
                
105
                if(windowExtent == null)
106
                        this.windowExtent = layerExtent;
107
                else
108
                        this.windowExtent = windowExtent;
109
                                
110
                rasterBuf = (RasterBuffer)dataSource.getRasterBuf();
111
                
112
                if (windowExtent.fitsIn(layerExtent))
113
                        reader = new GridNotInterpolated(dataSource, layerExtent, windowExtent, bands); 
114
                else
115
                        reader = new GridInterpolated(dataSource, layerExtent, windowExtent, bands);
116
                writer = new GridWriter(layerExtent, dataType, rasterBuf);
117
                
118
                init(dataSource);
119
        }
120
        
121
        /**
122
         * Crea un grid vacio a partir de un extent y un tipo de datos. Se crea un buffer vacio en el 
123
         * que puede escribirse a trav?s del writer. Los datos escritos pueden ser consultados con el
124
         * reader. No tiene una fuente de datos asociada ya que es un grid vacio basicamente para
125
         * escritura. 
126
         * @param layerExtent Tama?o completo de la capa
127
         * @param windowExtent Ventana de datos.
128
         * @param dataType Tipo de datos del buffer
129
         * @param bands n?mero de bandas requeridas y orden de dibujado en el buffer 
130
         */
131
        public Grid(GridExtent layerExtent,
132
                                GridExtent windowExtent,
133
                                int dataType, 
134
                                int[] bands) throws RasterBufferInvalidException{
135
                this.windowExtent = windowExtent;
136
                this.layerExtent = layerExtent;
137
                this.dataType = dataType;
138
                
139
                rasterBuf = RasterBuffer.getBuffer(dataType, layerExtent.getNX(), layerExtent.getNY(), bands.length, true, null);
140
                
141
                if (windowExtent.fitsIn(layerExtent))
142
                        reader = new GridNotInterpolated(rasterBuf, layerExtent, windowExtent, bands); 
143
                else
144
                        reader = new GridInterpolated(rasterBuf, layerExtent, windowExtent, bands);
145
                writer = new GridWriter(layerExtent, dataType, rasterBuf);
146
                init(null);
147
        }
148
        
149
        /**
150
         * Crea un grid a partir de un BufferFactory. El buffer debe estar cargado de datos y el extent
151
         * de este viene definido en el par?metro windowExtent.
152
         * @param dataSource Fuente de datos 
153
         * @param windowExtent        Extent de los datos cargados en dataSource
154
         * @param notInterp Si es true fuerza a que el reader sea sin interpolaci?n. Si es false decide si
155
         * el reader es interpolado o no a partir de los extents de capa y la ventana seleccionada.
156
         */
157
        public Grid(BufferFactory dataSource, boolean notInterp)throws RasterBufferInvalidException{
158
                this.layerExtent = new GridExtent(dataSource.getExtent(), dataSource.getXCellSize());
159
                dataType = dataSource.getDataType();
160
                bands = dataSource.getDrawableBands();
161
                
162
                this.windowExtent = new GridExtent(dataSource.getDataExtent(), dataSource.getXCellSize());
163
                                
164
                rasterBuf = (RasterBuffer)dataSource.getRasterBuf();
165
                                
166
                if(notInterp){
167
                        reader = new GridNotInterpolated(rasterBuf, layerExtent, windowExtent, bands);
168
                }else{
169
                        if (windowExtent.fitsIn(layerExtent))
170
                                reader = new GridNotInterpolated(rasterBuf, layerExtent, windowExtent, bands); 
171
                        else
172
                                reader = new GridInterpolated(rasterBuf, layerExtent, windowExtent, bands);
173
                }
174
                writer = new GridWriter(layerExtent, dataType, rasterBuf);
175
                init(dataSource);
176
        }
177
        
178
        /**
179
         * Crea un grid a partir de un BufferFactory. Se har? una petici?n del extent completo de la fuente.
180
         * dataSource tiene asociada una fuente de datos pero se ignorar? si tiene el buffer lleno. La instanciaci?n
181
         * de GridNotInterpolated har? que se haga la petici?n para cargar raster completo. 
182
         * @param dataSource Fuente de datos
183
         * @param bands n?mero de bandas requeridas y orden de dibujado en el buffer
184
         */
185
        public Grid(BufferFactory dataSource, int[] bands) 
186
                        throws RasterBufferInvalidException{
187
                //La petici?n es del raster completo
188
                windowExtent = layerExtent = new GridExtent(dataSource.getExtent(), dataSource.getXCellSize());
189
                dataType = dataSource.getDataType();
190
                this.bands = bands;
191
                        
192
                reader = new GridNotInterpolated(dataSource, layerExtent, windowExtent, bands);
193
                rasterBuf = (RasterBuffer)dataSource.getRasterBuf();
194
                writer = new GridWriter(windowExtent, dataType, rasterBuf);
195
                
196
                init(dataSource);
197
        }
198
        
199
        /**
200
         * Crea un grid a partir de un BufferFactory. Se har? una petici?n del extent completo de la fuente.
201
         * dataSource tiene asociada una fuente de datos pero se ignorar? si tiene el buffer lleno. La instanciaci?n
202
         * de GridNotInterpolated har? que se haga la petici?n para cargar raster completo. El buffer se cargar? 
203
         * con todas las bandas disponibles. 
204
         * @param dataSource Fuente de datos
205
         */
206
        public Grid(BufferFactory dataSource) 
207
                        throws RasterBufferInvalidException{
208
                //La petici?n es del raster completo
209
                windowExtent = layerExtent = new GridExtent(dataSource.getExtent(), dataSource.getXCellSize());
210
                dataType = dataSource.getDataType();
211
                                                        
212
                bands = new int[dataSource.getBandCount()];
213
                for(int i = 0; i < dataSource.getBandCount(); i ++)
214
                        bands[i] = i;
215
                reader = new GridNotInterpolated(dataSource, layerExtent, windowExtent, bands);
216
                rasterBuf = (RasterBuffer)dataSource.getRasterBuf();
217
                writer = new GridWriter(windowExtent, dataType, rasterBuf);
218
                
219
                init(dataSource);
220
        }
221
        
222
        /**
223
         * Selecciona la forma de obtener datos con o sin interpolaci?n. Si pasamos el par?metro
224
         * false al aplicar un m?todo de consulta de datos este ser? aplicado sin interpolaci?n. 
225
         * @param interpolation
226
         */
227
        public void switchToInterpolationMethod(boolean interpolation){
228
                //GridExtent layer = new GridExtent(0, 0, rasterBuf.getWidth(), rasterBuf.getHeight(), 1);
229
                if(interpolation)
230
                        reader = new GridInterpolated(rasterBuf, layerExtent, windowExtent, bands);
231
                else
232
                        reader = new GridNotInterpolated(rasterBuf, layerExtent, windowExtent, bands);
233
                init(null);
234
        }
235
        
236
        /**
237
         * Inicializaci?n de constantes
238
         */
239
        private void init(BufferFactory ds){
240
                int i;
241
                double dCellSize = getCellSize();
242
                
243
                statistic = new GridStatistic(this);
244
                if(ds == null)
245
                        transparency = new GridTransparency();
246
                else{
247
                        DatasetListTransparency transp = ds.getGeoRasterMultiFile().getTransparencyFilesStatus();
248
                        if(transp != null)
249
                                transparency = new GridTransparency(transp);
250
                        this.palette = new GridPalette[ds.getPalettes().length];
251
                        for(int iPal = 0; iPal < ds.getPalettes().length; iPal++){
252
                                if(ds.getPalettes()[iPal] != null)
253
                                        this.palette[iPal] = new GridPalette(ds.getPalettes()[iPal]);        
254
                        }
255
                }
256
                filterList = new RasterFilterList();
257
                filterList.setInitRasterBuf(rasterBuf);
258
                
259
                m_dDist = new double[8];
260
                
261
            for (i = 0; i < 8; i++){
262
                m_dDist[i] = Math.sqrt ( m_iOffsetX[i] * dCellSize * m_iOffsetX[i] * dCellSize
263
                                + m_iOffsetY[i] * dCellSize * m_iOffsetY[i] * dCellSize );
264
            }
265
            
266
            _2DX =  dCellSize * 2.0;
267
            _6DX = dCellSize * 6.0;
268
                _DX_2 = dCellSize * dCellSize;
269
                _4DX_2 = 4.0 * _DX_2;
270
        }
271
                
272
        //************* Write Services *********************
273
        
274
        /*
275
         *  (non-Javadoc)
276
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(byte)
277
         */
278
        public void assign(byte value)throws RasterBufferInvalidAccessException{
279
                writer.assign(value);                
280
        }
281
        
282
        /*
283
         *  (non-Javadoc)
284
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(short)
285
         */
286
        public void assign(short value)throws RasterBufferInvalidAccessException{
287
                writer.assign(value);                
288
        }
289
        
290
        /*
291
         *  (non-Javadoc)
292
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(int)
293
         */
294
        public void assign(int value)throws RasterBufferInvalidAccessException{
295
                writer.assign(value);                
296
        }
297
        
298
        /*
299
         *  (non-Javadoc)
300
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(float)
301
         */
302
        public void assign(float value)throws RasterBufferInvalidAccessException{
303
                writer.assign(value);                
304
        }
305
        
306
        /*
307
         *  (non-Javadoc)
308
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(double)
309
         */
310
        public void assign(double value)throws RasterBufferInvalidAccessException{
311
                writer.assign(value);                
312
        }
313
        
314
        /*
315
         *  (non-Javadoc)
316
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(org.gvsig.fmap.dataaccess.BufferFactory)
317
         */
318
        public void assign(BufferFactory dataSource)throws RasterBufferInvalidException, OutOfGridException{
319
                Grid window = new Grid(dataSource, bands, windowExtent);
320
                write(window);
321
                writer.setNoDataValue(window.getNoDataValue());                
322
        }
323
        
324
        /*
325
         *  (non-Javadoc)
326
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(org.gvsig.fmap.grid.Grid)
327
         */
328
        public void assign(Grid driver)throws OutOfGridException{
329
                if (driver.getGridExtent().equals(layerExtent)){
330
                        write(driver);
331
                        writer.setNoDataValue(driver.getNoDataValue());
332
                }                
333
        }        
334
        
335
        /**
336
         * Sobreescribe los datos del grid actual con los datos del grid pasado por par?metro
337
         * @param g Grid desde donde se obtienen los datos
338
         */
339
        private void write(Grid g)throws OutOfGridException{
340
                try{
341
                        switch(rasterBuf.getDataType()){
342
                        case IBuffer.TYPE_BYTE: for (int x = 0; x < g.getNX(); x++){
343
                                                                                for (int y = 0; y < g.getNY(); y++){
344
                                                                                        writer.setCellValue(x, y, g.getCellValueAsByte(x, y));
345
                                                                                }
346
                                                                        } 
347
                                                                        break;
348
                        case IBuffer.TYPE_SHORT:for (int x = 0; x < g.getNX(); x++){
349
                                                                                for (int y = 0; y < g.getNY(); y++){
350
                                                                                        writer.setCellValue(x, y, g.getCellValueAsShort(x, y));
351
                                                                                }
352
                                                                        } 
353
                                                                        break;
354
                        case IBuffer.TYPE_INT:         for (int x = 0; x < g.getNX(); x++){
355
                                                                                for (int y = 0; y < g.getNY(); y++){
356
                                                                                        writer.setCellValue(x, y, g.getCellValueAsInt(x, y));
357
                                                                                }
358
                                                                        } 
359
                                                                        break;
360
                        case IBuffer.TYPE_FLOAT:for (int x = 0; x < g.getNX(); x++){
361
                                                                                for (int y = 0; y < g.getNY(); y++){
362
                                                                                        writer.setCellValue(x, y, g.getCellValueAsFloat(x, y));
363
                                                                                }
364
                                                                        } 
365
                                                                        break;
366
                        case IBuffer.TYPE_DOUBLE:for (int x = 0; x < g.getNX(); x++){
367
                                                                                for (int y = 0; y < g.getNY(); y++){
368
                                                                                        writer.setCellValue(x, y, g.getCellValueAsDouble(x, y));
369
                                                                                }
370
                                                                        } 
371
                                                                        break;
372
                        }
373
                } catch (OutOfGridException e) {
374
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
375
                        //No hacemos nada para manejar la excepci?n
376
                        e.printStackTrace();
377
                } catch (RasterBufferInvalidAccessException e1) {
378
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
379
                        //No hacemos nada para manejar la excepci?n
380
                        e1.printStackTrace();
381
                }
382
        }
383
        
384
        /*
385
         *  (non-Javadoc)
386
         * @see org.gvsig.fmap.grid.IWritableGrid#assignNoData()
387
         */
388
        public void assignNoData(){        
389
                try {
390
                        switch(rasterBuf.getDataType()){
391
                        case IBuffer.TYPE_BYTE: writer.assign((byte)rasterBuf.getNoDataValue());break;
392
                        case IBuffer.TYPE_SHORT: writer.assign((short)rasterBuf.getNoDataValue());break;
393
                        case IBuffer.TYPE_INT: writer.assign((int)rasterBuf.getNoDataValue());break;
394
                        case IBuffer.TYPE_FLOAT: writer.assign((float)rasterBuf.getNoDataValue());break;
395
                        case IBuffer.TYPE_DOUBLE: writer.assign((double)rasterBuf.getNoDataValue());break;
396
                        }
397
                } catch (RasterBufferInvalidAccessException e) {
398
                        //No hacemos nada. El tipo de dato al que se accede no es controlado por el usuario por lo
399
                        //que no le mandamos la excepci?n hacia arriba.
400
                        e.printStackTrace();
401
                }
402
        }
403
        
404
        /*
405
         *  (non-Javadoc)
406
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, byte)
407
         */
408
        public void setCellValue(int x, int y, byte value)throws OutOfGridException{
409
                writer.setCellValue(x, y, value);
410
        }
411
        
412
        /*
413
         *  (non-Javadoc)
414
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, short)
415
         */
416
        public void setCellValue(int x, int y, short value)throws OutOfGridException{
417
                writer.setCellValue(x, y, value);
418
        }
419
        
420
        /*
421
         *  (non-Javadoc)
422
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, int)
423
         */
424
        public void setCellValue(int x, int y, int value)throws OutOfGridException{
425
                writer.setCellValue(x, y, value);
426
        }
427
        
428
        /*
429
         *  (non-Javadoc)
430
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, float)
431
         */
432
        public void setCellValue(int x, int y, float value)throws OutOfGridException{
433
                writer.setCellValue(x, y, value);
434
        }
435
        
436
        /*
437
         *  (non-Javadoc)
438
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, double)
439
         */
440
        public void setCellValue(int x, int y, double value)throws OutOfGridException{
441
                writer.setCellValue(x, y, value);
442
        }
443
        
444
        /*
445
         *  (non-Javadoc)
446
         * @see org.gvsig.fmap.grid.IWritableGrid#add(org.gvsig.fmap.grid.Grid)
447
         */
448
        public void add(Grid g){
449
                if (g.getGridExtent().equals(getGridExtent())){
450
                        boolean interp = (reader instanceof GridInterpolated);
451
                        switchToInterpolationMethod(false);
452
                        try{
453
                                switch(rasterBuf.getDataType()){
454
                                case IBuffer.TYPE_BYTE: for (int x = 0; x < g.getNX(); x++){
455
                                                                                        for (int y = 0; y < g.getNY(); y++){
456
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsByte(x, y) + g.getCellValueAsByte(x,y));
457
                                                                                        }
458
                                                                                } 
459
                                                                                break;
460
                                case IBuffer.TYPE_SHORT:for (int x = 0; x < g.getNX(); x++){
461
                                                                                        for (int y = 0; y < g.getNY(); y++){
462
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsShort(x, y) + g.getCellValueAsShort(x,y));
463
                                                                                        }
464
                                                                                } 
465
                                                                                break;
466
                                case IBuffer.TYPE_INT:         for (int x = 0; x < g.getNX(); x++){
467
                                                                                        for (int y = 0; y < g.getNY(); y++){
468
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsInt(x, y) + g.getCellValueAsInt(x,y));
469
                                                                                        }
470
                                                                                } 
471
                                                                                break;
472
                                case IBuffer.TYPE_FLOAT:for (int x = 0; x < g.getNX(); x++){
473
                                                                                        for (int y = 0; y < g.getNY(); y++){
474
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsFloat(x, y) + g.getCellValueAsFloat(x,y));
475
                                                                                        }
476
                                                                                } 
477
                                                                                break;
478
                                case IBuffer.TYPE_DOUBLE:for (int x = 0; x < g.getNX(); x++){
479
                                                                                        for (int y = 0; y < g.getNY(); y++){
480
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsDouble(x, y) + g.getCellValueAsDouble(x,y));
481
                                                                                        }
482
                                                                                } 
483
                                                                                break;
484
                                }
485
                        } catch (OutOfGridException e) {
486
                                //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
487
                                //No hacemos nada para manejar la excepci?n
488
                                e.printStackTrace();
489
                        } catch (RasterBufferInvalidAccessException e1) {
490
                                //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
491
                                //No hacemos nada para manejar la excepci?n
492
                                e1.printStackTrace();
493
                        }
494
                        //Restauramos el reader que hab?a
495
                        switchToInterpolationMethod(interp);
496
                }
497
        }
498
        
499
        /*
500
         *  (non-Javadoc)
501
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, byte)
502
         */
503
        public void addToCellValue(int x, int y, byte value)
504
                throws OutOfGridException, RasterBufferInvalidAccessException{
505
                writer.setCellValue(x, y, (byte)(reader.getCellValueAsByte(x, y) + value));
506
        }
507
        
508
        /*
509
         *  (non-Javadoc)
510
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, short)
511
         */
512
        public void addToCellValue(int x, int y, short value)
513
                throws OutOfGridException, RasterBufferInvalidAccessException{
514
                writer.setCellValue(x, y, (short)(reader.getCellValueAsShort(x, y) + value));
515
        }
516
        
517
        /*
518
         *  (non-Javadoc)
519
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, int)
520
         */
521
        public void addToCellValue(int x, int y, int value)
522
                throws OutOfGridException, RasterBufferInvalidAccessException{
523
                writer.setCellValue(x, y, (int)(reader.getCellValueAsInt(x, y) + value));
524
        }
525
        
526
        /*
527
         *  (non-Javadoc)
528
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, float)
529
         */
530
        public void addToCellValue(int x, int y, float value)
531
                throws OutOfGridException, RasterBufferInvalidAccessException{
532
                writer.setCellValue(x, y, (float)(reader.getCellValueAsFloat(x, y) + value));
533
        }
534
        
535
        /*
536
         *  (non-Javadoc)
537
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, double)
538
         */
539
        public void addToCellValue(int x, int y, double value)
540
                throws OutOfGridException, RasterBufferInvalidAccessException{
541
                writer.setCellValue(x, y, (double)(reader.getCellValueAsDouble(x, y) + value));
542
        } 
543
        
544
        /*
545
         *  (non-Javadoc)
546
         * @see org.gvsig.fmap.grid.IWritableGrid#multiply(double)
547
         */
548
        public void multiply(double value){
549
                boolean interp = (reader instanceof GridInterpolated);
550
                switchToInterpolationMethod(false);
551
                try{
552
                        switch(rasterBuf.getDataType()){
553
                        case IBuffer.TYPE_BYTE: for (int x = 0; x < getNX(); x++){
554
                                                                                for (int y = 0; y < getNY(); y++)
555
                                                                                        writer.setCellValue(x, y, (byte)(reader.getCellValueAsByte(x, y) * value));
556
                                                                        } 
557
                                                                        break;
558
                        case IBuffer.TYPE_SHORT:for (int x = 0; x < getNX(); x++){
559
                                                                                for (int y = 0; y < getNY(); y++)
560
                                                                                        writer.setCellValue(x, y, (short)(reader.getCellValueAsShort(x, y) * value));
561
                                                                        } 
562
                                                                        break;
563
                        case IBuffer.TYPE_INT:         for (int x = 0; x < getNX(); x++){
564
                                                                                for (int y = 0; y < getNY(); y++)
565
                                                                                        writer.setCellValue(x, y, (int)(reader.getCellValueAsInt(x, y) * value));
566
                                                                        } 
567
                                                                        break;
568
                        case IBuffer.TYPE_FLOAT:for (int x = 0; x < getNX(); x++){
569
                                                                                for (int y = 0; y < getNY(); y++)
570
                                                                                        writer.setCellValue(x, y, (float)(reader.getCellValueAsFloat(x, y) * value));
571
                                                                        } 
572
                                                                        break;
573
                        case IBuffer.TYPE_DOUBLE:for (int x = 0; x < getNX(); x++){
574
                                                                                for (int y = 0; y < getNY(); y++)
575
                                                                                        writer.setCellValue(x, y, (double)(reader.getCellValueAsDouble(x, y) * value));
576
                                                                        } 
577
                                                                        break;
578
                        }
579
                } catch (OutOfGridException e) {
580
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
581
                        //No hacemos nada para manejar la excepci?n
582
                        e.printStackTrace();
583
                } catch (RasterBufferInvalidAccessException e1) {
584
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
585
                        //No hacemos nada para manejar la excepci?n
586
                        e1.printStackTrace();
587
                }
588
                //Restauramos el reader que hab?a
589
                switchToInterpolationMethod(interp);
590
        }
591
                
592
        /*
593
         *  (non-Javadoc)
594
         * @see org.gvsig.fmap.grid.IWritableGrid#setNoDataValue(double)
595
         */
596
        public void setNoDataValue(double dNoDataValue){
597
                writer.setNoDataValue((float) dNoDataValue);
598
        }
599
        
600
        /*
601
         *  (non-Javadoc)
602
         * @see org.gvsig.fmap.grid.IWritableGrid#setNoData(int, int)
603
         */
604
        public void setNoData(int x, int y){
605
                writer.setNoData(x,y);
606
        }
607
                        
608
        public void ExportToArcViewASCIIFile(String sFilename){        
609
                try {
610
                        writer.ExportToArcViewASCIIFile(sFilename);
611
                } catch (NumberFormatException e) {
612
                        e.printStackTrace();
613
                } catch (IOException e) {
614
                        e.printStackTrace();
615
                }
616
        }
617
        
618
        //************* Query Services *********************
619
        
620
        /*
621
         *  (non-Javadoc)
622
         * @see org.gvsig.fmap.grid.IQueryableGrid#isNoDataValue(double)
623
         */
624
        public boolean isNoDataValue(double noDataValue){
625
                return (reader.getNoDataValue() == noDataValue);
626
        }
627
        
628
        /*
629
         *  (non-Javadoc)
630
         * @see org.gvsig.fmap.grid.IQueryableGrid#isInGrid(int, int)
631
         */
632
        public boolean isInGrid(int x, int y){
633
                return reader.isCellInGrid(x, y);
634
        }
635
        
636
        /*
637
         *  (non-Javadoc)
638
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellSize()
639
         */
640
        public double getCellSize() {
641
                return reader.getCellSize();
642
        }
643
        
644
        /*
645
         *  (non-Javadoc)
646
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsByte(int, int)
647
         */
648
        public byte getCellValueAsByte(int x, int y)throws RasterBufferInvalidAccessException {
649
                return  reader.getCellValueAsByte(x, y);
650
        }
651
        
652
        /*
653
         *  (non-Javadoc)
654
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsShort(int, int)
655
         */
656
        public short getCellValueAsShort(int x, int y)throws RasterBufferInvalidAccessException {
657
                return (short) reader.getCellValueAsShort(x, y);
658
        }
659
        
660
        /*
661
         *  (non-Javadoc)
662
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsInt(int, int)
663
         */
664
        public int getCellValueAsInt(int x, int y)throws RasterBufferInvalidAccessException {
665
                return (int) reader.getCellValueAsInt(x, y);
666
        }
667

    
668
        /*
669
         *  (non-Javadoc)
670
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsFloat(int, int)
671
         */
672
        public float getCellValueAsFloat(int x, int y)throws RasterBufferInvalidAccessException {
673
                return reader.getCellValueAsFloat(x, y);
674
        }
675
        
676
        /*
677
         *  (non-Javadoc)
678
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsDouble(int, int)
679
         */
680
        public double getCellValueAsDouble(int x, int y)throws RasterBufferInvalidAccessException {
681
                return (double) reader.getCellValueAsDouble(x, y);
682
        }
683
        
684
        /*
685
         *  (non-Javadoc)
686
         * @see org.gvsig.fmap.grid.IQueryableGrid#getNoDataValue()
687
         */
688
        public double getNoDataValue(){
689
                return (double) rasterBuf.getNoDataValue();
690
        }
691
        
692
        /*
693
         *  (non-Javadoc)
694
         * @see org.gvsig.fmap.grid.IQueryableGrid#getMinValue()
695
         */
696
        public double getMinValue(){
697
                if (!statistic.isStatisticsCalculated())
698
                        try {
699
                                statistic.calculateStatistics();
700
                        } catch (RasterBufferInvalidAccessException e) {
701
                                //No se calculan las estad?sticas. No hacemos nada 
702
                                e.printStackTrace();
703
                        }
704
                return statistic.getMin();
705
        }
706
        
707
        /*
708
         *  (non-Javadoc)
709
         * @see org.gvsig.fmap.grid.IQueryableGrid#getMaxValue()
710
         */
711
        public double getMaxValue(){
712
                if (!statistic.isStatisticsCalculated())
713
                        try {
714
                                statistic.calculateStatistics();
715
                        } catch (RasterBufferInvalidAccessException e) {
716
                                //No se calculan las estad?sticas. No hacemos nada
717
                                e.printStackTrace();
718
                        }
719
                return statistic.getMin();
720
        }
721
        
722
        /*
723
         *  (non-Javadoc)
724
         * @see org.gvsig.fmap.grid.IQueryableGrid#getMeanValue()
725
         */
726
        public double getMeanValue(){
727
                if (!statistic.isStatisticsCalculated())
728
                        try {
729
                                statistic.calculateStatistics();
730
                        } catch (RasterBufferInvalidAccessException e) {
731
                                //No se calculan las estad?sticas. No hacemos nada
732
                                e.printStackTrace();
733
                        }
734
                return statistic.getMin();
735
        }
736
        
737
        /*
738
         *  (non-Javadoc)
739
         * @see org.gvsig.fmap.grid.IQueryableGrid#getVariance()
740
         */
741
        public double getVariance(){
742
                if (!statistic.isStatisticsCalculated())
743
                        try {
744
                                statistic.calculateStatistics();
745
                        } catch (RasterBufferInvalidAccessException e) {
746
                                //No se calculan las estad?sticas. No hacemos nada
747
                                e.printStackTrace();
748
                        }
749
                return statistic.getVariance();
750
        }
751
        
752
        /*
753
         *  (non-Javadoc)
754
         * @see org.gvsig.fmap.grid.IQueryableGrid#setInterpolationMethod(int)
755
         */
756
        public void setInterpolationMethod(int iMethod){
757
                if (reader instanceof GridInterpolated)
758
                        ((GridInterpolated) reader).setInterpolationMethod(iMethod);
759
                else{
760
                        this.switchToInterpolationMethod(true);
761
                        ((GridInterpolated) reader).setInterpolationMethod(iMethod);
762
                }
763
        }
764
        
765
        /*
766
         *  (non-Javadoc)
767
         * @see org.gvsig.fmap.grid.IQueryableGrid#getNX()
768
         */
769
        public int getNX(){
770
                return reader.getNX();
771
        }
772
        
773
        /*
774
         *  (non-Javadoc)
775
         * @see org.gvsig.fmap.grid.IQueryableGrid#getNY()
776
         */
777
        public int getNY(){
778
                return reader.getNY();
779
        }
780
        
781
        /*
782
         *  (non-Javadoc)
783
         * @see org.gvsig.fmap.grid.IQueryableGrid#getLayerNX()
784
         */
785
        public int getLayerNX(){
786
                return layerExtent.getNX();
787
        }
788
        
789
        /*
790
         *  (non-Javadoc)
791
         * @see org.gvsig.fmap.grid.IQueryableGrid#getLayerNY()
792
         */
793
        public int getLayerNY(){
794
                return layerExtent.getNY();
795
        }
796
        
797
        /*
798
         *  (non-Javadoc)
799
         * @see org.gvsig.fmap.grid.IWritableGrid#getGridExtent()
800
         */
801
        /*public GridExtent getGridExtent(){
802
                return windowExtent;
803
        }*/
804
        
805
        public int getDataType(){
806
                return dataType;
807
        }
808
        
809
        private boolean getSubMatrix3x3(int x, int y, double SubMatrix[])throws RasterBufferInvalidAccessException{
810
                int        i;
811
                int iDir;
812
                double        z, z2;
813

    
814
                z = getCellValueAsDouble(x, y);
815

    
816
                if(isNoDataValue(z)){
817
                        return false;
818
                }
819
                else{
820
                        //SubMatrix[4]        = 0.0;
821
                        for(i=0; i<4; i++){
822
                                
823
                                iDir = 2 * i;
824
                                z2 = getCellValueAsDouble(x + m_iOffsetX[iDir], y + m_iOffsetY[iDir]);
825
                                if( !isNoDataValue(z2)){
826
                                        SubMatrix[i]        =  z2 - z;
827
                                }
828
                                else{
829
                                        z2 = getCellValueAsDouble(x + m_iOffsetX[(iDir + 4) % 8], y + m_iOffsetY[(iDir  + 4) % 8]);
830
                                        if( !isNoDataValue(z2)){
831
                                                SubMatrix[i]        = z - z2;
832
                                        }
833
                                        else{
834
                                                SubMatrix[i]        = 0.0;
835
                                        }
836
                                }
837
                        }
838

    
839
                        return true;
840
                }
841
        }
842
        
843
        public double getSlope(int x, int y)throws RasterBufferInvalidAccessException{
844
                double        zm[], G, H;
845

    
846
                zm = new double[4];
847
                
848
                if( getSubMatrix3x3(x, y, zm) ){
849
                        G        =  (zm[0] - zm[2])                                        / _2DX;
850
                H        =  (zm[1] - zm[3])                                        / _2DX;
851
                return Math.atan(Math.sqrt(G*G + H*H));
852
                }
853
                else{
854
                        return rasterBuf.getNoDataValue();
855
                }
856
        }
857
                        
858
        public double getAspect(int x, int y)throws RasterBufferInvalidAccessException{
859
                double        zm[], G, H, dAspect;
860

    
861
                zm = new double[4];
862
                
863
                if( getSubMatrix3x3(x, y, zm) ){
864
                        G        =  (zm[0] - zm[2]) / _2DX;
865
                H        =  (zm[1] - zm[3]) / _2DX;
866
                        if( G != 0.0 )
867
                                dAspect = DEG_180_IN_RAD + Math.atan2(H, G);
868
                        else
869
                                dAspect = H > 0.0 ? DEG_270_IN_RAD : (H < 0.0 ? DEG_90_IN_RAD : -1.0);
870
                        return dAspect;
871
                }
872
                else
873
                        return rasterBuf.getNoDataValue();
874
        }
875
        
876
        public static int getXOffsetInDir(int iDir){
877
                return m_iOffsetX[iDir];
878
        }
879
        
880
        public static int getYOffsetInDir(int iDir){
881
                return m_iOffsetY[iDir];
882
        }
883
        
884
        public double getDistToNeighborInDir(int iDir){
885
                return m_dDist[iDir];
886
        }
887
        
888
        public static double getUnitDistToNeighborInDir(int iDir){
889
                return( (iDir % 2 != 0) ? Math.sqrt(2.0)  : 1.0 );
890
        }
891
        
892
        /*
893
         *  (non-Javadoc)
894
         * @see org.gvsig.fmap.grid.IQueryableGrid#getDirToNextDownslopeCell(int, int)
895
         */
896
        public int getDirToNextDownslopeCell(int x, int y)throws RasterBufferInvalidAccessException{
897
                return getDirToNextDownslopeCell(x, y, true);
898
        }
899
        
900
        /*
901
         *  (non-Javadoc)
902
         * @see org.gvsig.fmap.grid.IQueryableGrid#getDirToNextDownslopeCell(int, int, boolean)
903
         */
904
        public int getDirToNextDownslopeCell(int x, int y, boolean bForceDirToNoDataCell)
905
                throws RasterBufferInvalidAccessException{
906
                
907
                int                i, iDir;
908
                double        z, z2, dSlope, dMaxSlope;
909

    
910
                z = getCellValueAsDouble(x, y);
911

    
912
                if(isNoDataValue(z)){
913
                        return -1;
914
                }
915

    
916
                dMaxSlope = 0.0;
917
                for(iDir=-1, i=0; i<8; i++){
918
                        z2 = getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
919
                        if(isNoDataValue(z2)){
920
                                if (bForceDirToNoDataCell){ 
921
                                        return i;
922
                                }
923
                                else{
924
                                        return -1;
925
                                }
926
                        }
927
                        else{
928
                                dSlope        = (z - z2) / getDistToNeighborInDir(i);
929
                                if( dSlope > dMaxSlope ){
930
                                        iDir = i;
931
                                        dMaxSlope = dSlope;
932
                                }
933
                        }
934
                }
935
                
936
                return iDir;
937
        
938
        }
939
        
940
        public GridCell[] getSortedArrayOfCells()throws RasterBufferInvalidAccessException{
941
                int i;
942
                int iX,iY;
943
                int iNX =  getNX();
944
                int iCells = getNX() * getNY();
945
                GridCell [] cells = null;
946
                GridCell cell = null;
947
                                
948
                cells = new GridCell[iCells];
949
                
950
                for (i = 0; i < iCells; i++){
951
                        iX = i % iNX;
952
                        iY = i / iNX;
953
                        switch(getDataType()){
954
                        case IBuffer.TYPE_BYTE: cell = new GridCell(iX, iY, getCellValueAsByte(iX, iY)); break;
955
                        case IBuffer.TYPE_SHORT: cell = new GridCell(iX, iY, getCellValueAsShort(iX, iY)); break;
956
                        case IBuffer.TYPE_INT: cell = new GridCell(iX, iY, getCellValueAsInt(iX, iY)); break;
957
                        case IBuffer.TYPE_FLOAT: cell = new GridCell(iX, iY, getCellValueAsFloat(iX, iY)); break;
958
                        case IBuffer.TYPE_DOUBLE: cell = new GridCell(iX, iY, getCellValueAsDouble(iX, iY)); break;
959
                        }
960
                        
961
                        cells[i] = cell;
962
                }
963

    
964
                Arrays.sort(cells);
965
                
966
                return cells;
967
        }
968

    
969
        /**
970
         * Obtiene el estado de transparencia
971
         * @return Objeto con el estado de transparencia del grid
972
         */
973
        public GridTransparency getTransparency() {
974
                return transparency;
975
        }
976

    
977
        /**
978
         * Asigna el estado de transparencia
979
         * @param Objeto con el estado de transparencia del grid
980
         */
981
        public void setTransparency(GridTransparency transparency) {
982
                this.transparency = transparency;
983
        }
984

    
985
        /**
986
         * Obtiene la paleta para el caso de un MDT. Esta funci?n evita el tener que obtener
987
         * un array de paletas y buscar en el cuando se trata de un caso simple de MDT de una
988
         * sola banda. Comprueba que se trata de un raster monobanda con paleta asociada antes
989
         * de devolverla.
990
         * @return GridPalette asociada al Grid
991
         */
992
        public GridPalette        getMDTPalette(){
993
                if(        rasterBuf != null && 
994
                        rasterBuf.getBandCount() == 1 &&
995
                        palette != null)
996
                        return palette[0];
997
                return null;
998
        }
999
        
1000
        /**
1001
         * Obtiene la lista de paletas asociadas al grid
1002
         * @return Lista de objetos GridPalette
1003
         */
1004
        public GridPalette[] getPalettes() {
1005
                return palette;
1006
        }
1007

    
1008
        /**
1009
         * Asigna la lista de paletas asociadas al grid
1010
         * @param palette Lista de objetos GridPalette
1011
         */
1012
        public void setPalettes(GridPalette[] palette) {
1013
                this.palette = palette;
1014
        }
1015
        
1016
        /**
1017
         * Obtiene la lista de filtros.
1018
         * @return Lista de filtros.
1019
         */
1020
        public RasterFilterList getFilterList(){
1021
                return filterList;
1022
        }
1023
        
1024
        /**
1025
         * Asigna la lista de filtros 
1026
         * @param filterList
1027
         */
1028
        public void setFilterList(RasterFilterList filterList){
1029
                this.filterList = filterList;
1030
        }
1031
        
1032
        /**
1033
         *Aplica la lista de filtros sobre el buffer
1034
         */
1035
        public void applyFilters(){
1036
                if(filterList == null)
1037
                        return;
1038
                filterList.setInitRasterBuf(rasterBuf);
1039
                filterList.execute();
1040
                rasterBuf = (RasterBuffer)filterList.getResult();
1041
                dataType = rasterBuf.getDataType();
1042
        }
1043
        
1044
        /**
1045
         * Obtiene el buffer de datos del grid
1046
         * @return RasterBuf
1047
         */
1048
        public IBuffer getRasterBuf() {
1049
                return rasterBuf;
1050
        }
1051
        
1052
        /**
1053
         * Asigna la banda sobre la que se realizan las operaciones. Por defecto es la banda 0
1054
         * con lo que para el uso de MDTs no habr? que modificar este valor.
1055
         * @param band Banda sobre la que se realizan las operaciones.
1056
         */
1057
        public void setBandToOperate(int band){
1058
                if(writer != null)
1059
                        writer.setBandToOperate(band);
1060
                if(reader != null)
1061
                        reader.setBandToOperate(band);
1062
        }
1063
        
1064
        /**
1065
         * Obtiene el extent de la ventana seleccionada para petici?n de datos
1066
         * @return GridExtent
1067
         */
1068
        public GridExtent getWindowExtent(){
1069
                return windowExtent;
1070
        }
1071
        
1072
        /**
1073
         * Obtiene el extent del grid para petici?n de datos
1074
         * @return GridExtent
1075
         */
1076
        public GridExtent getGridExtent(){
1077
                return layerExtent;
1078
        }
1079
}