Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1009 / libraries / libCq_CMS_praster / src / org / cresques / io / GdalNative.java @ 12649

History | View | Annotate | Download (44.3 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 *
4
 * Copyright (C) 2004-5.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 * cresques@gmail.com
23
 */
24
package org.cresques.io;
25

    
26
import java.awt.geom.Point2D;
27
import java.io.IOException;
28
import java.util.Vector;
29

    
30
import org.cresques.io.data.BandList;
31
import org.cresques.io.data.RasterBuf;
32
import org.cresques.io.datastruct.Metadata;
33
import org.cresques.io.datastruct.Palette;
34
import org.cresques.px.Extent;
35
import org.cresques.util.Utilities;
36

    
37
import es.gva.cit.jgdal.Gdal;
38
import es.gva.cit.jgdal.GdalBuffer;
39
import es.gva.cit.jgdal.GdalException;
40
import es.gva.cit.jgdal.GdalRasterBand;
41
import es.gva.cit.jgdal.GeoTransform;
42

    
43
/**
44
 * Soporte 'nativo' para ficheros desde GDAL.
45
 * Este conjunto de funcionalidades est? tomado de manera casi literal
46
 * del soporte para ECW de ermapper.<br>
47
 * Probablemente esto deber?a formar parte del JNI que recubre a la
48
 * librer?a en C extraida de gdal.<br>
49
 * Lo pongo aqu? a manera de ejemplo de como atacar un formato binario
50
 * desde Java.<br><br>
51
 * @author Luis W. Sevilla.
52
 */
53

    
54
class GdalNative extends Gdal {
55
        static boolean                                 WITH_OVERVIEWS = true;
56
        protected GdalFile                        driver = null;
57
        protected String                                 ext = "";
58
        protected String                                 fileName = null;
59
        /**
60
         * Nombre corto del driver de gdal
61
         */
62
        protected String                                 shortName = "";
63
        public         GeoTransform                 trans = null;
64
        /**
65
         * Contorno en coordenadas geogr?ficas. (y Extent del raster).
66
         */
67
        public Contour                                 bBoxRot = new Contour();
68
        /**
69
         * Contorno en coordenadas geogr?ficas sin rotaci?n aplicada. Esto es util para poder
70
         * calcular los pixeles necesarios que se van a leer del raster. Cuando el raster no tiene
71
         * rotaci?n coincide con esq.
72
         */
73
        public Contour                                bBoxWithoutRot = new Contour();
74
        public int                                         width = 0, height = 0;
75
        public double                                 originX = 0D, originY = 0D;
76
        public String                                 version = "";
77
        private int                                 alpha = 0;
78
        protected int                                 rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
79
        private int                                 dataType = GDT_Byte;
80
        /**
81
         * Metadatos leidos de la imagen
82
         */
83
        protected Metadata                        metadata = null;
84
        protected boolean                         georeferenced = true;
85

    
86
        /**
87
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
88
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
89
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
90
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de
91
         * distinto tama?o que el resto.
92
         */
93
        public int[]                                stepArrayX = null, stepArrayY = null;
94
        protected GdalRasterBand[]         gdalBands = null;
95
        private double                                lastReadLine = -1;
96
        private int                                 currentFullWidth = -1;
97
        private int                                 currentFullHeight = -1;
98
        private int                                 currentViewWidth = -1;
99
        private int                                 currentViewHeight = -1;
100
        private double                                 currentViewX = 0D;
101
        private double                                 currentViewY = 0D;
102
        private double                                 viewportScaleX = 0D;
103
        private double                                 viewportScaleY = 0D;
104
        private double                                 wcWidth = 0D;
105
        private double                                 stepX = 0D;
106
        private double                                 stepY = 0D;
107
        public boolean                          isSupersampling = false;
108
        private boolean[]                         orientation;
109

    
110
        /**
111
         * Overview usada en el ?ltimo setView
112
         */
113
        int currentOverview = -1;
114

    
115
        // Polilinea con extent
116
        public class Contour extends Vector {
117
                final private static long serialVersionUID = -3370601314380922368L;
118
                public double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
119
                public double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
120
                public Contour() {
121
                        super();
122
                }
123
                public void add(Point2D pt) {
124
                        super.add(pt);
125
                        if (pt.getX() > maxX) maxX = pt.getX();
126
                        if (pt.getX() < minX) minX = pt.getX();
127
                        if (pt.getY() > maxY) maxY = pt.getY();
128
                        if (pt.getY() < minY) minY = pt.getY();
129
                }
130
        }
131

    
132
        public GdalNative(){
133
                super();
134
        }
135
        
136
        public GdalNative(String fName, GdalFile driver) throws GdalException, IOException {
137
                super();
138
                this.driver = driver;
139
                init(fName);
140
        }
141

    
142
        public Point2D rasterToWorld(Point2D pt) {
143
                double x = bBoxWithoutRot.minX + ((pt.getX() * (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) / width);
144
                double y = bBoxWithoutRot.maxY - ((pt.getY() * (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) / height);
145
                Point2D ptRes = new Point2D.Double(x, y);
146
                return ptRes;
147
        }
148

    
149
        /**
150
         * <P>
151
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
152
         * el tama?o de pixel y la rotaci?n. Esto lo hace con los valores de transformaci?n
153
         * leidos por gdal en el vector de 6 elementos adfGeoTransform donde cada elemento
154
         * del vector represnta los siguientes valores
155
         * </P>
156
         * <UL>
157
         * <LI>0-origen X</LI>
158
         * <LI>1-tama?o de pixel X</LI>
159
         * <LI>2-shear en X</LI>
160
         * <LI>3-origen Y</LI>
161
         * <LI>4-shear en Y</LI>
162
         * <LI>5-Tama?o de pixel Y</LI>
163
         * </UL>
164
         * <P>
165
         * Para el calculo de una esquina aplicamos la formula siguiente:<BR>
166
         * PtoX = originX + pixelSizeX * x + shearX * y;<BR>
167
         * PtoY = originY + shearY * x + pixelSizeY * y;<BR>
168
         * Aplicandolo a las cuatro esquinas sustituimos en cada una de ellas por.
169
         * </P>
170
         * <UL>
171
         * <LI>Esquina superior izquierda: x = 0; y = 0;</LI>
172
         * <LI>Esquina superior derecha: x = MaxX; y = 0;</LI>
173
         * <LI>Esquina inferior izquierda: x = 0; y = MaxY;</LI>
174
         * <LI>Esquina inferior derecha: x = MaxX; y = MaxY;</LI>
175
         * </UL>
176
         * <P>
177
         * quedandonos en los cuatro casos:
178
         * </P>
179
         * <UL>
180
         * <LI>Esquina superior izquierda: originX; originY;</LI>
181
         * <LI>Esquina superior derecha: PtoX = originX + pixelSizeX * x; PtoY = originY + shearY * x;</LI>
182
         * <LI>Esquina inferior izquierda:  PtoX = originX + shearX * y; PtoY = originY + pixelSizeY * y;</LI>
183
         * <LI>Esquina inferior derecha: PtoX = originX + pixelSizeX * x + shearX * y; PtoY = originY + shearY * x + pixelSizeY * y;</LI>
184
         * </UL>
185
         *
186
         */
187
        protected void boundingBoxFromGeoTransform(){
188
                double geoX = 0D, geoY = 0D;
189

    
190
                //Upper left corner
191
                bBoxRot.add(new Point2D.Double(trans.adfgeotransform[0], trans.adfgeotransform[3]));
192

    
193
                //Lower left corner
194
                geoX = trans.adfgeotransform[0] +  trans.adfgeotransform[2] * height;
195
                geoY = trans.adfgeotransform[3] +  trans.adfgeotransform[5] * height;
196
                bBoxRot.add(new Point2D.Double(geoX, geoY));
197

    
198
                //Upper right corner
199
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width;
200
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width;
201
                bBoxRot.add(new Point2D.Double(geoX, geoY));
202

    
203
                //Lower right corner
204
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width + trans.adfgeotransform[2] * height;
205
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width + trans.adfgeotransform[5] * height;
206
                bBoxRot.add(new Point2D.Double(geoX, geoY));
207

    
208
                //TODO: ?OJO! con coordenadas geogr?ficas
209
        }
210

    
211
        /**
212
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
213
         * el tama?o de pixel y la rotaci?n.
214
         */
215
        protected void boundingBoxWithoutRotation(){
216
                double ox = trans.adfgeotransform[0];
217
                double oy = trans.adfgeotransform[3];
218
                double resx = trans.adfgeotransform[1];
219
                double resy = trans.adfgeotransform[5];
220

    
221
                bBoxWithoutRot.add(new Point2D.Double(ox, oy));
222
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy));
223
                bBoxWithoutRot.add(new Point2D.Double(ox, oy + resy * height));
224
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy + resy * height));
225

    
226
                //TODO: ?OJO! con coordenadas geogr?ficas
227
        }
