Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1006 / libraries / libCq_CMS_praster / src / org / cresques / io / GdalFile.java @ 12458

History | View | Annotate | Download (67.8 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.Image;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.NoninvertibleTransformException;
29
import java.awt.geom.Point2D;
30
import java.awt.geom.Rectangle2D;
31
import java.awt.image.BufferedImage;
32
import java.io.IOException;
33
import java.util.Vector;
34

    
35
import org.cresques.cts.ICoordTrans;
36
import org.cresques.cts.IProjection;
37
import org.cresques.io.data.BandList;
38
import org.cresques.io.data.RasterBuf;
39
import org.cresques.io.datastruct.Metadata;
40
import org.cresques.io.datastruct.Palette;
41
import org.cresques.io.exceptions.NotSupportedExtensionException;
42
import org.cresques.io.exceptions.SupersamplingNotSupportedException;
43
import org.cresques.px.Extent;
44
import org.cresques.util.Utilities;
45

    
46
import es.gva.cit.jgdal.Gdal;
47
import es.gva.cit.jgdal.GdalBuffer;
48
import es.gva.cit.jgdal.GdalException;
49
import es.gva.cit.jgdal.GdalRasterBand;
50
import es.gva.cit.jgdal.GeoTransform;
51

    
52
/**
53
 * Soporte 'nativo' para ficheros desde GDAL.
54
 * Este conjunto de funcionalidades est? tomado de manera casi literal
55
 * del soporte para ECW de ermapper.<br>
56
 * Probablemente esto deber?a formar parte del JNI que recubre a la
57
 * librer?a en C extraida de gdal.<br>
58
 * Lo pongo aqu? a manera de ejemplo de como atacar un formato binario
59
 * desde Java.<br><br>   
60
 * @author Luis W. Sevilla.
61
 */
62

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

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

    
195
                //Upper left corner
196
                bBoxRot.add(new Point2D.Double(trans.adfgeotransform[0], trans.adfgeotransform[3]));
197

    
198
                //Lower left corner
199
                geoX = trans.adfgeotransform[0] +  trans.adfgeotransform[2] * height;
200
                geoY = trans.adfgeotransform[3] +  trans.adfgeotransform[5] * height;
201
                bBoxRot.add(new Point2D.Double(geoX, geoY));
202
                
203
                //Upper right corner
204
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width;
205
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width;
206
                bBoxRot.add(new Point2D.Double(geoX, geoY));
207
                
208
                //Lower right corner
209
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width + trans.adfgeotransform[2] * height;
210
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width + trans.adfgeotransform[5] * height;
211
                bBoxRot.add(new Point2D.Double(geoX, geoY));
212
                
213
                //TODO: ?OJO! con coordenadas geogr?ficas
214
        }
215
        
216
        /**
217
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
218
         * el tama?o de pixel y la rotaci?n. 
219
         */
220
        private void boundingBoxWithoutRotation(){
221
                double ox = trans.adfgeotransform[0];
222
                double oy = trans.adfgeotransform[3];
223
                double resx = trans.adfgeotransform[1];
224
                double resy = trans.adfgeotransform[5];
225
                                
226
                bBoxWithoutRot.add(new Point2D.Double(ox, oy));
227
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy));
228
                bBoxWithoutRot.add(new Point2D.Double(ox, oy + resy * height));
229
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy + resy * height));
230

    
231
                //TODO: ?OJO! con coordenadas geogr?ficas
232
        }
233
        
234
        private void init(String fName) throws GdalException, IOException {
235
                fileName = fName;
236
                open(fName,GA_ReadOnly);
237
                ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
238
                if (ext.compareTo("tif") == 0)
239
                        WITH_OVERVIEWS = false;
240
                width = getRasterXSize();
241
                height = getRasterYSize();
242
                setDataType(this.getRasterBand(1).getRasterDataType());
243
                shortName = getDriverShortName();
244
                metadata = new Metadata(getMetadata());
245
                
246
                //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
247
                //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
248
                metadata.initColorInterpretation(getRasterCount());
249
                metadata.initNoDataByBand(getRasterCount());
250
            for(int i = 0; i < getRasterCount(); i++){
251
                    GdalRasterBand rb = getRasterBand(i + 1);
252
                    String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
253
                    metadata.setNoDataValue(i, rb.getRasterNoDataValue());
254
                    metadata.setColorInterpValue(i, colorInt);
255
                    if(colorInt.equals("Red"))
256
                            rBandNr = i + 1;
257
                    if(colorInt.equals("Green"))
258
                            gBandNr = i + 1;        
259
                    if(colorInt.equals("Blue"))
260
                            bBandNr = i + 1;                
261
                    if(colorInt.equals("Alpha"))
262
                            aBandNr = i + 1;
263
            }
264
            
265
                try{
266
                        trans = getGeoTransform();
267
                        
268
                        boolean isCorrect = false;
269
                        for(int i = 0; i < trans.adfgeotransform.length; i++)
270
                                if(trans.adfgeotransform[i] != 0)
271
                                        isCorrect = true;
272
                        if(!isCorrect)
273
                                throw new GdalException("");
274
                        
275
                        boundingBoxWithoutRotation();
276
                        boundingBoxFromGeoTransform();
277
                                                
278
                        this.georeferenced = true;
279
                }catch(GdalException exc){
280
                        bBoxRot.add(new Point2D.Double(0, 0));
281
                        bBoxRot.add(new Point2D.Double(width, 0));
282
                        bBoxRot.add(new Point2D.Double(0, height));
283
                        bBoxRot.add(new Point2D.Double(width, height));                
284
                        bBoxWithoutRot = bBoxRot;
285
                        this.georeferenced = false;
286
                }
287
                readPalette();        
288
        }
289
        
290
        public void readPalette(){
291
                //Cargamos la tabla de color si la tiene
292
                try{
293
                        gdalBands = new GdalRasterBand[1];
294
                        gdalBands[0] = getRasterBand(1);
295
                if(gdalBands[0] != null && gdalBands[0].getRasterColorTable() != null){
296
                        Palette palette = new Palette();
297
                        palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
298
                        driver.setPalette(palette);
299
                }
300
                }catch(GdalException exc){
301
                        //No cargamos la tabla de color
302
                }
303
        }
304
        
305
        /**
306
         * Asigna el valor de Alpha
307
         * @param a
308
         */
309
        public void setAlpha(int a) { 
310
                alpha = a; 
311
        }
312
        
313
        /**
314
         * Asigna el tipo de dato
315
         * @param dt entero que representa el tipo de dato
316
         */
317
        public void setDataType(int dt) { 
318
                dataType = dt; 
319
        }
320
        
321
        /**
322
         * Obtiene el tipo de dato
323
         * @return entero que representa el tipo de dato
324
         */
325
        public int getDataType() { 
326
                return dataType; 
327
        }
328
                
329
        // Supone rasters no girados
