Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / io / GdalNative.java @ 18040

History | View | Annotate | Download (44 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.dataset.io;
20

    
21
import java.awt.geom.AffineTransform;
22
import java.awt.geom.NoninvertibleTransformException;
23
import java.awt.geom.Point2D;
24
import java.io.IOException;
25

    
26
import org.gvsig.raster.RasterLibrary;
27
import org.gvsig.raster.dataset.BandList;
28
import org.gvsig.raster.dataset.IBuffer;
29
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
30
import org.gvsig.raster.dataset.properties.DatasetMetadata;
31
import org.gvsig.raster.datastruct.ColorTable;
32
import org.gvsig.raster.datastruct.Extent;
33
import org.gvsig.raster.datastruct.Transparency;
34
import org.gvsig.raster.process.RasterTask;
35
import org.gvsig.raster.process.RasterTaskQueue;
36
import org.gvsig.raster.util.RasterUtilities;
37

    
38
import es.gva.cit.jgdal.Gdal;
39
import es.gva.cit.jgdal.GdalBuffer;
40
import es.gva.cit.jgdal.GdalException;
41
import es.gva.cit.jgdal.GdalRasterBand;
42
import es.gva.cit.jgdal.GeoTransform;
43
/**
44
 * Soporte 'nativo' para ficheros desde GDAL.
45
 * 
46
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
47
 * @author Nacho Brodin (nachobrodin@gmail.com)
48
 */
49
public class GdalNative extends Gdal {
50
        static boolean                       WITH_OVERVIEWS = true;
51
        private String                       ext = "";
52
        private String                       fileName = null;
53
        /**
54
         * Nombre corto del driver de gdal
55
         */
56
        private String                       shortName = "";
57
        public         GeoTransform                 trans = null;
58
        
59
        public int                           width = 0, height = 0;
60
        public double                        originX = 0D, originY = 0D;
61
        public String                        version = "";
62
        protected int                        rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
63
        private int[]                        dataType = null;
64
        /**
65
         * Metadatos leidos de la imagen
66
         */
67
        protected DatasetMetadata            metadata = null;
68
        protected boolean                    georeferenced = true;
69
        
70
        /**
71
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
72
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
73
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
74
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
75
         * distinto tama?o que el resto.   
76
         */
77
        public int[]                          stepArrayX = null, stepArrayY = null;
78
        protected GdalRasterBand[]            gdalBands = null;
79
        private double                        lastReadLine = -1;
80
        private int                           currentFullWidth = -1;
81
        private int                           currentFullHeight = -1;
82
        private int                           currentViewWidth = -1;
83
        private int                           currentViewHeight = -1;
84
        private double                        currentViewX = 0D;
85
        private double                        viewportScaleX = 0D;
86
        private double                        viewportScaleY = 0D;
87
        //private double                        wcWidth = 0D;
88
        private double                        stepX = 0D;
89
        private double                        stepY = 0D;
90
        public boolean                        isSupersampling = false;
91
        /**
92
         * Estado de transparencia del raster.
93
         */
94
        protected Transparency                fileTransparency = null;
95
        protected ColorTable                  palette = null;
96
        protected DatasetColorInterpretation  colorInterpr = null;
97
        protected AffineTransform             ownTransformation = null;
98
        protected AffineTransform             externalTransformation = new AffineTransform();
99
        
100
        /**
101
         * Overview usada en el ?ltimo setView
102
         */
103
        int currentOverview = -1;
104
        
105
        
106
        public GdalNative(String fName) throws GdalException, IOException {
107
                super();
108
                init(fName);
109
        }
110
        
111
        private void init(String fName) throws GdalException, IOException {
112
                fileName = fName;
113
                open(fName, GA_ReadOnly);
114
                ext = RasterUtilities.getExtensionFromFileName(fName);
115
                if (ext != null && ext.compareTo("tif") == 0)
116
                        WITH_OVERVIEWS = false;
117
                width = getRasterXSize();
118
                height = getRasterYSize();
119
                int[] dt = new int[getRasterCount()];
120
                for (int i = 0; i < getRasterCount(); i++)
121
                        dt[i] = this.getRasterBand(i + 1).getRasterDataType();
122
                setDataType(dt);
123
                shortName = getDriverShortName();
124
                fileTransparency = new Transparency();
125
                colorInterpr = new DatasetColorInterpretation();
126
                metadata = new DatasetMetadata(getMetadata(), colorInterpr);
127

    
128
                // Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
129
                // nos sirve para saber que banda de la imagen va asignada a cada banda de
130
                // visualizaci?n (ARGB)
131
                colorInterpr.initColorInterpretation(getRasterCount());
132
                metadata.initNoDataByBand(getRasterCount());
133
                for (int i = 0; i < getRasterCount(); i++) {
134
                        GdalRasterBand rb = getRasterBand(i + 1);
135
                        String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
136
                        metadata.setNoDataValue(i, rb.getRasterNoDataValue());
137
                        colorInterpr.setColorInterpValue(i, colorInt);
138
                        if (colorInt.equals("Alpha"))
139
                                fileTransparency.setTransparencyBand(i);
140

    
141
                        if (rb.getRasterColorTable() != null && palette == null) {
142
                                palette = new ColorTable();
143
                                palette.createPaletteFromGdalColorTable(rb.getRasterColorTable());
144
                                //fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
145
                        }
146
                }
147
                fileTransparency.setTransparencyByPixelFromMetadata(metadata);
148

    
149
                try {
150
                        trans = getGeoTransform();
151

    
152
                        boolean isCorrect = false;
153
                        for (int i = 0; i < trans.adfgeotransform.length; i++)
154
                                if (trans.adfgeotransform[i] != 0)
155
                                        isCorrect = true;
156
                        if (!isCorrect)
157
                                throw new GdalException("");
158

    
159
                        ownTransformation = new AffineTransform(trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
160
                        externalTransformation = (AffineTransform) ownTransformation.clone();
161
                        currentFullWidth = width;
162
                        currentFullHeight = height;
163

    
164
                        this.georeferenced = true;
165
                } catch (GdalException exc) {
166
                        // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
167
                        // ya que las WC decrecen de
168
                        // arriba a abajo y los pixeles crecen de arriba a abajo
169
                        ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
170
                        externalTransformation = (AffineTransform) ownTransformation.clone();
171
                        currentFullWidth = width;
172
                        currentFullHeight = height;
173
                        this.georeferenced = false;
174
                }
175
        }
176

    
177
        /**
178
         * Devuelve el valor NoData en caso de existir, sino existe devuelve null.
179
         * @return
180
         */
181
        public double getNoDataValue() {
182
                if (metadata == null)
183
                        return RasterLibrary.defaultNoDataValue;
184

    
185
                if (metadata.getNoDataValue().length == 0)
186
                        return RasterLibrary.defaultNoDataValue;
187

    
188
                return metadata.getNoDataValue()[0];
189
        }
190

    
191
        /**
192
   * Asigna el tipo de dato
193
   * @param dt entero que representa el tipo de dato
194
   */
195
        public void setDataType(int[] dt) { 
196
                dataType = dt; 
197
        }
198
        
199
        /**
200
         * Obtiene el tipo de dato
201
         * @return entero que representa el tipo de dato
202
         */
203
        public int[] getDataType() { 
204
                return dataType; 
205
        }
206
        
207
        /**
208
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
209
         * del punto real.
210
         * Supone rasters no girados
211
         * @param pt        punto en coordenadas del punto real
212
         * @return        punto en coordenadas del raster
213
         */
214
        public Point2D worldToRasterWithoutRot(Point2D pt) {
215
                Point2D p = new Point2D.Double();
216
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
217
                                                                                                        0, externalTransformation.getScaleY(), 
218
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
219
                try {
220
                        at.inverseTransform(pt, p);
221
                } catch (NoninvertibleTransformException e) {
222
                        return pt;
223
                }
224
                return p;
225
        }
226
                
227
        /**
228
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
229
         * del punto real.
230
         * Supone rasters no girados
231
         * @param pt        punto en coordenadas del punto real
232
         * @return        punto en coordenadas del raster
233
         */
234
        public Point2D worldToRaster(Point2D pt) {
235
                Point2D p = new Point2D.Double();
236
                try {
237
                        externalTransformation.inverseTransform(pt, p);
238
                } catch (NoninvertibleTransformException e) {
239
                        return pt;
240
                }
241
                return p;
242
        }
243
        
244
        /**
245
         * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
246
         * reales. 
247
         * @param pt Punto en coordenadas reales
248
         * @return Punto en coordenadas pixel.
249
         */
250
        public Point2D rasterToWorld(Point2D pt) {
251
                Point2D p = new Point2D.Double();
252
                externalTransformation.transform(pt, p);
253
                return p;
254
        }
255
        
256
        /**
257
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
258
         * viewPortScale, currentFullWidth y currentFulHeight
259
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
260
         * @throws GdalException
261
         */
262
        private void calcOverview(Point2D tl, Point2D br) throws GdalException{
263
                gdalBands[0] = getRasterBand(1);
264
                currentOverview = -1;
265
                if (WITH_OVERVIEWS && gdalBands[0].getOverviewCount() > 0) {
266
                        GdalRasterBand ovb = null;
267
                        for (int i = gdalBands[0].getOverviewCount()-1; i > 0; i--) {              
268
                                ovb = gdalBands[0].getOverview(i);
269
                                if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
270
                                        currentOverview = i;
271
                            viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
272
                            viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
273
                            stepX = 1D/viewportScaleX;
274
                            stepY = 1D/viewportScaleY;
275
                            currentFullWidth = ovb.getRasterBandXSize();
276
                            currentFullHeight = ovb.getRasterBandYSize();
277
                            currentViewX = Math.min(tl.getX(), br.getX());
278
                            lastReadLine = Math.min(tl.getY(), br.getY());
279
                            break;
280
                                }
281
                        }
282
                }
283
        }
284
        
285
        public void setView(double dWorldTLX, double dWorldTLY,
286
            double dWorldBRX, double dWorldBRY,
287
            int nWidth, int nHeight) throws GdalException {
288
                currentFullWidth = width;
289
                currentFullHeight = height;
290
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
291
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
292
                // Calcula cual es la primera l?nea a leer;
293
                currentViewWidth = nWidth;
294
                currentViewHeight = nHeight;
295
                //wcWidth = Math.abs(br.getX() - tl.getX());
296
                
297
                currentViewX = Math.min(tl.getX(), br.getX());
298
                
299
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
300
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
301
                stepX = 1D/viewportScaleX;
302
                stepY = 1D/viewportScaleY;
303
                                                
304
                lastReadLine = Math.min(tl.getY(), br.getY());
305
                
306
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
307

    
308
                // calcula el overview a usar
309
                gdalBands = new GdalRasterBand[4];
310
                calcOverview(tl, br);
311

    
312
                // Selecciona las bandas y los overviews necesarios
313
                /*gdalBands[0] = getRasterBand(rBandNr);
314
                gdalBands[1] = gdalBands[0]; 
315
                gdalBands[2] = gdalBands[1]; 
316

317
                if(getRasterCount() >= 2) {
318
                        gdalBands[1] = getRasterBand(gBandNr);
319
                        gdalBands[2] = gdalBands[1]; 
320
                }
321
                if(this.getRasterCount() >= 3) 
322
                        gdalBands[2] = getRasterBand(bBandNr);
323
                if(colorInterpr.isAlphaBand())
324
                        gdalBands[3] = getRasterBand(aBandNr);                        
325

326
                assignDataTypeFromGdalRasterBands(gdalBands);
327

328
                if (currentOverview > 0) {
329
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
330
                        if(getRasterCount() >= 2) {
331
                                gdalBands[1] = gdalBands[1].getOverview(currentOverview);
332
                        }
333
                        if(this.getRasterCount() >= 3) 
334
                                gdalBands[2] = gdalBands[2].getOverview(currentOverview);
335
                        if(colorInterpr.isAlphaBand())
336
                                gdalBands[3] = gdalBands[3].getOverview(currentOverview);                        
337

338
                }*/
339
        }
340
        
341
        /**
342
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
343
         * @param nbands N?mero de bandas solicitado.
344
         * @throws GdalException
345
         */
346
        public void selectGdalBands(int nbands)throws GdalException{
347
                gdalBands = new GdalRasterBand[nbands];
348
                //Selecciona las bandas y los overviews necesarios
349
                gdalBands[0] = getRasterBand(1);
350
                for(int i = 0; i < nbands; i++)
351
                        gdalBands[i] = gdalBands[0];
352
                 
353
                assignDataTypeFromGdalRasterBands(gdalBands);
354
                //setDataType(gdalBands[0].getRasterDataType());
355
                
356
                for(int i = 2; i <= nbands; i++){
357
                        if(getRasterCount() >= i){
358
                                gdalBands[i - 1] = getRasterBand(i);
359
                                for(int j = i; j < nbands; j++)
360
                                        gdalBands[j] = gdalBands[i - 1];
361
                        }
362
                }
363
                                
364
                if (currentOverview > 0) {
365
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
366
                        for(int i = 2; i <= nbands; i++){
367
                                if(getRasterCount() >= i)
368
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
369
                        }
370
                }
371
        }
372
                
373
        int lastY = -1;
374
        
375
        /**
376
         * Lee una l?nea de bytes
377
         * @param line Buffer donde se cargan los datos
378
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
379
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
380
         * por la izquierda a mitad de pixel
381
         * @param gdalBuffer Buffer con la l?nea de datos original
382
         */
383
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer){
384
                double j = 0D;
385
                  int i = 0;
386
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
387
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
388
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
389
                        }
390
                }
