Statistics
| Revision:

root / trunk / libraries / libCq_CMS_praster / src / org / cresques / io / GdalFile.java @ 8026

History | View | Annotate | Download (47 KB)

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

    
26
import java.awt.Image;
27
import java.awt.geom.AffineTransform;
28
import java.awt.geom.NoninvertibleTransformException;
29
import java.awt.geom.Point2D;
30
import java.awt.geom.Rectangle2D;
31
import java.awt.image.BufferedImage;
32
import java.io.IOException;
33
import java.util.Vector;
34

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

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

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

    
63
class GdalNative extends Gdal {
64
        static boolean                                 WITH_OVERVIEWS = true;
65
        private GdalFile                        driver = null;
66
        private String                                 ext = "";
67
        private String                                 fileName = null;
68
        /**
69
         * Nombre corto del driver de gdal
70
         */
71
        private String                                 shortName = "";
72
        public         GeoTransform                 trans = null;
73
        /**
74
         * Contorno en coordenadas geogr?ficas. (y Extent del raster).
75
         */
76
        public Contour                                 bBoxRot = new Contour();
77
        /**
78
         * Contorno en coordenadas geogr?ficas sin rotaci?n aplicada. Esto es util para poder
79
         * calcular los pixeles necesarios que se van a leer del raster. Cuando el raster no tiene 
80
         * rotaci?n coincide con esq. 
81
         */
82
        public Contour                                bBoxWithoutRot = new Contour();
83
        public int                                         width = 0, height = 0;
84
        public double                                 originX = 0D, originY = 0D;
85
        public String                                 version = "";
86
        private int                                 alpha = 0;
87
        protected int                                 rBandNr = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
88
        private int                                 dataType = GDT_Byte;
89
        /**
90
         * Metadatos leidos de la imagen
91
         */
92
        private Metadata                        metadata = null;
93
        private boolean                         georeferenced = true;
94
        
95
        /**
96
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
97
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
98
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
99
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
100
         * distinto tama?o que el resto.   
101
         */
102
        public int[]                                stepArrayX = null, stepArrayY = null;
103
        protected GdalRasterBand[]         gdalBands = null;
104
        private double                                lastReadLine = -1;
105
        private int                                 currentFullWidth = -1;
106
        private int                                 currentFullHeight = -1;
107
        private int                                 currentViewWidth = -1;
108
        private int                                 currentViewHeight = -1;
109
        private double                                 currentViewX = 0D;
110
        private double                                 currentViewY = 0D;
111
        private double                                 viewportScaleX = 0D;
112
        private double                                 viewportScaleY = 0D;
113
        private double                                 wcWidth = 0D;
114
        private double                                 stepX = 0D;
115
        private double                                 stepY = 0D;
116
        public boolean                          isSupersampling = false;
117
        
118
        /**
119
         * Overview usada en el ?ltimo setView
120
         */
121
        int currentOverview = -1;
122
        
123
        // Polilinea con extent
124
        public class Contour extends Vector {
125
                final private static long serialVersionUID = -3370601314380922368L;
126
                public double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE;
127
                public double maxX = -Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
128
                public Contour() {
129
                        super();
130
                }
131
                public void add(Point2D pt) {
132
                        super.add(pt);
133
                        if (pt.getX() > maxX) maxX = pt.getX();
134
                        if (pt.getX() < minX) minX = pt.getX();
135
                        if (pt.getY() > maxY) maxY = pt.getY();
136
                        if (pt.getY() < minY) minY = pt.getY();
137
                }
138
        }
139
                
140
        public GdalNative(String fName, GdalFile driver) throws GdalException, IOException {
141
                super();
142
                this.driver = driver;
143
                init(fName);
144
        }
145
        
146
        /**
147
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
148
         * el tama?o de pixel y la rotaci?n. 
149
         */
150
        private void boundingBoxFromGeoTransform(){
151
                double geoX = 0D, geoY = 0D;
152
                bBoxRot.add(new Point2D.Double(trans.adfgeotransform[0], trans.adfgeotransform[3]));
153
                
154
                geoX = trans.adfgeotransform[0] +  trans.adfgeotransform[2] * height;
155
                geoY = trans.adfgeotransform[3] +  trans.adfgeotransform[5] * height;
156
                bBoxRot.add(new Point2D.Double(geoX, geoY));
157
                
158
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width;
159
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width;
160
                bBoxRot.add(new Point2D.Double(geoX, geoY));
161
                
162
                geoX = trans.adfgeotransform[0] + trans.adfgeotransform[1] * width + trans.adfgeotransform[2] * height;
163
                geoY = trans.adfgeotransform[3] + trans.adfgeotransform[4] * width + trans.adfgeotransform[5] * height;
164
                bBoxRot.add(new Point2D.Double(geoX, geoY));
165
                
166
                //TODO: ?OJO! con coordenadas geogr?ficas
167
        }
168
        
169
        /**
170
         * Calcula la bounding box en la que est? metido el raster teniendo en cuenta
171
         * el tama?o de pixel y la rotaci?n. 
172
         */
173
        private void boundingBoxWithoutRotation(){
174
                double ox = trans.adfgeotransform[0];
175
                double oy = trans.adfgeotransform[3];
176
                double resx = trans.adfgeotransform[1];
177
                double resy = trans.adfgeotransform[5];
178
                
179
                bBoxWithoutRot.add(new Point2D.Double(ox, oy));
180
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy));
181
                bBoxWithoutRot.add(new Point2D.Double(ox, oy + resy * height));
182
                bBoxWithoutRot.add(new Point2D.Double(ox + resx * width, oy + resy * height));
183
                
184
                //TODO: ?OJO! con coordenadas geogr?ficas
185
        }
186
        