228

    
229
        private void init(String fName) throws GdalException, IOException {
230
                fileName = fName;
231
                open(fName,GA_ReadOnly);
232
                ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
233
                if (ext.compareTo("tif") == 0)
234
                        WITH_OVERVIEWS = false;
235
                width = getRasterXSize();
236
                height = getRasterYSize();
237
                setDataType(this.getRasterBand(1).getRasterDataType());
238
                shortName = getDriverShortName();
239
                metadata = new Metadata(getMetadata());
240

    
241
                //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
242
                //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
243
                metadata.initColorInterpretation(getRasterCount());
244
                metadata.initNoDataByBand(getRasterCount());
245
            for(int i = 0; i < getRasterCount(); i++){
246
                    GdalRasterBand rb = getRasterBand(i + 1);
247
                    String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
248
                    metadata.setNoDataValue(i, rb.getRasterNoDataValue());
249
                    metadata.setColorInterpValue(i, colorInt);
250
                    if(colorInt.equals("Red"))
251
                            rBandNr = i + 1;
252
                    if(colorInt.equals("Green"))
253
                            gBandNr = i + 1;
254
                    if(colorInt.equals("Blue"))
255
                            bBandNr = i + 1;
256
                    if(colorInt.equals("Alpha"))
257
                            aBandNr = i + 1;
258
            }
259

    
260
                try{
261
                        trans = getGeoTransform();
262

    
263
                        boolean isCorrect = false;
264
                        for(int i = 0; i < trans.adfgeotransform.length; i++)
265
                                if(trans.adfgeotransform[i] != 0)
266
                                        isCorrect = true;
267
                        if(!isCorrect)
268
                                throw new GdalException("");
269

    
270
                        boundingBoxWithoutRotation();
271
                        boundingBoxFromGeoTransform();
272

    
273
                        this.georeferenced = true;
274
                }catch(GdalException exc){
275
                        bBoxRot.add(new Point2D.Double(0, 0));
276
                        bBoxRot.add(new Point2D.Double(width, 0));
277
                        bBoxRot.add(new Point2D.Double(0, height));
278
                        bBoxRot.add(new Point2D.Double(width, height));
279
                        bBoxWithoutRot = bBoxRot;
280
                        this.georeferenced = false;
281
                }
282
                readPalette();
283
        }