391
        }
392
        
393
        /**
394
         * Lee una l?nea de shorts
395
         * @param line Buffer donde se cargan los datos
396
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
397
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
398
         * por la izquierda a mitad de pixel
399
         * @param gdalBuffer Buffer con la l?nea de datos original
400
         */
401
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer){
402
                  double j = 0D; 
403
                  int i = 0;
404
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
405
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
406
                                line[iBand][i] = (short)(gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
407
                        }
408
                }
409
        }
410

    
411
        /**
412
         * Lee una l?nea de ints
413
         * @param line Buffer donde se cargan los datos
414
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
415
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
416
         * por la izquierda a mitad de pixel
417
         * @param gdalBuffer Buffer con la l?nea de datos original
418
         */
419
        private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer){
420
                double j = 0D;
421
                  int i = 0;
422
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
423
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
424
                                line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
425
                        }
426
                }
427
        }
428

    
429
        /**
430
         * Lee una l?nea de float
431
         * @param line Buffer donde se cargan los datos
432
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
433
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
434
         * por la izquierda a mitad de pixel
435
         * @param gdalBuffer Buffer con la l?nea de datos original
436
         */
437
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer){
438
                double j = 0D;
439
                  int i = 0;
440
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
441
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
442
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
443
                        }
444
                }