187
        private void init(String fName) throws GdalException, IOException {
188
                fileName = fName;
189
                open(fName,GA_ReadOnly);
190
                ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
191
                if (ext.compareTo("tif") == 0)
192
                        WITH_OVERVIEWS = false;
193
                width = getRasterXSize();
194
                height = getRasterYSize();
195
                setDataType(this.getRasterBand(1).getRasterDataType());
196
                shortName = getDriverShortName();
197
                metadata = new Metadata(getMetadata());
198
                
199
                //Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto nos sirve
200
                //para saber que banda de la imagen va asignada a cada banda de visualizaci?n (ARGB)
201
                metadata.initColorInterpretation(getRasterCount());
202
                metadata.initNoDataByBand(getRasterCount());
203
            for(int i = 0; i < getRasterCount(); i++){
204
                    GdalRasterBand rb = getRasterBand(i + 1);
205
                    String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
206
                    metadata.setNoDataValue(i, rb.getRasterNoDataValue());
207
                    metadata.setColorInterpValue(i, colorInt);
208
                    if(colorInt.equals("Red"))
209
                            rBandNr = i + 1;
210
                    if(colorInt.equals("Green"))
211
                            gBandNr = i + 1;        
212
                    if(colorInt.equals("Blue"))
213
                            bBandNr = i + 1;                
214
                    if(colorInt.equals("Alpha"))
215
                            aBandNr = i + 1;
216
            }
217
            
218
                double ox=0D, oy=0D, resx=0D, resy=0D;
219
                try{
220
                        trans = getGeoTransform();
221
                                                
222
                        boundingBoxWithoutRotation();
223
                        boundingBoxFromGeoTransform();
224
                                                
225
                        this.georeferenced = true;
226
                }catch(GdalException exc){
227
                        bBoxRot.add(new Point2D.Double(0, 0));
228
                        bBoxRot.add(new Point2D.Double(width, 0));
229
                        bBoxRot.add(new Point2D.Double(0, height));
230
                        bBoxRot.add(new Point2D.Double(width, height));                        
231
                        this.georeferenced = false;
232
                }
233
        }
234
        
235
        /**
236
         * Asigna el valor de Alpha
237
         * @param a
238
         */
239
        public void setAlpha(int a) { 
240
                alpha = a; 
241
        }
242
        
243
        /**
244
         * Asigna el tipo de dato
245
         * @param dt entero que representa el tipo de dato
246
         */
247
        public void setDataType(int dt) { 
248
                dataType = dt; 
249
        }
250
        
251
        /**
252
         * Obtiene el tipo de dato
253
         * @return entero que representa el tipo de dato
254
         */
255
        public int getDataType() { 
256
                return dataType; 
257
        }
258
                
259
        // Supone rasters no girados
260
        public Point2D worldToRaster(Point2D pt) {
261
                double x = (((double) currentFullWidth) / (bBoxWithoutRot.maxX - bBoxWithoutRot.minX)) * (pt.getX() - bBoxWithoutRot.minX);
262
                double y = (((double) currentFullHeight) / (bBoxWithoutRot.maxY - bBoxWithoutRot.minY)) * (bBoxWithoutRot.maxY - pt.getY());
263
                Point2D ptRes = new Point2D.Double(x, y);
264
                return ptRes;
265
        }
266
        
267
        /**
268
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
269
         * viewPortScale, currentFullWidth y currentFulHeight
270
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
271
         * @throws GdalException
272
         */
273
        private void calcOverview(Point2D tl) throws GdalException{
274
                gdalBands[0] = getRasterBand(1);
275
                currentOverview = -1;
276
                if (WITH_OVERVIEWS && gdalBands[0].getOverviewCount() > 0) {
277
                        GdalRasterBand ovb = null;
278
                        for (int i = gdalBands[0].getOverviewCount()-1; i > 0; i--) {              
279
                                ovb = gdalBands[0].getOverview(i);
280
                                if (ovb.getRasterBandXSize()>getRasterXSize()*viewportScaleX) {
281
                                        currentOverview = i;
282
                            viewportScaleX *= ((double) width/(double) ovb.getRasterBandXSize());
283
                            viewportScaleY *= ((double) height/(double) ovb.getRasterBandYSize());
284
                            stepX = 1D/viewportScaleX;
285
                            stepY = 1D/viewportScaleY;
286
                            currentFullWidth = ovb.getRasterBandXSize();
287
                            currentFullHeight = ovb.getRasterBandYSize();
288
                            currentViewX = tl.getX();
289
                            lastReadLine = tl.getY();
290
                            break;
291
                                }
292
                        }
293
                }
294
        }
295
        
296
        public void setView(double dWorldTLX, double dWorldTLY,
297
            double dWorldBRX, double dWorldBRY,
298
            int nWidth, int nHeight) {
299
                
300
                currentFullWidth = width;
301
                currentFullHeight = height;
302
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
303
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
304
                // Calcula cual es la primera l?nea a leer;
305
                currentViewWidth = nWidth;
306
                currentViewHeight = nHeight;
307
                wcWidth = Math.abs(br.getX() - tl.getX());
308
                
309
                currentViewX = tl.getX();
310
                viewportScaleX = (double) currentViewWidth/(br.getX()-tl.getX());
311
                viewportScaleY = (double) currentViewHeight/(br.getY()-tl.getY());
312
                stepX = 1D/viewportScaleX;
313
                stepY = 1D/viewportScaleY;
314
                                                
315
                lastReadLine = currentViewY = tl.getY();
316
                
317
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
318
                try {
319
                        // calcula el overview a usar
320
                        gdalBands = new GdalRasterBand[4];
321
                        calcOverview(tl);
322
                        calcArraySteps();
323
                                                                                                    
324
                        // Selecciona las bandas y los overviews necesarios
325
                        gdalBands[0] = getRasterBand(rBandNr);
326
                        gdalBands[1] = gdalBands[0]; 
327
                        gdalBands[2] = gdalBands[1]; 
328
                        setDataType(gdalBands[0].getRasterDataType());
329
                        if(this.getRasterCount() >= 2) {
330
                                gdalBands[1] = getRasterBand(gBandNr);
331
                                gdalBands[2] = gdalBands[1]; 
332
                        }
333
                        if(this.getRasterCount() >= 3) 
334
                                gdalBands[2] = getRasterBand(bBandNr);
335
                        if(metadata.isAlphaBand())
336
                                gdalBands[3] = getRasterBand(aBandNr);                        
337
                        
338
                        
339
                        if (currentOverview > 0) {
340
                                gdalBands[0] = gdalBands[0].getOverview(currentOverview);
341
                                gdalBands[1] = gdalBands[0]; 
342
                                gdalBands[2] = gdalBands[1];
343
                                if(this.getRasterCount() >= 2) {
344
                                        gdalBands[1] = gdalBands[1].getOverview(currentOverview);
345
                                        gdalBands[2] = gdalBands[1]; 
346
                                }
347
                                if(this.getRasterCount() >= 3) 
348
                                        gdalBands[2] = gdalBands[2].getOverview(currentOverview);
349
                                if(metadata.isAlphaBand())
350
                                        gdalBands[3] = gdalBands[3].getOverview(currentOverview);                        
351
                                
352
                        }
353
                        
354
                } catch (GdalException e) {
355
                        e.printStackTrace();
356
                }
357
        }
