Statistics
| Revision:

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

History | View | Annotate | Download (34 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.filter.RasterBuf;
38
import org.cresques.io.data.Metadata;
39
import org.cresques.px.Extent;
40

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

    
57
class GdalNative extends Gdal {
58
        static boolean                                 WITH_OVERVIEWS = true;
59
        private String                                 ext = "";
60
        /**
61
         * Nombre corto del driver de gdal
62
         */
63
        private String                                 shortName = "";
64
        public         GeoTransform                 trans = null;
65
        /**
66
         * Contorno en coordenadas geogr?ficas. (y Extent del raster).
67
         */
68
        public Contour                                 esq = new Contour();
69
        public int                                         width = 0, height = 0;
70
        public double                                 originX = 0D, originY = 0D;
71
        public String                                 version = "";
72
        private int                                 alpha = 0;
73
        protected int                                 rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
74
        private int                                 dataType = GDT_Byte;
75
        /**
76
         * Metadatos leidos de la imagen
77
         */
78
        private Metadata                        metadata = null;
79
        private boolean                         georeferenced = true;
80

    
81
        
82
        // Polilinea con extent
83
        public class Contour extends Vector {
84
                final private static long serialVersionUID = -3370601314380922368L;
85
                public double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
86
                public double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
87
                public Contour() {
88
                        super();
89
                }
90
                public void add(Point2D pt) {
91
                        super.add(pt);
92
                        if (pt.getX() > maxX) maxX = pt.getX();
93
                        if (pt.getX() < minX) minX = pt.getX();
94
                        if (pt.getY() > maxY) maxY = pt.getY();
95
                        if (pt.getY() < minY) minY = pt.getY();
96
                }
97
        }
98
                
99
        public GdalNative(String fName) throws GdalException, IOException {
100
                super();
101
                init(fName);
102
        }
103
        
104
        private void init(String fName) throws GdalException, IOException {
105
                open(fName,GA_ReadOnly);
106
                ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
107
                if (ext.compareTo("tif") == 0)
108
                        WITH_OVERVIEWS = false;
109
                width = getRasterXSize();
110
                height = getRasterYSize();
111
                setDataType(this.getRasterBand(1).getRasterDataType());
112
                shortName = getDriverShortName();
113
                metadata = new Metadata(getMetadata());
114
                
115
                //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
116
                //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
117
                metadata.initColorInterpretation(getRasterCount());
118
                metadata.initNoDataByBand(getRasterCount());
119
            for(int i = 0; i < getRasterCount(); i++){
120
                    GdalRasterBand rb = getRasterBand(i + 1);
121
                    String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
122
                    metadata.setNoDataValue(i, rb.getRasterNoDataValue());
123
                    metadata.setColorInterpValue(i, colorInt);
124
                    if(colorInt.equals("Red"))
125
                            rBandNr = i + 1;
126
                    if(colorInt.equals("Green"))
127
                            gBandNr = i + 1;        
128
                    if(colorInt.equals("Blue"))
129
                            bBandNr = i + 1;                
130
                    if(colorInt.equals("Alpha"))
131
                            aBandNr = i + 1;
132
            }
133
            
134
                double ox=0D, oy=0D, resx=0D, resy=0D;
135
                try{
136
                        trans = getGeoTransform();
137
                        ox = trans.adfgeotransform[0];
138
                        oy = trans.adfgeotransform[3];
139
                        resx = trans.adfgeotransform[1];
140
                        resy = trans.adfgeotransform[5];
141
                        
142
                        esq.add(new Point2D.Double(ox, oy));
143
                        esq.add(new Point2D.Double(ox+resx*width, oy));
144
                        esq.add(new Point2D.Double(ox, oy+resy*height));
145
                        this.georeferenced = true;
146
                        esq.add(new Point2D.Double(ox+resx*width, oy+resy*height));
147
                }catch(GdalException exc){
148
                        esq.add(new Point2D.Double(0, 0));
149
                        esq.add(new Point2D.Double(width, 0));
150
                        esq.add(new Point2D.Double(0, height));
151
                        esq.add(new Point2D.Double(width, height));
152
                        this.georeferenced = false;
153
                }
154
        }
155
        
156
        public void setAlpha(int a) { alpha = a; }
157
        
158
        public void setDataType(int dt) { dataType = dt; }
159
        public int getDataType() { return dataType; }
160
        
161
        double lastReadLine = -1;
162
        int currentFullWidth = -1;
163
        int currentFullHeight = -1;
164
        int currentViewWidth = -1;
165
        int currentViewHeight = -1;
166
        double currentViewX = 0D;
167
        double currentViewY = 0D;
168
        double viewportScaleX = 0D;
169
        double viewportScaleY = 0D;
170
        double wcWidth = 0D;
171
        double stepX = 0D;
172
        double stepY = 0D;
173
        int currentOverview = -1;
174
        
175
        protected GdalRasterBand bandR = null, bandG = null, bandB = null, bandA = null;
176
        
177
        /**
178
         * Devuelve la banda actualmente en uso para el color especificado.
179
         * @param color 0=Rojo, 1=Green, 2=Blue.
180
         * @return
181
         */
182
        public GdalRasterBand getCurrentBand(int color) {
183
                if (color == 0) 
184
                        return bandR;
185
                else if (color == 1) 
186
                        return bandG;
187
                return bandB;
188
        }
189
        // Supone rasters no girados
190
        public Point2D worldToRaster(Point2D pt) {
191
                double x = (((double) currentFullWidth)/(esq.maxX-esq.minX))*(pt.getX()-esq.minX);
192
                double y = (((double) currentFullHeight)/(esq.maxY-esq.minY))*(esq.maxY-pt.getY());
193
                Point2D ptRes = new Point2D.Double(x, y);
194
                return ptRes;
195
        }
196
        
197
        public int setView(double dWorldTLX, double dWorldTLY,
198
            double dWorldBRX, double dWorldBRY,
199
            int nWidth, int nHeight) {
200
                int err = 0;
201
                currentFullWidth = width;
202
                currentFullHeight = height;
203
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
204
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
205
                // Calcula cual es la primera l?nea a leer;
206
                currentViewWidth = nWidth;
207
                currentViewHeight = nHeight;
208
                wcWidth = Math.abs(br.getX() - tl.getX());
209
                
210
                currentViewX = tl.getX();
211
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
212
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
213
                stepX = 1D/viewportScaleX;
214
                stepY = 1D/viewportScaleY;
215
                lastReadLine = tl.getY();
216
                try {
217
                        // calcula el overview a usar
218
                        bandR = getRasterBand(1);
219
                        currentOverview = -1;
220
                        if (WITH_OVERVIEWS && bandR.getOverviewCount() > 0) {
221
                                GdalRasterBand ovb = null;
222
                                for (int i=bandR.getOverviewCount()-1; i>0; i--) {              
223
                                        ovb = bandR.getOverview(i);
224
                                        if (ovb.getRasterBandXSize()>getRasterXSize()*viewportScaleX) {
225
                                                currentOverview = i;
226
                                    viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
227
                                    viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
228
                                    stepX = 1D/viewportScaleX;
229
                                    stepY = 1D/viewportScaleY;
230
                                    currentFullWidth = ovb.getRasterBandXSize();
231
                                    currentFullHeight = ovb.getRasterBandYSize();
232
                                    tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
233
                                    currentViewX = tl.getX();
234
                                    lastReadLine = tl.getY();
235
                                    break;
236
                                        }
237
                                }
238
                        }
239
        
240
                        // Selecciona las bandas y los overviews necesarios
241
                        bandR = getRasterBand(rBandNr);
242
                        setDataType(bandR.getRasterDataType());
243
                        
244
                        if (this.getRasterCount() > 1) {
245
                                bandG = getRasterBand(gBandNr);
246
                                bandB = getRasterBand(bBandNr);                                
247
                                if(metadata.isAlphaBand())
248
                                //if(this.getRasterCount() == 4 && shortName.equals("PNG"))
249
                                        bandA = getRasterBand(aBandNr); 
250
                        }
251
                        if (currentOverview > 0) {
252
                                bandR = bandR.getOverview(currentOverview);
253
                            if (this.getRasterCount() > 1) {
254
                                        bandG = bandG.getOverview(currentOverview);
255
                                        bandB = bandB.getOverview(currentOverview);
256
                                        if(metadata.isAlphaBand())
257
                                        //if(this.getRasterCount() == 4 && shortName.equals("PNG"))
258
                                                bandA = bandA.getOverview(currentOverview);
259
                                }
260
                        }
261

    
262
                        //System.out.println(band.)
263
                } catch (GdalException e) {
264
                        // TODO Auto-generated catch block
265
                        e.printStackTrace();
266
                }
267

    
268
                System.out.println("GdalFile: TL=("+dWorldTLX+","+dWorldTLY+
269
                        "); BR=("+dWorldBRX+","+dWorldBRY+")\n"+
270
                        "GdalFile: escala="+viewportScaleX+"; lastReadLine="+lastReadLine+"\n"+
271
                    "Actual Raster Size="+currentFullWidth+"x"+currentFullHeight+
272
                        "\nDataType="+dataType);
273
                return err;
274
        }
275
        
276
        int lastY = -1;
277
        
278
        public void readLine(int[][] line) throws GdalException {
279
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
280
        int x = (int) Math.ceil(currentViewX);
281
        int y = (int) Math.ceil(lastReadLine);
282
        GdalBuffer r = null, g = null, b = null, p = null;
283
        GdalBuffer a = new GdalBuffer();
284
        
285
        //if (alpha > 0) a = alpha << 24;
286
        if (x+w > bandR.getRasterBandXSize()) 
287
                w = bandR.getRasterBandXSize()-x;
288
        
289
        if(bandR.getRasterColorTable() != null){
290
                p = bandR.readRasterWithPalette(x, y, w, 1, w, 1, dataType);
291
                a.buffByte = p.buffAPalette;
292
                r = new GdalBuffer();
293
                r.buffByte = p.buffRPalette;
294
                g = new GdalBuffer();
295
                g.buffByte = p.buffGPalette;
296
                b = new GdalBuffer();
297
                b.buffByte = p.buffBPalette;
298
        }else{
299
                a.buffByte = new byte[w];
300
                        r = bandR.readRaster(x, y, w, 1, w, 1, dataType);
301
                        if (bandG != null)
302
                            g = bandG.readRaster(x, y, w, 1, w, 1, dataType);
303
                        if (bandB != null)
304
                            b = bandB.readRaster(x, y, w, 1, w, 1, dataType);
305
        }
306
                          
307
        lastReadLine += stepY;
308
        
309
                  int i=0;
310
                  double j = 0D;
311
                  double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
312
                  
313
                  if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
314
                          if (g == null){ // Sibgle Band (Typical DEM)
315
                                  for (int k=0; k<4; k++){
316
                                          for (i=0, j = initOffset; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
317
                                                  if(k<3)
318
                                                          line[i][k] = (r.buffShort[(int) j] & 0xffff);
319
                                                  else
320
                                                          line[i][3] = 0xff;
321
                                          }
322
                              }
323
                          }else { // Multiband
324
                                  //System.err.println("readLine(): Raster 16bits multibanda");
325
                                  GdalBuffer [] bands = {r,g,b};
326
                                  for (int k=0; k<4; k++){
327
                                      for (i=0, j = initOffset; i<currentViewWidth && j<r.getSize(); i++, j+=stepX){
328
                                              if(k<3)
329
                                                      line[i][k] = (bands[k].buffShort[(int) j] & 0xffff);
330
                                              else
331
                                                      line[i][3] = 0xff;
332
                                      }
333
                                  }
334
                          }
335
                  }else if(dataType == GDT_Float32){
336
                          GdalBuffer [] bands = {r,g,b};
337
                        for (int k=0; k<4; k++){
338
                              for (i=0, j = initOffset; i<currentViewWidth && j<r.getSize(); i++, j+=stepX){
339
                                      if(k < 3)
340
                                              line[i][k] = (int)bands[0].buffFloat[(int) j];
341
                                      else
342
                                              line[i][3] = 0xff;
343
                              }
344
                        }
345
                  }
346
                  
347
                return;
348
        }
349
        
350
        int readLineRGBA(int [] line) throws GdalException {
351
                int err = 0;
352
                
353
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
354
        int x = (int) currentViewX;
355
        int y = (int) lastReadLine;
356
        GdalBuffer r = null, g = null, b = null, p = null;
357
        GdalBuffer a = new GdalBuffer();
358
        
359
        while(y >= bandR.getRasterBandYSize())
360
                y--;
361
        
362
        //if (alpha > 0) a = alpha << 24;
363
        if (x+w > bandR.getRasterBandXSize()) 
364
                w = bandR.getRasterBandXSize()-x;
365
        
366
        if(bandR.getRasterColorTable() != null){
367
                p = bandR.readRasterWithPalette(x, y, w, 1, w, 1, dataType);
368
                a.buffByte = p.buffAPalette;
369
                r = new GdalBuffer();
370
                r.buffByte = p.buffRPalette;
371
                g = new GdalBuffer();
372
                g.buffByte = p.buffGPalette;
373
                b = new GdalBuffer();
374
                b.buffByte = p.buffBPalette;
375
        }else{
376
                
377
                r = bandR.readRaster(x, y, w, 1, w, 1, dataType);
378
                        if (bandG != null)
379
                            g = bandG.readRaster(x, y, w, 1, w, 1, dataType);
380
                        if (bandB != null)
381
                            b = bandB.readRaster(x, y, w, 1, w, 1, dataType);
382
                
383
                if(metadata.isAlphaBand()){
384
                //if(getRasterCount() == 4 && shortName.equals("PNG")){
385
                        a = bandA.readRaster(x, y, w, 1, w, 1, GDT_Byte);        
386
                }else{
387
                            a.buffByte = new byte[w];
388
                            for (int i = 0;i < w;i++)
389
                                    a.buffByte[i] = (byte)255;
390
                }
391
        }
392
                  lastReadLine += stepY;
393
          
394
                  int i=0;
395
                  double j =  Math.abs(currentViewX - ((int)currentViewX));
396
                int alpha = (this.alpha & 0xff) << 24;
397
                //try{
398
                  if (dataType == GDT_Byte){
399
                          if (g != null)
400
                              for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
401
                                      int jInt = (int)(j);
402
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
403
                              }
404
                      else
405
                              for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
406
                                      int jInt = (int)(j);
407
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
408
                              }
409
                  }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