445
        }
446
        
447
        /**
448
         * Lee una l?nea de doubles
449
         * @param line Buffer donde se cargan los datos
450
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
451
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
452
         * por la izquierda a mitad de pixel
453
         * @param gdalBuffer Buffer con la l?nea de datos original
454
         */
455
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer){
456
                double j = 0D;
457
                  int i = 0;
458
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
459
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
460
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
461
                        }
462
                }
463
        }
464

    
465
        /**
466
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
467
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
468
         * @param nLine N?mero de l?nea a leer
469
         * @param band Banda requerida
470
         * @return Object que es un array unidimendional del tipo de datos del raster
471
         * @throws GdalException
472
         */
473
        public Object readCompleteLine(int nLine, int band) throws GdalException {
474
                GdalRasterBand gdalBand = super.getRasterBand(band + 1);
475
                GdalBuffer gdalBuf = null;
476
                                
477
                gdalBuf = gdalBand.readRaster(0, nLine, getRasterXSize(), 1, getRasterXSize(), 1, dataType[band]);
478
                                
479
                  if (dataType[band] == GDT_Byte)
480
                          return gdalBuf.buffByte;
481
                else if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_Int16  || dataType[band] == GDT_UInt16)
482
                        return gdalBuf.buffShort;
483
                else if (dataType[band] == GDT_CInt32 || dataType[band] == GDT_Int32  || dataType[band] == GDT_UInt32)
