Statistics
| Revision:

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

History | View | Annotate | Download (33.9 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
                filterList.addParam("IStatistics", ds.getMultiRasterDataset().getStatistics());
262
                filterList.addParam("MultiRasterDataset", ds.getMultiRasterDataset());
263
                filterList.setInitRasterBuf(rasterBuf);
264
                
265
                m_dDist = new double[8];
266
                
267
            for (i = 0; i < 8; i++){
268
                m_dDist[i] = Math.sqrt ( m_iOffsetX[i] * dCellSize * m_iOffsetX[i] * dCellSize
269
                                + m_iOffsetY[i] * dCellSize * m_iOffsetY[i] * dCellSize );
270
            }
271
            
272
            _2DX =  dCellSize * 2.0;
273
            _6DX = dCellSize * 6.0;
274
                _DX_2 = dCellSize * dCellSize;
275
                _4DX_2 = 4.0 * _DX_2;
276
        }
277
                
278
        //************* Write Services *********************
279
        
280
        /*
281
         *  (non-Javadoc)
282
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(byte)
283
         */
284
        public void assign(byte value)throws RasterBufferInvalidAccessException{
285
                writer.assign(value);                
286
        }
287
        
288
        /*
289
         *  (non-Javadoc)
290
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(short)
291
         */
292
        public void assign(short value)throws RasterBufferInvalidAccessException{
293
                writer.assign(value);                
294
        }
295
        
296
        /*
297
         *  (non-Javadoc)
298
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(int)
299
         */
300
        public void assign(int value)throws RasterBufferInvalidAccessException{
301
                writer.assign(value);                
302
        }
303
        
304
        /*
305
         *  (non-Javadoc)
306
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(float)
307
         */
308
        public void assign(float value)throws RasterBufferInvalidAccessException{
309
                writer.assign(value);                
310
        }
311
        
312
        /*
313
         *  (non-Javadoc)
314
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(double)
315
         */
316
        public void assign(double value)throws RasterBufferInvalidAccessException{
317
                writer.assign(value);                
318
        }
319
        
320
        /*
321
         *  (non-Javadoc)
322
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(org.gvsig.fmap.dataaccess.BufferFactory)
323
         */
324
        public void assign(BufferFactory dataSource)throws RasterBufferInvalidException, OutOfGridException{
325
                Grid window = new Grid(dataSource.getMultiRasterDataset(), bands, windowExtent);
326
                write(window);
327
                writer.setNoDataValue(window.getNoDataValue());                
328
        }
329
        
330
        /*
331
         *  (non-Javadoc)
332
         * @see org.gvsig.fmap.grid.IWritableGrid#assign(org.gvsig.fmap.grid.Grid)
333
         */
334
        public void assign(Grid driver)throws OutOfGridException{
335
                if (driver.getGridExtent().equals(layerExtent)){
336
                        write(driver);
337
                        writer.setNoDataValue(driver.getNoDataValue());
338
                }                
339
        }        
340
        
341
        /**
342
         * Sobreescribe los datos del grid actual con los datos del grid pasado por par?metro
343
         * @param g Grid desde donde se obtienen los datos
344
         */
345
        private void write(Grid g)throws OutOfGridException{
346
                try{
347
                        switch(rasterBuf.getDataType()){
348
                        case IBuffer.TYPE_BYTE: for (int x = 0; x < g.getNX(); x++){
349
                                                                                for (int y = 0; y < g.getNY(); y++){
350
                                                                                        writer.setCellValue(x, y, g.getCellValueAsByte(x, y));
351
                                                                                }
352
                                                                        } 
353
                                                                        break;
354
                        case IBuffer.TYPE_SHORT:for (int x = 0; x < g.getNX(); x++){
355
                                                                                for (int y = 0; y < g.getNY(); y++){
356
                                                                                        writer.setCellValue(x, y, g.getCellValueAsShort(x, y));
357
                                                                                }
358
                                                                        } 
359
                                                                        break;
360
                        case IBuffer.TYPE_INT:         for (int x = 0; x < g.getNX(); x++){
361
                                                                                for (int y = 0; y < g.getNY(); y++){
362
                                                                                        writer.setCellValue(x, y, g.getCellValueAsInt(x, y));
363
                                                                                }
364
                                                                        } 
365
                                                                        break;
366
                        case IBuffer.TYPE_FLOAT:for (int x = 0; x < g.getNX(); x++){
367
                                                                                for (int y = 0; y < g.getNY(); y++){
368
                                                                                        writer.setCellValue(x, y, g.getCellValueAsFloat(x, y));
369
                                                                                }
370
                                                                        } 
371
                                                                        break;
372
                        case IBuffer.TYPE_DOUBLE:for (int x = 0; x < g.getNX(); x++){
373
                                                                                for (int y = 0; y < g.getNY(); y++){
374
                                                                                        writer.setCellValue(x, y, g.getCellValueAsDouble(x, y));
375
                                                                                }
376
                                                                        } 
377
                                                                        break;
378
                        }
379
                } catch (OutOfGridException e) {
380
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
381
                        //No hacemos nada para manejar la excepci?n
382
                        e.printStackTrace();
383
                } catch (RasterBufferInvalidAccessException e1) {
384
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
385
                        //No hacemos nada para manejar la excepci?n
386
                        e1.printStackTrace();
387
                }
388
        }