330
        public Point2D worldToRaster(Point2D pt) {
331
                double x = (((double) currentFullWidth) / (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) * (pt.getX() - bBoxWithoutRot.minX);
332
                double y = (((double) currentFullHeight) / (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) * (bBoxWithoutRot.maxY - pt.getY());
333
                Point2D ptRes = new Point2D.Double(x, y);
334
                return ptRes;
335
        }
336
        
337
        /**
338
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
339
         * viewPortScale, currentFullWidth y currentFulHeight
340
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
341
         * @throws GdalException
342
         */
343
        private void calcOverview(Point2D tl, Point2D br, boolean[] orientation) throws GdalException{
344
                gdalBands[0] = getRasterBand(1);
345
                currentOverview = -1;
346
                if (WITH_OVERVIEWS && gdalBands[0].getOverviewCount() > 0) {
347
                        GdalRasterBand ovb = null;
348
                        for (int i = gdalBands[0].getOverviewCount()-1; i > 0; i--) {              
349
                                ovb = gdalBands[0].getOverview(i);
350
                                if (ovb.getRasterBandXSize()>getRasterXSize()*viewportScaleX) {
351
                                        currentOverview = i;
352
                            viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
353
                            viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
354
                            stepX = 1D/viewportScaleX;
355
                            stepY = 1D/viewportScaleY;
356
                            currentFullWidth = ovb.getRasterBandXSize();
357
                            currentFullHeight = ovb.getRasterBandYSize();
358
                            if(!orientation[0])//Invierte la orientaci?n en X
359
                                    currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
360
                            else
361
                                    currentViewX = tl.getX();
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
                            break;
367
                                }
368
                        }
369
                }
370
        }
371
        
372
        public void setView(double dWorldTLX, double dWorldTLY,
373
            double dWorldBRX, double dWorldBRY,
374
            int nWidth, int nHeight, boolean[] orientation) {
375
                this.orientation = orientation;
376
                currentFullWidth = width;
377
                currentFullHeight = height;
378
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
379
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
380
                // Calcula cual es la primera l?nea a leer;
381
                currentViewWidth = nWidth;
382
                currentViewHeight = nHeight;
383
                wcWidth = Math.abs(br.getX() - tl.getX());
384
                
385
                if(!orientation[0]) //Invierte la orientaci?n en X
386
                        currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
387
                else
388
                        currentViewX = tl.getX();
389
                
390
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
391
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
392
                stepX = 1D/viewportScaleX;
393
                stepY = 1D/viewportScaleY;
394
                                                
395
                if(orientation[1])//Invierte la orientaci?n en Y
396
                        lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
397
                else
398
                        lastReadLine = tl.getY();
399
                
400
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
401
                try {
402
                        // calcula el overview a usar
403
                        gdalBands = new GdalRasterBand[4];
404
                        calcOverview(tl, br, orientation);
405
                        calcArraySteps();
406
                                                                                                    
407
                        // Selecciona las bandas y los overviews necesarios
408
                        gdalBands[0] = getRasterBand(rBandNr);
409
                        gdalBands[1] = gdalBands[0]; 
410
                        gdalBands[2] = gdalBands[1]; 
411
                        setDataType(gdalBands[0].getRasterDataType());
412
                        if(this.getRasterCount() >= 2) {
413
                                gdalBands[1] = getRasterBand(gBandNr);
414
                                gdalBands[2] = gdalBands[1]; 
415
                        }
416
                        if(this.getRasterCount() >= 3) 
417
                                gdalBands[2] = getRasterBand(bBandNr);
418
                        if(metadata.isAlphaBand())
419
                                gdalBands[3] = getRasterBand(aBandNr);                        
420
                        
421
                        
422
                        if (currentOverview > 0) {
423
                                gdalBands[0] = gdalBands[0].getOverview(currentOverview);
424
                                gdalBands[1] = gdalBands[0]; 
425
                                gdalBands[2] = gdalBands[1];
426
                                if(this.getRasterCount() >= 2) {
427
                                        gdalBands[1] = gdalBands[1].getOverview(currentOverview);
428
                                        gdalBands[2] = gdalBands[1]; 
429
                                }
430
                                if(this.getRasterCount() >= 3) 
431
                                        gdalBands[2] = gdalBands[2].getOverview(currentOverview);
432
                                if(metadata.isAlphaBand())
433
                                        gdalBands[3] = gdalBands[3].getOverview(currentOverview);                        
434
                                
435
                        }
436
                        
437
                } catch (GdalException e) {
438
                        e.printStackTrace();
439
                }
440
        }
441
        
442
        /**
443
         * Esta funci?n calcula los arrays de steps en X e Y para que cuando hay supersampleo 
444
         * se aplique el filtro solo a la esquina superior izquierda de cada pixel. 
445
         */
446
        private void calcArraySteps(){
447
                if(stepX < 1 && stepY < 1){
448
                        isSupersampling = true;
449
                        int w = (int) (Math.ceil(((double)currentViewWidth) * stepX) + 1);
450
                        this.stepArrayX = new int[w];
451
                        for (double j =  Math.abs(currentViewX - ((int)currentViewX)); j < w; j += stepX) 
452
                                        stepArrayX[(int)(j)] ++;
453
                                                        
454
                        int h = (int) (Math.ceil(((double)currentViewHeight) * stepY) + 1);
455
                        this.stepArrayY = new int[h];
456
                        for (double j =  Math.abs(lastReadLine - ((int)lastReadLine)); j < h; j += stepY) 
457
                                stepArrayY[(int)(j)] ++;
458
                }else{
459
                        isSupersampling = false;
460
                        this.stepArrayX = this.stepArrayY = null;
461
                }
462
        }
463
        
464
        int lastY = -1;
465
        
466
        /**
467
         * Lee una l?nea de bytes
468
         * @param line Buffer donde se cargan los datos
469
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
470
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
471
         * por la izquierda a mitad de pixel
472
         * @param gdalBuffer Buffer con la l?nea de datos original
473
         */
474
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer){
475
                double j = 0D;
476
                  int i = 0;
477
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
478
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
479
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
480
                        }
481
                }
482
        }
483
        
484
        /**
485
         * Lee una l?nea de shorts
486
         * @param line Buffer donde se cargan los datos
487
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
488
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
489
         * por la izquierda a mitad de pixel
490
         * @param gdalBuffer Buffer con la l?nea de datos original
491
         */
492
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer){
493
                  double j = 0D; 
494
                  int i = 0;
495
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
496
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
497
                                line[iBand][i] = (short)(gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
498
                        }
499
                }
500
        }
501

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

    
520
        /**
521
         * Lee una l?nea de float
522
         * @param line Buffer donde se cargan los datos
523
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
524
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
525
         * por la izquierda a mitad de pixel
526
         * @param gdalBuffer Buffer con la l?nea de datos original
527
         */
528
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer){
529
                double j = 0D;
530
                  int i = 0;
531
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
532
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
533
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
534
                        }
535
                }
536
        }
537
        
538
        /**
539
         * Lee una l?nea de doubles
540
         * @param line Buffer donde se cargan los datos
541
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
542
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
543
         * por la izquierda a mitad de pixel
544
         * @param gdalBuffer Buffer con la l?nea de datos original
545
         */
546
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer){
547
                double j = 0D;
548
                  int i = 0;
549
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
550
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
551
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
552
                        }
553
                }
554
        }
555
        
556
        public void readLine(Object line) throws GdalException {
557
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
558
        int x = (int) (currentViewX);
559
        int y = (int) (lastReadLine);
560
        GdalBuffer r = null, g = null, b = null;
561
        GdalBuffer a = new GdalBuffer();
562
        
563
        while(y >= gdalBands[0].getRasterBandYSize())
564
                y--;
565
        
566
        if (x+w > gdalBands[0].getRasterBandXSize()) 
567
                w = gdalBands[0].getRasterBandXSize()-x;
568
        
569
        if(gdalBands[0].getRasterColorTable() != null){
570
                /*Palette palette = new Palette();
571
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
572
                driver.setPalette(palette);*/
573
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
574
        }else{
575
                a.buffByte = new byte[w];
576
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
577
                        g = b = r;
578
                        if (getRasterCount() > 1 && gdalBands[1] != null)
579
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType);
580
                        if (getRasterCount() > 2 && gdalBands[2] != null)
581
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType);
582
        }
583
                          
584
        lastReadLine += stepY;
585
        
586
                  double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
587
                  GdalBuffer[] bands = {r, g, b};
588
                                    
589
                  if (dataType == GDT_Byte)
590
                          readLine((byte[][])line, initOffset, bands);
591
                else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16)
592
                        readLine((short[][])line, initOffset, bands);
593
                else if (dataType == GDT_CInt32 || dataType == GDT_Int32  || dataType == GDT_UInt32)
594
                        readLine((int[][])line, initOffset, bands);
595
                  else if(dataType == GDT_Float32 || dataType == GDT_CFloat32)
596
                          readLine((float[][])line, initOffset, bands);
597
                  else if(dataType == GDT_Float64 || dataType == GDT_CFloat64)
598
                          readLine((double[][])line, initOffset, bands);
599
          
600
                return;