484
                        return gdalBuf.buffInt;
485
                  else if(dataType[band] == GDT_Float32 || dataType[band] == GDT_CFloat32)
486
                          return gdalBuf.buffFloat;
487
                  else if(dataType[band] == GDT_Float64 || dataType[band] == GDT_CFloat64)
488
                          return gdalBuf.buffDouble;
489
                  return null;
490
        }
491
        
492
        /**
493
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
494
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
495
         * @param nLine N?mero de l?nea a leer
496
         * @param band Banda requerida
497
         * @return Object que es un array unidimendional del tipo de datos del raster
498
         * @throws GdalException
499
         */
500
        public Object readBlock(int pos, int blockHeight) throws GdalException, InterruptedException {
501
                bBandNr = super.getRasterCount();
502
                int nX = getRasterXSize();
503

    
504
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
505
                                
506
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
507
                for (int iBand = 0; iBand < gdalBand.length; iBand++) 
508
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
509
                                
510
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
511
                                
512
                if (dataType[0] == GDT_Byte) {
513
                        byte[][][] buf = new byte[bBandNr][blockHeight][getRasterXSize()];
514
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
515
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
516
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
517
                                        for (int iCol = 0; iCol < nX; iCol++) 
518
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * nX + iCol];
519
                                        if(task.getEvent() != null)
520
                                                task.manageEvent(task.getEvent());
521
                                }
522
                        }        
523
                        return buf;
524
                } else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
525
                        short[][][] buf = new short[bBandNr][blockHeight][getRasterXSize()];
526
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
527
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
528
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
529
                                        for (int iCol = 0; iCol < nX; iCol++) 
530
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * nX + iCol];
531
                                        if(task.getEvent() != null)
532
                                                task.manageEvent(task.getEvent());
533
                                }
534
                        }        
535
                        return buf;
536
                } else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
537
                        int[][][] buf = new int[bBandNr][blockHeight][getRasterXSize()];
538
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
539
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
540
                                for (int iRow = 0; iRow < blockHeight; iRow++) { 
541
                                        for (int iCol = 0; iCol < nX; iCol++)
542
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * nX + iCol];
543
                                        if(task.getEvent() != null)
544
                                                task.manageEvent(task.getEvent());
545
                                }
546
                        }        
547
                        return buf;
548
                } else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
549
                        float[][][] buf = new float[bBandNr][blockHeight][getRasterXSize()];
550
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
551
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
552
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
553
                                        for (int iCol = 0; iCol < nX; iCol++)
554
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * nX + iCol];
555
                                        if(task.getEvent() != null)
556
                                                task.manageEvent(task.getEvent());
557
                                }
558
                        }        
559
                        return buf;
560
                } else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