410
                          if (g == null) // Sibgle Band (Typical DEM)
411
                              /*for (i=0, j=0F, i2 = 1; i<currentViewWidth && i2<r.length;
412
                                      i++, j+=step, i2 = (((int) j)*2)+1) {
413
                                      line[i] = a + ((r[i2-1]) << 8) + r[i2];
414
                              }*/
415
                                    for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
416
                                            int jInt = (int)(j);
417
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
418
                              }
419
                          else { // Multiband
420
                                  // System.err.println("Raster 16bits multibanda");
421
                              for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
422
                                      int jInt = (int)(j);
423
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | 
424
                                                                                                                           (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
425
                                                                                                                           (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
426
                              }
427
                          }
428
                  }
429
                //}catch(ArrayIndexOutOfBoundsException ex){}
430
                return err;
431
        }
432
                
433
        /**
434
         * Lee una franja de la imagen.
435
         * @param bandH Altura de la franja
436
         * @param bufH        Altura del buffer
437
         * @param buf        Buffer con la franja (retorno)
438
         * @return
439
         * @throws GdalException
440
         */
441
        public int readBandRGBA(int bandH, int bufH, int [] buf) throws GdalException {
442
                int err = 0;
443
        int w = (int)(((double)currentViewWidth)*stepX);
444
        int x = (int)(((double)currentViewX)*stepX);
445
        int y = (int) lastReadLine;
446
        int h = (int) (((double)bandH)*stepX);
447
        System.out.println("Leyendo "+y);
448
        GdalBuffer r = null, g = null, b = null, p = null;
449
        GdalBuffer a = new GdalBuffer();
450
        
451
        if (x+w > bandR.getRasterBandXSize()) 
452
                w = bandR.getRasterBandXSize()-x;
453
        
454
        if(bandR.getRasterColorTable() != null){
455
                p = bandR.readRasterWithPalette(x, y, w, h, w, h, GDT_Byte);
456
                a.buffByte = p.buffAPalette;
457
                r = new GdalBuffer();
458
                r.buffByte = p.buffRPalette;
459
                g = new GdalBuffer();
460
                g.buffByte = p.buffGPalette;
461
                b = new GdalBuffer();
462
                b.buffByte = p.buffBPalette;
463
        }else{
464
                r = bandR.readRaster(x, y, w, h, w, h, dataType);
465
                        if (bandG != null)
466
                            g = bandG.readRaster(x, y, w, h, w, h, dataType);
467
                        if (bandB != null)
468
                            b = bandB.readRaster(x, y, w, h, w, h, dataType);
469
                        
470
                if(metadata.isAlphaBand()){
471
                //if(getRasterCount() == 4 && shortName.equals("PNG")){
472
                        a = bandA.readRaster(x, y, w, h, w, h, GDT_Byte);
473
                }else{
474
                            a.buffByte = new byte[w];
475
                            for (int i = 0;i < w*h;i++)
476
                                    a.buffByte[i] = (byte)255;
477
                }
478
        }
479
                  lastReadLine += ((double)bandH)*stepY;
480
                  
481
                  // TODO Acabar de implementarlo
482
                  float k=0F;
483
                int alpha = (this.alpha & 0xff) << 24;
484
                  for (int j=0, t=0; j<bandH; j++) {
485
                          k = j*w; t=j*currentViewWidth;
486
                          for (int i=0; i<currentViewWidth && k<r.getSize(); i++, k+=stepX) {
487
                                  buf[t+i] = (alpha & ((a.buffByte[(int)j])& 0xff) << 24) + ((r.buffByte[(int) k]) << 16) + ((g.buffByte[(int) k]) << 8) + b.buffByte[(int) k];
488
                          }
489
                  }
490
                
491
                return err;
492
                
493
        }