284

    
285
        public void readPalette(){
286
                //Cargamos la tabla de color si la tiene
287
                try{
288
                        gdalBands = new GdalRasterBand[1];
289
                        gdalBands[0] = getRasterBand(1);
290
                if(gdalBands[0] != null && gdalBands[0].getRasterColorTable() != null){
291
                        Palette palette = new Palette();
292
                        palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
293
                        driver.setPalette(palette);
294
                }
295
                }catch(GdalException exc){
296
                        //No cargamos la tabla de color
297
                }
298
        }
299

    
300
        /**
301
         * Asigna el valor de Alpha
302
         * @param a
303
         */
304
        public void setAlpha(int a) {
305
                alpha = a;
306
        }
307

    
308
        /**
309
         * Asigna el tipo de dato
310
         * @param dt entero que representa el tipo de dato
311
         */
312
        public void setDataType(int dt) {
313
                dataType = dt;
314
        }
315

    
316
        /**
317
         * Obtiene el tipo de dato
318
         * @return entero que representa el tipo de dato
319
         */
320
        public int getDataType() {
321
                return dataType;
322
        }
323

    
324
        // Supone rasters no girados
325
        public Point2D worldToRaster(Point2D pt) {
326
                double x = (((double) currentFullWidth) / (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) * (pt.getX() - bBoxWithoutRot.minX);
327
                double y = (((double) currentFullHeight) / (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) * (bBoxWithoutRot.maxY - pt.getY());
328
                Point2D ptRes = new Point2D.Double(x, y);
329
                return ptRes;
330
        }
331

    
332
        /**
333
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
334
         * viewPortScale, currentFullWidth y currentFulHeight
335
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
336
         * @throws GdalException
337
         */
338
        private void calcOverview(Point2D tl, Point2D br, boolean[] orientation) throws GdalException{
339
                gdalBands[0] = getRasterBand(1);
340
                currentOverview = -1;
341
                if (WITH_OVERVIEWS && gdalBands[0].getOverviewCount() > 0) {
342
                        GdalRasterBand ovb = null;
343
                        for (int i = gdalBands[0].getOverviewCount()-1; i > 0; i--) {
344
                                ovb = gdalBands[0].getOverview(i);
345
                                if (ovb.getRasterBandXSize()>getRasterXSize()*viewportScaleX) {
346
                                        currentOverview = i;
347
                            viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
348
                            viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
349
                            stepX = 1D/viewportScaleX;
350
                            stepY = 1D/viewportScaleY;
351
                            currentFullWidth = ovb.getRasterBandXSize();
352
                            currentFullHeight = ovb.getRasterBandYSize();
353
                            if(!orientation[0])//Invierte la orientaci?n en X
354
                                    currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
355
                            else
356
                                    currentViewX = tl.getX();
357
                            if(orientation[1])//Invierte la orientaci?n en Y
358
                                    lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
359
                            else
360
                                    lastReadLine = tl.getY();
361
                            break;
362
                                }
363
                        }
364
                }
365
        }
366

    
367
        public void setView(double dWorldTLX, double dWorldTLY,
368
            double dWorldBRX, double dWorldBRY,
369
            int nWidth, int nHeight, boolean[] orientation) {
370
                this.orientation = orientation;
371
                currentFullWidth = width;
372
                currentFullHeight = height;
373
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
374
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
375
                // Calcula cual es la primera l?nea a leer;
376
                currentViewWidth = nWidth;
377
                currentViewHeight = nHeight;
378
                wcWidth = Math.abs(br.getX() - tl.getX());
379

    
380
                if(!orientation[0]) //Invierte la orientaci?n en X
381
                        currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
382
                else
383
                        currentViewX = tl.getX();
384

    
385
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
386
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
387
                stepX = 1D/viewportScaleX;
388
                stepY = 1D/viewportScaleY;
389

    
390
                if(orientation[1])//Invierte la orientaci?n en Y
391
                        lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
392
                else
393
                        lastReadLine = tl.getY();
394

    
395
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
396
                try {
397
                        // calcula el overview a usar
398
                        gdalBands = new GdalRasterBand[4];
399
                        calcOverview(tl, br, orientation);
400
                        calcArraySteps();
401

    
402
                        // Selecciona las bandas y los overviews necesarios
403
                        gdalBands[0] = getRasterBand(rBandNr);
404
                        gdalBands[1] = gdalBands[0];
405
                        gdalBands[2] = gdalBands[1];
406
                        setDataType(gdalBands[0].getRasterDataType());
407
                        if(this.getRasterCount() >= 2) {
408
                                gdalBands[1] = getRasterBand(gBandNr);
409
                                gdalBands[2] = gdalBands[1];
410
                        }
411
                        if(this.getRasterCount() >= 3)
412
                                gdalBands[2] = getRasterBand(bBandNr);
413
                        if(metadata.isAlphaBand())
414
                                gdalBands[3] = getRasterBand(aBandNr);
415

    
416

    
417
                        if (currentOverview > 0) {
418
                                gdalBands[0] = gdalBands[0].getOverview(currentOverview);
419
                                gdalBands[1] = gdalBands[0];
420
                                gdalBands[2] = gdalBands[1];
421
                                if(this.getRasterCount() >= 2) {
422
                                        gdalBands[1] = gdalBands[1].getOverview(currentOverview);
423
                                        gdalBands[2] = gdalBands[1];
424
                                }
425
                                if(this.getRasterCount() >= 3)
426
                                        gdalBands[2] = gdalBands[2].getOverview(currentOverview);
427
                                if(metadata.isAlphaBand())
428
                                        gdalBands[3] = gdalBands[3].getOverview(currentOverview);
429

    
430
                        }
431

    
432
                } catch (GdalException e) {
433
                        e.printStackTrace();
434
                }
435
        }
436

    
437
        /**
438
         * Esta funci?n calcula los arrays de steps en X e Y para que cuando hay supersampleo
439
         * se aplique el filtro solo a la esquina superior izquierda de cada pixel.
440
         */
441
        private void calcArraySteps(){
442
                if(stepX < 1 && stepY < 1){
443
                        isSupersampling = true;
444
                        int w = (int) (Math.ceil(((double)currentViewWidth) * stepX) + 1);
445
                        this.stepArrayX = new int[w];
446
                        for (double j =  Math.abs(currentViewX - ((int)currentViewX)); j < w; j += stepX)
447
                                        stepArrayX[(int)(j)] ++;
448

    
449
                        int h = (int) (Math.ceil(((double)currentViewHeight) * stepY) + 1);
450
                        this.stepArrayY = new int[h];
451
                        for (double j =  Math.abs(lastReadLine - ((int)lastReadLine)); j < h; j += stepY)
452
                                stepArrayY[(int)(j)] ++;
453
                }else{
454
                        isSupersampling = false;
455
                        this.stepArrayX = this.stepArrayY = null;
456
                }
457
        }
458

    
459
        int lastY = -1;
460

    
461
        /**
462
         * Lee una l?nea de bytes
463
         * @param line Buffer donde se cargan los datos
464
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
465
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
466
         * por la izquierda a mitad de pixel
467
         * @param gdalBuffer Buffer con la l?nea de datos original
468
         */
469
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer){
470
                double j = 0D;
471
                  int i = 0;
472
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
473
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
474
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
475
                        }
476
                }
