Statistics
| Revision:

gvsig-raster / org.gvsig.raster.cache / trunk / org.gvsig.raster.cache / org.gvsig.raster.cache.lib.impl / src / main / java / org / gvsig / raster / cache / buffer / impl / io / GdalRead.java @ 995

History | View | Annotate | Download (14.4 KB)

1
package org.gvsig.raster.cache.buffer.impl.io;
2

    
3

    
4
import java.awt.geom.AffineTransform;
5
import java.io.IOException;
6

    
7
import org.gvsig.jgdal.Gdal;
8
import org.gvsig.jgdal.GdalBuffer;
9
import org.gvsig.jgdal.GdalException;
10
import org.gvsig.jgdal.GdalRasterBand;
11
import org.gvsig.jgdal.GeoTransform;
12
import org.gvsig.raster.cache.buffer.Buffer;
13
/**
14
 * Lectura de datos de un TIFF de disco
15
 * @author Nacho Brodin (nachobrodin@gmail.com)
16
 */
17
public class GdalRead extends Gdal {
18
        public         GeoTransform                 trans = null;
19
        public int                           width = 0, height = 0;
20
        public double                        originX = 0D, originY = 0D;
21
        protected int                        rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
22
        private int                          dataType = 0;
23
        protected GdalRasterBand[]           gdalBands = null;
24

    
25
        /**
26
         * Estado de transparencia del raster.
27
         */
28
        protected AffineTransform            ownTransformation = null;
29
        private int                          nBands            = 0;
30
        
31
        
32
        public GdalRead(String fName) throws GdalException, IOException {
33
                super();
34
                init(fName);
35
        }
36
        
37
        /**
38
         * Acciones de inicializaci?n
39
         * @param fName
40
         * @throws GdalException
41
         * @throws IOException
42
         */
43
        private void init(String fName) throws GdalException, IOException {
44
                open(fName, GA_ReadOnly);
45
                if (getPtro() == -1)
46
                        throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
47

    
48
                width = getRasterXSize();
49
                height = getRasterYSize();
50
                int[] dt = new int[getRasterCount()];
51
                for (int i = 0; i < getRasterCount(); i++)
52
                        dt[i] = this.getRasterBand(i + 1).getRasterDataType();
53
                nBands = getRasterCount();
54
                dataType = dt[0];
55
                
56

    
57
                try {
58
                        trans = getGeoTransform();
59

    
60
                        boolean isCorrect = false;
61
                        for (int i = 0; i < trans.adfgeotransform.length; i++)
62
                                if (trans.adfgeotransform[i] != 0)
63
                                        isCorrect = true;
64
                        if (!isCorrect)
65
                                throw new GdalException("");
66

    
67
                        ownTransformation = new AffineTransform(trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
68
                } catch (GdalException exc) {
69
                        // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
70
                        // ya que las WC decrecen de
71
                        // arriba a abajo y los pixeles crecen de arriba a abajo
72
                        ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
73
                }
74
        }
75
        
76
        /**
77
         * Conversi?n de los tipos de datos de gdal a los tipos de datos de RasterBuf
78
         * @param gdalType Tipo de dato de gdal
79
         * @return Tipo de dato de RasterBuf
80
         */
81
        public int getRasterBufTypeFromGdalType(int gdalType) {
82
                switch (gdalType) {
83
                        case 1:// Eight bit unsigned integer GDT_Byte = 1
84
                                return Buffer.TYPE_BYTE;
85

    
86
                        case 3:// Sixteen bit signed integer GDT_Int16 = 3,
87
                                return Buffer.TYPE_SHORT;
88

    
89
                        case 2:// Sixteen bit unsigned integer GDT_UInt16 = 2
90
                                //return RasterBuffer.TYPE_USHORT;
91
                                return Buffer.TYPE_SHORT; //Apa?o para usar los tipos de datos que soportamos
92

    
93
                        case 5:// Thirty two bit signed integer GDT_Int32 = 5
94
                                return Buffer.TYPE_INT;
95

    
96
                        case 6:// Thirty two bit floating point GDT_Float32 = 6
97
                                return Buffer.TYPE_FLOAT;
98

    
99
                        case 7:// Sixty four bit floating point GDT_Float64 = 7
100
                                return Buffer.TYPE_DOUBLE;
101

    
102
                                // TODO:Estos tipos de datos no podemos gestionarlos. Habria que definir
103
                                // el tipo complejo y usar el tipo long que de momento no se gasta.
104
                        case 4:// Thirty two bit unsigned integer GDT_UInt32 = 4,
105
                                return Buffer.TYPE_INT;
106
                                //return RasterBuffer.TYPE_UNDEFINED; // Deberia devolver un Long
107

    
108
                        case 8:// Complex Int16 GDT_CInt16 = 8
109
                        case 9:// Complex Int32 GDT_CInt32 = 9
110
                        case 10:// Complex Float32 GDT_CFloat32 = 10
111
                        case 11:// Complex Float64 GDT_CFloat64 = 11
112
                                return Buffer.TYPE_UNDEFINED;
113
                }
114
                return Buffer.TYPE_UNDEFINED;
115
        }
116
        
117
        /**
118
         * Conversi?n de los tipos de datos de gdal a los tipos de datos de RasterBuf
119
         * @param gdalType Tipo de dato de gdal
120
         * @return Tipo de dato de RasterBuf
121
         */
122
        public int getGdalTypeFromRasterBufType(int rasterBufType) {
123
                switch (rasterBufType) {
124
                        case Buffer.TYPE_BYTE: return Gdal.GDT_Byte;
125
                        case Buffer.TYPE_USHORT: return Gdal.GDT_UInt16;
126
                        case Buffer.TYPE_SHORT: return Gdal.GDT_Int16;
127
                        case Buffer.TYPE_INT: return Gdal.GDT_Int32;
128
                        case Buffer.TYPE_FLOAT: return Gdal.GDT_Float32;
129
                        case Buffer.TYPE_DOUBLE: return Gdal.GDT_Float64;
130
                        case Buffer.TYPE_UNDEFINED: return Gdal.GDT_Unknown;
131
                }
132
                return Gdal.GDT_Unknown;
133
        }
134
        
135
        /**
136
         * Obtiene el anchura del raster
137
         * @return
138
         */
139
        public int getWidth() { 
140
                return this.width;
141
        }
142
        
143
        /**
144
         * Obtiene la altura del raster
145
         * @return 
146
         */
147
        public int getHeight() { 
148
                return this.height;
149
        }
150
        
151
        /**
152
         * Obtiene el flag que informa de si el raster tiene valor no data o no.
153
         * Consultar? todas las bandas del mismo y si alguna tiene valor no data
154
         * devuelve true sino devolver? false.
155
         * @return true si tiene valor no data y false si no lo tiene
156
         * @throws GdalException
157
         */
158
        public boolean existsNoDataValue() throws GdalException {
159
                for (int i = 0; i < getRasterCount(); i++) {
160
                        GdalRasterBand rb = getRasterBand(i + 1);
161
                        if (rb.existsNoDataValue())
162
                                return true;
163
                }
164
                return false;
165
        }
166
        
167
        /**
168
         * Obtiene el flag que informa de si el raster tiene valor no data o no
169
         * en una banda concreta.
170
         * @return true si tiene valor no data en esa banda y false si no lo tiene
171
         * @param band Posici?n de la banda a consultar (0..n)
172
         * @throws GdalException
173
         */
174
        public boolean existsNoDataValue(int band) throws GdalException {
175
                GdalRasterBand rb = getRasterBand(band + 1);
176
                return rb.existsNoDataValue();
177
        }
178
        
179
        /**
180
         * Obtiene el tipo de dato
181
         * @return entero que representa el tipo de dato
182
         */
183
        public int getDataType() { 
184
                return dataType; 
185
        }
186
        
187
        /**
188
         * Obtiene el n?mero de bandas
189
         * @return
190
         */
191
        public int getBandCount() {
192
                return nBands;
193
        }
194
        
195
        /**
196
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
197
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
198
         * @param nLine N?mero de l?nea a leer
199
         * @param band Banda requerida
200
         * @return Object que es un array unidimendional del tipo de datos del raster
201
         * @throws GdalException
202
         */
203
        public Object readBlock(int posX, int posY, int blockWidth, int blockHeight) throws GdalException, InterruptedException {
204
                bBandNr = super.getRasterCount();
205
                                
206
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
207
                for (int iBand = 0; iBand < gdalBand.length; iBand++) 
208
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
209
                                
210
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
211
                                
212
                if (dataType == GDT_Byte) {
213
                        byte[][][] buf = new byte[bBandNr][blockHeight][getRasterXSize()];
214
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
215
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
216
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
217
                                        for (int iCol = 0; iCol < blockWidth; iCol++) 
218
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * blockWidth + iCol];
219
                                }
220
                        }        
221
                        return buf;
222
                } else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16) {
223
                        short[][][] buf = new short[bBandNr][blockHeight][getRasterXSize()];
224
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
225
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
226
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
227
                                        for (int iCol = 0; iCol < blockWidth; iCol++) 
228
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * blockWidth + iCol];
229
                                }
