Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / grid / Grid.java @ 12066

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

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

    
823
                z = getCellValueAsDouble(x, y);
824

    
825
                if(isNoDataValue(z)){
826
                        return false;
827
                }
828
                else{
829
                        //SubMatrix[4]        = 0.0;
830
                        for(i=0; i<4; i++){
831
                                
832
                                iDir = 2 * i;
833
                                z2 = getCellValueAsDouble(x + m_iOffsetX[iDir], y + m_iOffsetY[iDir]);
834
                                if( !isNoDataValue(z2)){
835
                                        SubMatrix[i]        =  z2 - z;
836
                                }
837
                                else{
838
                                        z2 = getCellValueAsDouble(x + m_iOffsetX[(iDir + 4) % 8], y + m_iOffsetY[(iDir  + 4) % 8]);
839
                                        if( !isNoDataValue(z2)){
840
                                                SubMatrix[i]        = z - z2;
841
                                        }
842
                                        else{
843
                                                SubMatrix[i]        = 0.0;
844
                                        }
845
                                }
846
                        }
847

    
848
                        return true;
849
                }
850
        }
851
        
852
        public double getSlope(int x, int y)throws RasterBufferInvalidAccessException{
853
                double        zm[], G, H;
854

    
855
                zm = new double[4];
856
                
857
                if( getSubMatrix3x3(x, y, zm) ){
858
                        G        =  (zm[0] - zm[2])                                        / _2DX;
859
                H        =  (zm[1] - zm[3])                                        / _2DX;
860
                return Math.atan(Math.sqrt(G*G + H*H));
861
                }
862
                else{
863
                        return rasterBuf.getNoDataValue();
864
                }
865
        }
866
                        
867
        public double getAspect(int x, int y)throws RasterBufferInvalidAccessException{
868
                double        zm[], G, H, dAspect;
869

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

    
919
                z = getCellValueAsDouble(x, y);
920

    
921
                if(isNoDataValue(z)){
922
                        return -1;
923
                }
924

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

    
973
                Arrays.sort(cells);
974
                
975
                return cells;
976
        }
977

    
978
        /**
979
         * Obtiene el estado de transparencia
980
         * @return Objeto con el estado de transparencia del grid
981
         */
982
        public GridTransparency getTransparency() {
983
                return transparency;
984
        }
985

    
986
        /**
987
         * Asigna el estado de transparencia
988
         * @param Objeto con el estado de transparencia del grid
989
         */
990
        public void setTransparency(GridTransparency transparency) {
991
                this.transparency = transparency;
992
        }
993

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

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