477
        }
478

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

    
497
        /**
498
         * Lee una l?nea de ints
499
         * @param line Buffer donde se cargan los datos
500
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
501
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
502
         * por la izquierda a mitad de pixel
503
         * @param gdalBuffer Buffer con la l?nea de datos original
504
         */
505
        private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer){
506
                double j = 0D;
507
                  int i = 0;
508
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
509
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
510
                                line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
511
                        }
512
                }
513
        }
514

    
515
        /**
516
         * Lee una l?nea de float
517
         * @param line Buffer donde se cargan los datos
518
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
519
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
520
         * por la izquierda a mitad de pixel
521
         * @param gdalBuffer Buffer con la l?nea de datos original
522
         */
523
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer){
524
                double j = 0D;
525
                  int i = 0;
526
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
527
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
528
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
529
                        }
530
                }
531
        }
532

    
533
        /**
534
         * Lee una l?nea de doubles
535
         * @param line Buffer donde se cargan los datos
536
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
537
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
538
         * por la izquierda a mitad de pixel
539
         * @param gdalBuffer Buffer con la l?nea de datos original
540
         */
541
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer){
542
                double j = 0D;
543
                  int i = 0;
544
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
545
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
546
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
547
                        }
548
                }
549
        }
550

    
551
        public void readLine(Object line) throws GdalException {
552
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
553
        int x = (int) (currentViewX);
554
        int y = (int) (lastReadLine);
555
        GdalBuffer r = null, g = null, b = null;
556
        GdalBuffer a = new GdalBuffer();
557

    
558
        while(y >= gdalBands[0].getRasterBandYSize())
559
                y--;
560

    
561
        if (x+w > gdalBands[0].getRasterBandXSize())
562
                w = gdalBands[0].getRasterBandXSize()-x;
563

    
564
        if(gdalBands[0].getRasterColorTable() != null){
565
                /*Palette palette = new Palette();
566
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
567
                driver.setPalette(palette);*/
568
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
569
        }else{
570
                a.buffByte = new byte[w];
571
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
572
                        g = b = r;
573
                        if (getRasterCount() > 1 && gdalBands[1] != null)
574
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType);
575
                        if (getRasterCount() > 2 && gdalBands[2] != null)
576
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType);
577
        }