358
        
359
        /**
360
         * Esta funci?n calcula los arrays de steps en X e Y para que cuando hay supersampleo 
361
         * se aplique el filtro solo a la esquina superior izquierda de cada pixel. 
362
         */
363
        private void calcArraySteps(){
364
                if(stepX < 1 && stepY < 1){
365
                        isSupersampling = true;
366
                        int w = (int) (Math.ceil(((double)currentViewWidth) * stepX) + 1);
367
                        this.stepArrayX = new int[w];
368
                        for (double j =  Math.abs(currentViewX - ((int)currentViewX)); j < w; j += stepX) 
369
                                        stepArrayX[(int)(j)] ++;
370
                                                        
371
                        int h = (int) (Math.ceil(((double)currentViewHeight) * stepY) + 1);
372
                        this.stepArrayY = new int[h];
373
                        for (double j =  Math.abs(currentViewY - ((int)currentViewY)); j < h; j += stepY) 
374
                                stepArrayY[(int)(j)] ++;
375
                }else{
376
                        isSupersampling = false;
377
                        this.stepArrayX = this.stepArrayY = null;
378
                }
379
        }
380
        
381
        int lastY = -1;
382
        
383
        /**
384
         * Lee una l?nea de bytes
385
         * @param line Buffer donde se cargan los datos
386
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
387
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
388
         * por la izquierda a mitad de pixel
389
         * @param gdalBuffer Buffer con la l?nea de datos original
390
         */
391
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer){
392
                double j = 0D;
393
                  int i = 0;
394
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
395
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
396
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
397
                        }
398
                }
399
        }
400
        
401
        /**
402
         * Lee una l?nea de shorts
403
         * @param line Buffer donde se cargan los datos
404
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
405
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
406
         * por la izquierda a mitad de pixel
407
         * @param gdalBuffer Buffer con la l?nea de datos original
408
         */
409
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer){
410
                  double j = 0D; 
411
                  int i = 0;
412
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
413
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
414
                                line[iBand][i] = (short)(gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
415
                        }
416
                }
417
        }
418

    
419
        /**
420
         * Lee una l?nea de ints
421
         * @param line Buffer donde se cargan los datos
422
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
423
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
424
         * por la izquierda a mitad de pixel
425
         * @param gdalBuffer Buffer con la l?nea de datos original
426
         */
427
        private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer){
428
                double j = 0D;
429
                  int i = 0;
430
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
431
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
432
                                line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
433
                        }
434
                }
435
        }
436

    
437
        /**
438
         * Lee una l?nea de float
439
         * @param line Buffer donde se cargan los datos
440
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
441
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
442
         * por la izquierda a mitad de pixel
443
         * @param gdalBuffer Buffer con la l?nea de datos original
444
         */
445
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer){
446
                double j = 0D;
447
                  int i = 0;
448
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
449
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
450
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
451
                        }
452
                }
453
        }
454
        
455
        /**
456
         * Lee una l?nea de doubles
457
         * @param line Buffer donde se cargan los datos
458
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
459
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
460
         * por la izquierda a mitad de pixel
461
         * @param gdalBuffer Buffer con la l?nea de datos original
462
         */
463
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer){
464
                double j = 0D;
465
                  int i = 0;
466
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++){
467
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j+=stepX) {
468
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
469
                        }
470
                }
471
        }
472
        
473
        public void readLine(Object line) throws GdalException {
474
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
475
        int x = (int) Math.ceil(currentViewX);
476
        int y = (int) Math.ceil(lastReadLine);
477
        GdalBuffer r = null, g = null, b = null;
478
        GdalBuffer a = new GdalBuffer();
479
        
480
        while(y >= gdalBands[0].getRasterBandYSize())
481
                y--;
482
        
483
        if (x+w > gdalBands[0].getRasterBandXSize()) 
484
                w = gdalBands[0].getRasterBandXSize()-x;
485
        
486
        if(gdalBands[0].getRasterColorTable() != null){
487
                Palette palette = new Palette();
488
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
489
                driver.setPalette(palette);
490
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
491
        }else{
492
                a.buffByte = new byte[w];
493
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
494
                        g = b = r;
495
                        if (getRasterCount() > 1 && gdalBands[1] != null)
496
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType);
497
                        if (getRasterCount() > 2 && gdalBands[2] != null)
498
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType);
499
        }
500
                          
501
        lastReadLine += stepY;
502
        
503
                  double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
504
                  GdalBuffer[] bands = {r, g, b};
505
                                    
506
                  if (dataType == GDT_Byte)
507
                          readLine((byte[][])line, initOffset, bands);
508
                else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16)
509
                        readLine((short[][])line, initOffset, bands);
510
                else if (dataType == GDT_CInt32 || dataType == GDT_Int32  || dataType == GDT_UInt32)
511
                        readLine((int[][])line, initOffset, bands);
512
                  else if(dataType == GDT_Float32 || dataType == GDT_CFloat32)
513
                          readLine((float[][])line, initOffset, bands);
514
                  else if(dataType == GDT_Float64 || dataType == GDT_CFloat64)
515
                          readLine((double[][])line, initOffset, bands);
516
          
517
                return;
518
        }
519
        
520
        /**
521
         * Lee una l?nea y la guarda cada elemento sobre un entero. Este entero representa
522
         * un valor ARGB
523
         * @param line Buffer sobre el que se escribe la linea
524
         * @return 
525
         * @throws GdalException
526
         */
527
        int readLineRGBA(int[] line) throws GdalException {
528
                int err = 0;
529
                
530
        int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
531
        int x = (int) currentViewX;
532
        int y = (int) lastReadLine;
533
        GdalBuffer r = null, g = null, b = null, p = null;
534
        GdalBuffer a = new GdalBuffer();
535
        
536
        while(y >= gdalBands[0].getRasterBandYSize())
537
                y--;
538
        
539
        if (x+w > gdalBands[0].getRasterBandXSize()) 
540
                w = gdalBands[0].getRasterBandXSize()-x;
541
        
542
        if(gdalBands[0].getRasterColorTable() != null){
543
                Palette palette = new Palette();
544
                palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
545
                driver.setPalette(palette);
546
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
547
        }else{
548
                
549
                r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType);
550
                g = b = r;
551
                        if (getRasterCount() > 1 && gdalBands[1] != null)
552
                            g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType);