601
        }
602
        
603
        /**
604
         * Lee una l?nea y la guarda cada elemento sobre un entero. Este entero representa
605
         * un valor ARGB
606
         * @param line Buffer sobre el que se escribe la linea
607
         * @return 
608
         * @throws GdalException
609
         */
610
        int readLineRGBA(int[] line) throws GdalException {
611
                int err = 0;
612
                
613
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
614
        int x = (int) currentViewX;
615
        int y = (int) lastReadLine;
616
        GdalBuffer r = null, g = null, b = null, p = null;
617
        GdalBuffer a = new GdalBuffer();
618
        
619
        while(y >= gdalBands[0].getRasterBandYSize())
620
                y--;
621
        
622
        if (x+w > gdalBands[0].getRasterBandXSize()) 
623
                w = gdalBands[0].getRasterBandXSize()-x;
624
        
625
        if(gdalBands[0].getRasterColorTable() != null){
626
                /*Palette palette = new Palette();
627
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
628
                driver.setPalette(palette);*/
629
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
630
        }else{
631
                
632
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
633
                g = b = r;
634
                        if (getRasterCount() > 1 && gdalBands[1] != null)
635
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType);
636
                        if (getRasterCount() > 2 && gdalBands[2] != null)
637
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType);
638
                
639
                if(metadata.isAlphaBand()){
640
                        a = gdalBands[3].readRaster(x, y, w, 1, w, 1, GDT_Byte);        
641
                }else{
642
                            a.buffByte = new byte[w];
643
                            for (int i = 0;i < w;i++)
644
                                    a.buffByte[i] = (byte)255;
645
                }
646
        }
647
                  lastReadLine += stepY;
648
                  
649
                  int i=0;
650
                  double j =  Math.abs(currentViewX - ((int)currentViewX));
651
                int alpha = (this.alpha & 0xff) << 24;
652
                
653
                if(orientation[0]){ //Pixel size en X positivo
654
                        if (dataType == GDT_Byte){
655
                                  if(gdalBands[0].getRasterColorTable() != null){
656
                                          for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
657
                                              int jInt = (int)(j);
658
                                              line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
659
                                      }
660
                                  }else{
661
                                          for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
662
                                              int jInt = (int)(j);
663
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
664
                                      }
665
                                  }
666
                          }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
667
                                  if (g == null) // Sibgle Band (Typical DEM)
668
                                            for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
669
                                                    int jInt = (int)(j);
670
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
671
                                      }
672
                                  else { // Multiband
673
                                          // System.err.println("Raster 16bits multibanda");
674
                                      for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
675
                                              int jInt = (int)(j);
676
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | 
677
                                                                                                                                   (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
678
                                                                                                                                   (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
679
                                      }
680
                                  }
681
                          }
682
                }else{ //Pixel size en X negativo
683
                        if (dataType == GDT_Byte){
684
                                  if(gdalBands[0].getRasterColorTable() != null){
685
                                          for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX)  {
686
                                              int jInt = (int)(j);
687
                                              line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
688
                                      }
689
                                  }else{
690
                                          for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX)  {
691
                                              int jInt = (int)(j);
692
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
693
                                      }
694
                                  }
695
                          }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
696
                                  if (g == null) // Sibgle Band (Typical DEM)
697
                                            for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
698
                                                    int jInt = (int)(j);
699
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
700
                                      }
701
                                  else { // Multiband
702
                                          // System.err.println("Raster 16bits multibanda");
703
                                      for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
704
                                              int jInt = (int)(j);
705
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | 
706
                                                                                                                                   (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
707
                                                                                                                                   (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
708
                                      }
709
                                  }
710
                          }                        
711
                }
712
                return err;
713
        }
714
                
715
        /**
716
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
717
         * @param buf Buffer donde se almacenan los datos
718
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
719
         * @param dWorldTLX Posici?n X en pixeles
720
         * @param dWorldTLY Posici?n Y en pixeles
721
         * @param w Ancho en pixeles
722
         * @param h Alto en pixeles
723
         * @throws GdalException
724
         */
725
        public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY,
726
                                            int nWidth, int nHeight) throws GdalException {
727
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
728

    
729
                gdalBands = new GdalRasterBand[getRasterCount()];
730
                isSupersampling = false;
731
                if(gdalBands.length == 0)
732
                        return;
733
                
734
                try {                        
735
                        // Selecciona las bandas
736
                        gdalBands[0] = getRasterBand(1);
737
                        setDataType(gdalBands[0].getRasterDataType());
738
                        for(int iBand = 1; iBand < gdalBands.length; iBand++)
739
                                gdalBands[iBand] = getRasterBand(iBand + 1);
740
                        
741
                } catch (GdalException e) {
742
                        e.printStackTrace();
743
                }
744
                
745
        int x = (int) Math.ceil(tl.getX());
746
        int y = (int) Math.ceil(tl.getY());
747
        
748
        if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
749
                nWidth = gdalBands[0].getRasterBandXSize() - x;
750
        
751
        if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
752
                nHeight = gdalBands[0].getRasterBandYSize() - y;
753
        
754
                int yMax = y + nHeight;
755
        readData(buf, bandList, x, y, nWidth, yMax);
756
        }
757
        
758
        /**
759
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
760
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
761
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
762
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de 
763
         * mayor tama?o que el n?mero de pixels solicitado.
764
         * 
765
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor 
766
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer 
767
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
768
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del 
769
         * raster de disco completos sino que en los bordes del buffer quedan cortados.  
770
         *  
771
         * @param buf Buffer donde se almacenan los datos
772
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
773
         * @param dWorldTLX Posici?n X en pixeles
774
         * @param dWorldTLY Posici?n Y en pixeles
775
         * @param nWidth Ancho en pixeles
776
         * @param nHeight Alto en pixeles
777
         * @param bufWidth Ancho del buffer
778
         * @param bufHeight Alto del buffer
779
         * @throws GdalException
780
         */
781
        public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY,
782
                                            double nWidth, double nHeight, int bufWidth, int bufHeight) throws GdalException {
783
                setView(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, bufWidth, bufHeight, new boolean[]{true, false});
784
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
785
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
786
                
787
                if(gdalBands.length == 0)
788
                        return;
789
                
790
                selectGdalBands(buf.getBandCount());
791
                                
792
        int x = (int) tl.getX();
793
        int y = (int) tl.getY();
794
        int endX = (int) Math.ceil(br.getX());
795
        int endY = (int) Math.ceil(br.getY());
796
                
797
        int stpX = 0;
798
        int stpY = 0;
799
        
800
                if(bufWidth > Math.ceil(nWidth)){
801
                        stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
802
                        bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth);
803
                }
804
                if(bufHeight > Math.ceil(nHeight)){
805
                        stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
806
                        bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight);
807
                }
808
                        
809
        nWidth = (int)Math.abs(endX - x);
810
        nHeight = (int)Math.abs(endY - y);
811
        
812
        if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
813
                nWidth = gdalBands[0].getRasterBandXSize() - x;
814
        
815
        if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
816
                nHeight = gdalBands[0].getRasterBandYSize() - y;
817
        
818
        int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
819
                readData(buf, bandList, x, y, (int)nWidth, (int)nHeight, bufWidth, bufHeight, stpX, stpY, stpBuffer);
820
        }
821
                
822
        /**
823
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
824
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
825
         * @param buf Buffer donde se almacenan los datos
826
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
827
         * @param x Posici?n X en pixeles
828
         * @param y Posici?n Y en pixeles
829
         * @param w Ancho en pixeles
830
         * @param yMax altura m?xima de y
831
         * @throws GdalException
832
         */
