Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_897 / libraries / libCq CMS for java.old / src / org / cresques / io / GdalFile.java @ 10444

History | View | Annotate | Download (43.3 KB)

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

    
26
import java.awt.Image;
27
import java.awt.Point;
28
import java.awt.geom.NoninvertibleTransformException;
29
import java.awt.geom.Point2D;
30
import java.awt.image.BufferedImage;
31
import java.awt.image.DataBuffer;
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.Metadata;
38
import org.cresques.io.data.RasterBuf;
39
import org.cresques.io.exceptions.NotSupportedExtensionException;
40
import org.cresques.px.Extent;
41

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

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

    
88
        
89
        // Polilinea con extent
90
        public class Contour extends Vector {
91
                final private static long serialVersionUID = -3370601314380922368L;
92
                public double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
93
                public double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
94
                public Contour() {
95
                        super();
96
                }
97
                public void add(Point2D pt) {
98
                        super.add(pt);
99
                        if (pt.getX() > maxX) maxX = pt.getX();
100
                        if (pt.getX() < minX) minX = pt.getX();
101
                        if (pt.getY() > maxY) maxY = pt.getY();
102
                        if (pt.getY() < minY) minY = pt.getY();
103
                }
104
        }
105
                
106
        public GdalNative(String fName) throws GdalException, IOException {
107
                super();
108
                init(fName);
109
        }
110
        
111
        /**
112
         * <P>
113
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
114
         * el tama?o de pixel y la rotaci?n. Esto lo hace con los valores de transformaci?n 
115
         * leidos por gdal en el vector de 6 elementos adfGeoTransform donde cada elemento
116
         * del vector represnta los siguientes valores
117
         * </P>
118
         * <UL>
119
         * <LI>0-origen X</LI>
120
         * <LI>1-tama?o de pixel X</LI>
121
         * <LI>2-shear en X</LI>
122
         * <LI>3-origen Y</LI>
123
         * <LI>4-shear en Y</LI>
124
         * <LI>5-Tama?o de pixel Y</LI>
125
         * </UL>
126
         * <P>
127
         * Para el calculo de una esquina aplicamos la formula siguiente:<BR>
128
         * PtoX = originX + pixelSizeX * x + shearX * y;<BR>
129
         * PtoY = originY + shearY * x + pixelSizeY * y;<BR>
130
         * Aplicandolo a las cuatro esquinas sustituimos en cada una de ellas por.
131
         * </P>
132
         * <UL> 
133
         * <LI>Esquina superior izquierda: x = 0; y = 0;</LI>
134
         * <LI>Esquina superior derecha: x = MaxX; y = 0;</LI>
135
         * <LI>Esquina inferior izquierda: x = 0; y = MaxY;</LI>
136
         * <LI>Esquina inferior derecha: x = MaxX; y = MaxY;</LI>
137
         * </UL> 
138
         * <P>
139
         * quedandonos en los cuatro casos:
140
         * </P>
141
         * <UL> 
142
         * <LI>Esquina superior izquierda: originX; originY;</LI>
143
         * <LI>Esquina superior derecha: PtoX = originX + pixelSizeX * x; PtoY = originY + shearY * x;</LI>
144
         * <LI>Esquina inferior izquierda:  PtoX = originX + shearX * y; PtoY = originY + pixelSizeY * y;</LI>
145
         * <LI>Esquina inferior derecha: PtoX = originX + pixelSizeX * x + shearX * y; PtoY = originY + shearY * x + pixelSizeY * y;</LI>
146
         * </UL>
147
         * 
148
         */
149
        private void boundingBoxFromGeoTransform(){
150
                double geoX = 0D, geoY = 0D;
151

    
152
                //Upper left corner
153
                bBoxRot.add(new Point2D.Double(trans.adfgeotransform[0], trans.adfgeotransform[3]));
154

    
155
                //Lower left corner
156
                geoX = trans.adfgeotransform[0] +  trans.adfgeotransform[2] * height;
157
                geoY = trans.adfgeotransform[3] +  trans.adfgeotransform[5] * height;
158
                bBoxRot.add(new Point2D.Double(geoX, geoY));
159
                
160
                //Upper right corner
161
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width;
162
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width;
163
                bBoxRot.add(new Point2D.Double(geoX, geoY));
164
                
165
                //Lower right corner
166
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width + trans.adfgeotransform[2] * height;
167
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width + trans.adfgeotransform[5] * height;
168
                bBoxRot.add(new Point2D.Double(geoX, geoY));
169
                
170
                //TODO: ?OJO! con coordenadas geogr?ficas
171
        }
172
        
173
        /**
174
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
175
         * el tama?o de pixel y la rotaci?n. 
176
         */
177
        private void boundingBoxWithoutRotation(){
178
                double ox = trans.adfgeotransform[0];
179
                double oy = trans.adfgeotransform[3];
180
                double resx = trans.adfgeotransform[1];
181
                double resy = trans.adfgeotransform[5];
182
                                
183
                bBoxWithoutRot.add(new Point2D.Double(ox, oy));
184
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy));
185
                bBoxWithoutRot.add(new Point2D.Double(ox, oy + resy * height));
186
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy + resy * height));
187

    
188
                //TODO: ?OJO! con coordenadas geogr?ficas
189
        }
190
        
