Statistics
| Revision:

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

History | View | Annotate | Download (45.6 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.Point2D;
22
import java.io.IOException;
23
import java.util.Vector;
24

    
25
import org.gvsig.raster.dataset.BandList;
26
import org.gvsig.raster.dataset.IBuffer;
27
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
28
import org.gvsig.raster.dataset.properties.DatasetMetadata;
29
import org.gvsig.raster.dataset.properties.DatasetPalette;
30
import org.gvsig.raster.dataset.properties.DatasetTransparency;
31
import org.gvsig.raster.shared.Extent;
32
import org.gvsig.raster.util.RasterUtilities;
33

    
34
import es.gva.cit.jgdal.Gdal;
35
import es.gva.cit.jgdal.GdalBuffer;
36
import es.gva.cit.jgdal.GdalException;
37
import es.gva.cit.jgdal.GdalRasterBand;
38
import es.gva.cit.jgdal.GeoTransform;
39

    
40
/**
41
 * Soporte 'nativo' para ficheros desde GDAL.
42
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
43
 * @author Nacho Brodin (nachobrodin@gmail.com)
44
 */
45

    
46
public class GdalNative extends Gdal {
47
        static boolean                                         WITH_OVERVIEWS = true;
48
        private String                                         ext = "";
49
        private String                                         fileName = null;
50
        /**
51
         * Nombre corto del driver de gdal
52
         */
53
        private String                                         shortName = "";
54
        public         GeoTransform                         trans = null;
55
        /**
56
         * Contorno en coordenadas geogr?ficas. (y Extent del raster).
57
         */
58
        public Contour                                         bBoxRot = new Contour();
59
        /**
60
         * Contorno en coordenadas geogr?ficas sin rotaci?n aplicada. Esto es util para poder
61
         * calcular los pixeles necesarios que se van a leer del raster. Cuando el raster no tiene 
62
         * rotaci?n coincide con esq. 
63
         */
64
        public Contour                                        bBoxWithoutRot = new Contour();
65
        public int                                                 width = 0, height = 0;
66
        public double                                         originX = 0D, originY = 0D;
67
        public String                                         version = "";
68
        protected int                                         rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
69
        private int                                         dataType = GDT_Byte;
70
        /**
71
         * Metadatos leidos de la imagen
72
         */
73
        protected DatasetMetadata                metadata = null;
74
        protected boolean                                 georeferenced = true;
75
        
76
        /**
77
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
78
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
79
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
80
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
81
         * distinto tama?o que el resto.   
82
         */
83
        public int[]                                        stepArrayX = null, stepArrayY = null;
84
        protected GdalRasterBand[]                 gdalBands = null;
85
        private double                                        lastReadLine = -1;
86
        private int                                         currentFullWidth = -1;
87
        private int                                         currentFullHeight = -1;
88
        private int                                         currentViewWidth = -1;
89
        private int                                         currentViewHeight = -1;
90
        private double                                         currentViewX = 0D;
91
        private double                                         currentViewY = 0D;
92
        private double                                         viewportScaleX = 0D;
93
        private double                                         viewportScaleY = 0D;
94
        private double                                         wcWidth = 0D;
95
        private double                                         stepX = 0D;
96
        private double                                         stepY = 0D;
97
        public boolean                                  isSupersampling = false;
98
        private boolean[]                                 orientation;
99
        /**
100
         * Estado de transparencia del raster.
101
         */
102
        protected DatasetTransparency                fileTransparency = null;
103
        protected DatasetPalette                        palette = null;
104
        protected DatasetColorInterpretation                colorInterpr = null;
105
        
106
        /**
107
         * Overview usada en el ?ltimo setView
108
         */
109
        int currentOverview = -1;
110
        
111
        // Polilinea con extent
112
        public class Contour extends Vector {
113
                final private static long serialVersionUID = -3370601314380922368L;
114
                public double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
115
                public double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
116
                public Contour() {
117
                        super();
118
                }
119
                public void add(Point2D pt) {
120
                        super.add(pt);
121
                        if (pt.getX() > maxX) maxX = pt.getX();
122
                        if (pt.getX() < minX) minX = pt.getX();
123
                        if (pt.getY() > maxY) maxY = pt.getY();
124
                        if (pt.getY() < minY) minY = pt.getY();
125
                }
126
        }
127

    
128
        public GdalNative(String fName) throws GdalException, IOException {
129
                super();
130
                init(fName);
131
        }
132
        
133
        /**
134
         * <P>
135
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
136
         * el tama?o de pixel y la rotaci?n. Esto lo hace con los valores de transformaci?n 
137
         * leidos por gdal en el vector de 6 elementos adfGeoTransform donde cada elemento
138
         * del vector represnta los siguientes valores
139
         * </P>
140
         * <UL>
141
         * <LI>0-origen X</LI>
142
         * <LI>1-tama?o de pixel X</LI>
143
         * <LI>2-shear en X</LI>
144
         * <LI>3-origen Y</LI>
145
         * <LI>4-shear en Y</LI>
146
         * <LI>5-Tama?o de pixel Y</LI>
147
         * </UL>
148
         * <P>
149
         * Para el calculo de una esquina aplicamos la formula siguiente:<BR>
150
         * PtoX = originX + pixelSizeX * x + shearX * y;<BR>
151
         * PtoY = originY + shearY * x + pixelSizeY * y;<BR>
152
         * Aplicandolo a las cuatro esquinas sustituimos en cada una de ellas por.
153
         * </P>
154
         * <UL> 
155
         * <LI>Esquina superior izquierda: x = 0; y = 0;</LI>
156
         * <LI>Esquina superior derecha: x = MaxX; y = 0;</LI>
157
         * <LI>Esquina inferior izquierda: x = 0; y = MaxY;</LI>
158
         * <LI>Esquina inferior derecha: x = MaxX; y = MaxY;</LI>
159
         * </UL> 
160
         * <P>
161
         * quedandonos en los cuatro casos:
162
         * </P>
163
         * <UL> 
164
         * <LI>Esquina superior izquierda: originX; originY;</LI>
165
         * <LI>Esquina superior derecha: PtoX = originX + pixelSizeX * x; PtoY = originY + shearY * x;</LI>
166
         * <LI>Esquina inferior izquierda:  PtoX = originX + shearX * y; PtoY = originY + pixelSizeY * y;</LI>
167
         * <LI>Esquina inferior derecha: PtoX = originX + pixelSizeX * x + shearX * y; PtoY = originY + shearY * x + pixelSizeY * y;</LI>
168
         * </UL>
169
         * 
170
         */
171
        private void boundingBoxFromGeoTransform(){
172
                double geoX = 0D, geoY = 0D;
173

    
174
                //Upper left corner
175
                bBoxRot.add(new Point2D.Double(trans.adfgeotransform[0], trans.adfgeotransform[3]));
176

    
177
                //Lower left corner
178
                geoX = trans.adfgeotransform[0] +  trans.adfgeotransform[2] * height;
179
                geoY = trans.adfgeotransform[3] +  trans.adfgeotransform[5] * height;
180
                bBoxRot.add(new Point2D.Double(geoX, geoY));
181
                
182
                //Upper right corner
183
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width;
184
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width;
185
                bBoxRot.add(new Point2D.Double(geoX, geoY));
186
                
187
                //Lower right corner
188
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width + trans.adfgeotransform[2] * height;
189
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width + trans.adfgeotransform[5] * height;
190
                bBoxRot.add(new Point2D.Double(geoX, geoY));
191
                
192
                //TODO: ?OJO! con coordenadas geogr?ficas
193
        }
194
        
195
        /**
196
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
197
         * el tama?o de pixel y la rotaci?n. 
198
         */
199
        private void boundingBoxWithoutRotation(){
200
                double ox = trans.adfgeotransform[0];
201
                double oy = trans.adfgeotransform[3];
202
                double resx = trans.adfgeotransform[1];
203
                double resy = trans.adfgeotransform[5];
204
                                
205
                bBoxWithoutRot.add(new Point2D.Double(ox, oy));
206
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy));
207
                bBoxWithoutRot.add(new Point2D.Double(ox, oy + resy * height));
208
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy + resy * height));
209

    
210
                //TODO: ?OJO! con coordenadas geogr?ficas