553
                        if (getRasterCount() > 2 && gdalBands[2] != null)
554
                            b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType);
555
                
556
                if(metadata.isAlphaBand()){
557
                        a = gdalBands[3].readRaster(x, y, w, 1, w, 1, GDT_Byte);        
558
                }else{
559
                            a.buffByte = new byte[w];
560
                            for (int i = 0;i < w;i++)
561
                                    a.buffByte[i] = (byte)255;
562
                }
563
        }
564
                  lastReadLine += stepY;
565
                  
566
                  int i=0;
567
                  double j =  Math.abs(currentViewX - ((int)currentViewX));
568
                int alpha = (this.alpha & 0xff) << 24;
569
                //try{
570
                  if (dataType == GDT_Byte){
571
                          if(gdalBands[0].getRasterColorTable() != null){
572
                                  for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
573
                                      int jInt = (int)(j);
574
                                      line[i] = (alpha) + ((r.buffByte[jInt] & 0xff) << 16) + ((r.buffByte[jInt] & 0xff) << 8) + (r.buffByte[jInt] & 0xff);
575
                              }
576
                          }else{
577
                                  for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
578
                                      int jInt = (int)(j);
579
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + ((r.buffByte[jInt] & 0xff) << 16) + ((g.buffByte[jInt] & 0xff) << 8) + (b.buffByte[jInt] & 0xff);
580
                              }
581
                          }
582
                  }else if (dataType == GDT_CInt16 || dataType == GDT_Int16  || dataType == GDT_UInt16){
583
                          if (g == null) // Sibgle Band (Typical DEM)
584
                                    for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
585
                                            int jInt = (int)(j);
586
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) + r.buffShort[jInt];
587
                              }
588
                          else { // Multiband
589
                                  // System.err.println("Raster 16bits multibanda");
590
                              for (i=0; i<currentViewWidth && j<r.getSize(); i++, j+=stepX) {
591
                                      int jInt = (int)(j);
592
                                      line[i] = (alpha & ((a.buffByte[jInt])& 0xff) << 24) | (((r.buffShort[jInt] & 0xfff0) << 12) & 0xff0000 ) | 
593
                                                                                                                           (((g.buffShort[jInt] & 0xfff0) << 4 ) & 0xff00 ) |
594
                                                                                                                           (((b.buffShort[jInt] & 0xfff0) >> 4 ) & 0xff );
595
                              }
596
                          }
597
                  }
598
                //}catch(ArrayIndexOutOfBoundsException ex){}
599
                return err;
600
        }
601
                
602
        /**
603
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
604
         * @param buf Buffer donde se almacenan los datos
605
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
606
         * @param dWorldTLX Posici?n X en pixeles
607
         * @param dWorldTLY Posici?n Y en pixeles
608
         * @param w Ancho en pixeles
609
         * @param h Alto en pixeles
610
         * @throws GdalException
611
         */
612
        public void readWindow(RasterBuf buf, BandList bandList, double dWorldTLX, double dWorldTLY,
613
                                            int nWidth, int nHeight) throws GdalException {
614
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
615

    
616
                gdalBands = new GdalRasterBand[getRasterCount()];
617
                isSupersampling = false;
618
                if(gdalBands.length == 0)
619
                        return;
620
                
621
                try {                        
622
                        // Selecciona las bandas
623
                        gdalBands[0] = getRasterBand(1);
624
                        setDataType(gdalBands[0].getRasterDataType());
625
                        for(int iBand = 1; iBand < gdalBands.length; iBand++)
626
                                gdalBands[iBand] = getRasterBand(iBand + 1);
627
                        
628
                } catch (GdalException e) {
629
                        e.printStackTrace();
630
                }
631
                
632
        int x = (int) Math.ceil(tl.getX());
633
        int y = (int) Math.ceil(tl.getY());
634
        
635
        if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
636
                nWidth = gdalBands[0].getRasterBandXSize() - x;
637
        
638
        if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
639
                nHeight = gdalBands[0].getRasterBandYSize() - y;
640
        
641
                int yMax = y + nHeight;
642
        readData(buf, bandList, x, y, nWidth, yMax);
643
        }
644
        
645
        /**
646
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
647
         * @param buf Buffer donde se almacenan los datos
648
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
649
         * @param x Posici?n X en pixeles
650
         * @param y Posici?n Y en pixeles
651
         * @param w Ancho en pixeles
652
         * @param h Alto en pixeles
653
         * @throws GdalException
654
         */
655
        public void readWindow(RasterBuf buf, BandList bandList, int x, int y, int w, int h) throws GdalException {
656
        GdalBuffer gdalBuf = null;
657
                gdalBands = new GdalRasterBand[getRasterCount()];
658
                isSupersampling = false;
659
                if(gdalBands.length == 0)
660
                        return;
661
                
662
                // Selecciona las bandas
663
                gdalBands[0] = getRasterBand(1);
664
                setDataType(gdalBands[0].getRasterDataType());
665
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
666
                        gdalBands[iBand] = getRasterBand(iBand + 1);
667
                                        
668
                int yMax = y + h;
669
                readData(buf, bandList, x, y, w, yMax);
670
        }
671
        
672
        /**
673
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
674
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
675
         * @param buf Buffer donde se almacenan los datos
676
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
677
         * @param x Posici?n X en pixeles
678
         * @param y Posici?n Y en pixeles
679
         * @param w Ancho en pixeles
680
         * @param yMax altura m?xima de y
681
         * @throws GdalException
682
         */
683
        private void readData(RasterBuf buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException {
684
                GdalBuffer gdalBuf = null;
685
                int rasterBufLine;
686
                for(int iBand = 0; iBand < gdalBands.length; iBand++){
687
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
688
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
689
                                continue;        
690
                        if(dataType == Gdal.GDT_Byte){
691
                                for (int line = y; line < yMax; line++) {
692
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
693
                                        rasterBufLine = line - y;
694
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
695
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[drawBands]);
696
                                }
697
                        }else if((dataType == Gdal.GDT_UInt16) || (dataType == Gdal.GDT_Int16) || (dataType == Gdal.GDT_CInt16)){
698
                                for (int line = y; line < yMax; line++) {
699
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
700
                                        rasterBufLine = line - y;
701
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
702
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[drawBands]);
703
                                }
704
                        }else if((dataType == Gdal.GDT_UInt32) || (dataType == Gdal.GDT_Int32) || (dataType == Gdal.GDT_CInt32)){
705
                                for (int line = y; line < yMax; line++) {
706
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
707
                                        rasterBufLine = line - y;
708
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
709
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[drawBands]);
710
                                }
711
                        }else if(dataType == Gdal.GDT_Float32){
712
                                for (int line = y; line < yMax; line++) {
713
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
714
                                        rasterBufLine = line - y;
715
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
716
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[drawBands]);
717
                                }