191
        private void init(String fName) throws GdalException, IOException {
192
                open(fName,GA_ReadOnly);
193
                ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
194
                if (ext.compareTo("tif") == 0)
195
                        WITH_OVERVIEWS = false;
196
                width = getRasterXSize();
197
                height = getRasterYSize();
198
                setDataType(this.getRasterBand(1).getRasterDataType());
199
                shortName = getDriverShortName();
200
                metadata = new Metadata(getMetadata());
201
                
202
                //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
203
                //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
204
                metadata.initColorInterpretation(getRasterCount());
205
                metadata.initNoDataByBand(getRasterCount());
206
            for(int i = 0; i < getRasterCount(); i++){
207
                    GdalRasterBand rb = getRasterBand(i + 1);
208
                    String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
209
                    metadata.setNoDataValue(i, rb.getRasterNoDataValue());
210
                    metadata.setColorInterpValue(i, colorInt);
211
                    if(colorInt.equals("Red"))
212
                            rBandNr = i + 1;
213
                    if(colorInt.equals("Green"))
214
                            gBandNr = i + 1;        
215
                    if(colorInt.equals("Blue"))
216
                            bBandNr = i + 1;                
217
                    if(colorInt.equals("Alpha"))
218
                            aBandNr = i + 1;
219
            }
220
            
221
                double ox=0D, oy=0D, resx=0D, resy=0D;
222
                try{
223
                        trans = getGeoTransform();
224
                        
225
                        boundingBoxWithoutRotation();
226
                        boundingBoxFromGeoTransform();
227
                                                
228
                        this.georeferenced = true;
229
                }catch(GdalException exc){
230
                        bBoxRot.add(new Point2D.Double(0, 0));
231
                        bBoxRot.add(new Point2D.Double(width, 0));
232
                        bBoxRot.add(new Point2D.Double(0, height));
233
                        bBoxRot.add(new Point2D.Double(width, height));
234
                        bBoxWithoutRot = bBoxRot;
235
                        this.georeferenced = false;
236
                }
237
        }
238
        
239
        public void setAlpha(int a) { alpha = a; }
240
        
241
        public void setDataType(int dt) { dataType = dt; }
242
        public int getDataType() { return dataType; }
243
        
244
        double lastReadLine = -1;
245
        int currentFullWidth = -1;
246
        int currentFullHeight = -1;
247
        int currentViewWidth = -1;
248
        int currentViewHeight = -1;
249
        double currentViewX = 0D;
250
        double currentViewY = 0D;
251
        double viewportScaleX = 0D;
252
        double viewportScaleY = 0D;
253
        double wcWidth = 0D;
254
        double stepX = 0D;
255
        double stepY = 0D;
256
        int currentOverview = -1;
257
        
258
        protected GdalRasterBand bandR = null, bandG = null, bandB = null, bandA = null;
259
        
260
        private boolean[] orientation;
261
        
262
        /**
263
         * Devuelve la banda actualmente en uso para el color especificado.
264
         * @param color 0=Rojo, 1=Green, 2=Blue.
265
         * @return
266
         */
267
        public GdalRasterBand getCurrentBand(int color) {
268
                if (color == 0) 
269
                        return bandR;
270
                else if (color == 1) 
271
                        return bandG;
272
                return bandB;
273
        }
274
        
275
        //Supone rasters no girados