230
                        }        
231
                        return buf;
232
                } else if (dataType == GDT_CInt32 || dataType == GDT_Int32  || dataType == GDT_UInt32) {
233
                        int[][][] buf = new int[bBandNr][blockHeight][getRasterXSize()];
234
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
235
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
236
                                for (int iRow = 0; iRow < blockHeight; iRow++) { 
237
                                        for (int iCol = 0; iCol < blockWidth; iCol++)
238
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * blockWidth + iCol];
239
                                }
240
                        }        
241
                        return buf;
242
                } else if(dataType == GDT_Float32 || dataType == GDT_CFloat32) {
243
                        float[][][] buf = new float[bBandNr][blockHeight][getRasterXSize()];
244
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
245
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
246
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
247
                                        for (int iCol = 0; iCol < blockWidth; iCol++)
248
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * blockWidth + iCol];
249
                                }
250
                        }        
251
                        return buf;
252
                } else if(dataType == GDT_Float64 || dataType == GDT_CFloat64) {
253
                        double[][][] buf = new double[bBandNr][blockHeight][getRasterXSize()];
254
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
255
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
256
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
257
                                        for (int iCol = 0; iCol < blockWidth; iCol++) 
258
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * blockWidth + iCol];
259
                                }
260
                        }                
261
                        return buf;