718
                        }else if(dataType == Gdal.GDT_Float64){
719
                                for (int line = y; line < yMax; line++) {
720
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType);
721
                                        rasterBufLine = line - y;
722
                                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++)
723
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[drawBands]);
724
                                }
725
                        }
726
                }
727
        }
728
        
729
        void pintaInfo() {
730
                try {
731
                        //System.out.println("Origin = "+originX+","+originY);
732
                        //System.out.println("Origin = "+this.);
733
                        System.out.println("GeoTransform:");
734
                        GeoTransform trans = getGeoTransform();
735
                        for (int i=0; i<6; i++)
736
                                System.out.println("  param["+i+"]="+trans.adfgeotransform[i]);
737
                        System.out.println("Metadata:");
738
                        String [] metadata = getMetadata();
739
                        for (int i=0; i<metadata.length; i++) {
740
                                System.out.println(metadata[i]);
741
                        }
742
                } catch (GdalException e) {
743
                        
744
                }
745
                
746
        }
747
        
748
        void pintaPaleta() {
749
        }
750
        
751
        public int getBlockSize(){
752
                return this.getBlockSize();
753
        }
754

    
755
        /**
756
         * Obtiene el objeto que contiene los metadatos
757
         */
758
        public Metadata getMetadataJavaObject() {
759
                return metadata;
760
        }
761

    
762
        /**
763
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
764
         * @return true si est? georreferenciada y false si no lo est?.
765
         */
766
        public boolean isGeoreferenced() {
767
                return georeferenced;
768
        }
769
        
770
}
771

    
772
/**
773
 * @author Luis W. Sevilla
774
 */
775
public class GdalFile extends GeoRasterFile {
776
        public final static int         BAND_HEIGHT = 64;
777
        protected GdalNative                 file = null;
778
        /**
779
         * Tama?o de pixel para las imagenes con fichero RMF. No podemos salvarlo en file porque es necesario conocer el
780
         * tama?o de pixel asignado por rl .rmf y el tama?o de pixel real.
781
         */
782
        private double                                pixelSizeX = 0D, pixelSizeY = 0D;
783

    
784
        private Extent v = null;
785
        
786
        public GdalFile(IProjection proj, String fName)throws NotSupportedExtensionException{
787
                super(proj, fName);
788
                extent = new Extent();
789
                try {
790
                        file = new GdalNative(fName, this);
791
                        load();
792
                        readGeoInfo(fName);
793
                        bandCount = file.getRasterCount(); 
794
                        if ( bandCount > 2) {
795
                                setBand(RED_BAND,   0);
796
                                setBand(GREEN_BAND, 1);
797
                                setBand(BLUE_BAND,  2);
798
                        } else
799
                                setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);
800
                } catch (GdalException e) {
801
                        throw new NotSupportedExtensionException("Extension not supported");
802
                } catch(Exception e){
803
                          System.out.println("Error en GdalOpen");
804
                          e.printStackTrace();
805
                          file = null;
806
                }
807
                
808
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
809
                setDataType(org.cresques.util.Utilities.getRasterBufTypeFromGdalType(file.getDataType()));
810
        }
811
        
812
        /**
813
         * Obtenemos o calculamos el extent de la imagen.
814
         */
815
        public GeoFile load() {
816
                extent = new Extent(file.bBoxRot.minX, file.bBoxRot.minY, file.bBoxRot.maxX, file.bBoxRot.maxY);
817
                requestExtent = new Extent(file.bBoxWithoutRot.minX, file.bBoxWithoutRot.minY, file.bBoxWithoutRot.maxX, file.bBoxWithoutRot.maxY);
818
                return this;
819
        }
820
        
821
        /**
822
         * Cierra el fichero de imagen
823
         */
824
        public void close() {
825
                try {
826
                        if(file != null){
827
                                file.close();
828
                                file = null;
829
                        }
830
                } catch (GdalException e) {
831
                        // TODO Auto-generated catch block
832
                        e.printStackTrace();
833
                }
834
        }
835
        
836
        /**
837
         * Asigna a cada banda R,G o B una banda de la imagen
838
         */
839
        public void setBand(int flag, int bandNr) {
840
                super.setBand(flag, bandNr);
841
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) file.rBandNr = bandNr+1;
842
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) file.gBandNr = bandNr+1;
843
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) file.bBandNr = bandNr+1;
844
        }
845
        
846
        /**
847
         * Asigna el extent de la vista actual. existe un fichero .rmf debemos hacer una transformaci?n
848
         * de la vista asignada ya que la petici?n viene en coordenadas del fichero .rmf y la vista (v)
849
         * ha de estar en coordenadas del fichero.
850
         */
851
        public void setView(Extent e) { 
852
                if(rmfExists){
853
                        //Trasladamos la petici?n al origen
854
                        Point2D.Double petInit = null, petEnd = null;
855
                        try{
856
                                petInit = new Point2D.Double(e.minX(),  e.maxY());
857
                                petEnd = new Point2D.Double(e.maxX(), e.minY());
858
                                transformNewExtent.inverseTransform(petInit, petInit);
859
                                transformNewExtent.inverseTransform(petEnd, petEnd);
860
                        }catch(NoninvertibleTransformException ex){}
861
                        
862
                        //Redimensionamos la petici?n al tama?o de caja del destino
863
                        double originX = (petInit.getX() * getExtentRatio().getX()) / extent.width();
864
                        double originY = (petInit.getY() * getExtentRatio().getY()) / extent.height();
865
                        double endX = (petEnd.getX() * getExtentRatio().getX()) / extent.width();
866
                        double endY = (petEnd.getY() * getExtentRatio().getY()) / extent.height();
867
                        
868
                        //Trasladamos a su sistema de coordenadas
869
                        Point2D.Double destInit = new Point2D.Double(originX, originY);
870
                        Point2D.Double destEnd = new Point2D.Double(endX, endY);
871
                        
872
                        transformOldExtent.transform(destInit, destInit);
873
                        transformOldExtent.transform(destEnd, destEnd);
874
                        if(file.trans == null){
875
                                destInit.y = getExtentRatio().getY() + destInit.y; 
876
                                destEnd.y = getExtentRatio().getY() + destEnd.y;
877
                        }
878
                        v = new Extent(        destInit.getX(), destInit.getY(), destEnd.getX(), destEnd.getY());
879
                                                
880
                }else
881
                        v = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());        