389
        
390
        /*
391
         *  (non-Javadoc)
392
         * @see org.gvsig.fmap.grid.IWritableGrid#assignNoData()
393
         */
394
        public void assignNoData(){        
395
                try {
396
                        switch(rasterBuf.getDataType()){
397
                        case IBuffer.TYPE_BYTE: writer.assign((byte)rasterBuf.getNoDataValue());break;
398
                        case IBuffer.TYPE_SHORT: writer.assign((short)rasterBuf.getNoDataValue());break;
399
                        case IBuffer.TYPE_INT: writer.assign((int)rasterBuf.getNoDataValue());break;
400
                        case IBuffer.TYPE_FLOAT: writer.assign((float)rasterBuf.getNoDataValue());break;
401
                        case IBuffer.TYPE_DOUBLE: writer.assign((double)rasterBuf.getNoDataValue());break;
402
                        }
403
                } catch (RasterBufferInvalidAccessException e) {
404
                        //No hacemos nada. El tipo de dato al que se accede no es controlado por el usuario por lo
405
                        //que no le mandamos la excepci?n hacia arriba.
406
                        e.printStackTrace();
407
                }
408
        }
409
        
410
        /*
411
         *  (non-Javadoc)
412
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, byte)
413
         */
414
        public void setCellValue(int x, int y, byte value)throws OutOfGridException{
415
                writer.setCellValue(x, y, value);
416
        }
417
        
418
        /*
419
         *  (non-Javadoc)
420
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, short)
421
         */
422
        public void setCellValue(int x, int y, short value)throws OutOfGridException{
423
                writer.setCellValue(x, y, value);
424
        }
425
        
426
        /*
427
         *  (non-Javadoc)
428
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, int)
429
         */
430
        public void setCellValue(int x, int y, int value)throws OutOfGridException{
431
                writer.setCellValue(x, y, value);
432
        }
433
        
434
        /*
435
         *  (non-Javadoc)
436
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, float)
437
         */
438
        public void setCellValue(int x, int y, float value)throws OutOfGridException{
439
                writer.setCellValue(x, y, value);
440
        }
441
        
442
        /*
443
         *  (non-Javadoc)
444
         * @see org.gvsig.fmap.grid.IWritableGrid#setCellValue(int, int, double)
445
         */
446
        public void setCellValue(int x, int y, double value)throws OutOfGridException{
447
                writer.setCellValue(x, y, value);
448
        }
449
        
450
        /*
451
         *  (non-Javadoc)
452
         * @see org.gvsig.fmap.grid.IWritableGrid#add(org.gvsig.fmap.grid.Grid)
453
         */
454
        public void add(Grid g){
455
                if (g.getGridExtent().equals(getGridExtent())){
456
                        boolean interp = (reader instanceof GridInterpolated);
457
                        switchToInterpolationMethod(false);
458
                        try{
459
                                switch(rasterBuf.getDataType()){
460
                                case IBuffer.TYPE_BYTE: for (int x = 0; x < g.getNX(); x++){
461
                                                                                        for (int y = 0; y < g.getNY(); y++){
462
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsByte(x, y) + g.getCellValueAsByte(x,y));
463
                                                                                        }
464
                                                                                } 
465
                                                                                break;
466
                                case IBuffer.TYPE_SHORT:for (int x = 0; x < g.getNX(); x++){
467
                                                                                        for (int y = 0; y < g.getNY(); y++){
468
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsShort(x, y) + g.getCellValueAsShort(x,y));
469
                                                                                        }
470
                                                                                } 
471
                                                                                break;
472
                                case IBuffer.TYPE_INT:         for (int x = 0; x < g.getNX(); x++){
473
                                                                                        for (int y = 0; y < g.getNY(); y++){
474
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsInt(x, y) + g.getCellValueAsInt(x,y));
475
                                                                                        }
476
                                                                                } 
477
                                                                                break;
478
                                case IBuffer.TYPE_FLOAT:for (int x = 0; x < g.getNX(); x++){
479
                                                                                        for (int y = 0; y < g.getNY(); y++){
480
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsFloat(x, y) + g.getCellValueAsFloat(x,y));
481
                                                                                        }
482
                                                                                } 