578

    
579
        lastReadLine += stepY;
580

    
581
                  double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
582
                  GdalBuffer[] bands = {r, g, b};
583

    
584
                  if (dataType == GDT_Byte)
585
                          readLine((byte[][])line, initOffset, bands);
586
                else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16)
587
                        readLine((short[][])line, initOffset, bands);
588
                else if (dataType == GDT_CInt32 || dataType == GDT_Int32  || dataType == GDT_UInt32)
589
                        readLine((int[][])line, initOffset, bands);
590
                  else if(dataType == GDT_Float32 || dataType == GDT_CFloat32)
591
                          readLine((float[][])line, initOffset, bands);
592
                  else if(dataType == GDT_Float64 || dataType == GDT_CFloat64)
593
                          readLine((double[][])line, initOffset, bands);
594

    
595
                return;
596
        }
597

    
598
        /**
599
         * Lee una l?nea y la guarda cada elemento sobre un entero. Este entero representa
600
         * un valor ARGB
601
         * @param line Buffer sobre el que se escribe la linea
602
         * @return
603
         * @throws GdalException
604
         */
605
        int readLineRGBA(int[] line) throws GdalException {
606
                int err = 0;
607

    
608
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
609
        int x = (int) currentViewX;
610
        int y = (int) lastReadLine;
611
        GdalBuffer r = null, g = null, b = null, p = null;
612
        GdalBuffer a = new GdalBuffer();
613

    
614
        while(y >= gdalBands[0].getRasterBandYSize())
615
                y--;
616

    
617
        if (x+w > gdalBands[0].getRasterBandXSize())
618
                w = gdalBands[0].getRasterBandXSize()-x;
619

    
620
        if(gdalBands[0].getRasterColorTable() != null){
621
                /*Palette palette = new Palette();
622
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
623
                driver.setPalette(palette);*/
624
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
625
        }else{
626

    
627
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
628
                g = b = r;
629
                        if (getRasterCount() > 1 && gdalBands[1] != null)
630
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType);
631
                        if (getRasterCount() > 2 && gdalBands[2] != null)
632
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType);
633

    
634
                if(metadata.isAlphaBand()){
635
                        a = gdalBands[3].readRaster(x, y, w, 1, w, 1, GDT_Byte);
636
                }else{
637
                            a.buffByte = new byte[w];
638
                            for (int i = 0;i < w;i++)
639
                                    a.buffByte[i] = (byte)255;
640
                }
641
        }
642
                  lastReadLine += stepY;
643

    
644
                  int i=0;
645
                  double j =  Math.abs(currentViewX - ((int)currentViewX));
646
                int alpha = (this.alpha & 0xff) << 24;
647

    
648
                if(orientation[0]){ //Pixel size en X positivo
649
                        if (dataType == GDT_Byte){
650
                                  if(gdalBands[0].getRasterColorTable() != null){
651
                                          for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
652
                                              int jInt = (int)(j);
653
                                              line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
654
                                      }
655
                                  }else{
656
                                          for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
657
                                              int jInt = (int)(j);
658
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
659
                                      }
660
                                  }
661
                          }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
662
                                  if (g == null) // Sibgle Band (Typical DEM)
663
                                            for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
664
                                                    int jInt = (int)(j);
665
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
666
                                      }
667
                                  else { // Multiband
668
                                          // System.err.println("Raster 16bits multibanda");
669
                                      for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
670
                                              int jInt = (int)(j);
671
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) |
672
                                                                                                                                   (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
673
                                                                                                                                   (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
674
                                      }
675
                                  }
676
                          }
677
                }else{ //Pixel size en X negativo
678
                        if (dataType == GDT_Byte){
679
                                  if(gdalBands[0].getRasterColorTable() != null){
680
                                          for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX)  {
681
                                              int jInt = (int)(j);
682
                                              line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
683
                                      }
684
                                  }else{
685
                                          for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX)  {
686
                                              int jInt = (int)(j);
687
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
688
                                      }
689
                                  }
690
                          }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
691
                                  if (g == null) // Sibgle Band (Typical DEM)
692
                                            for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
693
                                                    int jInt = (int)(j);
694
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
695
                                      }
696
                                  else { // Multiband
697
                                          // System.err.println("Raster 16bits multibanda");
698
                                      for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
699
                                              int jInt = (int)(j);
700
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) |
701
                                                                                                                                   (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
702
                                                                                                                                   (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
703
                                      }
704
                                  }
705
                          }
706
                }
707
                return err;
708
        }
709

    
710
        /**
711
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
712
         * @param buf Buffer donde se almacenan los datos
713
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
714
         * @param dWorldTLX Posici?n X en pixeles
715
         * @param dWorldTLY Posici?n Y en pixeles
716
         * @param w Ancho en pixeles
717
         * @param h Alto en pixeles
718
         * @throws GdalException
719
         */
720
        public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY,