833
        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 {
834
                //TODO: FUNCIONALIDAD: Orientaci?n del raster. orientaion[0] para pixels en X y orientation[1] para pixels en Y
835
                GdalBuffer gdalBuf = null;
836
                for(int iBand = 0; iBand < gdalBands.length; iBand++){
837
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
838
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
839
                                continue;        
840
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
841
                        int pos = init;
842
                        gdalBuf = gdalBands[iBand].readRaster(x, y, w, h, bufWidth, bufHeight, dataType);
843
                        if(dataType == Gdal.GDT_Byte){
844
                                for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
845
                                        pos = (int)((bufWidth * line) + init);
846
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++){
847
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
848
                                                        buf.setElemByte(line, col, drawableBands[drawBands], gdalBuf.buffByte[pos]);
849
                                                }
850
                                                pos ++;
851
                                        }
852
                                }
853
                        }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){
854
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
855
                                        pos = (int)((bufWidth * line) + init);
856
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
857
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
858
                                                        buf.setElemShort(line, col, drawableBands[drawBands], gdalBuf.buffShort[pos]);
859
                                                }
860
                                                pos ++;
861
                                        }
862
                                }
863
                        }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){
864
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
865
                                        pos = (int)((bufWidth * line) + init);
866
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
867
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
868
                                                        buf.setElemInt(line, col, drawableBands[drawBands], gdalBuf.buffInt[pos]);
869
                                                }
870
                                                pos ++;
871
                                        }
872
                                }
873
                        }else if(dataType == Gdal.GDT_Float32){
874
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
875
                                        pos = (int)((bufWidth * line) + init);
876
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
877
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
878
                                                        buf.setElemFloat(line, col, drawableBands[drawBands], gdalBuf.buffFloat[pos]);
879
                                                }
880
                                                pos ++;
881
                                        }
882
                                }
883
                        }else if(dataType == Gdal.GDT_Float64){
884
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
885
                                        pos = (int)((bufWidth * line) + init);
886
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++){
887
                                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){ //Una misma banda del raster puede ir dibujada en varias bandas del buffer.
888
                                                        buf.setElemDouble(line, col, drawableBands[drawBands], gdalBuf.buffDouble[pos]);
889
                                                }
890
                                                pos ++;
891
                                        }
892
                                }
893
                        }
894
                }
895
        }
896
        
897
        
898
        /**
899
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
900
         * @param buf Buffer donde se almacenan los datos
901
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
902
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
903
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
904
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
905
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
906
         * @param nWidth Ancho en pixeles del buffer
907
         * @param nHeight Alto en pixeles del buffer
908
         * @throws GdalException
909
         */
910
        public void readWindowWithNoData(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY,double dWorldBRX, double dWorldBRY,
911
                                            int nWidth, int nHeight) throws GdalException {
912
                Extent petExtent = new Extent(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY);
913
                if(dWorldTLX < bBoxWithoutRot.minX)
914
                        dWorldTLX = bBoxWithoutRot.minX;
915
                if(dWorldTLY > bBoxWithoutRot.maxY)
916
                        dWorldTLY = bBoxWithoutRot.maxY;
917
                if(dWorldBRX > bBoxWithoutRot.maxX)
918
                        dWorldBRX = bBoxWithoutRot.maxX;
919
                if(dWorldBRY < bBoxWithoutRot.minY)
920
                        dWorldBRY = bBoxWithoutRot.minY;
921
                setView(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY, nWidth, nHeight, new boolean[]{true, false});
922
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
923
                                
924
                if(gdalBands.length == 0)
925
                        return;
926
                
927
                selectGdalBands(buf.getBandCount());
928
                                
929
        int x = (int) tl.getX();
930
        int y = (int) tl.getY();
931
        
932
        int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
933
        //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
934
        //ya que lo que cae fuera ser?n valores NoData
935
        
936
        int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
937
        if(x < 0)
938
                x  = 0;
939
        if(y < 0)
940
                y  = 0;
941
        readData(buf, bandList, x, y, wh[0], wh[1], wh[0], wh[1], 0, 0, stpBuffer);
942
        }
943
        
944
        /**
945
         * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede estar ajustada a la extensi?n del raster
946
         * o no estarlo. En caso de no estarlo los pixeles del buffer que caen fuera de la extensi?n del raster tendr?n valor
947
         * de NoData. Esta funci?n calcula en que pixel del buffer hay que empezar a escribir en caso de que este sea mayor
948
         * que los datos a leer.
949
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
950
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
951
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
952
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
953
         * @param nWidth Ancho en pixeles del buffer
954
         * @param nHeight Alto en pixeles del buffer
955
         * @return desplazamiento dentro del buffer en X e Y
956
         */ 
957
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer){
958
            Extent imageExtent = new Extent(bBoxWithoutRot.minX, bBoxWithoutRot.minY, bBoxWithoutRot.maxX, bBoxWithoutRot.maxY);
959
            Extent ajustDataExtent = Utilities.calculateAdjustedView(dataExtent, imageExtent);
960
            if(!Utilities.compareExtents(dataExtent, ajustDataExtent)){
961
                    Point2D p1 = worldToRaster(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
962
                    Point2D p2 = worldToRaster(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
963
                    Point2D p3 = worldToRaster(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
964
                    Point2D p4 = worldToRaster(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
965
                    //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
966
                    int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
967
                    int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
968
                    
969
                    stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
970
                    stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
971
                    stpBuffer[2] = stpBuffer[0] + w; 
972
                    stpBuffer[3] = stpBuffer[1] + h;
973
                    return new int[]{w, h};
974
            }
975
            return new int[]{nWidth, nHeight};
976
        }
977
        
978
        /**
979
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
980
         * @param nbands N?mero de bandas solicitado.
981
         * @throws GdalException
982
         */
983
        public void selectGdalBands(int nbands)throws GdalException{
984
                gdalBands = new GdalRasterBand[nbands];
985
                //Selecciona las bandas y los overviews necesarios
986
                gdalBands[0] = getRasterBand(1);
987
                for(int i = 0; i < nbands; i++)
988
                        gdalBands[i] = gdalBands[0];
989
                 
990
                setDataType(gdalBands[0].getRasterDataType());
991
                
992
                for(int i = 2; i <= nbands; i++){
993
                        if(getRasterCount() >= i){
994
                                gdalBands[i - 1] = getRasterBand(i);
995
                                for(int j = i; j < nbands; j++)
996
                                        gdalBands[j] = gdalBands[i - 1];
997
                        }
998
                }
999
                                
1000
                if (currentOverview > 0) {
1001
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
1002
                        for(int i = 2; i <= nbands; i++){
1003
                                if(getRasterCount() >= i)
1004
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
1005
                        }
1006
                }
1007
        }
1008
        
1009
        /**
1010
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
1011
         * @param buf Buffer donde se almacenan los datos
1012
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1013
         * @param x Posici?n X en pixeles
1014
         * @param y Posici?n Y en pixeles
1015
         * @param w Ancho en pixeles
1016
         * @param h Alto en pixeles
1017
         * @throws GdalException
1018
         */
1019
        public void readWindow(RasterBuf buf, BandList bandList, int x, int y, int w, int h) throws GdalException {
1020
        GdalBuffer gdalBuf = null;
1021
                gdalBands = new GdalRasterBand[getRasterCount()];
1022
                isSupersampling = false;
1023
                if(gdalBands.length == 0)
1024
                        return;
1025
                
1026
                // Selecciona las bandas
1027
                gdalBands[0] = getRasterBand(1);
1028
                setDataType(gdalBands[0].getRasterDataType());
1029
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
1030
                        gdalBands[iBand] = getRasterBand(iBand + 1);
1031
                                        
1032
                int yMax = y + h;
1033
                readData(buf, bandList, x, y, w, yMax);
1034
        }
1035
        
1036
        /**
1037
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1038
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1039
         * @param buf Buffer donde se almacenan los datos
1040
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1041
         * @param x Posici?n X en pixeles
1042
         * @param y Posici?n Y en pixeles
1043
         * @param w Ancho en pixeles
1044
         * @param yMax altura m?xima de y
1045
         * @throws GdalException
1046
         */
1047
        private void readData(RasterBuf buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException {
1048
                GdalBuffer gdalBuf = null;
1049
                int rasterBufLine;
1050
                for(int iBand = 0; iBand < gdalBands.length; iBand++){
1051
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
1052
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1053
                                continue;        
1054
                        if(dataType == Gdal.GDT_Byte){
1055
                                for (int line = y; line < yMax; line++) {
1056
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1057
                                        rasterBufLine = line - y;
1058
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1059
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[drawBands]);
1060
                                }
1061
                        }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){
1062
                                for (int line = y; line < yMax; line++) {
1063
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1064
                                        rasterBufLine = line - y;
1065
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1066
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[drawBands]);
1067
                                }
1068
                        }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){
1069
                                for (int line = y; line < yMax; line++) {
1070
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1071
                                        rasterBufLine = line - y;
1072
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1073
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[drawBands]);
1074
                                }
1075
                        }else if(dataType == Gdal.GDT_Float32){
1076
                                for (int line = y; line < yMax; line++) {
1077
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1078
                                        rasterBufLine = line - y;
1079
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1080
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[drawBands]);
1081
                                }
1082
                        }else if(dataType == Gdal.GDT_Float64){
1083
                                for (int line = y; line < yMax; line++) {
1084
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
1085
                                        rasterBufLine = line - y;
1086
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
1087
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[drawBands]);
1088
                                }
1089
                        }