483
                                                                                break;
484
                                case IBuffer.TYPE_DOUBLE:for (int x = 0; x < g.getNX(); x++){
485
                                                                                        for (int y = 0; y < g.getNY(); y++){
486
                                                                                                writer.setCellValue(x, y, reader.getCellValueAsDouble(x, y) + g.getCellValueAsDouble(x,y));
487
                                                                                        }
488
                                                                                } 
489
                                                                                break;
490
                                }
491
                        } catch (OutOfGridException e) {
492
                                //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
493
                                //No hacemos nada para manejar la excepci?n
494
                                e.printStackTrace();
495
                        } catch (RasterBufferInvalidAccessException e1) {
496
                                //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
497
                                //No hacemos nada para manejar la excepci?n
498
                                e1.printStackTrace();
499
                        }
500
                        //Restauramos el reader que hab?a
501
                        switchToInterpolationMethod(interp);
502
                }
503
        }
504
        
505
        /*
506
         *  (non-Javadoc)
507
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, byte)
508
         */
509
        public void addToCellValue(int x, int y, byte value)
510
                throws OutOfGridException, RasterBufferInvalidAccessException{
511
                writer.setCellValue(x, y, (byte)(reader.getCellValueAsByte(x, y) + value));
512
        }
513
        
514
        /*
515
         *  (non-Javadoc)
516
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, short)
517
         */
518
        public void addToCellValue(int x, int y, short value)
519
                throws OutOfGridException, RasterBufferInvalidAccessException{
520
                writer.setCellValue(x, y, (short)(reader.getCellValueAsShort(x, y) + value));
521
        }
522
        
523
        /*
524
         *  (non-Javadoc)
525
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, int)
526
         */
527
        public void addToCellValue(int x, int y, int value)
528
                throws OutOfGridException, RasterBufferInvalidAccessException{
529
                writer.setCellValue(x, y, (int)(reader.getCellValueAsInt(x, y) + value));
530
        }
531
        
532
        /*
533
         *  (non-Javadoc)
534
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, float)
535
         */
536
        public void addToCellValue(int x, int y, float value)
537
                throws OutOfGridException, RasterBufferInvalidAccessException{
538
                writer.setCellValue(x, y, (float)(reader.getCellValueAsFloat(x, y) + value));
539
        }
540
        
541
        /*
542
         *  (non-Javadoc)
543
         * @see org.gvsig.fmap.grid.IWritableGrid#addToCellValue(int, int, double)
544
         */
545
        public void addToCellValue(int x, int y, double value)
546
                throws OutOfGridException, RasterBufferInvalidAccessException{
547
                writer.setCellValue(x, y, (double)(reader.getCellValueAsDouble(x, y) + value));
548
        } 
549
        
550
        /*
551
         *  (non-Javadoc)
552
         * @see org.gvsig.fmap.grid.IWritableGrid#multiply(double)
553
         */