276
        public Point2D worldToRaster(Point2D pt) {
277
                double x = (((double) currentFullWidth) / (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) * (pt.getX() - bBoxWithoutRot.minX);
278
                double y = (((double) currentFullHeight) / (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) * (bBoxWithoutRot.maxY - pt.getY());
279
                Point2D ptRes = new Point2D.Double(x, y);
280
                return ptRes;
281
        }
282
        
283
        /**
284
         * Si el tama?o de pixel en X es menor que 0 entonces la imagen se orienta al contrario en X por lo que en los zooms
285
         * habr? que invertir la petici?n de la parte derecha a la izquierda y viceversa. Esto lo detectamos con la 
286
         * variable orientation , si orientation[0] es false entonces el punto inicial del zoom lo invertimos de la 
287
         * siguiente forma:
288
         * Nuevo_punto_inicialX = (Ancho_total_raster - punto_inicial_del_zoomX) - Ancho_de_petici?n
289
         *
290
         * Si el tama?o de pixel en Y es mayor que 0 entonces la imagen se orienta al contrario en Y por 
291
         * lo que en los zooms habr? que invertir la petici?n de abajo a arriba y viceversa. Esto lo detectamos con la 
292
         * variable orientation , si orientation[1] es true entonces el punto inicial del zoom lo invertimos de la 
293
         * siguiente forma:
294
         * Nuevo_punto_inicialY = (Alto_total_raster - punto_inicial_del_zoomY) - Alto_de_petici?n
295
         * 
296
         * @param dWorldTLX
297
         * @param dWorldTLY
298
         * @param dWorldBRX
299
         * @param dWorldBRY
300
         * @param nWidth
301
         * @param nHeight
302
         * @param orientation array de dos elementos que representa la orientaci?n de la petici?n en
303
         * X e Y. El primer elemento representa el signo de pixelSize en X, true si es positivo y false
304
         * si es negativo. El segundo elemento representa el signo de pixelSize en Y
305
         * @return
306
         */
307
        public int setView(double dWorldTLX, double dWorldTLY,
308
            double dWorldBRX, double dWorldBRY,
309
            int nWidth, int nHeight, boolean[] orientation) {
310
                int err = 0;
311
                this.orientation = orientation;
312
                currentFullWidth = width;
313
                currentFullHeight = height;
314
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
315
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
316
                // Calcula cual es la primera l?nea a leer;
317
                currentViewWidth = nWidth;
318
                currentViewHeight = nHeight;
319
                wcWidth = Math.abs(br.getX() - tl.getX());
320
                
321
                if(!orientation[0]) //Invierte la orientaci?n en X
322
                        currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
323
                else
324
                        currentViewX = tl.getX();
325
                
326
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
327
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
328
                stepX = 1D/viewportScaleX;
329
                stepY = 1D/viewportScaleY;
330

    
331
                if(orientation[1])//Invierte la orientaci?n en Y
332
                        lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
333
                else
334
                        lastReadLine = tl.getY();
335
                
336
                try {
337
                        // calcula el overview a usar
338
                        bandR = getRasterBand(1);
339
                        currentOverview = -1;
340
                        if (WITH_OVERVIEWS && bandR.getOverviewCount() > 0) {
341
                                GdalRasterBand ovb = null;
342
                                for (int i=bandR.getOverviewCount()-1; i>0; i--) {              
343
                                        ovb = bandR.getOverview(i);
344
                                        if (ovb.getRasterBandXSize()>getRasterXSize()*viewportScaleX) {
345
                                                currentOverview = i;
346
                                    viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
347
                                    viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
348
                                    stepX = 1D/viewportScaleX;
349
                                    stepY = 1D/viewportScaleY;
350
                                    currentFullWidth = ovb.getRasterBandXSize();
351
                                    currentFullHeight = ovb.getRasterBandYSize();
352
                                    tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
353
                                    if(!orientation[0])//Invierte la orientaci?n en X
354
                                            currentViewX = (width - tl.getX()) - (br.getX()-tl.getX());
355
                                    else
356
                                            currentViewX = tl.getX();
357
                                    if(orientation[1])//Invierte la orientaci?n en Y
358
                                            lastReadLine = (height - tl.getY()) - (br.getY()-tl.getY());
359
                                    else
360
                                            lastReadLine = tl.getY();
361
                                    break;
362
                                        }
363
                                }
364
                        }
365
        
366
                        // Selecciona las bandas y los overviews necesarios
367
                        bandR = getRasterBand(rBandNr);
368
                        setDataType(bandR.getRasterDataType());
369
                        
370
                        if (this.getRasterCount() > 1) {
371
                                bandG = getRasterBand(gBandNr);
372
                                bandB = getRasterBand(bBandNr);                                
373
                                if(metadata.isAlphaBand())
374
                                        bandA = getRasterBand(aBandNr); 
375
                        }
376
                        if (currentOverview > 0) {
377
                                bandR = bandR.getOverview(currentOverview);
378
                            if (this.getRasterCount() > 1) {
379
                                        bandG = bandG.getOverview(currentOverview);
380
                                        bandB = bandB.getOverview(currentOverview);
381
                                        if(metadata.isAlphaBand())
382
                                                bandA = bandA.getOverview(currentOverview);
383
                                }
384
                        }
385

    
386
                } catch (GdalException e) {
387
                        e.printStackTrace();
388
                }
389
                return err;
390
        }
391
        
392
        int lastY = -1;
393
        
394
        public void readLine(int[][] line) throws GdalException {
395
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
396
        int x = (int) Math.ceil(currentViewX);
397
        int y = (int) Math.ceil(lastReadLine);
398
        GdalBuffer r = null, g = null, b = null, p = null;
399
        GdalBuffer a = new GdalBuffer();
400
        
401
        //if (alpha > 0) a = alpha << 24;
402
        if (x+w > bandR.getRasterBandXSize()) 
403
                w = bandR.getRasterBandXSize()-x;
404
        
405
        if(bandR.getRasterColorTable() != null){
406
                p = bandR.readRasterWithPalette(x, y, w, 1, w, 1, dataType);
407
                a.buffByte = p.buffAPalette;
408
                r = new GdalBuffer();
409
                r.buffByte = p.buffRPalette;
410
                g = new GdalBuffer();
411
                g.buffByte = p.buffGPalette;
412
                b = new GdalBuffer();
413
                b.buffByte = p.buffBPalette;
414
        }else{
415
                a.buffByte = new byte[w];
416
                        r = bandR.readRaster(x, y, w, 1, w, 1, dataType);
417
                        if (bandG != null)
418
                            g = bandG.readRaster(x, y, w, 1, w, 1, dataType);
419
                        if (bandB != null)
420
                            b = bandB.readRaster(x, y, w, 1, w, 1, dataType);
421
        }
422
          
423
                lastReadLine += stepY;
424
        
425
                  int i=0;
426
                  double j = 0D;
427
                  double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
428
                  
429
                  if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
430
                          if (g == null){ // Sibgle Band (Typical DEM)
431
                                  for (int k=0; k<4; k++){
432
                                          for (i=0, j = initOffset; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
433
                                                  if(k<3)
434
                                                          line[i][k] = (r.buffShort[(int) j] & 0xffff);
435
                                                  else
436
                                                          line[i][3] = 0xff;
437
                                          }
438
                              }
439
                          }else { // Multiband
440
                                  //System.err.println("readLine(): Raster 16bits multibanda");
441
                                  GdalBuffer [] bands = {r,g,b};
442
                                  for (int k=0; k<4; k++){
443
                                      for (i=0, j = initOffset; i<currentViewWidth && j<r.getSize(); i++, j+=stepX){
444
                                              if(k<3)
445
                                                      line[i][k] = (bands[k].buffShort[(int) j] & 0xffff);
446
                                              else
447
                                                      line[i][3] = 0xff;
448
                                      }
449
                                  }
450
                          }
451
                  }else if(dataType == GDT_Float32){
452
                          GdalBuffer [] bands = {r,g,b};
453
                        for (int k=0; k<4; k++){
454
                              for (i=0, j = initOffset; i<currentViewWidth && j<r.getSize(); i++, j+=stepX){
455
                                      if(k < 3)
456
                                              line[i][k] = (int)bands[0].buffFloat[(int) j];
457
                                      else
458
                                              line[i][3] = 0xff;
459
                              }
460
                        }
461
                  }
462
                  
463
                return;
464
        }
465
        
466
        //int liney = 0;
467
        int readLineRGBA(int [] line) throws GdalException {
468
                int err = 0;
469
                
470
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
471
        int x = (int) currentViewX;
472
        int y = (int) lastReadLine;
473
        GdalBuffer r = null, g = null, b = null, p = null;
474
        GdalBuffer a = new GdalBuffer();
475
        
476
        while(y >= bandR.getRasterBandYSize())
477
                y--;
478
        
479
        //if (alpha > 0) a = alpha << 24;
480
        if (x+w > bandR.getRasterBandXSize()) 
481
                w = bandR.getRasterBandXSize()-x;
482
                       
483
        if(bandR.getRasterColorTable() != null){
484
                p = bandR.readRasterWithPalette(x, y, w, 1, w, 1, dataType);
485
                a.buffByte = p.buffAPalette;
486
                r = new GdalBuffer();
487
                r.buffByte = p.buffRPalette;
488
                g = new GdalBuffer();
489
                g.buffByte = p.buffGPalette;
490
                b = new GdalBuffer();
491
                b.buffByte = p.buffBPalette;
492
        }else{                        
493
                r = bandR.readRaster(x, y, w, 1, w, 1, dataType);
494
                        if (bandG != null)
495
                            g = bandG.readRaster(x, y, w, 1, w, 1, dataType);
496
                        if (bandB != null)
497
                            b = bandB.readRaster(x, y, w, 1, w, 1, dataType);
498
                
499
                if(metadata.isAlphaBand()){
500
                //if(getRasterCount() == 4 && shortName.equals("PNG")){
501
                        a = bandA.readRaster(x, y, w, 1, w, 1, GDT_Byte);        
502
                }else{
503
                            a.buffByte = new byte[w];
504
                            for (int i = 0;i < w;i++)
505
                                    a.buffByte[i] = (byte)255;
506
                }
507
        }
508
       
509
        lastReadLine += stepY;
510
          
511
                  int i=0;
512
                  double j =  Math.abs(currentViewX - ((int)currentViewX));
513
                int alpha = (this.alpha & 0xff) << 24;
514

    
515
                if(orientation[0]){ //Pixel size en X positivo
516
                          if (dataType == GDT_Byte){
517
                                  if (g != null)
518
                                      for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
519
                                              int jInt = (int)(j);
520
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
521
                                      }
522
                              else
523
                                      for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
524
                                              int jInt = (int)(j);
525
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
526
                                      }
527
                          }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
528
                                  if (g == null) // Sibgle Band (Typical DEM)
529
                                            for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
530
                                                    int jInt = (int)(j);
531
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
532
                                      }