262
                }
263
                return null;
264
        }
265
        
266
        /**
267
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
268
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
269
         * @param nLine N?mero de l?nea a leer
270
         * @param band Banda requerida
271
         * @return Object que es un array unidimendional del tipo de datos del raster
272
         * @throws GdalException
273
         */
274
        public Object readBlock(int posX, int posY, int blockWidth, int blockHeight, int iBand) throws GdalException, InterruptedException {
275
                                
276
                GdalRasterBand gdalBand = null;
277
                gdalBand = super.getRasterBand(iBand + 1);
278
                                
279
                GdalBuffer gdalBuf = null;
280
                                
281
                if (dataType == GDT_Byte) {
282
                        byte[][] buf = new byte[blockHeight][blockWidth];
283
                                gdalBuf = gdalBand.readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
284
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
285
                                        for (int iCol = 0; iCol < blockWidth; iCol++) 
286
                                                buf[iRow][iCol] = gdalBuf.buffByte[iRow * blockWidth + iCol];
287
                                }
288
                        return buf;
289
                } else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16) {
290
                        short[][] buf = new short[blockHeight][blockWidth];
291
                                gdalBuf = gdalBand.readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
292
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
293
                                        for (int iCol = 0; iCol < blockWidth; iCol++) 
294
                                                buf[iRow][iCol] = gdalBuf.buffShort[iRow * blockWidth + iCol];
295
                                }