494

    
495
        void pintaInfo() {
496
                try {
497
                        //System.out.println("Origin = "+originX+","+originY);
498
                        //System.out.println("Origin = "+this.);
499
                        System.out.println("GeoTransform:");
500
                        GeoTransform trans = getGeoTransform();
501
                        for (int i=0; i<6; i++)
502
                                System.out.println("  param["+i+"]="+trans.adfgeotransform[i]);
503
                        System.out.println("Metadata:");
504
                        String [] metadata = getMetadata();
505
                        for (int i=0; i<metadata.length; i++) {
506
                                System.out.println(metadata[i]);
507
                        }
508
                } catch (GdalException e) {
509
                        
510
                }
511
                
512
        }
513
        
514
        void pintaPaleta() {
515
        }
516
        
517
        public int getBlockSize(){
518
                return this.getBlockSize();
519
        }
520

    
521
        /**
522
         * Obtiene el objeto que contiene los metadatos
523
         */
524
        public Metadata getMetadataJavaObject() {
525
                return metadata;
526
        }
527

    
528
        /**
529
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
530
         * @return true si est? georreferenciada y false si no lo est?.
531
         */
532
        public boolean isGeoreferenced() {
533
                return georeferenced;
534
        }
535
}
536

    
537
/**
538
 * @author Luis W. Sevilla
539
 */