533
                                  else { // Multiband - Raster 16bits multibanda
534
                                      for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
535
                                              int jInt = (int)(j);
536
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | 
537
                                                                                                                                   (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
538
                                                                                                                                   (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
539
                                      }
540
                                  }
541
                          }
542
                }else{ //Pixel size en X negativo
543
                        if (dataType == GDT_Byte){
544
                                  if (g != null)
545
                                      for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
546
                                              int jInt = (int)(j);
547
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
548
                                      }
549
                              else
550
                                      for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
551
                                              int jInt = (int)(j);
552
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
553
                                      }
554
                          }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
555
                                  if (g == null) // Sibgle Band (Typical DEM)
556
                                          for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
557
                                                    int jInt = (int)(j);
558
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
559
                                      }
560
                                  else { // Multiband - Raster 16bits multibanda;
561
                                          for (i=currentViewWidth - 1; i>=0 && j<r.getSize(); i--, j+=stepX) {
562
                                              int jInt = (int)(j);
563
                                              line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | 
564
                                                                                                                                   (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
565
                                                                                                                                   (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
566
                                      }
567
                                  }
568
                          }
569
                        
570
                }
571

    
572
                return err;
573
        }
574
                
575
        /**
576
         * Lee una franja de la imagen.
577
         * @param bandH Altura de la franja
578
         * @param bufH        Altura del buffer
579
         * @param buf        Buffer con la franja (retorno)
580
         * @return
581
         * @throws GdalException
582
         */
583
        public int readBandRGBA(int bandH, int bufH, int [] buf) throws GdalException {
584
                int err = 0;
585
        int w = (int)(((double)currentViewWidth)*stepX);
586
        int x = (int)(((double)currentViewX)*stepX);
587
        int y = (int) lastReadLine;
588
        int h = (int) (((double)bandH)*stepX);
589
        System.out.println("Leyendo "+y);
590
        GdalBuffer r = null, g = null, b = null, p = null;
591
        GdalBuffer a = new GdalBuffer();
592
        
593
        if (x+w > bandR.getRasterBandXSize()) 
594
                w = bandR.getRasterBandXSize()-x;
595
        
596
        if(bandR.getRasterColorTable() != null){
597
                p = bandR.readRasterWithPalette(x, y, w, h, w, h, GDT_Byte);
598
                a.buffByte = p.buffAPalette;
599
                r = new GdalBuffer();
600
                r.buffByte = p.buffRPalette;
601
                g = new GdalBuffer();
602
                g.buffByte = p.buffGPalette;
603
                b = new GdalBuffer();
604
                b.buffByte = p.buffBPalette;
605
        }else{
606
                r = bandR.readRaster(x, y, w, h, w, h, dataType);
607
                        if (bandG != null)
608
                            g = bandG.readRaster(x, y, w, h, w, h, dataType);
609
                        if (bandB != null)
610
                            b = bandB.readRaster(x, y, w, h, w, h, dataType);
611
                        
612
                if(metadata.isAlphaBand()){
613
                //if(getRasterCount() == 4 && shortName.equals("PNG")){
614
                        a = bandA.readRaster(x, y, w, h, w, h, GDT_Byte);
615
                }else{
616
                            a.buffByte = new byte[w];
617
                            for (int i = 0;i < w*h;i++)
618
                                    a.buffByte[i] = (byte)255;
619
                }
620
        }
621
        
622
        lastReadLine += ((double)bandH)*stepY;
623
                  
624
                  // TODO Acabar de implementarlo
625
                  float k=0F;
626
                int alpha = (this.alpha & 0xff) << 24;
627
                  for (int j=0, t=0; j<bandH; j++) {
628
                          k = j*w; t=j*currentViewWidth;
629
                          for (int i=0; i<currentViewWidth && k<r.getSize(); i++, k+=stepX) {
630
                                  buf[t+i] = (alpha & ((a.buffByte[(int)j])& 0xff) << 24) + ((r.buffByte[(int) k]) << 16) + ((g.buffByte[(int) k]) << 8) + b.buffByte[(int) k];
631
                          }
632
                  }
633
                
634
                return err;
635
                
636
        }
637

    
638
        /* (non-Javadoc)
639
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
640
         */
641
        public Object[] getData(int x, int y) {
642
                try {
643
                        Object[] data = new Object[getRasterCount()];
644
                        for(int i = 0; i < getRasterCount(); i++){
645
                                GdalRasterBand rb = getRasterBand(i + 1);
646
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType);
647
                                switch(dataType){
648
                                case 0:        break;                                                                        //Sin tipo
649
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
650
                                                break;
651
                                case 2:                                                                                        //Buffer short (16)
652
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
653
                                                break;
654
                                case 4:                                                                                        //Buffer int (32)
655
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
656
                                                break;
657
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
658
                                                break;
659
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
660
                                                break;
661
                                }
662
                        }
663
                        return data;
664
                } catch (GdalException e) {
665
                        return null;
666
                }