1090
                }
1091
        }
1092
        
1093
        /* (non-Javadoc)
1094
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
1095
         */
1096
        public Object[] getData(int x, int y) {
1097
                try {
1098
                        Object[] data = new Object[getRasterCount()];
1099
                        for(int i = 0; i < getRasterCount(); i++){
1100
                                GdalRasterBand rb = getRasterBand(i + 1);
1101
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType);
1102
                                switch(dataType){
1103
                                case 0:        break;                                                                        //Sin tipo
1104
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1105
                                                break;
1106
                                case 2:                                                                                        //Buffer short (16)
1107
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1108
                                                break;
1109
                                case 4:                                                                                        //Buffer int (32)
1110
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1111
                                                break;
1112
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1113
                                                break;
1114
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1115
                                                break;
1116
                                }
1117
                        }
1118
                        return data;
1119
                } catch (GdalException e) {
1120
                        return null;
1121
                }
1122
        }
1123
        
1124
        void pintaInfo() {
1125
                try {
1126
                        //System.out.println("Origin = "+originX+","+originY);
1127
                        //System.out.println("Origin = "+this.);
1128
                        System.out.println("GeoTransform:");
1129
                        GeoTransform trans = getGeoTransform();
1130
                        for (int i=0; i<6; i++)
1131
                                System.out.println("  param["+i+"]="+trans.adfgeotransform[i]);
1132
                        System.out.println("Metadata:");
1133
                        String [] metadata = getMetadata();
1134
                        for (int i=0; i<metadata.length; i++) {
1135
                                System.out.println(metadata[i]);
1136
                        }
1137
                } catch (GdalException e) {
1138
                        
1139
                }
1140
                
1141
        }
1142
        
1143
        void pintaPaleta() {
1144
        }
1145
        
1146
        public int getBlockSize(){
1147
                return this.getBlockSize();
1148
        }
1149

    
1150
        /**
1151
         * Obtiene el objeto que contiene los metadatos
1152
         */
1153
        public Metadata getMetadataJavaObject() {
1154
                return metadata;
1155
        }
1156

    
1157
        /**
1158
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1159
         * @return true si est? georreferenciada y false si no lo est?.
1160
         */
1161
        public boolean isGeoreferenced() {
1162
                return georeferenced;
1163
        }
1164
        
1165
}
1166

    
1167
/**
1168
 * @author Luis W. Sevilla
1169
 */
1170
public class GdalFile extends GeoRasterFile {
1171
        public final static int         BAND_HEIGHT = 64;
1172
        protected GdalNative                 file = null;
1173
        /**
1174
         * Tama?o de pixel para las imagenes con fichero RMF. No podemos salvarlo en file porque es necesario conocer el
1175
         * tama?o de pixel asignado por rl .rmf y el tama?o de pixel real.
1176
         */
1177
        private double                                pixelSizeX = 0D, pixelSizeY = 0D;
1178

    
1179
        private Extent v = null;
1180
        
1181
        public GdalFile(IProjection proj, String fName)throws NotSupportedExtensionException{
1182
                super(proj, fName);
1183
                extent = new Extent();
1184
                try {
1185
                        file = new GdalNative(fName, this);
1186
                        load();
1187
                        readGeoInfo(fName);
1188
                        bandCount = file.getRasterCount(); 
1189
                        if ( bandCount > 2) {
1190
                                setBand(RED_BAND,   0);
1191
                                setBand(GREEN_BAND, 1);
1192
                                setBand(BLUE_BAND,  2);
1193
                        } else
1194
                                setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);
1195
                } catch (GdalException e) {
1196
                        throw new NotSupportedExtensionException("Extension not supported");
1197
                } catch(Exception e){
1198
                          System.out.println("Error en GdalOpen");
1199
                          e.printStackTrace();
1200
                          file = null;
1201
                }
1202
                
1203
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
1204
                setDataType(org.cresques.util.Utilities.getRasterBufTypeFromGdalType(file.getDataType()));
1205
        }
1206
        
1207
        /**
1208
         * Obtenemos o calculamos el extent de la imagen.
1209
         */
1210
        public GeoFile load() {
1211
                extent = new Extent(file.bBoxRot.minX, file.bBoxRot.minY, file.bBoxRot.maxX, file.bBoxRot.maxY);
1212
                requestExtent = new Extent(file.bBoxWithoutRot.minX, file.bBoxWithoutRot.minY, file.bBoxWithoutRot.maxX, file.bBoxWithoutRot.maxY);
1213
                return this;
1214
        }
1215
        
1216
        /**
1217
         * Cierra el fichero de imagen
1218
         */
1219
        public void close() {
1220
                try {
1221
                        if(file != null){
1222
                                file.close();
1223
                                file = null;
1224
                        }
1225
                } catch (GdalException e) {
1226
                        // TODO Auto-generated catch block
1227
                        e.printStackTrace();
1228
                }
1229
        }
1230
        
1231
        /**
1232
         * Asigna a cada banda R,G o B una banda de la imagen
1233
         */
1234
        public void setBand(int flag, int bandNr) {
1235
                super.setBand(flag, bandNr);
1236
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) file.rBandNr = bandNr+1;
1237
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) file.gBandNr = bandNr+1;
1238
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) file.bBandNr = bandNr+1;
1239
        }
1240
        
1241
        /**
1242
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
1243
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
1244
         * ha de estar en coordenadas del fichero.
1245
         */
1246
        public void setView(Extent e) { 
1247
                if(rmfExists){
1248
                        
1249
                        Point2D.Double petInit = null, petEnd = null;
1250
                        try{
1251
                                petInit = new Point2D.Double(e.minX(),  e.maxY());
1252
                                petEnd = new Point2D.Double(e.maxX(), e.minY());
1253
                                transformRMF.inverseTransform(petInit, petInit);
1254
                                transformRMF.inverseTransform(petEnd, petEnd);
1255
                                transformTFW.transform(petInit, petInit);
1256
                                transformTFW.transform(petEnd, petEnd);
1257
                        }catch(NoninvertibleTransformException ex){}
1258
                        double h = file.bBoxWithoutRot.maxY - file.bBoxWithoutRot.minY;
1259
                        if(!file.isGeoreferenced())
1260
                                v = new Extent(        petInit.getX(), h - petInit.getY(), petEnd.getX(), h - petEnd.getY()); 
1261
                        else
1262
                                v = new Extent(        petInit.getX(), petInit.getY(), petEnd.getX(), petEnd.getY());
1263
                        
1264
                }else
1265
                        v = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());        
1266
        }
1267
                
1268
         /**
1269
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
1270
         * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo. De la
1271
         * misma forma calcula la matriz de transformaci?n de la cabecera del fichero o del world file asociado
1272
         * @param originX Origen de la imagen en la coordenada X
1273
         * @param originY Origen de la imagen en la coordenada Y
1274
         */