211
        }
212
        
213
        private void init(String fName) throws GdalException, IOException {
214
                fileName = fName;
215
                open(fName,GA_ReadOnly);
216
                ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
217
                if (ext.compareTo("tif") == 0)
218
                        WITH_OVERVIEWS = false;
219
                width = getRasterXSize();
220
                height = getRasterYSize();
221
                setDataType(this.getRasterBand(1).getRasterDataType());
222
                shortName = getDriverShortName();
223
                fileTransparency = new DatasetTransparency();
224
                colorInterpr = new DatasetColorInterpretation();
225
                metadata = new DatasetMetadata(getMetadata(), colorInterpr);
226
                
227
                //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
228
                //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
229
                colorInterpr.initColorInterpretation(getRasterCount());
230
                metadata.initNoDataByBand(getRasterCount());
231
            for(int i = 0; i < getRasterCount(); i++){
232
                    GdalRasterBand rb = getRasterBand(i + 1);
233
                    String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
234
                    metadata.setNoDataValue(i, rb.getRasterNoDataValue());
235
                    colorInterpr.setColorInterpValue(i, colorInt);                
236
                    if(colorInt.equals("Alpha"))
237
                            fileTransparency.setTransparencyBand(i);
238
                    
239
                    if(rb.getRasterColorTable() != null && palette == null){
240
                            palette = new DatasetPalette();
241
                         palette.createPaletteFromGdalColorTable(rb.getRasterColorTable());
242
                    }
243
            }
244
            fileTransparency.setTransparencyByPixelFromMetadata(metadata);
245

    
246
                try{
247
                        trans = getGeoTransform();
248
                        
249
                        boolean isCorrect = false;
250
                        for(int i = 0; i < trans.adfgeotransform.length; i++)
251
                                if(trans.adfgeotransform[i] != 0)
252
                                        isCorrect = true;
253
                        if(!isCorrect)
254
                                throw new GdalException("");
255
                                                
256
                        boundingBoxWithoutRotation();
257
                        boundingBoxFromGeoTransform();
258
                        currentFullWidth = width;
259
                    currentFullHeight = height;
260
                                                
261
                        this.georeferenced = true;
262
                }catch(GdalException exc){
263
                        bBoxRot.add(new Point2D.Double(0, 0));
264
                        bBoxRot.add(new Point2D.Double(width, 0));
265
                        bBoxRot.add(new Point2D.Double(0, height));
266
                        bBoxRot.add(new Point2D.Double(width, height));                
267
                        bBoxWithoutRot = bBoxRot;
268
                        this.georeferenced = false;
269
                }
270
        }