667
        }
668
        
669
        void pintaInfo() {
670
                try {
671
                        //System.out.println("Origin = "+originX+","+originY);
672
                        //System.out.println("Origin = "+this.);
673
                        System.out.println("GeoTransform:");
674
                        GeoTransform trans = getGeoTransform();
675
                        for (int i=0; i<6; i++)
676
                                System.out.println("  param["+i+"]="+trans.adfgeotransform[i]);
677
                        System.out.println("Metadata:");
678
                        String [] metadata = getMetadata();
679
                        for (int i=0; i<metadata.length; i++) {
680
                                System.out.println(metadata[i]);
681
                        }
682
                } catch (GdalException e) {
683
                        
684
                }
685
                
686
        }
687
        
688
        void pintaPaleta() {
689
        }
690
        
691
        public int getBlockSize(){
692
                return this.getBlockSize();
693
        }
694

    
695
        /**
696
         * Obtiene el objeto que contiene los metadatos
697
         */
698
        public Metadata getMetadataJavaObject() {
699
                return metadata;
700
        }
701

    
702
        /**
703
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
704
         * @return true si est? georreferenciada y false si no lo est?.
705
         */
706
        public boolean isGeoreferenced() {
707
                return georeferenced;
708
        }
709
}
710

    
711
/**
712
 * @author Luis W. Sevilla
713
 */
714
public class GdalFile extends GeoRasterFile {
715
        public final static int         BAND_HEIGHT = 64;
716
        protected GdalNative                 file = null;
717

    
718
        private Extent v = null;
719
        
720
        public GdalFile(IProjection proj, String fName)throws NotSupportedExtensionException{
721
                super(proj, fName);
722
                extent = new Extent();
723
                try {
724
                        file = new GdalNative(fName);
725
                        load();
726
                        readGeoInfo(fName);
727
                        bandCount = file.getRasterCount(); 
728
                        if ( bandCount > 2) {
729
                                setBand(RED_BAND,   0);
730
                                setBand(GREEN_BAND, 1);
731
                                setBand(BLUE_BAND,  2);
732
                        } else
733
                                setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);
734
                } catch (GdalException e) {
735
                        throw new NotSupportedExtensionException("Extension not supported");
736
                } catch(Exception e){
737
                          System.out.println("Error en GdalOpen");
738
                          e.printStackTrace();
739
                          file = null;
740
                }
741
                
742
                switch(file.getDataType()){
743
                case 1:setDataType(DataBuffer.TYPE_BYTE);break;//GDT_BYTE 
744
                case 2://GDT_UInt16 
745
                case 3:setDataType(DataBuffer.TYPE_SHORT);break;//GDT_Int16        
746
                case 4://GDT_UInt32
747
                case 5:setDataType(DataBuffer.TYPE_INT);break;//GDT_Int32
748
                case 6:setDataType(DataBuffer.TYPE_FLOAT);break;//GDT_Float32
749
                case 7:setDataType(DataBuffer.TYPE_DOUBLE);break;//GDT_Float64
750
                case 8:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CInt16
751
                case 9:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CInt32
752
                case 10:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CFloat32
753
                case 11:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CFloat64
754
                }
755
                
756
        }
757
        
758
        /**
759
         * Obtenemos o calculamos el extent de la imagen.
760
         */
761
        public GeoFile load() {
762
                extent = new Extent(file.bBoxRot.minX, file.bBoxRot.minY, file.bBoxRot.maxX, file.bBoxRot.maxY);
763
                requestExtent = new Extent(file.bBoxWithoutRot.minX, file.bBoxWithoutRot.minY, file.bBoxWithoutRot.maxX, file.bBoxWithoutRot.maxY);
764
                return this;
765
        }
766
        
767
        /**
768
         * Cierra el fichero de imagen
769
         */
770
        public void close() {
771
                try {
772
                        if(file != null){
773
                                file.close();
774
                                file = null;
775
                        }
776
                } catch (GdalException e) {
777
                        // TODO Auto-generated catch block
778
                        e.printStackTrace();
779
                }
780
        }
781
        
782
        /**
783
         * Asigna a cada banda R,G o B una banda de la imagen
784
         */
785
        public void setBand(int flag, int bandNr) {
786
                super.setBand(flag, bandNr);
787
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) file.rBandNr = bandNr+1;
788
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) file.gBandNr = bandNr+1;
789
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) file.bBandNr = bandNr+1;
790
        }
791
        
792
        /**
793
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
794
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
795
         * ha de estar en coordenadas del fichero.
796
         */
797
        public void setView(Extent e) { 
798
                if(rmfExists){
799
                                                                                                
800
                        Point2D.Double petInit = null, petEnd = null;
801
                        try{
802
                                petInit = new Point2D.Double(e.minX(),  e.maxY());
803
                                petEnd = new Point2D.Double(e.maxX(), e.minY());
804
                                transformRMF.inverseTransform(petInit, petInit);
805
                                transformRMF.inverseTransform(petEnd, petEnd);
806
                                transformTFW.transform(petInit, petInit);
807
                                transformTFW.transform(petEnd, petEnd);
808
                        }catch(NoninvertibleTransformException ex){}
809
                        double h = file.bBoxWithoutRot.maxY - file.bBoxWithoutRot.minY;
810
                        if(!file.isGeoreferenced())
811
                                v = new Extent(        petInit.getX(), h - petInit.getY(), petEnd.getX(), h - petEnd.getY()); 
812
                        else
813
                                v = new Extent(        petInit.getX(), petInit.getY(), petEnd.getX(), petEnd.getY());
814
                        
815
                }else
816
                        v = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());        
817
        }
818
        
819
         /**
820
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
821
         * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo. De la
822
         * misma forma calcula la matriz de transformaci?n de la cabecera del fichero o del world file asociado
823
         * @param originX Origen de la imagen en la coordenada X
824
         * @param originY Origen de la imagen en la coordenada Y
825
         */