1275
        public void setExtentTransform(double originX, double originY, double psX, double psY) {                
1276
                transformRMF.setToTranslation(originX, originY);
1277
                transformRMF.scale(psX, psY);
1278
                
1279
                if(file.trans != null){        
1280
                        transformTFW.setToTranslation(file.trans.adfgeotransform[0], file.trans.adfgeotransform[3]);
1281
                        transformTFW.scale(file.trans.adfgeotransform[1], file.trans.adfgeotransform[5]);
1282
                }
1283
        }
1284
        
1285
        /**
1286
         * Obtiene extent de la vista actual
1287
         */
1288
        public Extent getView() { 
1289
                return v; 
1290
        }
1291
        
1292
        /**
1293
         * Obtiene la anchura del fichero
1294
         */
1295
        public int getWidth() {        
1296
                return file.width; 
1297
        }
1298
        
1299
        /**
1300
         * Obtiene la altura del fichero
1301
         */
1302
        public int getHeight() { 
1303
                return file.height;
1304
        }
1305

    
1306
        /* (non-Javadoc)
1307
         * @see org.cresques.io.GeoRasterFile#reProject(org.cresques.cts.ICoordTrans)
1308
         */
1309
        public void reProject(ICoordTrans rp) {
1310
                // TODO Auto-generated method stub
1311
        }
1312
        
1313
        /**
1314
         * Obtiene la orientaci?n de la imagen a partir del signo del tama?o de pixel para poder
1315
         * asignarlo en el setView. Esto es util para poder conocer como debe leerse la image, 
1316
         * de abajo a arriba, de arriba a abajo, de izquierda a derecha o de derecha a izquierda. 
1317
         * La posici?n habitual es la que el pixel size en X es positivo y en Y negativo leyendose 
1318
         * en este caso las X de menor a mayor y las Y de mayor a menor. Los casos posibles son:
1319
         * <UL>
1320
         * <LI><B>X > 0; Y < 0;</B> {true, false}</LI>
1321
         * <LI><B>X > 0; Y > 0;</B> {true, true}</LI>
1322
         * <LI><B>X < 0; Y > 0;</B> {false, true}</LI>
1323
         * <LI><B>X < 0; Y < 0;</B> {false, false}</LI>
1324
         * </UL>
1325
         *  
1326
         * @return
1327
         */
1328
        private boolean[] getOrientation(){
1329
                boolean[] orientation = {true, false};
1330
                if(!rmfExists){
1331
                        if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[5] > 0)
1332
                                orientation[1] = true;
1333
                        if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[1] < 0)
1334
                                orientation[0] = false;
1335
                }else{
1336
                        if(rmfTransform.getScaleY() > 0)
1337
                                orientation[1] = true;
1338
                        if(rmfTransform.getScaleX() < 0)
1339
                                orientation[0] = false;
1340
                }
1341
                return orientation;
1342
        }
1343
        
1344
        /* (non-Javadoc)
1345
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans)
1346
         */
1347
        public Image updateImage(int width, int height, ICoordTrans rp) {
1348
                int line, pRGBArray[] = null;
1349
                Image image = null;
1350
                        
1351
                if (mustVerifySize()) {
1352
                        // Work out the correct aspect for the setView call.
1353
                        double dFileAspect = (double)v.width()/(double)v.height();
1354
                        double dWindowAspect = (double)width /(double)height;
1355
        
1356
                        if (dFileAspect > dWindowAspect) {
1357
                          height =(int)((double)width/dFileAspect);
1358
                        } else {
1359
                          width = (int)((double)height*dFileAspect);
1360
                        }
1361
                }
1362
                
1363
                // Set the view
1364
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height, getOrientation());
1365
                setStep(file.stepArrayX, file.stepArrayY);
1366
                
1367
                if(width<=0)width=1;
1368
                if(height<=0)height=1;
1369
                
1370
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
1371
                //image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
1372
                pRGBArray = new int[width/**BAND_HEIGHT*/];
1373
                try {
1374
                        //int nLin = height % BAND_HEIGHT;
1375
                        file.setAlpha(getAlpha());
1376
                        setBand(RED_BAND,   rBandNr);
1377
                        setBand(GREEN_BAND, gBandNr);
1378
                        setBand(BLUE_BAND,  bBandNr);
1379
                        for (line=0; line < height; line++) { //+=BAND_HEIGHT) {
1380
                                //int bandH = Math.min(BAND_HEIGHT, height-line);
1381
                                //file.readBandRGBA(bandH, BAND_HEIGHT, pRGBArray);
1382
                                file.readLineRGBA(pRGBArray);
1383
                                setRGBLine((BufferedImage) image, 0, line, width, 1/*bandH*/, pRGBArray, 0, width);
1384
                        }
1385
                } catch (Exception e) {
1386
                        // TODO Auto-generated catch block
1387
                        e.printStackTrace();
1388
                }
1389
                
1390
                return image;
1391
        }
1392
        
1393
        public RasterBuf getRaster(int width, int height, ICoordTrans rp) {
1394
                int line;
1395
                RasterBuf raster = null;
1396
                        
1397
                if(mustVerifySize()){
1398
                        // Work out the correct aspect for the setView call.
1399
                        double dFileAspect = (double)v.width()/(double)v.height();
1400
                        double dWindowAspect = (double)width /(double)height;
1401
        
1402
                        if (dFileAspect > dWindowAspect) {
1403
                          height =(int)((double)width/dFileAspect);
1404
                        } else {
1405
                          width = (int)((double)height*dFileAspect);
1406
                        }
1407
                }
1408
                
1409
                // Set the view
1410
                boolean[] orientation = getOrientation();
1411
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
1412
                        width, height, orientation);
1413
                setStep(file.stepArrayX, file.stepArrayY);
1414
                
1415
                try {
1416
                        //Esta funci?n se usa para la renderizaci?n, por eso se crean 4 bandas a pi?on fijo
1417
                        raster = new RasterBuf(getDataType(), width, height, 4, true);
1418
                
1419
                        file.setAlpha(getAlpha());
1420
                        setBand(RED_BAND,   rBandNr);
1421
                        setBand(GREEN_BAND, gBandNr);
1422
                        setBand(BLUE_BAND,  bBandNr);
1423
                        
1424
                        switch(getDataType()){
1425
                        case RasterBuf.TYPE_BYTE: 
1426
                                for (line = 0; line < height; line++) 
1427
                                        file.readLine(raster.getLineByte(line));
1428
                                break;
1429
                        case RasterBuf.TYPE_SHORT:;        
1430
                                for (line = 0; line < height; line++) 
1431
                                        file.readLine(raster.getLineShort(line));
1432
                                break;
1433
                        case RasterBuf.TYPE_INT:
1434
                                for (line = 0; line < height; line++) 
1435
                                        file.readLine(raster.getLineInt(line));
1436
                                break;
1437
                        case RasterBuf.TYPE_FLOAT:
1438
                                for (line = 0; line < height; line++) 
1439
                                        file.readLine(raster.getLineFloat(line));
1440
                                break;
1441
                        case RasterBuf.TYPE_DOUBLE:
1442
                                for (line = 0; line < height; line++) 
1443
                                        file.readLine(raster.getLineDouble(line));
1444
                                break;
1445
                        case RasterBuf.TYPE_UNDEFINED:break;
1446
                        }
1447
                        
1448
                } catch (Exception e) {
1449
                        e.printStackTrace();
1450
                }
1451
                
1452
                return raster;
1453
        }
1454
        
1455
        /**
1456
         * Asigna al objeto Image los valores con los dato de la imagen contenidos en el 
1457
         * vector de enteros.
1458
         * @param image        imagen con los datos actuales
1459
         * @param startX        inicio de la posici?n en X dentro de la imagen
1460
         * @param startY        inicio de la posici?n en X dentro de la imagen
1461
         * @param w        Ancho de la imagen
1462
         * @param h        Alto de la imagen
1463
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1464
         * @param offset        desplazamiento
1465
         * @param scansize        tama?o de imagen recorrida por cada p
1466
         */