554
        public void multiply(double value){
555
                boolean interp = (reader instanceof GridInterpolated);
556
                switchToInterpolationMethod(false);
557
                try{
558
                        switch(rasterBuf.getDataType()){
559
                        case IBuffer.TYPE_BYTE: for (int x = 0; x < getNX(); x++){
560
                                                                                for (int y = 0; y < getNY(); y++)
561
                                                                                        writer.setCellValue(x, y, (byte)(reader.getCellValueAsByte(x, y) * value));
562
                                                                        } 
563
                                                                        break;
564
                        case IBuffer.TYPE_SHORT:for (int x = 0; x < getNX(); x++){
565
                                                                                for (int y = 0; y < getNY(); y++)
566
                                                                                        writer.setCellValue(x, y, (short)(reader.getCellValueAsShort(x, y) * value));
567
                                                                        } 
568
                                                                        break;
569
                        case IBuffer.TYPE_INT:         for (int x = 0; x < getNX(); x++){
570
                                                                                for (int y = 0; y < getNY(); y++)
571
                                                                                        writer.setCellValue(x, y, (int)(reader.getCellValueAsInt(x, y) * value));
572
                                                                        } 
573
                                                                        break;
574
                        case IBuffer.TYPE_FLOAT:for (int x = 0; x < getNX(); x++){
575
                                                                                for (int y = 0; y < getNY(); y++)
576
                                                                                        writer.setCellValue(x, y, (float)(reader.getCellValueAsFloat(x, y) * value));
577
                                                                        } 
578
                                                                        break;
579
                        case IBuffer.TYPE_DOUBLE:for (int x = 0; x < getNX(); x++){
580
                                                                                for (int y = 0; y < getNY(); y++)
581
                                                                                        writer.setCellValue(x, y, (double)(reader.getCellValueAsDouble(x, y) * value));
582
                                                                        } 
583
                                                                        break;
584
                        }
585
                } catch (OutOfGridException e) {
586
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
587
                        //No hacemos nada para manejar la excepci?n
588
                        e.printStackTrace();
589
                } catch (RasterBufferInvalidAccessException e1) {
590
                        //No es probable que se salga fuera ya que el bucle se controla dentro de la misma funci?n
591
                        //No hacemos nada para manejar la excepci?n
592
                        e1.printStackTrace();
593
                }
594
                //Restauramos el reader que hab?a
595
                switchToInterpolationMethod(interp);
596
        }
597
                
598
        /*
599
         *  (non-Javadoc)
600
         * @see org.gvsig.fmap.grid.IWritableGrid#setNoDataValue(double)
601
         */
602
        public void setNoDataValue(double dNoDataValue){
603
                writer.setNoDataValue((float) dNoDataValue);
604
        }
605
        
606
        /*
607
         *  (non-Javadoc)
608
         * @see org.gvsig.fmap.grid.IWritableGrid#setNoData(int, int)
609
         */
610
        public void setNoData(int x, int y){
611
                writer.setNoData(x,y);
612
        }
613
                        
614
        public void ExportToArcViewASCIIFile(String sFilename){        
615
                try {
616
                        writer.ExportToArcViewASCIIFile(sFilename);
617
                } catch (NumberFormatException e) {
618
                        e.printStackTrace();
619
                } catch (IOException e) {
620
                        e.printStackTrace();
621
                }
622
        }
623
        
624
        //************* Query Services *********************
625
        
626
        /*
627
         *  (non-Javadoc)
628
         * @see org.gvsig.fmap.grid.IQueryableGrid#isNoDataValue(double)
629
         */
630
        public boolean isNoDataValue(double noDataValue){
631
                return (reader.getNoDataValue() == noDataValue);
632
        }
633
        
634
        /*
635
         *  (non-Javadoc)
636
         * @see org.gvsig.fmap.grid.IQueryableGrid#isInGrid(int, int)
637
         */
638
        public boolean isInGrid(int x, int y){
639
                return reader.isCellInGrid(x, y);
640
        }
641
        
642
        /*
643
         *  (non-Javadoc)
644
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellSize()
645
         */
646
        public double getCellSize() {
647
                return reader.getCellSize();
648
        }
649
        
650
        /*
651
         *  (non-Javadoc)
652
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsByte(int, int)
653
         */
654
        public byte getCellValueAsByte(int x, int y)throws RasterBufferInvalidAccessException {
655
                return  reader.getCellValueAsByte(x, y);
656
        }
657
        
658
        /*
659
         *  (non-Javadoc)
660
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsShort(int, int)
661
         */
662
        public short getCellValueAsShort(int x, int y)throws RasterBufferInvalidAccessException {
663
                return (short) reader.getCellValueAsShort(x, y);
664
        }
665
        
666
        /*
667
         *  (non-Javadoc)
668
         * @see org.gvsig.fmap.grid.IQueryableGrid#getCellValueAsInt(int, int)
669
         */
670
        public int getCellValueAsInt(int x, int y)throws RasterBufferInvalidAccessException {
671
                return (int) reader.getCellValueAsInt(x, y);
672
        }
673

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

    
820
                z = getCellValueAsDouble(x, y);
821

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

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

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

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

    
916
                z = getCellValueAsDouble(x, y);
917

    
918
                if(isNoDataValue(z)){
919
                        return -1;
920
                }
921

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

    
970
                Arrays.sort(cells);
971
                
972
                return cells;
973
        }
974

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

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

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

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