540
public class GdalFile extends GeoRasterFile {
541
        public final static int         BAND_HEIGHT = 64;
542
        protected GdalNative                 file = null;
543
        /**
544
         * Tama?o de pixel para las imagenes con fichero RMF. No podemos salvarlo en file porque es necesario conocer el
545
         * tama?o de pixel asignado por rl .rmf y el tama?o de pixel real.
546
         */
547
        private double                                pixelSizeX = 0D, pixelSizeY = 0D;
548

    
549
        private Extent v = null;
550
        
551
        public GdalFile(IProjection proj, String fName){
552
                super(proj, fName);
553
                extent = new Extent();
554
                try {
555
                        file = new GdalNative(fName);
556
                        load();
557
                        readGeoInfo(fName);
558
                        bandCount = file.getRasterCount(); 
559
                        if ( bandCount > 2) {
560
                                setBand(RED_BAND,   0);
561
                                setBand(GREEN_BAND, 1);
562
                                setBand(BLUE_BAND,  2);
563
                        } else
564
                                setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);
565
                } catch(Exception e){
566
                          System.out.println("Error en GdalOpen");
567
                          e.printStackTrace();
568
                          file = null;
569
                }
570
                
571
                switch(file.getDataType()){
572
                case 1:setDataType(DataBuffer.TYPE_BYTE);break;//GDT_BYTE 
573
                case 2://GDT_UInt16 
574
                case 3:setDataType(DataBuffer.TYPE_SHORT);break;//GDT_Int16        
575
                case 4://GDT_UInt32
576
                case 5:setDataType(DataBuffer.TYPE_INT);break;//GDT_Int32
577
                case 6:setDataType(DataBuffer.TYPE_FLOAT);break;//GDT_Float32
578
                case 7:setDataType(DataBuffer.TYPE_DOUBLE);break;//GDT_Float64
579
                case 8:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CInt16
580
                case 9:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CInt32
581
                case 10:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CFloat32
582
                case 11:setDataType(DataBuffer.TYPE_UNDEFINED);break;//GDT_CFloat64
583
                }
584
                
585
        }