1467
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1468
                         int offset, int scansize) {
1469
                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
1470
        }
1471
        
1472
        /**
1473
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
1474
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
1475
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
1476
         * banda correspondiente a flags es sustituida por los datos del vector.
1477
         * @param image        imagen con los datos actuales
1478
         * @param startX        inicio de la posici?n en X dentro de la imagen
1479
         * @param startY        inicio de la posici?n en X dentro de la imagen
1480
         * @param w        Ancho de la imagen
1481
         * @param h        Alto de la imagen
1482
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1483
         * @param offset        desplazamiento
1484
         * @param scansize        tama?o de imagen recorrida por cada paso
1485
         * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
1486
         */
1487
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1488
                         int offset, int scansize, int flags) {
1489
                int [] line = new int[rgbArray.length]; 
1490
                image.getRGB(startX, startY, w, h, line, offset, scansize);
1491
                if (flags == GeoRasterFile.RED_BAND)
1492
                        for (int i=0; i<line.length; i++)
1493
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
1494
                else if (flags == GeoRasterFile.GREEN_BAND)
1495
                        for (int i=0; i<line.length; i++)
1496
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
1497
                else if (flags == GeoRasterFile.BLUE_BAND)
1498
                        for (int i=0; i<line.length; i++)
1499
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
1500
                image.setRGB(startX, startY, w, h, line, offset, scansize);
1501
        }
1502
        
1503
        /**
1504
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
1505
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
1506
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
1507
         * banda correspondiente a flags es sustituida por los datos del vector.
1508
         * @param image        imagen con los datos actuales
1509
         * @param startX        inicio de la posici?n en X dentro de la imagen
1510
         * @param startY        inicio de la posici?n en X dentro de la imagen
1511
         * @param w        Ancho de la imagen
1512
         * @param h        Alto de la imagen
1513
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1514
         * @param offset        desplazamiento
1515
         * @param scansize        tama?o de imagen recorrida por cada paso
1516
         * @param origBand        Banda origen del GeoRasterFile
1517
         * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
1518
         */
1519
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1520
                         int offset, int scansize, int origBand, int destBandFlag) {
1521
                int [] line = new int[rgbArray.length]; 
1522
                image.getRGB(startX, startY, w, h, line, offset, scansize);
1523
                if (origBand == 0 && destBandFlag == GeoRasterFile.RED_BAND)
1524
                        for (int i=0; i<line.length; i++)
1525
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
1526
                else if (origBand == 1 && destBandFlag == GeoRasterFile.GREEN_BAND)
1527
                        for (int i=0; i<line.length; i++)
1528
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
1529
                else if (origBand == 2 && destBandFlag == GeoRasterFile.BLUE_BAND)
1530
                        for (int i=0; i<line.length; i++)
1531
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
1532
                
1533
                else if (origBand == 0 && destBandFlag == GeoRasterFile.GREEN_BAND)
1534
                        for (int i=0; i<line.length; i++)
1535
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x00ff0000) >> 8) ;
1536
                else if (origBand == 0 && destBandFlag == GeoRasterFile.BLUE_BAND)
1537
                        for (int i=0; i<line.length; i++)
1538
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x00ff0000) >> 16);
1539
                else if (origBand == 1 && destBandFlag == GeoRasterFile.RED_BAND)
1540
                        for (int i=0; i<line.length; i++)
1541
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x0000ff00) << 8);
1542
                
1543
                else if (origBand == 1 && destBandFlag == GeoRasterFile.BLUE_BAND)
1544
                        for (int i=0; i<line.length; i++)
1545
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x0000ff00) >> 8);
1546
                else if (origBand == 2 && destBandFlag == GeoRasterFile.RED_BAND)
1547
                        for (int i=0; i<line.length; i++)
1548
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x000000ff) << 16);
1549
                else if (origBand == 2 && destBandFlag == GeoRasterFile.GREEN_BAND)
1550
                        for (int i=0; i<line.length; i++)
1551
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x000000ff) << 8);
1552
                image.setRGB(startX, startY, w, h, line, offset, scansize);
1553
        }
1554
        
1555
        private void showOnOpen() {
1556
                  // Report en la apertura (quitar)
1557
                  System.out.println("Fichero GDAL '"+getName()+"' abierto.");
1558
                  System.out.println("Version = "+file.version);
1559
                  System.out.println("   Size = ("+file.width+","+file.height+")");
1560
                  try {
1561
                        System.out.println("   NumBands = ("+file.getRasterCount()+")");
1562
                } catch (GdalException e) {
1563
                        // TODO Auto-generated catch block
1564
                        e.printStackTrace();
1565
                }
1566
                  //file.pintaInfo();
1567
                  file.pintaPaleta();
1568

    
1569
        }
1570

    
1571
        /* (non-Javadoc)
1572
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int, int)
1573
         */
1574
        public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBandFlag)throws SupersamplingNotSupportedException{
1575
                int line, pRGBArray[] = null;
1576
                        
1577
                if(mustVerifySize()){
1578
                        // Work out the correct aspect for the setView call.
1579
                        double dFileAspect = (double)v.width()/(double)v.height();
1580
                        double dWindowAspect = (double)width /(double)height;
1581
        
1582
                        if (dFileAspect > dWindowAspect) {
1583
                          height =(int)((double)width/dFileAspect);
1584
                        } else {
1585
                          width = (int)((double)height*dFileAspect);
1586
                        }
1587
                }
1588

    
1589
//                 Set the view
1590
                boolean[] orientation = getOrientation();
1591
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
1592
                        width, height, orientation);
1593
                setStep(file.stepArrayX, file.stepArrayY);
1594

    
1595
                if(width<=0)width=1;
1596
                if(height<=0)height=1;
1597
                                
1598
                pRGBArray = new int[width];
1599
                try {
1600
                        setBand(RED_BAND,   rBandNr);
1601
                        setBand(GREEN_BAND, gBandNr);
1602
                        setBand(BLUE_BAND,  bBandNr);
1603
                        file.setAlpha(getAlpha());
1604
                        if(img!=null){
1605
                                if(orientation[1]){
1606
                                        for (line=0; line < height; line++) {
1607
                                                file.readLineRGBA(pRGBArray);
1608
                                                setRGBLine((BufferedImage) img, 0, height - 1 - line, width, 1, pRGBArray, 0, width, origBand, destBandFlag);
1609
                                        }        
1610
                                }else{
1611
                                        for (line=0; line < height; line++) {
1612
                                                file.readLineRGBA(pRGBArray);
1613
                                                setRGBLine((BufferedImage) img, 0, line, width, 1, pRGBArray, 0, width, origBand, destBandFlag);
1614
                                        }
1615
                                }
1616
                                return img;
1617
                        }else{
1618
                                Image image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
1619
                                if(orientation[1]){
1620
                                        for (line=0; line < height; line++) {
1621
                                                file.readLineRGBA(pRGBArray);
1622
                                                setRGBLine((BufferedImage) image, 0, height - 1 - line, width, 1, pRGBArray, 0, width);
1623
                                        }        
1624
                                }else{
1625
                                        for (line=0; line < height; line++) {
1626
                                                file.readLineRGBA(pRGBArray);
1627
                                                setRGBLine((BufferedImage) image, 0, line, width, 1, pRGBArray, 0, width);
1628
                                        }
1629
                                }
1630
                                return image;
1631
                        }
1632
                } catch (Exception e) {
1633
                        // TODO Auto-generated catch block
1634
                        e.printStackTrace();
1635
                }
1636
                
1637
                return img;
1638
        }
1639
                        
1640
        /* (non-Javadoc)
1641
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
1642
         */
1643
        public Object getData(int x, int y, int band) {
1644
                if(file != null){
1645
                        Object[] data = file.getData(x, y);
1646
                        return data[band];
1647
                }
1648
                return null;
1649
        }
1650
        
1651
        /**
1652
         * Devuelve los datos de una ventana solicitada
1653
         * @param ulX        coordenada X superior izda.
1654
         * @param ulY        coordenada Y superior derecha.
1655
         * @param sizeX        tama?o en X de la ventana.
1656
         * @param sizeY tama?o en Y de la ventana.
1657
         * @param band        Banda solicitada.
1658
         */