271
                
272
        /**
273
         * Asigna el tipo de dato
274
         * @param dt entero que representa el tipo de dato
275
         */
276
        public void setDataType(int dt) { 
277
                dataType = dt; 
278
        }
279
        
280
        /**
281
         * Obtiene el tipo de dato
282
         * @return entero que representa el tipo de dato
283
         */
284
        public int getDataType() { 
285
                return dataType; 
286
        }
287
                
288
        // Supone rasters no girados
289
        public Point2D worldToRaster(Point2D pt) {
290
                double x = ((pt.getX() - bBoxWithoutRot.minX) * ((double) currentFullWidth)) / (double)(bBoxWithoutRot.maxX - bBoxWithoutRot.minX);
291
                double y = ((bBoxWithoutRot.maxY - pt.getY()) * ((double) currentFullHeight)) / (double)(bBoxWithoutRot.maxY - bBoxWithoutRot.minY);
292
                Point2D ptRes = new Point2D.Double(x, y);
293
                return ptRes;
294
        }
295
        
296

    
297
        public Point2D rasterToWorld(Point2D pt) {
298
                double x = bBoxWithoutRot.minX + ((pt.getX() * (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) / width);
299
                double y = bBoxWithoutRot.maxY - ((pt.getY() * (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) / height);
300
                Point2D ptRes = new Point2D.Double(x, y);
301
                return ptRes;
302
        }
303
        
304
        /**
305
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
306
         * viewPortScale, currentFullWidth y currentFulHeight
307
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
308
         * @throws GdalException
309
         */
310
        private void calcOverview(Point2D tl, Point2D br, boolean[] orientation) throws GdalException{
311
                gdalBands[0] = getRasterBand(1);
312
                currentOverview = -1;
313
                if (WITH_OVERVIEWS && gdalBands[0].getOverviewCount() > 0) {
314
                        GdalRasterBand ovb = null;
315
                        for (int i = gdalBands[0].getOverviewCount()-1; i > 0; i--) {              
316
                                ovb = gdalBands[0].getOverview(i);
317
                                if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
318
                                        currentOverview = i;
319
                            viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
320
                            viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
321
                            stepX = 1D/viewportScaleX;
322
                            stepY = 1D/viewportScaleY;
323
                            currentFullWidth = ovb.getRasterBandXSize();
324
                            currentFullHeight = ovb.getRasterBandYSize();
325
                            if(!orientation[0])//Invierte la orientaci?n en X
326
                                    currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
327
                            else
328
                                    currentViewX = tl.getX();
329
                            if(orientation[1])//Invierte la orientaci?n en Y
330
                                    lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
331
                            else
332
                                    lastReadLine = tl.getY();
333
                            break;
334
                                }
335
                        }
336
                }
337
        }
338
        
339
        public void setView(double dWorldTLX, double dWorldTLY,
340
            double dWorldBRX, double dWorldBRY,
341
            int nWidth, int nHeight, boolean[] orientation) {
342
                this.orientation = orientation;
343
                currentFullWidth = width;
344
                currentFullHeight = height;
345
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
346
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
347
                // Calcula cual es la primera l?nea a leer;
348
                currentViewWidth = nWidth;
349
                currentViewHeight = nHeight;
350
                wcWidth = Math.abs(br.getX() - tl.getX());
351
                
352
                if(!orientation[0]) //Invierte la orientaci?n en X
353
                        currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
354
                else
355
                        currentViewX = tl.getX();
356
                
357
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
358
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
359
                stepX = 1D/viewportScaleX;
360
                stepY = 1D/viewportScaleY;
361
                                                
362
                if(orientation[1])//Invierte la orientaci?n en Y
363
                        lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
364
                else
365
                        lastReadLine = tl.getY();
366
                
367
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
368
                try {
369
                        // calcula el overview a usar
370
                        gdalBands = new GdalRasterBand[4];
371
                        calcOverview(tl, br, orientation);
372
                                                                                                    
373
                        // Selecciona las bandas y los overviews necesarios
374
                        gdalBands[0] = getRasterBand(rBandNr);
375
                        gdalBands[1] = gdalBands[0]; 
376
                        gdalBands[2] = gdalBands[1]; 
377
                        setDataType(gdalBands[0].getRasterDataType());
378
                        if(getRasterCount() >= 2) {
379
                                gdalBands[1] = getRasterBand(gBandNr);
380
                                gdalBands[2] = gdalBands[1]; 
381
                        }
382
                        if(this.getRasterCount() >= 3) 
383
                                gdalBands[2] = getRasterBand(bBandNr);
384
                        if(colorInterpr.isAlphaBand())
385
                                gdalBands[3] = getRasterBand(aBandNr);                        
386
                        
387
                        
388
                        if (currentOverview > 0) {
389
                                gdalBands[0] = gdalBands[0].getOverview(currentOverview);
390
                                if(getRasterCount() >= 2) {
391
                                        gdalBands[1] = gdalBands[1].getOverview(currentOverview);
392
                                }
393
                                if(this.getRasterCount() >= 3) 
394
                                        gdalBands[2] = gdalBands[2].getOverview(currentOverview);
395
                                if(colorInterpr.isAlphaBand())
396
                                        gdalBands[3] = gdalBands[3].getOverview(currentOverview);                        
397
                                
398
                        }
399
                        
400
                } catch (GdalException e) {
401
                        e.printStackTrace();
402
                }
403
        }
404
        
405
        /**
406
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
407
         * @param nbands N?mero de bandas solicitado.
408
         * @throws GdalException
409
         */
410
        public void selectGdalBands(int nbands)throws GdalException{
411
                gdalBands = new GdalRasterBand[nbands];
412
                //Selecciona las bandas y los overviews necesarios
413
                gdalBands[0] = getRasterBand(1);
414
                for(int i = 0; i < nbands; i++)
415
                        gdalBands[i] = gdalBands[0];
416
                 
417
                setDataType(gdalBands[0].getRasterDataType());
418
                
419
                for(int i = 2; i <= nbands; i++){
420
                        if(getRasterCount() >= i){
421
                                gdalBands[i - 1] = getRasterBand(i);
422
                                for(int j = i; j < nbands; j++)
423
                                        gdalBands[j] = gdalBands[i - 1];
424
                        }
425
                }
426
                                
427
                if (currentOverview > 0) {
428
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
429
                        for(int i = 2; i <= nbands; i++){
430
                                if(getRasterCount() >= i)
431
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
432
                        }
433
                }
434
        }
435
                
436
        int lastY = -1;
437
        
438
        /**
439
         * Lee una l?nea de bytes
440
         * @param line Buffer donde se cargan los datos
441
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
442
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
443
         * por la izquierda a mitad de pixel
444
         * @param gdalBuffer Buffer con la l?nea de datos original
445
         */
446
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer){
447
                double j = 0D;
448
                  int i = 0;
449
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
450
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
451
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
452
                        }