561
                        double[][][] buf = new double[bBandNr][blockHeight][getRasterXSize()];
562
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
563
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, nX, blockHeight, nX, blockHeight, dataType[0]);
564
                                for (int iRow = 0; iRow < blockHeight; iRow++) {
565
                                        for (int iCol = 0; iCol < nX; iCol++) 
566
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * nX + iCol];
567
                                        if(task.getEvent() != null)
568
                                                task.manageEvent(task.getEvent());
569
                                }
570
                        }                
571
                        return buf;
572
                }
573
                          
574
                  return null;
575
        }
576
        
577
        /**
578
         * Lectura de una l?nea de datos.
579
         * @param line
580
         * @throws GdalException
581
         */
582
        public void readLine(Object line) throws GdalException {
583
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
584
        int x = (int) (currentViewX);
585
        int y = (int) (lastReadLine);
586
        GdalBuffer r = null, g = null, b = null;
587
        GdalBuffer a = new GdalBuffer();
588
        
589
        while(y >= gdalBands[0].getRasterBandYSize())
590
                y--;
591
        
592
        if (x+w > gdalBands[0].getRasterBandXSize()) 
593
                w = gdalBands[0].getRasterBandXSize()-x;
594
        
595
        if(gdalBands[0].getRasterColorTable() != null) {
596
                palette = new ColorTable();
597
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
598
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
599
        } else {
600
                a.buffByte = new byte[w];
601
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
602
                        g = b = r;
603
                        if (getRasterCount() > 1 && gdalBands[1] != null)
604
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
605
                        if (getRasterCount() > 2 && gdalBands[2] != null)
606
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
607
        }
608
                          
609
        lastReadLine += stepY;
610
        
611
                  double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
612
                  GdalBuffer[] bands = {r, g, b};
613
                                    
614
                  if (dataType[0] == GDT_Byte)
615
                          readLine((byte[][])line, initOffset, bands);
616
                else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
617
                        readLine((short[][])line, initOffset, bands);
618
                else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
619
                        readLine((int[][])line, initOffset, bands);
620
                  else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
621
                          readLine((float[][])line, initOffset, bands);
622
                  else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
623
                          readLine((double[][])line, initOffset, bands);
624
          
625
                return;
626
        }
627
                        
628
        /**
629
   * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede
630
   * estar ajustada a la extensi?n del raster o no estarlo. En caso de no
631
   * estarlo los pixeles del buffer que caen fuera de la extensi?n del raster
632
   * tendr?n valor de NoData. Esta funci?n calcula en que pixel del buffer hay
633
   * que empezar a escribir en caso de que este sea mayor que los datos a leer.
634
   * 
635
   * @param dWorldTLX Posici?n X superior izquierda en coord reales
636
   * @param dWorldTLY Posici?n Y superior izquierda en coord reales
637
   * @param dWorldBRX Posici?n X inferior derecha en coord reales
638
   * @param dWorldBRY Posici?n Y inferior derecha en coord reales
639
   * @param nWidth Ancho en pixeles del buffer
640
   * @param nHeight Alto en pixeles del buffer
641
   * @return desplazamiento dentro del buffer en X e Y
642
   */ 
643
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
644
            Extent imageExtent = getExtentWithoutRot();
645
            Extent ajustDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, imageExtent);
646
            if(!RasterUtilities.compareExtents(dataExtent, ajustDataExtent)){
647
                    Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
648
                    Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
649
                    Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
650
                    Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
651
                    //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
652
                    int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
653
                    int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
654
                    
655
                    stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
656
                    stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
657
                    stpBuffer[2] = stpBuffer[0] + w; 
658
                    stpBuffer[3] = stpBuffer[1] + h;
659
                    return new int[]{w, h};
660
            }
661
            return new int[]{nWidth, nHeight};
662
        }
663
        
664
        /**
665
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
666
         * @param buf Buffer donde se almacenan los datos
667
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
668
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
669
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
670
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
671
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
672
         * @param nWidth Ancho en pixeles del buffer
673
         * @param nHeight Alto en pixeles del buffer
674
         * @throws GdalException
675
         */
676
        public void readWindow(IBuffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
677
                                            int nWidth, int nHeight, boolean adjustToExtent) throws GdalException, InterruptedException {
678
                Extent petExtent = new Extent(ulx, uly, lrx, lry);
679
                setView(ulx, uly, lrx, lry, nWidth, nHeight);
680
                Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
681
                Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
682
                                
683
                if(gdalBands.length == 0)
684
                        return;
685
                
686
                selectGdalBands(buf.getBandCount());
687
                                
688
        int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
689
        int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
690
        
691
        int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
692
        //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
693
        //ya que lo que cae fuera ser?n valores NoData
694
        if(!adjustToExtent){
695
                int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
696
                if(x < 0)
697
                        x  = 0;
698
                if(y < 0)
699
                        y  = 0;
700
                readData(buf, bandList, x, y, wh[0], wh[1], wh[0], wh[1], 0, 0, stpBuffer);
701
                return;
702
        }
703
                
704
                readData(buf, bandList, x, y, nWidth, nHeight, nWidth, nHeight, 0, 0, stpBuffer);
705
        }