882
        }
883
                
884
        /**
885
         * Obtiene extent de la vista actual
886
         */
887
        public Extent getView() { 
888
                return v; 
889
        }
890
        
891
        /**
892
         * Obtiene la anchura del fichero
893
         */
894
        public int getWidth() {        
895
                return file.width; 
896
        }
897
        
898
        /**
899
         * Obtiene la altura del fichero
900
         */
901
        public int getHeight() { 
902
                return file.height;
903
        }
904

    
905
        /* (non-Javadoc)
906
         * @see org.cresques.io.GeoRasterFile#reProject(org.cresques.cts.ICoordTrans)
907
         */
908
        public void reProject(ICoordTrans rp) {
909
                // TODO Auto-generated method stub
910
        }
911
        
912
        /* (non-Javadoc)
913
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans)
914
         */
915
        public Image updateImage(int width, int height, ICoordTrans rp) {
916
                int line, pRGBArray[] = null;
917
                Image image = null;
918
                        
919
                if (mustVerifySize()) {
920
                        // Work out the correct aspect for the setView call.
921
                        double dFileAspect = (double)v.width()/(double)v.height();
922
                        double dWindowAspect = (double)width /(double)height;
923
        
924
                        if (dFileAspect > dWindowAspect) {
925
                          height =(int)((double)width/dFileAspect);
926
                        } else {
927
                          width = (int)((double)height*dFileAspect);
928
                        }
929
                }
930
                
931
                // Set the view
932
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height);
933
                setStep(file.stepArrayX, file.stepArrayY);
934
                
935
                if(width<=0)width=1;
936
                if(height<=0)height=1;
937
                
938
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
939
                //image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
940
                pRGBArray = new int[width/**BAND_HEIGHT*/];
941
                try {
942
                        //int nLin = height % BAND_HEIGHT;
943
                        file.setAlpha(getAlpha());
944
                        setBand(RED_BAND,   rBandNr);
945
                        setBand(GREEN_BAND, gBandNr);
946
                        setBand(BLUE_BAND,  bBandNr);
947
                        for (line=0; line < height; line++) { //+=BAND_HEIGHT) {
948
                                //int bandH = Math.min(BAND_HEIGHT, height-line);
949
                                //file.readBandRGBA(bandH, BAND_HEIGHT, pRGBArray);
950
                                file.readLineRGBA(pRGBArray);
951
                                setRGBLine((BufferedImage) image, 0, line, width, 1/*bandH*/, pRGBArray, 0, width);
952
                        }
953
                } catch (Exception e) {
954
                        // TODO Auto-generated catch block
955
                        e.printStackTrace();
956
                }
957
                
958
                return image;
959
        }
960
        
961
        public RasterBuf getRaster(int width, int height, ICoordTrans rp) {
962
                int line;
963
                RasterBuf raster = null;
964
                        
965
                if(mustVerifySize()){
966
                        // Work out the correct aspect for the setView call.
967
                        double dFileAspect = (double)v.width()/(double)v.height();
968
                        double dWindowAspect = (double)width /(double)height;
969
        
970
                        if (dFileAspect > dWindowAspect) {
971
                          height =(int)((double)width/dFileAspect);
972
                        } else {
973
                          width = (int)((double)height*dFileAspect);
974
                        }
975
                }
976
                
977
                // Set the view
978
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height);
979
                setStep(file.stepArrayX, file.stepArrayY);
980
                
981
                try {
982
                        //Esta funci?n se usa para la renderizaci?n, por eso se crean 4 bandas a pi?on fijo
983
                        raster = new RasterBuf(getDataType(), width, height, 4, true);
984
                
985
                        file.setAlpha(getAlpha());
986
                        setBand(RED_BAND,   rBandNr);
987
                        setBand(GREEN_BAND, gBandNr);
988
                        setBand(BLUE_BAND,  bBandNr);
989
                        
990
                        switch(getDataType()){
991
                        case RasterBuf.TYPE_BYTE: 
992
                                for (line=0; line < height; line++) 
993
                                        file.readLine(raster.getLineByte(line));
994
                                break;
995
                        case RasterBuf.TYPE_SHORT:;        
996
                                for (line=0; line < height; line++) 
997
                                        file.readLine(raster.getLineShort(line));
998
                                break;
999
                        case RasterBuf.TYPE_INT:
1000
                                for (line=0; line < height; line++) 
1001
                                        file.readLine(raster.getLineInt(line));
1002
                                break;
1003
                        case RasterBuf.TYPE_FLOAT:
1004
                                for (line=0; line < height; line++) 
1005
                                        file.readLine(raster.getLineFloat(line));
1006
                                break;
1007
                        case RasterBuf.TYPE_DOUBLE:
1008
                                for (line=0; line < height; line++) 
1009
                                        file.readLine(raster.getLineDouble(line));
1010
                                break;
1011
                        case RasterBuf.TYPE_UNDEFINED:break;
1012
                        }
1013
                        
1014
                        
1015
                } catch (Exception e) {
1016
                        // TODO Auto-generated catch block
1017
                        e.printStackTrace();
1018
                }
1019
                
1020
                return raster;
1021
        }
1022
        
1023
        /**
1024
         * Asigna al objeto Image los valores con los dato de la imagen contenidos en el 
1025
         * vector de enteros.
1026
         * @param image        imagen con los datos actuales
1027
         * @param startX        inicio de la posici?n en X dentro de la imagen
1028
         * @param startY        inicio de la posici?n en X dentro de la imagen
1029
         * @param w        Ancho de la imagen
1030
         * @param h        Alto de la imagen
1031
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1032
         * @param offset        desplazamiento
1033
         * @param scansize        tama?o de imagen recorrida por cada p
1034
         */
1035
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1036
                         int offset, int scansize) {
1037
                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
1038
        }
1039
        