721
                                            int nWidth, int nHeight) throws GdalException {
722
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
723

    
724
                gdalBands = new GdalRasterBand[getRasterCount()];
725
                isSupersampling = false;
726
                if(gdalBands.length == 0)
727
                        return;
728

    
729
                try {
730
                        // Selecciona las bandas
731
                        gdalBands[0] = getRasterBand(1);
732
                        setDataType(gdalBands[0].getRasterDataType());
733
                        for(int iBand = 1; iBand < gdalBands.length; iBand++)
734
                                gdalBands[iBand] = getRasterBand(iBand + 1);
735

    
736
                } catch (GdalException e) {
737
                        e.printStackTrace();
738
                }
739

    
740
        int x = (int) Math.ceil(tl.getX());
741
        int y = (int) Math.ceil(tl.getY());
742

    
743
        if ((x + nWidth) > gdalBands[0].getRasterBandXSize())
744
                nWidth = gdalBands[0].getRasterBandXSize() - x;
745

    
746
        if ((y + nHeight) > gdalBands[0].getRasterBandYSize())
747
                nHeight = gdalBands[0].getRasterBandYSize() - y;
748

    
749
                int yMax = y + nHeight;
750
        readData(buf, bandList, x, y, nWidth, yMax);
751
        }
752

    
753
        /**
754
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
755
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
756
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
757
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de
758
         * mayor tama?o que el n?mero de pixels solicitado.
759
         *
760
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor
761
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer
762
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
763
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del
764
         * raster de disco completos sino que en los bordes del buffer quedan cortados.
765
         *
766
         * @param buf Buffer donde se almacenan los datos
767
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
768
         * @param dWorldTLX Posici?n X en pixeles
769
         * @param dWorldTLY Posici?n Y en pixeles
770
         * @param nWidth Ancho en pixeles
771
         * @param nHeight Alto en pixeles
772
         * @param bufWidth Ancho del buffer
773
         * @param bufHeight Alto del buffer
774
         * @throws GdalException
775
         */
776
        public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
777
                                            double nWidth, double nHeight, int bufWidth, int bufHeight) throws GdalException {
778
                setView(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, bufWidth, bufHeight, new boolean[]{true, false});
779
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
780
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
781

    
782
                if(gdalBands.length == 0)
783
                        return;
784

    
785
                selectGdalBands(buf.getBandCount());
786

    
787
        int x = (int) tl.getX();
788
        int y = (int) tl.getY();
789
        int endX = (int) Math.ceil(br.getX());
790
        int endY = (int) Math.ceil(br.getY());
791

    
792
        int stpX = 0;
793
        int stpY = 0;
794

    
795
                if(bufWidth > Math.ceil(nWidth)){
796
                        stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
797
                        bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth);
798
                }
799
                if(bufHeight > Math.ceil(nHeight)){
800
                        stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
801
                        bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight);
802
                }
803

    
804
        nWidth = (int)Math.abs(endX - x);
805
        nHeight = (int)Math.abs(endY - y);
806

    
807
        if ((x + nWidth) > gdalBands[0].getRasterBandXSize())
808
                nWidth = gdalBands[0].getRasterBandXSize() - x;
809

    
810
        if ((y + nHeight) > gdalBands[0].getRasterBandYSize())
811
                nHeight = gdalBands[0].getRasterBandYSize() - y;
812

    
813
        int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
814
                readData(buf, bandList, x, y, (int)nWidth, (int)nHeight, bufWidth, bufHeight, stpX, stpY, stpBuffer);
815
        }
816

    
817
        /**
818
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
819
         * readWindow para coordenadas reales y readWindow en coordenadas pixel.
820
         * @param buf Buffer donde se almacenan los datos
821
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
822
         * @param x Posici?n X en pixeles
823
         * @param y Posici?n Y en pixeles
824
         * @param w Ancho en pixeles
825
         * @param yMax altura m?xima de y
826
         * @throws GdalException
827
         */
828
        private void readData(RasterBuf buf, BandList bandList, int x, int y, int w, int h, int bufWidth, int bufHeight, int stpX, int stpY, int[] stepBuffer) throws GdalException {
829
                //TODO: FUNCIONALIDAD: Orientaci?n del raster. orientaion[0] para pixels en X y orientation[1] para pixels en Y
830
                GdalBuffer gdalBuf = null;
831
                for(int iBand = 0; iBand < gdalBands.length; iBand++){
832
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
833
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
834
                                continue;
835
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
836
                        int pos = init;
837
                        gdalBuf = gdalBands[iBand].readRaster(x, y, w, h, bufWidth, bufHeight, dataType);
838
                        if(dataType == Gdal.GDT_Byte){
839
                                for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
840
                                        pos = (int)((bufWidth * line) + init);
841
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++){
842
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
843
                                                        buf.setElemByte(line, col, drawableBands[drawBands], gdalBuf.buffByte[pos]);
844
                                                }
845
                                                pos ++;
846
                                        }
847
                                }
848
                        }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){
849
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
850
                                        pos = (int)((bufWidth * line) + init);
851
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
852
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
853
                                                        buf.setElemShort(line, col, drawableBands[drawBands], gdalBuf.buffShort[pos]);
854
                                                }
855
                                                pos ++;
856
                                        }
857
                                }
858
                        }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){
859
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
860
                                        pos = (int)((bufWidth * line) + init);
861
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
862
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
863
                                                        buf.setElemInt(line, col, drawableBands[drawBands], gdalBuf.buffInt[pos]);
864
                                                }
865
                                                pos ++;
