Statistics
| Revision:

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

History | View | Annotate | Download (33.7 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.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.BufferFactory;
27
import org.gvsig.raster.buffer.RasterBuffer;
28
import org.gvsig.raster.buffer.RasterBufferInvalidAccessException;
29
import org.gvsig.raster.buffer.RasterBufferInvalidException;
30
import org.gvsig.raster.dataset.IBuffer;
31
import org.gvsig.raster.dataset.properties.DatasetListTransparency;
32
import org.gvsig.raster.grid.filter.RasterFilterList;
33

    
34
/**
35
 * Clase que representa una rejilla de datos raster. Este tipo de grid tiene el interfaz necesario
36
 * de acceso a la informaci?n raster para aplicaciones de analisis raster. Contiene m?todos de acceso al
37
 * dato tanto en lectura como en escritura y encapsula operaciones entre grids. Adem?s contiene
38
 * objetos que contienen las caracter?sticas asociadas a ese grid. Sobre un grid pueden
39
 * aplicarse tambi?n operaciones de filtrado.
40
 * 
41
 * Podemos crear un Grid de cinco formas distitas:
42
 * <UL>
43
 * <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>
44
 * <LI>A partir de un extensi?n de capa, una extensi?n de vista, un tipo de dato y un n?mero de datos
45
 * crea un Grid vacio util para escritura.</LI>
46
 * <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>
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 las bandas seleccionadas por par?metro.</LI>
48
 * <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>
49
 * </UL>
50
 * 
51
 * @author Victor Olaya (volaya@ya.com)
52
 * @author Nacho Brodin (nachobrodin@gmail.com)
53
 */
54
public class Grid implements IQueryableGrid, IWritableGrid{
55

    
56
        //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 
57
        public static final int                 RASTER_DATA_TYPE_FLOAT = DataBuffer.TYPE_FLOAT;
58
        public static final int                 RASTER_DATA_TYPE_DOUBLE = DataBuffer.TYPE_DOUBLE;
59
        public static final int                 RASTER_DATA_TYPE_INT = DataBuffer.TYPE_INT;
60
        public static final int                 RASTER_DATA_TYPE_SHORT = DataBuffer.TYPE_SHORT;
61
        public static final int                 RASTER_DATA_TYPE_BYTE = DataBuffer.TYPE_BYTE;
62
        
63
    public final static double                 DEG_45_IN_RAD = Math.PI / 180. * 45.;
64
    public final static double                 DEG_90_IN_RAD = Math.PI / 180. * 90.;
65
    public final static double                 DEG_180_IN_RAD = Math.PI ;
66
    public final static double                 DEG_270_IN_RAD = Math.PI / 180. * 270.;
67
    public final static double                 DEG_360_IN_RAD = Math.PI * 2.;
68
    
69
        /* neighbor's address*/                        /* N  NE   E  SE   S  SW   W  NW */
70
        private final static int                 m_iOffsetX []=        {  0,  1,  1,  1,  0, -1, -1, -1};
71
        private final static int                m_iOffsetY []=        {  1,  1,  0, -1, -1, -1,  0,  1};
72
        
73
        private double                                         m_dDist[];
74
        public double                                         _2DX, _6DX, _DX_2, _4DX_2;
75
                        
76
        private int[]                                         bands = null;
77
        private int                                         dataType = IBuffer.TYPE_UNDEFINED;
78

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

    
89
        
90

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

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

    
815
                z = getCellValueAsDouble(x, y);
816

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

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

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

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

    
911
                z = getCellValueAsDouble(x, y);
912

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

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

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

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

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

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

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