1040
        /**
1041
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
1042
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
1043
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
1044
         * banda correspondiente a flags es sustituida por los datos del vector.
1045
         * @param image        imagen con los datos actuales
1046
         * @param startX        inicio de la posici?n en X dentro de la imagen
1047
         * @param startY        inicio de la posici?n en X dentro de la imagen
1048
         * @param w        Ancho de la imagen
1049
         * @param h        Alto de la imagen
1050
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1051
         * @param offset        desplazamiento
1052
         * @param scansize        tama?o de imagen recorrida por cada paso
1053
         * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
1054
         */
1055
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1056
                         int offset, int scansize, int flags) {
1057
                int [] line = new int[rgbArray.length]; 
1058
                image.getRGB(startX, startY, w, h, line, offset, scansize);
1059
                if (flags == GeoRasterFile.RED_BAND)
1060
                        for (int i=0; i<line.length; i++)
1061
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
1062
                else if (flags == GeoRasterFile.GREEN_BAND)
1063
                        for (int i=0; i<line.length; i++)
1064
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
1065
                else if (flags == GeoRasterFile.BLUE_BAND)
1066
                        for (int i=0; i<line.length; i++)
1067
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
1068
                image.setRGB(startX, startY, w, h, line, offset, scansize);
1069
        }
1070
        
1071
        /**
1072
         * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
1073
         * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
1074
         * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
1075
         * banda correspondiente a flags es sustituida por los datos del vector.
1076
         * @param image        imagen con los datos actuales
1077
         * @param startX        inicio de la posici?n en X dentro de la imagen
1078
         * @param startY        inicio de la posici?n en X dentro de la imagen
1079
         * @param w        Ancho de la imagen
1080
         * @param h        Alto de la imagen
1081
         * @param rgbArray        vector que contiene la banda que se va a sustituir
1082
         * @param offset        desplazamiento
1083
         * @param scansize        tama?o de imagen recorrida por cada paso
1084
         * @param origBand        Banda origen del GeoRasterFile
1085
         * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
1086
         */
1087
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
1088
                         int offset, int scansize, int origBand, int destBandFlag) {
1089
                int [] line = new int[rgbArray.length]; 
1090
                image.getRGB(startX, startY, w, h, line, offset, scansize);
1091
                if (origBand == 0 && destBandFlag == GeoRasterFile.RED_BAND)
1092
                        for (int i=0; i<line.length; i++)
1093
                                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
1094
                else if (origBand == 1 && destBandFlag == GeoRasterFile.GREEN_BAND)
1095
                        for (int i=0; i<line.length; i++)
1096
                                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
1097
                else if (origBand == 2 && destBandFlag == GeoRasterFile.BLUE_BAND)
1098
                        for (int i=0; i<line.length; i++)
1099
                                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
1100
                
1101
                else if (origBand == 0 && destBandFlag == GeoRasterFile.GREEN_BAND)
1102
                        for (int i=0; i<line.length; i++)
1103
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x00ff0000) >> 8) ;
1104
                else if (origBand == 0 && destBandFlag == GeoRasterFile.BLUE_BAND)
1105
                        for (int i=0; i<line.length; i++)
1106
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x00ff0000) >> 16);
1107
                else if (origBand == 1 && destBandFlag == GeoRasterFile.RED_BAND)
1108
                        for (int i=0; i<line.length; i++)
1109
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x0000ff00) << 8);
1110
                
1111
                else if (origBand == 1 && destBandFlag == GeoRasterFile.BLUE_BAND)
1112
                        for (int i=0; i<line.length; i++)
1113
                                line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x0000ff00) >> 8);
1114
                else if (origBand == 2 && destBandFlag == GeoRasterFile.RED_BAND)
1115
                        for (int i=0; i<line.length; i++)
1116
                                line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x000000ff) << 16);
1117
                else if (origBand == 2 && destBandFlag == GeoRasterFile.GREEN_BAND)
1118
                        for (int i=0; i<line.length; i++)
1119
                                line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x000000ff) << 8);
1120
                image.setRGB(startX, startY, w, h, line, offset, scansize);
1121
        }
1122
        
1123
        private void showOnOpen() {
1124
                  // Report en la apertura (quitar)
1125
                  System.out.println("Fichero GDAL '"+getName()+"' abierto.");
1126
                  System.out.println("Version = "+file.version);
1127
                  System.out.println("   Size = ("+file.width+","+file.height+")");
1128
                  try {
1129
                        System.out.println("   NumBands = ("+file.getRasterCount()+")");
1130
                } catch (GdalException e) {
1131
                        // TODO Auto-generated catch block
1132
                        e.printStackTrace();
1133
                }
1134
                  //file.pintaInfo();
1135
                  file.pintaPaleta();
1136

    
1137
        }
1138

    
1139
        /* (non-Javadoc)
1140
         * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int, int)
1141
         */
1142
        public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBandFlag)throws SupersamplingNotSupportedException{
1143
                int line, pRGBArray[] = null;
1144
                        
1145
                if(mustVerifySize()){
1146
                        // Work out the correct aspect for the setView call.
1147
                        double dFileAspect = (double)v.width()/(double)v.height();
1148
                        double dWindowAspect = (double)width /(double)height;
1149
        
1150
                        if (dFileAspect > dWindowAspect) {
1151
                          height =(int)((double)width/dFileAspect);
1152
                        } else {
1153
                          width = (int)((double)height*dFileAspect);
1154
                        }
1155
                }
1156

    
1157
                // Set the view
1158
                file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height);
1159
                setStep(file.stepArrayX, file.stepArrayY);
1160

    
1161
                if(width<=0)width=1;
1162
                if(height<=0)height=1;
1163
                                
1164
                pRGBArray = new int[width];
1165
                try {
1166
                        setBand(RED_BAND,   rBandNr);
1167
                        setBand(GREEN_BAND, gBandNr);
1168
                        setBand(BLUE_BAND,  bBandNr);
1169
                        file.setAlpha(getAlpha());
1170
                        if(img!=null){
1171
                                for (line=0; line < height; line++) { 
1172
                                        file.readLineRGBA(pRGBArray);
1173
                                        setRGBLine((BufferedImage) img, 0, line, width, 1/*bandH*/, pRGBArray, 0, width, origBand, destBandFlag);
1174
                                }
1175
                                return img;
1176
                        }else{
1177
                                Image image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
1178
                                for (line=0; line < height; line++) { 
1179
                                        file.readLineRGBA(pRGBArray);
1180
                                        setRGBLine((BufferedImage)image, 0, line, width, 1, pRGBArray, 0, width);
1181
                                }        
1182
                                return image;
1183
                        }
1184
                } catch (Exception e) {
1185
                        // TODO Auto-generated catch block
1186
                        e.printStackTrace();
1187
                }