586
        
587
        /**
588
         * Obtenemos o calculamos el extent de la imagen.
589
         */
590
        public GeoFile load() {
591
                extent = new Extent(file.esq.minX, file.esq.minY, file.esq.maxX, file.esq.maxY);        
592
                return this;
593
        }
594
        
595
        /**
596
         * Cierra el fichero de imagen
597
         */
598
        public void close() {
599
                try {
600
                        if(file != null){
601
                                file.close();
602
                                file = null;
603
                        }
604
                } catch (GdalException e) {
605
                        // TODO Auto-generated catch block
606
                        e.printStackTrace();
607
                }
608
        }
609
        
610
        /**
611
         * Asigna a cada banda R,G o B una banda de la imagen
612
         */
613
        public void setBand(int flag, int bandNr) {
614
                super.setBand(flag, bandNr);
615
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) file.rBandNr = bandNr+1;
616
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) file.gBandNr = bandNr+1;
617
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) file.bBandNr = bandNr+1;
618
        }
619
        
620
        /**
621
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
622
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
623
         * ha de estar en coordenadas del fichero.
624
         */
625
        public void setView(Extent e) { 
626
                if(rmfExists){
627
                        //Trasladamos la petici?n al origen
628
                        Point2D.Double petInit = null, petEnd = null;
629
                        try{
630
                                petInit = new Point2D.Double(e.minX(),  e.maxY());
631
                                petEnd = new Point2D.Double(e.maxX(), e.minY());
632
                                transformNewExtent.inverseTransform(petInit, petInit);
633
                                transformNewExtent.inverseTransform(petEnd, petEnd);
634
                        }catch(NoninvertibleTransformException ex){}
635
                        
636
                        //Redimensionamos la petici?n al tama?o de caja del destino
637
                        double originX = (petInit.getX() * getExtentRatio().getX()) / extent.width();
638
                        double originY = (petInit.getY() * getExtentRatio().getY()) / extent.height();
639
                        double endX = (petEnd.getX() * getExtentRatio().getX()) / extent.width();
640
                        double endY = (petEnd.getY() * getExtentRatio().getY()) / extent.height();
641
                        
642
                        //Trasladamos a su sistema de coordenadas
643
                        Point2D.Double destInit = new Point2D.Double(originX, originY);
644
                        Point2D.Double destEnd = new Point2D.Double(endX, endY);
645
                        
646
                        transformOldExtent.transform(destInit, destInit);
647
                        transformOldExtent.transform(destEnd, destEnd);
648
                        if(file.trans == null){
649
                                destInit.y = getExtentRatio().getY() + destInit.y; 
650
                                destEnd.y = getExtentRatio().getY() + destEnd.y;
651
                        }
652
                        v = new Extent(        destInit.getX(), destInit.getY(), destEnd.getX(), destEnd.getY());
653
                                                
654
                }else
655
                        v = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());        