706
                        
707
        /**
708
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
709
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
710
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
711
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de 
712
         * mayor tama?o que el n?mero de pixels solicitado.
713
         * 
714
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor 
715
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer 
716
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
717
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del 
718
         * raster de disco completos sino que en los bordes del buffer quedan cortados.  
719
         *  
720
         * @param buf Buffer donde se almacenan los datos
721
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
722
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
723
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
724
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
725
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
726
         * @param nWidth Ancho en pixeles de la petici?n
727
         * @param nHeight Alto en pixeles de la petici?n
728
         * @param bufWidth Ancho del buffer
729
         * @param bufHeight Alto del buffer
730
         * @throws GdalException
731
         */
732
        public void readWindow(IBuffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
733
                                            double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent) throws GdalException, InterruptedException {
734
                Extent petExtent = new Extent(ulx, uly, lrx, lry);
735
                setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
736
                Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
737
                Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
738
                                
739
                if(gdalBands.length == 0)
740
                        return;
741
                
742
                selectGdalBands(buf.getBandCount());
743
                                
744
                int x = (int) Math.min(tl.getX(), br.getX());
745
            int y = (int) Math.min(tl.getY(), br.getY());
746
            int endX = (int) Math.ceil(Math.max(br.getX(), tl.getX()));
747
            int endY = (int) Math.ceil(Math.max(br.getY(), tl.getY()));
748
                            
749
        int stpX = 0;
750
        int stpY = 0;
751
        
752
                if(bufWidth > Math.ceil(nWidth)){
753
                        stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
754
                        bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth);
755
                }
756
                if(bufHeight > Math.ceil(nHeight)){
757
                        stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
758
                        bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight);
759
                }
760
                        
761
        nWidth = (int)Math.abs(endX - x);
762
        nHeight = (int)Math.abs(endY - y);
763
               
764
        int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
765
        //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
766
        //ya que lo que cae fuera ser?n valores NoData
767
        if(!adjustToExtent){
768
                int[] wh = calcStepBuffer(petExtent, bufWidth, bufHeight, stpBuffer);
769
                if(x < 0)
770
                        x  = 0;
771
                if(y < 0)
772
                        y  = 0;
773
                stpBuffer[0] = (int)((stpBuffer[0] * bufWidth) / nWidth);
774
                stpBuffer[1] = (int)((stpBuffer[1] * bufHeight) / nHeight);
775
                stpBuffer[2] = (int)((stpBuffer[2] * bufWidth) / nWidth);
776
                stpBuffer[3] = (int)((stpBuffer[3] * bufHeight) / nHeight);
777
                bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
778
                bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
779
                readData(buf, bandList, x, y, wh[0], wh[1], bufWidth, bufHeight, 0, 0, stpBuffer);
780
                return;
781
        }
782
        
783
        if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
784
                nWidth = gdalBands[0].getRasterBandXSize() - x;
785
        
786
        if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
787
                nHeight = gdalBands[0].getRasterBandYSize() - y;
788
        
789
                readData(buf, bandList, x, y, (int)nWidth, (int)nHeight, bufWidth, bufHeight, stpX, stpY, stpBuffer);
790
        }
791
        
792
        /**
793
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
794
         * @param buf Buffer donde se almacenan los datos
795
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
796
         * @param x Posici?n X en pixeles
797
         * @param y Posici?n Y en pixeles
798
         * @param w Ancho en pixeles
799
         * @param h Alto en pixeles
800
         * @throws GdalException
801
         */
802
        public void readWindow(IBuffer buf, BandList bandList, int x, int y, int w, int h) 
803
                throws GdalException, InterruptedException {
804
                gdalBands = new GdalRasterBand[getRasterCount()];
805
                isSupersampling = false;
806
                if(gdalBands.length == 0)
807
                        return;
808
                
809
                // Selecciona las bandas
810
                gdalBands[0] = getRasterBand(1);
811
                
812
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
813
                        gdalBands[iBand] = getRasterBand(iBand + 1);
814
                
815
                assignDataTypeFromGdalRasterBands(gdalBands);
816
                
817
                int yMax = y + h;
818
                readDataByLine(buf, bandList, x, y, w, yMax);
819
        }
820
        
821
        /**
822
         * Lee una ventana de datos con resampleo a partir de coordenadas en pixeles. Este m?todo lee la
823
         * ventana de una vez cargando los datos de un golpe en el buffer.
824
         * @param buf Buffer donde se almacenan los datos
825
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
826
         * @param x Posici?n X en pixeles
827
         * @param y Posici?n Y en pixeles
828
         * @param w Ancho en pixeles
829
         * @param h Alto en pixeles
830
         * @param bufWidth Ancho del buffer
831
         * @param bufHeight Alto del buffer
832
         * @throws GdalException
833
         */