296
                        return buf;
297
                } else if (dataType == GDT_CInt32 || dataType == GDT_Int32  || dataType == GDT_UInt32) {
298
                        int[][] buf = new int[blockHeight][blockWidth];
299
                                gdalBuf = gdalBand.readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
300
                                for (int iRow = 0; iRow < blockHeight; iRow++) { 
301
                                        for (int iCol = 0; iCol < blockWidth; iCol++)
302
                                                buf[iRow][iCol] = gdalBuf.buffInt[iRow * blockWidth + iCol];
303
                                }
304
                        return buf;
305
                } else if(dataType == GDT_Float32 || dataType == GDT_CFloat32) {
306
                        float[][] buf = new float[blockHeight][blockWidth];
307
                                gdalBuf = gdalBand.readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
308
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
309
                                        for (int iCol = 0; iCol < blockWidth; iCol++)
310
                                                buf[iRow][iCol] = gdalBuf.buffFloat[iRow * blockWidth + iCol];
311
                                }
312
                        return buf;
313
                } else if(dataType == GDT_Float64 || dataType == GDT_CFloat64) {
314
                        double[][] buf = new double[blockHeight][blockWidth];
315
                                gdalBuf = gdalBand.readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
316
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
317
                                        for (int iCol = 0; iCol < blockWidth; iCol++) 
318
                                                buf[iRow][iCol] = gdalBuf.buffDouble[iRow * blockWidth + iCol];
319
                                }
320
                        return buf;
321
                }
322
                return null;
323
        }
324
        
325
        /**
326
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
327
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
328
         * @param nLine N?mero de l?nea a leer
329
         * @param band Banda requerida
330
         * @return Object que es un array unidimendional del tipo de datos del raster
331
         * @throws GdalException
332
         */
333
        public Object readData(int posX, int posY, int blockWidth, int blockHeight) throws GdalException, InterruptedException {
334
                bBandNr = super.getRasterCount();
335
                                
336
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
337
                for (int iBand = 0; iBand < gdalBand.length; iBand++) 
338
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
339
                                
340
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
341
                                
342
                if (dataType == GDT_Byte) {
343
                        byte[][] buf = new byte[bBandNr][];
344
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
345
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
346
                                buf[iBand] = gdalBuf[iBand].buffByte;        
347
                        }        
348
                        return buf;
349
                } else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16) {
350
                        short[][] buf = new short[bBandNr][];
351
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
352
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
353
                                buf[iBand] = gdalBuf[iBand].buffShort;
354
                        }        
355
                        return buf;
356
                } else if (dataType == GDT_CInt32 || dataType == GDT_Int32  || dataType == GDT_UInt32) {
357
                        int[][] buf = new int[bBandNr][];
358
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
359
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
360
                                buf[iBand] = gdalBuf[iBand].buffInt;
361
                        }        
362
                        return buf;
363
                } else if(dataType == GDT_Float32 || dataType == GDT_CFloat32) {
364
                        float[][] buf = new float[bBandNr][];
365
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
366
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
367
                                buf[iBand] = gdalBuf[iBand].buffFloat;
368
                        }        
369
                        return buf;
370
                } else if(dataType == GDT_Float64 || dataType == GDT_CFloat64) {
371
                        double[][] buf = new double[bBandNr][];
372
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
373
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(posX, posY, blockWidth, blockHeight, blockWidth, blockHeight, dataType);
374
                                buf[iBand] = gdalBuf[iBand].buffDouble;
375
                        }                
376
                        return buf;
377
                }
378
                                
379
                        return null;
380
        }
381
                
382
}
383

    
384

    
385

    
386