656
        }
657
                
658
        /**
659
         * Obtiene extent de la vista actual
660
         */
661
        public Extent getView() { 
662
                return v; 
663
        }
664
        
665
        /**
666
         * Obtiene la anchura del fichero
667
         */
668
        public int getWidth() {        
669
                return file.width; 
670
        }
671
        
672
        /**
673
         * Obtiene la altura del fichero
674
         */
675
        public int getHeight() { 
676
                return file.height;
677
        }
678

    
679
        /* (non-Javadoc)
680
         * @see org.cresques.io.GeoRasterFile#reProject(org.cresques.cts.ICoordTrans)
681
         */
682
        public void reProject(ICoordTrans rp) {
683
                // TODO Auto-generated method stub
684
        }
685
        
686
        /* (non-Javadoc)
687
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans)
688
         */
689
        public Image updateImage(int width, int height, ICoordTrans rp) {
690
                int line, pRGBArray[] = null;
691
                Image image = null;
692
                        
693
                if (mustVerifySize()) {
694
                        // Work out the correct aspect for the setView call.
695
                        double dFileAspect = (double)v.width()/(double)v.height();
696
                        double dWindowAspect = (double)width /(double)height;
697
        
698
                        if (dFileAspect > dWindowAspect) {
699
                          height =(int)((double)width/dFileAspect);
700
                        } else {
701
                          width = (int)((double)height*dFileAspect);
702
                        }
703
                }
704
                
705
                // Set the view
706
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
707
                        width, height);
708
                
709
                if(width<=0)width=1;
710
                if(height<=0)height=1;
711
                
712
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
713
                //image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
714
                pRGBArray = new int[width/**BAND_HEIGHT*/];
715
                try {
716
                        //int nLin = height % BAND_HEIGHT;
717
                        file.setAlpha(getAlpha());
718
                        setBand(RED_BAND,   rBandNr);
719
                        setBand(GREEN_BAND, gBandNr);
720
                        setBand(BLUE_BAND,  bBandNr);
721
                        for (line=0; line < height; line++) { //+=BAND_HEIGHT) {
722
                                //int bandH = Math.min(BAND_HEIGHT, height-line);
723
                                //file.readBandRGBA(bandH, BAND_HEIGHT, pRGBArray);
724
                                file.readLineRGBA(pRGBArray);
725
                                setRGBLine((BufferedImage) image, 0, line, width, 1/*bandH*/, pRGBArray, 0, width);
726
                        }
727
                } catch (Exception e) {
728
                        // TODO Auto-generated catch block
729
                        e.printStackTrace();
730
                }
731
                
732
                return image;
733
        }
734
        
735
        public RasterBuf getRaster(int width, int height, ICoordTrans rp) {
736
                int line;
737
                RasterBuf raster = null;
738
                        
739
                if(mustVerifySize()){
740
                        // Work out the correct aspect for the setView call.
741
                        double dFileAspect = (double)v.width()/(double)v.height();
742
                        double dWindowAspect = (double)width /(double)height;
743
        
744
                        if (dFileAspect > dWindowAspect) {
745
                          height =(int)((double)width/dFileAspect);
746
                        } else {
747
                          width = (int)((double)height*dFileAspect);
748
                        }
749
                }
750
                
751
                // Set the view
752
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
753
                        width, height);
754
                
755
                raster = new RasterBuf(DataBuffer.TYPE_INT, width, height, 4, new Point(0,0));
756
                try {
757
                        //int nLin = height % BAND_HEIGHT;
758
                        file.setAlpha(getAlpha());
759
                        setBand(RED_BAND,   rBandNr);
760
                        setBand(GREEN_BAND, gBandNr);
761
                        setBand(BLUE_BAND,  bBandNr);
762
                        for (line=0; line < height; line++) { //+=BAND_HEIGHT) {
763
                                file.readLine(raster.getLineInt(line));
764
                        }
765
                } catch (Exception e) {
766
                        // TODO Auto-generated catch block
767
                        e.printStackTrace();
768
                }
769
                
770
                return raster;
771
        }
772
        
773
        /**
774
         * Asigna al objeto Image los valores con los dato de la imagen contenidos en el 
775
         * vector de enteros.
776
         * @param image        imagen con los datos actuales
777
         * @param startX        inicio de la posici?n en X dentro de la imagen
778
         * @param startY        inicio de la posici?n en X dentro de la imagen
779
         * @param w        Ancho de la imagen
780
         * @param h        Alto de la imagen
781
         * @param rgbArray        vector que contiene la banda que se va a sustituir
782
         * @param offset        desplazamiento
783
         * @param scansize        tama?o de imagen recorrida por cada p
784
         */