866
                                        }
867
                                }
868
                        }else if(dataType == Gdal.GDT_Float32){
869
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
870
                                        pos = (int)((bufWidth * line) + init);
871
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
872
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
873
                                                        buf.setElemFloat(line, col, drawableBands[drawBands], gdalBuf.buffFloat[pos]);
874
                                                }
875
                                                pos ++;
876
                                        }
877
                                }
878
                        }else if(dataType == Gdal.GDT_Float64){
879
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
880
                                        pos = (int)((bufWidth * line) + init);
881
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
882
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
883
                                                        buf.setElemDouble(line, col, drawableBands[drawBands], gdalBuf.buffDouble[pos]);
884
                                                }
885
                                                pos ++;
886
                                        }
887
                                }
888
                        }
889
                }
890
        }
891

    
892

    
893
        /**
894
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
895
         * @param buf Buffer donde se almacenan los datos
896
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
897
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
898
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
899
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
900
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
901
         * @param nWidth Ancho en pixeles del buffer
902
         * @param nHeight Alto en pixeles del buffer
903
         * @throws GdalException
904
         */
905
        public void readWindowWithNoData(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY,double dWorldBRX, double dWorldBRY,
906
                                            int nWidth, int nHeight) throws GdalException {
907
                Extent petExtent = new Extent(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY);
908
                if(dWorldTLX < bBoxWithoutRot.minX)
909
                        dWorldTLX = bBoxWithoutRot.minX;
910
                if(dWorldTLY > bBoxWithoutRot.maxY)
911
                        dWorldTLY = bBoxWithoutRot.maxY;
912
                if(dWorldBRX > bBoxWithoutRot.maxX)
913
                        dWorldBRX = bBoxWithoutRot.maxX;
914
                if(dWorldBRY < bBoxWithoutRot.minY)
915
                        dWorldBRY = bBoxWithoutRot.minY;
916
                setView(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, new boolean[]{true, false});
917
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
918

    
919
                if(gdalBands.length == 0)
920
                        return;
921

    
922
                selectGdalBands(buf.getBandCount());
923

    
924
        int x = (int) tl.getX();
925
        int y = (int) tl.getY();
926

    
927
        int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
928
        //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
929
        //ya que lo que cae fuera ser?n valores NoData
930

    
931
        int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
932
        if(x < 0)
933
                x  = 0;
934
        if(y < 0)
935
                y  = 0;
936
        readData(buf, bandList, x, y, wh[0], wh[1], wh[0], wh[1], 0, 0, stpBuffer);
937
        }
938

    
939
        /**
940
         * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede estar ajustada a la extensi?n del raster
941
         * o no estarlo. En caso de no estarlo los pixeles del buffer que caen fuera de la extensi?n del raster tendr?n valor
942
         * de NoData. Esta funci?n calcula en que pixel del buffer hay que empezar a escribir en caso de que este sea mayor
943
         * que los datos a leer.
944
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
945
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
946
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
947
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
948
         * @param nWidth Ancho en pixeles del buffer
949
         * @param nHeight Alto en pixeles del buffer
950
         * @return desplazamiento dentro del buffer en X e Y
951
         */