826
        public void setExtentTransform(double originX, double originY, double psX, double psY) {                
827
                transformRMF.setToTranslation(originX, originY);
828
                transformRMF.scale(psX, psY);
829
                
830
                if(file.trans != null){        
831
                        transformTFW.setToTranslation(file.trans.adfgeotransform[0], file.trans.adfgeotransform[3]);
832
                        transformTFW.scale(file.trans.adfgeotransform[1], file.trans.adfgeotransform[5]);
833
                }
834
        }
835
                
836
        /**
837
         * Obtiene extent de la vista actual
838
         */
839
        public Extent getView() { 
840
                return v; 
841
        }
842
        
843
        /**
844
         * Obtiene la anchura del fichero
845
         */
846
        public int getWidth() {        
847
                return file.width; 
848
        }
849
        
850
        /**
851
         * Obtiene la altura del fichero
852
         */
853
        public int getHeight() { 
854
                return file.height;
855
        }
856

    
857
        /* (non-Javadoc)
858
         * @see org.cresques.io.GeoRasterFile#reProject(org.cresques.cts.ICoordTrans)
859
         */
860
        public void reProject(ICoordTrans rp) {
861
                // TODO Auto-generated method stub
862
        }
863
        
864
        /**
865
         * Obtiene la orientaci?n de la imagen a partir del signo del tama?o de pixel para poder
866
         * asignarlo en el setView. Esto es util para poder conocer como debe leerse la image, 
867
         * de abajo a arriba, de arriba a abajo, de izquierda a derecha o de derecha a izquierda. 
868
         * La posici?n habitual es la que el pixel size en X es positivo y en Y negativo leyendose 
869
         * en este caso las X de menor a mayor y las Y de mayor a menor. Los casos posibles son:
870
         * <UL>
871
         * <LI><B>X > 0; Y < 0;</B> {true, false}</LI>
872
         * <LI><B>X > 0; Y > 0;</B> {true, true}</LI>
873
         * <LI><B>X < 0; Y > 0;</B> {false, true}</LI>
874
         * <LI><B>X < 0; Y < 0;</B> {false, false}</LI>
875
         * </UL>
876
         *  
877
         * @return
878
         */
879
        private boolean[] getOrientation(){
880
                boolean[] orientation = {true, false};
881
                if(!rmfExists){
882
                        if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[5] > 0)
883
                                orientation[1] = true;
884
                        if(file.trans != null && file.trans.adfgeotransform != null && file.trans.adfgeotransform[1] < 0)
885
                                orientation[0] = false;
886
                }else{
887
                        if(rmfTransform.getScaleY() > 0)
888
                                orientation[1] = true;
889
                        if(rmfTransform.getScaleX() < 0)
890
                                orientation[0] = false;
891
                }
892
                return orientation;
893
        }
894
        
895
        /* (non-Javadoc)
896
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans)
897
         */
898
        public Image updateImage(int width, int height, ICoordTrans rp) {
899
                int line, pRGBArray[] = null;
900
                Image image = null;
901
                        
902
                if (mustVerifySize()) {
903
                        // Work out the correct aspect for the setView call.
904
                        double dFileAspect = (double)v.width()/(double)v.height();
905
                        double dWindowAspect = (double)width /(double)height;
906
        
907
                        if (dFileAspect > dWindowAspect) {
908
                          height =(int)((double)width/dFileAspect);
909
                        } else {
910
                          width = (int)((double)height*dFileAspect);
911
                        }
912
                }
913
                                                
914
                // Set the view                                
915
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
916
                        width, height, getOrientation());
917
                
918
                if(width<=0)width=1;
919
                if(height<=0)height=1;
920
                
921
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
922
                //image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
923
                pRGBArray = new int[width/**BAND_HEIGHT*/];
924
                try {
925
                        //int nLin = height % BAND_HEIGHT;
926
                        file.setAlpha(getAlpha());
927
                        setBand(RED_BAND,   rBandNr);
928
                        setBand(GREEN_BAND, gBandNr);
929
                        setBand(BLUE_BAND,  bBandNr);
930
                        for (line=0; line < height; line++) { //+=BAND_HEIGHT) {
931
                                //int bandH = Math.min(BAND_HEIGHT, height-line);
932
                                //file.readBandRGBA(bandH, BAND_HEIGHT, pRGBArray);
933
                                file.readLineRGBA(pRGBArray);
934
                                setRGBLine((BufferedImage) image, 0, line, width, 1/*bandH*/, pRGBArray, 0, width);
935
                        }
936
                } catch (Exception e) {
937
                        // TODO Auto-generated catch block
938
                        e.printStackTrace();
939
                }
940
                
941
                return image;
942
        }
943
        
944
        public RasterBuf getRaster(int width, int height, ICoordTrans rp) {
945
                int line;
946
                RasterBuf raster = null;
947
                        
948
                if(mustVerifySize()){
949
                        // Work out the correct aspect for the setView call.
950
                        double dFileAspect = (double)v.width()/(double)v.height();
951
                        double dWindowAspect = (double)width /(double)height;
952
        
953
                        if (dFileAspect > dWindowAspect) {
954
                          height =(int)((double)width/dFileAspect);
955
                        } else {
956
                          width = (int)((double)height*dFileAspect);
957
                        }
958
                }
959
                
960
                // Set the view
961
                boolean[] orientation = getOrientation();
962
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
963
                        width, height, orientation);
964
                
965
                raster = new RasterBuf(DataBuffer.TYPE_INT, width, height, 4, new Point(0,0));
966
                try {
967

    
968
                        file.setAlpha(getAlpha());
969
                        setBand(RED_BAND,   rBandNr);
970
                        setBand(GREEN_BAND, gBandNr);
971
                        setBand(BLUE_BAND,  bBandNr);
972
                        for (line=0; line < height; line++) { //+=BAND_HEIGHT) {
973
                                file.readLine(raster.getLineInt(line));
974
                        }
975
                } catch (Exception e) {
976
                        e.printStackTrace();
977
                }