1659
        public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band){
1660
                
1661
                return null;
1662
        }
1663
        
1664
        public RasterBuf getWindowRaster(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) {                
1665
                Extent selectedExtent = new Extent(x, y, x + w, y - h);
1666
                setView(selectedExtent);
1667
                
1668
                int width = 0;
1669
                int height = 0;
1670
                if(file.trans != null){
1671
                        width = (int)Math.abs(selectedExtent.width() / file.trans.adfgeotransform[1]);//(int)(selectedExtent.width() * file.width) / extent.width();
1672
                        height = (int)Math.abs(selectedExtent.height() / file.trans.adfgeotransform[5]);
1673
                }else{
1674
                        width = (int)Math.abs(selectedExtent.width());
1675
                        height = (int)Math.abs(selectedExtent.height());
1676
                }
1677
                                
1678
                try {
1679
                        file.readWindow(rasterBuf, bandList, x, y, width, height);
1680
                } catch (Exception e) {
1681
                        e.printStackTrace();
1682
                }
1683
                
1684
                return rasterBuf;
1685
        }
1686
        
1687
        /*
1688
         *  (non-Javadoc)
1689
         * @see org.gvsig.fmap.driver.GeoRasterFile#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.driver.BandList, org.gvsig.fmap.driver.IBuffer)
1690
         */
1691
        public RasterBuf getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, RasterBuf rasterBuf) {                
1692
                Extent selectedExtent = new Extent(minX, minY, maxX, maxY);
1693
                setView(selectedExtent);
1694
                
1695
                double width = 0;
1696
                double height = 0;
1697
                if(getTransform() != null){
1698
                        width = (double)(Math.abs(selectedExtent.width() / getTransform()[1]));//(int)(selectedExtent.width() * file.width) / extent.width();
1699
                        height = (double)(Math.abs(selectedExtent.height() / getTransform()[5]));
1700
                }else{
1701
                        width = (double)Math.abs(selectedExtent.width());
1702
                        height = (double)Math.abs(selectedExtent.height());
1703
                }
1704
                                
1705
                try {
1706
                        file.readWindow(rasterBuf, bandList, minX, maxY, maxX, minY, width, height, bufWidth, bufHeight);
1707
                } catch (Exception e) {
1708
                        e.printStackTrace();
1709
                }
1710
                
1711
                return rasterBuf;
1712
        }
1713
        
1714
        public RasterBuf getWindowRaster(int x, int y, int w, int h, BandList bandList, RasterBuf rasterBuf) {
1715
                try {
1716
                        setView(
1717
                        new Extent( Utilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
1718
                                                getWidth(), 
1719
                                                getHeight(),
1720
                                                new Rectangle2D.Double(x, y, w, h)))
1721
                        );
1722
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
1723
                } catch (Exception e) {
1724
                        e.printStackTrace();
1725
                }
1726
                return rasterBuf;
1727
        }
1728
        
1729
        public RasterBuf getWindowRasterWithNoData(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) {
1730
                Extent selectedExtent = new Extent(x, y, x + w, y - h);
1731
                setView(selectedExtent);
1732
                                
1733
                try {
1734
                        file.readWindowWithNoData(rasterBuf, bandList, x, y, x + w, y - h, rasterBuf.getWidth(), rasterBuf.getHeight());
1735
                } catch (Exception e) {
1736
                        e.printStackTrace();
1737
                }
1738
                
1739
                return rasterBuf;
1740
        }
1741
        
1742
        /**
1743
         * Obtiene la zona (Norte / Sur)
1744
         * @return true si la zona es norte y false si es sur
1745
         */
1746
        
1747
        public boolean getZone(){
1748
                
1749
                return false;
1750
        }
1751
        
1752
        /**
1753
         *Devuelve el n?mero de zona UTM
1754
         *@return N?mero de zona 
1755
         */
1756
        
1757
        public int getUTM(){
1758
                
1759
                return 0;        
1760
        }
1761
        
1762
        /**
1763
         * Obtiene el sistema de coordenadas geograficas
1764
         * @return Sistema de coordenadas geogr?ficas
1765
         */
1766
        public String getGeogCS(){
1767
                return new String("");        
1768
        }
1769
        
1770
        /**
1771
         * Devuelve el tama?o de bloque
1772
         * @return Tama?o de bloque
1773
         */
1774
        public int getBlockSize(){
1775
                if(file != null)
1776
                        return file.getBlockSize();
1777
                else
1778
                        return 0;
1779
        }
1780
        
1781
        /**
1782
         * Obtiene el objeto que contiene los metadatos
1783
         */
1784
        public Metadata getMetadata() {
1785
                if(file != null)
1786
                        return file.getMetadataJavaObject();
1787
                else
1788
                        return null;
1789
        }
1790
        
1791
        /**
1792
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1793
         * @return true si est? georreferenciada y false si no lo est?.
1794
         */
1795
        public boolean isGeoreferenced() {
1796
                if(file != null)
1797
                        return file.isGeoreferenced();
1798
                else 
1799
                        return false;
1800
        }
1801
    
1802
        /**
1803
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
1804
         * el valor de esta variable cada vez que dibuja. 
1805
         * @return true si se ha supersampleado y false si no se ha hecho.
1806
         */
1807
        public boolean isSupersampling() {
1808
                if(file != null)
1809
                        return file.isSupersampling;
1810
                else 
1811
                        return false;
1812
        }
1813
        
1814
        /**
1815
         * Obtiene los par?metros de la transformaci?n af?n que corresponde con los elementos de
1816
         * un fichero tfw.
1817
         * <UL> 
1818
         * <LI>[1]tama?o de pixel en X</LI>
1819
         * <LI>[2]rotaci?n en X</LI>
1820
         * <LI>[4]rotaci?n en Y</LI>
1821
         * <LI>[5]tama?o de pixel en Y</LI>
1822
         * <LI>[0]origen en X</LI>
1823
         * <LI>[3]origen en Y</LI>
1824
         * </UL>
1825
         * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n. En principio
1826
         * Gdal es capaz de proporcionarla de esta forma.
1827
         * 
1828
         * En caso de que exista fichero .rmf asociado al raster pasaremos de la informaci?n de georreferenciaci?n
1829
         * del .tfw y devolveremos la que est? asociada al rmf
1830
         * @return vector de double con los elementos de la transformaci?n af?n.
1831
         */
1832
        public double[] getTransform(){
1833
                if(file != null && file.trans != null && !this.rmfExists())
1834
                        return file.trans.adfgeotransform;
1835
                else{
1836
                        if(this.rmfExists){
1837
                                double[] rmfGeoref = {        rmfTransform.getTranslateX(), 
1838
                                                                                rmfTransform.getScaleX(),
1839
                                                                                rmfTransform.getShearX(), 
1840
                                                                                rmfTransform.getTranslateY(),
1841
                                                                                rmfTransform.getShearY(),
1842
                                                                                rmfTransform.getScaleY()};
1843
                                return rmfGeoref;
1844
                        }
1845
                        return null;
1846
                }
1847
                
1848
        }
1849

    
1850
        /*
1851
         *  (non-Javadoc)
1852
         * @see org.gvsig.fmap.driver.GeoRasterFile#rasterToWorld(java.awt.geom.Point2D)
1853
         */
1854
        public Point2D rasterToWorld(Point2D pt) {
1855
                return file.rasterToWorld(pt);
1856
        }
1857
        
1858
        /*
1859
         *  (non-Javadoc)
1860
         * @see org.gvsig.fmap.driver.GeoRasterFile#worldToRaster(java.awt.geom.Point2D)
1861
         */
1862
        public Point2D worldToRaster(Point2D pt){
1863
                return file.worldToRaster(pt);
1864
        }
1865
        
1866
        public void readPalette(){
1867
                file.readPalette();
1868
        }
1869
}
1870

    
1871

    
1872