785
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
786
                         int offset, int scansize) {
787
                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
788
        }
789
        
790
        /**
791
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
792
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
793
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
794
         * banda correspondiente a flags es sustituida por los datos del vector.
795
         * @param image        imagen con los datos actuales
796
         * @param startX        inicio de la posici?n en X dentro de la imagen
797
         * @param startY        inicio de la posici?n en X dentro de la imagen
798
         * @param w        Ancho de la imagen
799
         * @param h        Alto de la imagen
800
         * @param rgbArray        vector que contiene la banda que se va a sustituir
801
         * @param offset        desplazamiento
802
         * @param scansize        tama?o de imagen recorrida por cada paso
803
         * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
804
         */
805
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
806
                         int offset, int scansize, int flags) {
807
                int [] line = new int[rgbArray.length]; 
808
                image.getRGB(startX, startY, w, h, line, offset, scansize);
809
                if (flags == GeoRasterFile.RED_BAND)
810
                        for (int i=0; i<line.length; i++)
811
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
812
                else if (flags == GeoRasterFile.GREEN_BAND)
813
                        for (int i=0; i<line.length; i++)
814
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
815
                else if (flags == GeoRasterFile.BLUE_BAND)
816
                        for (int i=0; i<line.length; i++)
817
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
818
                image.setRGB(startX, startY, w, h, line, offset, scansize);
819
        }
820
        
821
        /**
822
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
823
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
824
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
825
         * banda correspondiente a flags es sustituida por los datos del vector.
826
         * @param image        imagen con los datos actuales
827
         * @param startX        inicio de la posici?n en X dentro de la imagen
828
         * @param startY        inicio de la posici?n en X dentro de la imagen
829
         * @param w        Ancho de la imagen
830
         * @param h        Alto de la imagen
831
         * @param rgbArray        vector que contiene la banda que se va a sustituir
832
         * @param offset        desplazamiento
833
         * @param scansize        tama?o de imagen recorrida por cada paso
834
         * @param origBand        Banda origen del GeoRasterFile
835
         * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
836
         */
837
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
838
                         int offset, int scansize, int origBand, int destBandFlag) {
839
                int [] line = new int[rgbArray.length]; 
840
                image.getRGB(startX, startY, w, h, line, offset, scansize);
841
                if (origBand == 0 && destBandFlag == GeoRasterFile.RED_BAND)
842
                        for (int i=0; i<line.length; i++)
843
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
844
                else if (origBand == 1 && destBandFlag == GeoRasterFile.GREEN_BAND)
845
                        for (int i=0; i<line.length; i++)
846
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
847
                else if (origBand == 2 && destBandFlag == GeoRasterFile.BLUE_BAND)
848
                        for (int i=0; i<line.length; i++)
849
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
850
                
851
                else if (origBand == 0 && destBandFlag == GeoRasterFile.GREEN_BAND)
852
                        for (int i=0; i<line.length; i++)
853
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x00ff0000) >> 8) ;
854
                else if (origBand == 0 && destBandFlag == GeoRasterFile.BLUE_BAND)
855
                        for (int i=0; i<line.length; i++)
856
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x00ff0000) >> 16);
857
                else if (origBand == 1 && destBandFlag == GeoRasterFile.RED_BAND)
858
                        for (int i=0; i<line.length; i++)
859
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x0000ff00) << 8);
860
                
861
                else if (origBand == 1 && destBandFlag == GeoRasterFile.BLUE_BAND)
862
                        for (int i=0; i<line.length; i++)
863
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x0000ff00) >> 8);
864
                else if (origBand == 2 && destBandFlag == GeoRasterFile.RED_BAND)
865
                        for (int i=0; i<line.length; i++)
866
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x000000ff) << 16);
867
                else if (origBand == 2 && destBandFlag == GeoRasterFile.GREEN_BAND)
868
                        for (int i=0; i<line.length; i++)
869
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x000000ff) << 8);
870
                image.setRGB(startX, startY, w, h, line, offset, scansize);
871
        }
872
        
873
        private void showOnOpen() {
874
                  // Report en la apertura (quitar)
875
                  System.out.println("Fichero GDAL '"+getName()+"' abierto.");
876
                  System.out.println("Version = "+file.version);
877
                  System.out.println("   Size = ("+file.width+","+file.height+")");
878
                  try {
879
                        System.out.println("   NumBands = ("+file.getRasterCount()+")");
880
                } catch (GdalException e) {
881
                        // TODO Auto-generated catch block
882
                        e.printStackTrace();
883
                }
884
                  //file.pintaInfo();
885
                  file.pintaPaleta();
886

    
887
        }
888

    
889
        /* (non-Javadoc)
890
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int, int)
891
         */