978
                
979
                return raster;
980
        }
981
        
982
        /**
983
         * Asigna al objeto Image los valores con los dato de la imagen contenidos en el 
984
         * vector de enteros.
985
         * @param image        imagen con los datos actuales
986
         * @param startX        inicio de la posici?n en X dentro de la imagen
987
         * @param startY        inicio de la posici?n en X dentro de la imagen
988
         * @param w        Ancho de la imagen
989
         * @param h        Alto de la imagen
990
         * @param rgbArray        vector que contiene la banda que se va a sustituir
991
         * @param offset        desplazamiento
992
         * @param scansize        tama?o de imagen recorrida por cada p
993
         */
994
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
995
                         int offset, int scansize) {
996
                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
997
        }
998
        
999
        /**
1000
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
1001
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
1002
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
1003
         * banda correspondiente a flags es sustituida por los datos del vector.
1004
         * @param image        imagen con los datos actuales
1005
         * @param startX        inicio de la posici?n en X dentro de la imagen
1006
         * @param startY        inicio de la posici?n en X dentro de la imagen
1007
         * @param w        Ancho de la imagen
1008
         * @param h        Alto de la imagen
1009
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1010
         * @param offset        desplazamiento
1011
         * @param scansize        tama?o de imagen recorrida por cada paso
1012
         * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
1013
         */
1014
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1015
                         int offset, int scansize, int flags) {
1016
                int [] line = new int[rgbArray.length]; 
1017
                image.getRGB(startX, startY, w, h, line, offset, scansize);
1018
                if (flags == GeoRasterFile.RED_BAND)
1019
                        for (int i=0; i<line.length; i++)
1020
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
1021
                else if (flags == GeoRasterFile.GREEN_BAND)
1022
                        for (int i=0; i<line.length; i++)
1023
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
1024
                else if (flags == GeoRasterFile.BLUE_BAND)
1025
                        for (int i=0; i<line.length; i++)
1026
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
1027
                image.setRGB(startX, startY, w, h, line, offset, scansize);
1028
        }
1029
        
1030
        /**
1031
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
1032
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
1033
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
1034
         * banda correspondiente a flags es sustituida por los datos del vector.
1035
         * @param image        imagen con los datos actuales
1036
         * @param startX        inicio de la posici?n en X dentro de la imagen
1037
         * @param startY        inicio de la posici?n en X dentro de la imagen
1038
         * @param w        Ancho de la imagen
1039
         * @param h        Alto de la imagen
1040
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1041
         * @param offset        desplazamiento
1042
         * @param scansize        tama?o de imagen recorrida por cada paso
1043
         * @param origBand        Banda origen del GeoRasterFile
1044
         * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
1045
         */
1046
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1047
                         int offset, int scansize, int origBand, int destBandFlag) {
1048
                int [] line = new int[rgbArray.length]; 
1049
                image.getRGB(startX, startY, w, h, line, offset, scansize);
1050
                if (origBand == 0 && destBandFlag == GeoRasterFile.RED_BAND)
1051
                        for (int i=0; i<line.length; i++)
1052
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
1053
                else if (origBand == 1 && destBandFlag == GeoRasterFile.GREEN_BAND)
1054
                        for (int i=0; i<line.length; i++)
1055
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
1056
                else if (origBand == 2 && destBandFlag == GeoRasterFile.BLUE_BAND)
1057
                        for (int i=0; i<line.length; i++)
1058
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
1059
                
1060
                else if (origBand == 0 && destBandFlag == GeoRasterFile.GREEN_BAND)
1061
                        for (int i=0; i<line.length; i++)
1062
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x00ff0000) >> 8) ;
1063
                else if (origBand == 0 && destBandFlag == GeoRasterFile.BLUE_BAND)
1064
                        for (int i=0; i<line.length; i++)
1065
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x00ff0000) >> 16);
1066
                else if (origBand == 1 && destBandFlag == GeoRasterFile.RED_BAND)
1067
                        for (int i=0; i<line.length; i++)
1068
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x0000ff00) << 8);
1069
                
1070
                else if (origBand == 1 && destBandFlag == GeoRasterFile.BLUE_BAND)
1071
                        for (int i=0; i<line.length; i++)
1072
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x0000ff00) >> 8);
1073
                else if (origBand == 2 && destBandFlag == GeoRasterFile.RED_BAND)
1074
                        for (int i=0; i<line.length; i++)
1075
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x000000ff) << 16);
1076
                else if (origBand == 2 && destBandFlag == GeoRasterFile.GREEN_BAND)
1077
                        for (int i=0; i<line.length; i++)
1078
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x000000ff) << 8);
1079
                image.setRGB(startX, startY, w, h, line, offset, scansize);
1080
        }
1081
        
1082
        private void showOnOpen() {
1083
                  // Report en la apertura (quitar)
1084
                  System.out.println("Fichero GDAL '"+getName()+"' abierto.");
1085
                  System.out.println("Version = "+file.version);
1086
                  System.out.println("   Size = ("+file.width+","+file.height+")");
1087
                  try {
1088
                        System.out.println("   NumBands = ("+file.getRasterCount()+")");
1089
                } catch (GdalException e) {
1090
                        // TODO Auto-generated catch block
1091
                        e.printStackTrace();
1092
                }
1093
                  //file.pintaInfo();
1094
                  file.pintaPaleta();
1095

    
1096
        }
1097

    
1098
        /* (non-Javadoc)
1099
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int, int)
1100
         */
1101
        public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBandFlag)throws SupersamplingNotSupportedException{
1102
                int line, pRGBArray[] = null;
1103
                        
1104
                if(mustVerifySize()){
1105
                        // Work out the correct aspect for the setView call.
1106
                        double dFileAspect = (double)v.width()/(double)v.height();
1107
                        double dWindowAspect = (double)width /(double)height;
1108
        
1109
                        if (dFileAspect > dWindowAspect) {
1110
                          height =(int)((double)width/dFileAspect);
1111
                        } else {
1112
                          width = (int)((double)height*dFileAspect);
1113
                        }
1114
                }
1115
                
1116
                // Set the view
1117
                boolean[] orientation = getOrientation();
1118
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
1119
                        width, height, orientation);