834
        public void readWindow(IBuffer buf, BandList bandList, int x, int y, int w, int h, int bufWidth, int bufHeight) throws GdalException, InterruptedException {
835
                gdalBands = new GdalRasterBand[getRasterCount()];
836
                
837
                if(gdalBands.length == 0)
838
                        return;
839
                
840
                // Selecciona las bandas
841
                gdalBands[0] = getRasterBand(1);
842
                
843
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
844
                        gdalBands[iBand] = getRasterBand(iBand + 1);
845
                
846
                assignDataTypeFromGdalRasterBands(gdalBands);
847
                
848
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
849
                readData(buf, bandList, x, y, w, h, bufWidth, bufHeight, 0, 0, stpBuffer);
850
        }
851
        
852
        /**
853
         * Asigna el tipo de datos de las bandas a partir de una lista de GdalRasterBands
854
         * @param gdalBands
855
         * @throws GdalException
856
         */
857
        private void assignDataTypeFromGdalRasterBands(GdalRasterBand[] gdalBands) throws GdalException {
858
                int[] dt = new int[gdalBands.length];
859
                for (int i = 0; i < gdalBands.length; i++) {
860
                        if(gdalBands[i] != null)
861
                                dt[i] = gdalBands[i].getRasterDataType();
862
                }
863
                setDataType(dt);
864
        }
865
                
866
        /**
867
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
868
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
869
         * @param buf Buffer donde se almacenan los datos
870
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
871
         * @param x Posici?n X en pixeles
872
         * @param y Posici?n Y en pixeles
873
         * @param w Ancho en pixeles
874
         * @param h Alto en pixeles
875
         * @param bufWidth Ancho del buffer
876
         * @param bufHeight Alto del buffer
877
         * @param stepX Desplazamiento en pixeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un 
878
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
879
         * parte de ellos. 
880
         * @param stepY Desplazamiento en pixeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un 
881
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde superior de la petici?n solo queramos una
882
         * parte de ellos.
883
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes 
884
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
885
         * <UL>
886
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
887
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
888
         * <LI>stepBuffer[2]:Posici?n X final</LI>
889
         * <LI>stepBuffer[3]:Posici?n Y final</LI>
890
         * </UL>
891
         * @throws GdalException
892
         */
893
        private void readData(IBuffer buf, BandList bandList, int x, int y, int w, int h, 
894
                        int bufWidth, int bufHeight, int stpX, int stpY, int[] stepBuffer) throws GdalException, InterruptedException {
895
                
896
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString()); 
897
                
898
                GdalBuffer gdalBuf = null;
899
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
900
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
901
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
902
                                continue;        
903
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
904
                        int pos = init;
905
                        gdalBuf = gdalBands[iBand].readRaster(x, y, w, h, bufWidth, bufHeight, dataType[iBand]);
906
                        if(dataType[iBand] == Gdal.GDT_Byte){
907
                                for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
908
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
909
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++) {
910
                                                buf.setElem(line, col, iBand, gdalBuf.buffByte[pos]);
911
                                                pos ++;
912
                                        }
913
                                        if(task.getEvent() != null)
914
                                                task.manageEvent(task.getEvent());
915
                                }
916
                        }else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)){
917
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
918
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
919
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
920
                                                buf.setElem(line, col, iBand, gdalBuf.buffShort[pos]);
921
                                                pos ++;
922
                                        }
923
                                        if(task.getEvent() != null)
924
                                                task.manageEvent(task.getEvent());
925
                                }
926
                        }else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)){
927
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
928
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
929
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
930
                                                buf.setElem(line, col, iBand, gdalBuf.buffInt[pos]);
931
                                                pos ++;
932
                                        }
933
                                        if(task.getEvent() != null)
934
                                                task.manageEvent(task.getEvent());
935
                                }
936
                        }else if(dataType[iBand] == Gdal.GDT_Float32){
937
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
938
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
939
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
940
                                                buf.setElem(line, col, iBand, gdalBuf.buffFloat[pos]);
941
                                                pos ++;
942
                                        }
943
                                        if(task.getEvent() != null)
944
                                                task.manageEvent(task.getEvent());
945
                                }
946
                        }else if(dataType[iBand] == Gdal.GDT_Float64){
947
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
948
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
949
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
950
                                                buf.setElem(line, col, iBand, gdalBuf.buffDouble[pos]);
951
                                                pos ++;
952
                                        }
953
                                        if(task.getEvent() != null)
954
                                                task.manageEvent(task.getEvent());
955
                                }
956
                        }
957
                }
958
        }
959
        