892
        public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBandFlag)throws SupersamplingNotSupportedException{
893
                int line, pRGBArray[] = null;
894
                        
895
                if(mustVerifySize()){
896
                        // Work out the correct aspect for the setView call.
897
                        double dFileAspect = (double)v.width()/(double)v.height();
898
                        double dWindowAspect = (double)width /(double)height;
899
        
900
                        if (dFileAspect > dWindowAspect) {
901
                          height =(int)((double)width/dFileAspect);
902
                        } else {
903
                          width = (int)((double)height*dFileAspect);
904
                        }
905
                }
906
                
907
                // Set the view
908
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(),
909
                        width, height);
910
                
911
                if(width<=0)width=1;
912
                if(height<=0)height=1;
913
                
914
                pRGBArray = new int[width/**BAND_HEIGHT*/];
915
                try {
916
                        setBand(RED_BAND,   rBandNr);
917
                        setBand(GREEN_BAND, gBandNr);
918
                        setBand(BLUE_BAND,  bBandNr);
919
                        file.setAlpha(getAlpha());
920
                        if(img!=null){
921
                                for (line=0; line < height; line++) { 
922
                                        file.readLineRGBA(pRGBArray);
923
                                        setRGBLine((BufferedImage) img, 0, line, width, 1/*bandH*/, pRGBArray, 0, width, origBand, destBandFlag);
924
                                }
925
                                return img;
926
                        }else{
927
                                Image image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
928
                                for (line=0; line < height; line++) { 
929
                                        file.readLineRGBA(pRGBArray);
930
                                        setRGBLine((BufferedImage) image, 0, line, width, 1/*bandH*/, pRGBArray, 0, width);
931
                                }
932
                                return image;
933
                        }
934
                } catch (Exception e) {
935
                        // TODO Auto-generated catch block
936
                        e.printStackTrace();
937
                }
938
                
939
                return img;
940
        }
941
        
942
        /* (non-Javadoc)
943
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
944
         */
945
        public Object getData(int x, int y, int band) {
946
                // TODO Auto-generated method stub
947
                return null;
948
        }
949
        
950
        /**
951
         * Devuelve los datos de una ventana solicitada
952
         * @param ulX        coordenada X superior izda.
953
         * @param ulY        coordenada Y superior derecha.
954
         * @param sizeX        tama?o en X de la ventana.
955
         * @param sizeY tama?o en Y de la ventana.
956
         * @param band        Banda solicitada.
957
         */
958
        public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band){
959
                
960
                return null;
961
        }
962
        
963
        /**
964
         * Obtiene la zona (Norte / Sur)
965
         * @return true si la zona es norte y false si es sur
966
         */
967
        
968
        public boolean getZone(){
969
                
970
                return false;
971
        }
972
        
973
        /**
974
         *Devuelve el n?mero de zona UTM
975
         *@return N?mero de zona 
976
         */
977
        
978
        public int getUTM(){
979
                
980
                return 0;        
981
        }
982
        
983
        /**
984
         * Obtiene el sistema de coordenadas geograficas
985
         * @return Sistema de coordenadas geogr?ficas
986
         */
987
        public String getGeogCS(){
988
                
989
                return new String("");        
990
        }
991
        
992
        /**
993
         * Devuelve el tama?o de bloque
994
         * @return Tama?o de bloque
995
         */
996
        public int getBlockSize(){
997
          return file.getBlockSize();
998
        }
999
        
1000
         /**
1001
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
1002
         * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo.
1003
         * @param originX Origen de la imagen en la coordenada X
1004
         * @param originY Origen de la imagen en la coordenada Y
1005
         */
1006
        public void setExtentTransform(double originX, double originY, double w, double h, double psX, double psY) {
1007
                pixelSizeX = psX;
1008
            pixelSizeY = psY;
1009
            
1010
                double oldOriginX = 0D;
1011
                double oldOriginY = 0D;
1012
                if(file.trans != null){
1013
                        oldOriginX = file.trans.adfgeotransform[0];
1014
                        oldOriginY = file.trans.adfgeotransform[3];
1015
                }
1016
                
1017
                transformNewExtent.translate(originX, originY);
1018
                transformOldExtent.translate(oldOriginX, oldOriginY);
1019
                extentsRatio.setLocation(extent.width(), extent.height());
1020
        }
1021
        
1022
        /**
1023
         * Obtiene el objeto que contiene los metadatos
1024
         */
1025
        public Metadata getMetadata() {
1026
                if(file != null)
1027
                        return file.getMetadataJavaObject();
1028
                else 
1029
                        return null;
1030
        }
1031
        
1032
        /**
1033
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1034
         * @return true si est? georreferenciada y false si no lo est?.
1035
         */
1036
        public boolean isGeoreferenced() {
1037
                return file.isGeoreferenced();
1038
        }
1039
    
1040
}
1041

    
1042