952
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer){
953
            Extent imageExtent = new Extent(bBoxWithoutRot.minX, bBoxWithoutRot.minY, bBoxWithoutRot.maxX, bBoxWithoutRot.maxY);
954
            Extent ajustDataExtent = Utilities.calculateAdjustedView(dataExtent, imageExtent);
955
            if(!Utilities.compareExtents(dataExtent, ajustDataExtent)){
956
                    Point2D p1 = worldToRaster(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
957
                    Point2D p2 = worldToRaster(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
958
                    Point2D p3 = worldToRaster(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
959
                    Point2D p4 = worldToRaster(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
960
                    //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
961
                    int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX()));
962
                    int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
963

    
964
                    stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
965
                    stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
966
                    stpBuffer[2] = stpBuffer[0] + w;
967
                    stpBuffer[3] = stpBuffer[1] + h;
968
                    return new int[]{w, h};
969
            }
970
            return new int[]{nWidth, nHeight};
971
        }
972

    
973
        /**
974
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
975
         * @param nbands N?mero de bandas solicitado.
976
         * @throws GdalException
977
         */
978
        public void selectGdalBands(int nbands)throws GdalException{
979
                gdalBands = new GdalRasterBand[nbands];
980
                //Selecciona las bandas y los overviews necesarios
981
                gdalBands[0] = getRasterBand(1);
982
                for(int i = 0; i < nbands; i++)
983
                        gdalBands[i] = gdalBands[0];
984

    
985
                setDataType(gdalBands[0].getRasterDataType());
986

    
987
                for(int i = 2; i <= nbands; i++){
988
                        if(getRasterCount() >= i){
989
                                gdalBands[i - 1] = getRasterBand(i);
990
                                for(int j = i; j < nbands; j++)
991
                                        gdalBands[j] = gdalBands[i - 1];
992
                        }
993
                }
994

    
995
                if (currentOverview > 0) {
996
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
997
                        for(int i = 2; i <= nbands; i++){
998
                                if(getRasterCount() >= i)
999
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
1000
                        }
1001
                }
1002
        }
1003

    
1004
        /**
1005
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
1006
         * @param buf Buffer donde se almacenan los datos
1007
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1008
         * @param x Posici?n X en pixeles
1009
         * @param y Posici?n Y en pixeles
1010
         * @param w Ancho en pixeles
1011
         * @param h Alto en pixeles
1012
         * @throws GdalException
1013
         */
1014
        public void readWindow(RasterBuf buf, BandList bandList, int x, int y, int w, int h) throws GdalException {
1015
        GdalBuffer gdalBuf = null;
1016
                gdalBands = new GdalRasterBand[getRasterCount()];
1017
                isSupersampling = false;
1018
                if(gdalBands.length == 0)
1019
                        return;
1020

    
1021
                // Selecciona las bandas
1022
                gdalBands[0] = getRasterBand(1);
1023
                setDataType(gdalBands[0].getRasterDataType());
1024
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
1025
                        gdalBands[iBand] = getRasterBand(iBand + 1);
1026

    
1027
                int yMax = y + h;
1028
                readData(buf, bandList, x, y, w, yMax);
1029
        }
1030

    
1031
        /**
1032
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1033
         * readWindow para coordenadas reales y readWindow en coordenadas pixel.
1034
         * @param buf Buffer donde se almacenan los datos
1035
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1036
         * @param x Posici?n X en pixeles
1037
         * @param y Posici?n Y en pixeles
1038
         * @param w Ancho en pixeles
1039
         * @param yMax altura m?xima de y
1040
         * @throws GdalException
1041
         */
1042
        private void readData(RasterBuf buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException {
1043
                GdalBuffer gdalBuf = null;
1044
                int rasterBufLine;
1045
                for(int iBand = 0; iBand < gdalBands.length; iBand++){
1046
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
1047
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1048
                                continue;
1049
                        if(dataType == Gdal.GDT_Byte){
1050
                                for (int line = y; line < yMax; line++) {
1051
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1052
                                        rasterBufLine = line - y;
1053
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1054
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[drawBands]);
1055
                                }
1056
                        }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){
1057
                                for (int line = y; line < yMax; line++) {
1058
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1059
                                        rasterBufLine = line - y;
1060
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1061
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[drawBands]);
1062
                                }
1063
                        }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){
1064
                                for (int line = y; line < yMax; line++) {
1065
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1066
                                        rasterBufLine = line - y;
1067
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1068
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[drawBands]);
1069
                                }
1070
                        }else if(dataType == Gdal.GDT_Float32){
1071
                                for (int line = y; line < yMax; line++) {
1072
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1073
                                        rasterBufLine = line - y;
1074
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1075
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[drawBands]);
1076
                                }
1077
                        }else if(dataType == Gdal.GDT_Float64){
1078
                                for (int line = y; line < yMax; line++) {
1079
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1080
                                        rasterBufLine = line - y;
1081
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1082
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[drawBands]);
1083
                                }
1084
                        }
1085
                }
1086
        }
1087

    
1088
        /* (non-Javadoc)
1089
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
1090
         */
1091
        public Object[] getData(int x, int y) {
1092
                try {
1093
                        Object[] data = new Object[getRasterCount()];
1094
                        for(int i = 0; i < getRasterCount(); i++){
1095
                                GdalRasterBand rb = getRasterBand(i + 1);
1096
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType);
1097
                                switch(dataType){
1098
                                case 0:        break;                                                                        //Sin tipo
1099
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1100
                                                break;
1101
                                case 2:                                                                                        //Buffer short (16)
1102
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1103
                                                break;
1104
                                case 4:                                                                                        //Buffer int (32)
1105
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1106
                                                break;
1107
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1108
                                                break;
1109
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1110
                                                break;
1111
                                }
1112
                        }
1113
                        return data;
1114
                } catch (GdalException e) {
1115
                        return null;
1116
                }
1117
        }
1118

    
1119
        void pintaInfo() {
1120
                try {
1121
                        //System.out.println("Origin = "+originX+","+originY);
1122
                        //System.out.println("Origin = "+this.);
1123
                        System.out.println("GeoTransform:");
1124
                        GeoTransform trans = getGeoTransform();
1125
                        for (int i=0; i<6; i++)
1126
                                System.out.println("  param["+i+"]="+trans.adfgeotransform[i]);
1127
                        System.out.println("Metadata:");
1128
                        String [] metadata = getMetadata();
1129
                        for (int i=0; i<metadata.length; i++) {
1130
                                System.out.println(metadata[i]);
1131
                        }
1132
                } catch (GdalException e) {
1133

    
1134
                }
1135

    
1136
        }
1137

    
1138
        void pintaPaleta() {
1139
        }
1140

    
1141
        public int getBlockSize(){
1142
                return this.getBlockSize();
1143
        }
1144

    
1145
        /**
1146
         * Obtiene el objeto que contiene los metadatos
1147
         */
1148
        public Metadata getMetadataJavaObject() {
1149
                return metadata;
1150
        }
1151

    
1152
        /**
1153
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1154
         * @return true si est? georreferenciada y false si no lo est?.
1155
         */
1156
        public boolean isGeoreferenced() {
1157
                return georeferenced;
1158
        }
1159

    
1160
}
1161

    
1162

    
1163