453
                }
454
        }
455
        
456
        /**
457
         * Lee una l?nea de shorts
458
         * @param line Buffer donde se cargan los datos
459
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
460
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
461
         * por la izquierda a mitad de pixel
462
         * @param gdalBuffer Buffer con la l?nea de datos original
463
         */
464
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer){
465
                  double j = 0D; 
466
                  int i = 0;
467
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
468
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
469
                                line[iBand][i] = (short)(gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
470
                        }
471
                }
472
        }
473

    
474
        /**
475
         * Lee una l?nea de ints
476
         * @param line Buffer donde se cargan los datos
477
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
478
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
479
         * por la izquierda a mitad de pixel
480
         * @param gdalBuffer Buffer con la l?nea de datos original
481
         */
482
        private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer){
483
                double j = 0D;
484
                  int i = 0;
485
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
486
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
487
                                line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
488
                        }
489
                }
490
        }
491

    
492
        /**
493
         * Lee una l?nea de float
494
         * @param line Buffer donde se cargan los datos
495
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
496
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
497
         * por la izquierda a mitad de pixel
498
         * @param gdalBuffer Buffer con la l?nea de datos original
499
         */
500
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer){
501
                double j = 0D;
502
                  int i = 0;
503
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
504
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
505
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
506
                        }
507
                }
508
        }
509
        
510
        /**
511
         * Lee una l?nea de doubles
512
         * @param line Buffer donde se cargan los datos
513
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
514
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
515
         * por la izquierda a mitad de pixel
516
         * @param gdalBuffer Buffer con la l?nea de datos original
517
         */
518
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer){
519
                double j = 0D;
520
                  int i = 0;
521
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
522
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
523
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
524
                        }
525
                }
526
        }
527

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

1101
                int stpX = (int)(((tl.getX() - x) * bufWidth) / Math.abs(br.getX() - tl.getX()));
1102
                int stpY = (int)(((tl.getY() - y) * bufHeight) / Math.abs(br.getY() - tl.getY()));
1103
                
1104
                return new int[]{stpX, stpY};
1105
        }*/
1106
        
1107
        public int getBlockSize(){
1108
                return this.getBlockSize();
1109
        }
1110
        
1111
}
1112

    
1113

    
1114

    
1115