960
        /**
961
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
962
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
963
         * @param buf Buffer donde se almacenan los datos
964
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
965
         * @param x Posici?n X en pixeles
966
         * @param y Posici?n Y en pixeles
967
         * @param w Ancho en pixeles
968
         * @param yMax altura m?xima de y
969
         * @throws GdalException
970
         */
971
        private void readDataByLine(IBuffer buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException, InterruptedException {
972
                GdalBuffer gdalBuf = null;
973
                int rasterBufLine;
974
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
975
                
976
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
977
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
978
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
979
                                continue;        
980
                        if(dataType[iBand] == Gdal.GDT_Byte) {
981
                                for (int line = y; line < yMax; line++) {
982
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
983
                                        rasterBufLine = line - y;
984
                                        buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, iBand);
985
                                        if(task.getEvent() != null)
986
                                                task.manageEvent(task.getEvent());
987
                                }
988
                        }else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
989
                                for (int line = y; line < yMax; line++) {
990
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
991
                                        rasterBufLine = line - y;
992
                                        buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, iBand);
993
                                        if(task.getEvent() != null)
994
                                                task.manageEvent(task.getEvent());
995
                                }
996
                        }else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
997
                                for (int line = y; line < yMax; line++) {
998
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
999
                                        rasterBufLine = line - y;
1000
                                        buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, iBand);
1001
                                        if(task.getEvent() != null)
1002
                                                task.manageEvent(task.getEvent());
1003
                                }
1004
                        }else if(dataType[iBand] == Gdal.GDT_Float32){
1005
                                for (int line = y; line < yMax; line++) {
1006
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1007
                                        rasterBufLine = line - y;
1008
                                        buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, iBand);
1009
                                        if(task.getEvent() != null)
1010
                                                task.manageEvent(task.getEvent());
1011
                                }
1012
                        }else if(dataType[iBand] == Gdal.GDT_Float64){
1013
                                for (int line = y; line < yMax; line++) {
1014
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1015
                                        rasterBufLine = line - y;
1016
                                        buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, iBand);
1017
                                        if(task.getEvent() != null)
1018
                                                task.manageEvent(task.getEvent());
1019
                                }
1020
                        }
1021
                }
1022
        }
1023
        
1024
        /**
1025
         * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
1026
         * por par?metro
1027
         * @param x Coordenada X del pixel
1028
         * @param y Coordenada Y del pixel
1029
         * @return Array de Object donde cada posici?n representa una banda y el valor ser? Integer
1030
         * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
1031
         */
1032
        public Object[] getData(int x, int y) {
1033
                try {
1034
                        Object[] data = new Object[getRasterCount()];
1035
                        for(int i = 0; i < getRasterCount(); i++){
1036
                                GdalRasterBand rb = getRasterBand(i + 1);
1037
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType[i]);
1038
                                switch(dataType[i]){
1039
                                case 0:        break;                                                                        //Sin tipo
1040
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1041
                                                break;
1042
                                case 2:                                                                                        //Buffer short (16)
1043
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1044
                                                break;
1045
                                case 4:                                                                                        //Buffer int (32)
1046
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1047
                                                break;
1048
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1049
                                                break;
1050
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1051
                                                break;
1052
                                }
1053
                        }
1054
                        return data;
1055
                } catch (GdalException e) {
1056
                        return null;
1057
                }
1058
        }
1059
        
1060
        public int getBlockSize(){
1061
                return this.getBlockSize();
1062
        }
1063

    
1064
        /**
1065
         * Devuelve la transformaci?n del fichero de georreferenciaci?n
1066
         * @return AffineTransform
1067
         */
1068
        public AffineTransform getOwnTransformation() {
1069
                return ownTransformation;
1070
        }
1071
                
1072
        /**
1073
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
1074
         * @return Extent
1075
         */
1076
        public Extent getExtentWithoutRot() {
1077
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
1078
                                                                                                        0, externalTransformation.getScaleY(), 
1079
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
1080
                Point2D p1 = new Point2D.Double(0, 0);
1081
                Point2D p2 = new Point2D.Double(width, height);
1082
                at.transform(p1, p1);
1083
                at.transform(p2, p2);
1084
                return new Extent(p1, p2);
1085
        }
1086
        
1087
        /**
1088
         * Asigna una transformaci?n que es aplicada sobre la que ya tiene el propio fichero
1089
         * @param t
1090
         */
1091
        public void setExternalTransform(AffineTransform t){
1092
                externalTransformation = t;
1093
        }
1094

    
1095
        /**
1096
         * Obtiene el nombre del driver de Gdal
1097
         * @return Cadena que representa el nombre del driver de gdal
1098
         */
1099
        public String getGdalShortName() {
1100
                return shortName;
1101
        }
1102
                
1103
}
1104

    
1105

    
1106

    
1107