1188
                
1189
                return img;
1190
        }
1191
                        
1192
        /* (non-Javadoc)
1193
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
1194
         */
1195
        public Object getData(int x, int y, int band) {
1196
                // TODO Auto-generated method stub
1197
                return null;
1198
        }
1199
        
1200
        /**
1201
         * Devuelve los datos de una ventana solicitada
1202
         * @param ulX        coordenada X superior izda.
1203
         * @param ulY        coordenada Y superior derecha.
1204
         * @param sizeX        tama?o en X de la ventana.
1205
         * @param sizeY tama?o en Y de la ventana.
1206
         * @param band        Banda solicitada.
1207
         */
1208
        public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band){
1209
                
1210
                return null;
1211
        }
1212
        
1213
        public RasterBuf getWindowRaster(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) {                
1214
                Extent selectedExtent = new Extent(x, y, x + w, y - h);
1215
                setView(selectedExtent);
1216
                
1217
                int width = 0;
1218
                int height = 0;
1219
                if(file.trans != null){
1220
                        width = (int)Math.abs(selectedExtent.width() / file.trans.adfgeotransform[1]);//(int)(selectedExtent.width() * file.width) / extent.width();
1221
                        height = (int)Math.abs(selectedExtent.height() / file.trans.adfgeotransform[5]);
1222
                }else{
1223
                        width = (int)Math.abs(selectedExtent.width());
1224
                        height = (int)Math.abs(selectedExtent.height());
1225
                }
1226
                                
1227
                try {
1228
                        file.readWindow(rasterBuf, bandList, x, y, width, height);
1229
                } catch (Exception e) {
1230
                        e.printStackTrace();
1231
                }
1232
                
1233
                return rasterBuf;
1234
        }
1235
        
1236
        public RasterBuf getWindowRaster(int x, int y, int w, int h, BandList bandList, RasterBuf rasterBuf) {
1237
                try {
1238
                        setView(
1239
                        new Extent( Utilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
1240
                                                getWidth(), 
1241
                                                getHeight(),
1242
                                                new Rectangle2D.Double(x, y, w, h)))
1243
                        );
1244
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
1245
                } catch (Exception e) {
1246
                        e.printStackTrace();
1247
                }
1248
                return rasterBuf;
1249
        }
1250
        
1251
        /**
1252
         * Obtiene la zona (Norte / Sur)
1253
         * @return true si la zona es norte y false si es sur
1254
         */
1255
        
1256
        public boolean getZone(){
1257
                
1258
                return false;
1259
        }
1260
        
1261
        /**
1262
         *Devuelve el n?mero de zona UTM
1263
         *@return N?mero de zona 
1264
         */
1265
        
1266
        public int getUTM(){
1267
                
1268
                return 0;        
1269
        }
1270
        
1271
        /**
1272
         * Obtiene el sistema de coordenadas geograficas
1273
         * @return Sistema de coordenadas geogr?ficas
1274
         */
1275
        public String getGeogCS(){
1276
                return new String("");        
1277
        }
1278
        
1279
        /**
1280
         * Devuelve el tama?o de bloque
1281
         * @return Tama?o de bloque
1282
         */
1283
        public int getBlockSize(){
1284
                if(file != null)
1285
                        return file.getBlockSize();
1286
                else
1287
                        return 0;
1288
        }
1289
        
1290
         /**
1291
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
1292
         * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo.
1293
         * @param originX Origen de la imagen en la coordenada X
1294
         * @param originY Origen de la imagen en la coordenada Y
1295
         */
1296
        public void setExtentTransform(double originX, double originY, double w, double h, double psX, double psY) {
1297
                pixelSizeX = psX;
1298
            pixelSizeY = psY;
1299
            
1300
                double oldOriginX = 0D;
1301
                double oldOriginY = 0D;
1302
                if(file.trans != null){
1303
                        oldOriginX = file.trans.adfgeotransform[0];
1304
                        oldOriginY = file.trans.adfgeotransform[3];
1305
                }
1306
                
1307
                transformNewExtent.translate(originX, originY);
1308
                transformOldExtent.translate(oldOriginX, oldOriginY);
1309
                extentsRatio.setLocation(extent.width(), extent.height());
1310
        }
1311
        
1312
        /**
1313
         * Obtiene el objeto que contiene los metadatos
1314
         */
1315
        public Metadata getMetadata() {
1316
                if(file != null)
1317
                        return file.getMetadataJavaObject();
1318
                else
1319
                        return null;
1320
        }
1321
        
1322
        /**
1323
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
1324
         * @return true si est? georreferenciada y false si no lo est?.
1325
         */
1326
        public boolean isGeoreferenced() {
1327
                if(file != null)
1328
                        return file.isGeoreferenced();
1329
                else 
1330
                        return false;
1331
        }
1332
    
1333
        /**
1334
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
1335
         * el valor de esta variable cada vez que dibuja. 
1336
         * @return true si se ha supersampleado y false si no se ha hecho.
1337
         */
1338
        public boolean isSupersampling() {
1339
                if(file != null)
1340
                        return file.isSupersampling;
1341
                else 
1342
                        return false;
1343
        }
1344
        
1345
        /**
1346
         * Obtiene los par?metros de la transformaci?n af?n que corresponde con los elementos de
1347
         * un fichero tfw.
1348
         * <UL> 
1349
         * <LI>[1]tama?o de pixel en X</LI>
1350
         * <LI>[2]rotaci?n en X</LI>
1351
         * <LI>[4]rotaci?n en Y</LI>
1352
         * <LI>[5]tama?o de pixel en Y</LI>
1353
         * <LI>[0]origen en X</LI>
1354
         * <LI>[3]origen en Y</LI>
1355
         * </UL>
1356
         * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n. En principio
1357
         * Gdal es capaz de proporcionarla de esta forma.
1358
         * @return vector de double con los elementos de la transformaci?n af?n.
1359
         */
1360
        public double[] getTransform(){
1361
                if(file != null && file.trans != null)
1362
                        return file.trans.adfgeotransform;
1363
                return null;
1364
        }
1365
        
1366
}
1367

    
1368

    
1369