1120
                
1121
                if(width<=0)width=1;
1122
                if(height<=0)height=1;
1123
                
1124
                pRGBArray = new int[width];
1125
                try {
1126
                        setBand(RED_BAND,   rBandNr);
1127
                        setBand(GREEN_BAND, gBandNr);
1128
                        setBand(BLUE_BAND,  bBandNr);
1129
                        file.setAlpha(getAlpha());
1130
                        if(img!=null){
1131
                                if(orientation[1]){
1132
                                        for (line=0; line < height; line++) {
1133
                                                file.readLineRGBA(pRGBArray);
1134
                                                setRGBLine((BufferedImage) img, 0, height - 1 - line, width, 1, pRGBArray, 0, width, origBand, destBandFlag);
1135
                                        }        
1136
                                }else{
1137
                                        for (line=0; line < height; line++) {
1138
                                                file.readLineRGBA(pRGBArray);
1139
                                                setRGBLine((BufferedImage) img, 0, line, width, 1, pRGBArray, 0, width, origBand, destBandFlag);
1140
                                        }
1141
                                }
1142
                                return img;
1143
                        }else{
1144
                                Image image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
1145
                                if(orientation[1]){
1146
                                        for (line=0; line < height; line++) {
1147
                                                file.readLineRGBA(pRGBArray);
1148
                                                setRGBLine((BufferedImage) image, 0, height - 1 - line, width, 1, pRGBArray, 0, width);
1149
                                        }        
1150
                                }else{
1151
                                        for (line=0; line < height; line++) {
1152
                                                file.readLineRGBA(pRGBArray);
1153
                                                setRGBLine((BufferedImage) image, 0, line, width, 1, pRGBArray, 0, width);
1154
                                        }
1155
                                }
1156
                                return image;
1157
                        }
1158
                } catch (Exception e) {
1159
                        // TODO Auto-generated catch block
1160
                        e.printStackTrace();
1161
                }
1162
                
1163
                return img;
1164
        }
1165
        
1166
        /* (non-Javadoc)
1167
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
1168
         */
1169
        public Object getData(int x, int y, int band) {
1170
                if(file != null){
1171
                        Object[] data = file.getData(x, y);
1172
                        return data[band];
1173
                }
1174
                return null;
1175
        }
1176
        
1177
        /**
1178
         * Devuelve los datos de una ventana solicitada
1179
         * @param ulX        coordenada X superior izda.
1180
         * @param ulY        coordenada Y superior derecha.
1181
         * @param sizeX        tama?o en X de la ventana.
1182
         * @param sizeY tama?o en Y de la ventana.
1183
         * @param band        Banda solicitada.
1184
         */
1185
        public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band){
1186
                
1187
                return null;
1188
        }
1189
        
1190
        /**
1191
         * Obtiene la zona (Norte / Sur)
1192
         * @return true si la zona es norte y false si es sur
1193
         */
1194
        
1195
        public boolean getZone(){
1196
                
1197
                return false;
1198
        }
1199
        
1200
        /**
1201
         *Devuelve el n?mero de zona UTM
1202
         *@return N?mero de zona 
1203
         */
1204
        
1205
        public int getUTM(){
1206
                
1207
                return 0;        
1208
        }
1209
        
1210
        /**
1211
         * Obtiene el sistema de coordenadas geograficas
1212
         * @return Sistema de coordenadas geogr?ficas
1213
         */
1214
        public String getGeogCS(){
1215
                
1216
                return new String("");        
1217
        }
1218
        
1219
        /**
1220
         * Devuelve el tama?o de bloque
1221
         * @return Tama?o de bloque
1222
         */
1223
        public int getBlockSize(){
1224
          return file.getBlockSize();
1225
        }
1226
                
1227
        /**
1228
         * Obtiene el objeto que contiene los metadatos
1229
         */
1230
        public Metadata getMetadata() {
1231
                if(file != null)
1232
                        return file.getMetadataJavaObject();
1233
                else 
1234
                        return null;
1235
        }
1236
        
1237
        /**
1238
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1239
         * @return true si est? georreferenciada y false si no lo est?.
1240
         */
1241
        public boolean isGeoreferenced() {
1242
                return file.isGeoreferenced();
1243
        }
1244
    
1245
        /**
1246
         * Obtiene los par?metros de la transformaci?n af?n que corresponde con los elementos de
1247
         * un fichero tfw.
1248
         * <UL> 
1249
         * <LI>[1]tama?o de pixel en X</LI>
1250
         * <LI>[2]rotaci?n en X</LI>
1251
         * <LI>[4]rotaci?n en Y</LI>
1252
         * <LI>[5]tama?o de pixel en Y</LI>
1253
         * <LI>[0]origen en X</LI>
1254
         * <LI>[3]origen en Y</LI>
1255
         * </UL>
1256
         * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n. En principio
1257
         * Gdal es capaz de proporcionarla de esta forma.
1258
         * 
1259
         * En caso de que exista fichero .rmf asociado al raster pasaremos de la informaci?n de georreferenciaci?n
1260
         * del .tfw y devolveremos la que est? asociada al rmf
1261
         * @return vector de double con los elementos de la transformaci?n af?n.
1262
         */
1263
        public double[] getTransform(){
1264
                if(file != null && file.trans != null && !this.rmfExists())
1265
                        return file.trans.adfgeotransform;
1266
                else{
1267
                        if(this.rmfExists){
1268
                                double[] rmfGeoref = {        rmfTransform.getTranslateX(), 
1269
                                                                                rmfTransform.getScaleX(),
1270
                                                                                rmfTransform.getShearX(), 
1271
                                                                                rmfTransform.getTranslateY(),
1272
                                                                                rmfTransform.getShearY(),
1273
                                                                                rmfTransform.getScaleY()};
1274
                                return rmfGeoref;
1275
                        }
1276
                        return null;
1277
                }
1278
                
1279
        }
1280
}
1281

    
1282