Statistics
| Revision:

gvsig-raster / org.gvsig.raster.gdal / trunk / org.gvsig.raster.gdal / org.gvsig.raster.gdal.io / src / main / java / org / gvsig / raster / gdal / io / GdalNative.java @ 1678

History | View | Annotate | Download (55.7 KB)

1
        /* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.io.IOException;
28

    
29
import org.gvsig.fmap.dal.coverage.RasterLibrary;
30
import org.gvsig.fmap.dal.coverage.RasterLocator;
31
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
32
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
33
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
34
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
35
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
36
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
37
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
38
import org.gvsig.fmap.dal.coverage.util.FileUtils;
39
import org.gvsig.jgdal.Gdal;
40
import org.gvsig.jgdal.GdalBuffer;
41
import org.gvsig.jgdal.GdalException;
42
import org.gvsig.jgdal.GdalRasterBand;
43
import org.gvsig.jgdal.GeoTransform;
44
import org.gvsig.raster.impl.datastruct.DefaultNoData;
45
import org.gvsig.raster.impl.datastruct.ExtentImpl;
46
import org.gvsig.raster.impl.process.RasterTask;
47
import org.gvsig.raster.impl.process.RasterTaskQueue;
48
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
49
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
50
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
51
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
52
import org.gvsig.tools.dispose.Disposable;
53
import org.gvsig.tools.task.TaskStatus;
54
/**
55
 * Soporte 'nativo' para ficheros desde GDAL.
56
 * 
57
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
58
 * @author Nacho Brodin (nachobrodin@gmail.com)
59
 */
60
public class GdalNative extends Gdal implements Disposable {
61
        private String                       fileName                = null;
62
        private String                       shortName               = "";
63
        public         GeoTransform                 trans                   = null;
64
        public int                           width                   = 0, height = 0;
65
        public double                        originX                 = 0D, originY = 0D;
66
        public String                        version                 = "";
67
        protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
68
        private int[]                        dataType                = null;
69
        DataStoreMetadata                    metadata                = null;
70
        protected boolean                    georeferenced           = true;
71
        
72
        /**
73
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
74
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
75
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
76
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
77
         * distinto tama?o que el resto.   
78
         */
79
        public int[]                              stepArrayX             = null;
80
        public int[]                              stepArrayY             = null;
81
        protected GdalRasterBand[]                gdalBands              = null;
82
        private double                            lastReadLine           = -1;
83
        private int                               currentFullWidth       = -1;
84
        private int                               currentFullHeight      = -1;
85
        private int                               currentViewWidth       = -1;
86
        private int                               currentViewHeight      = -1;
87
        private double                            currentViewX           = 0D;
88
        private double                            viewportScaleX         = 0D;
89
        private double                            viewportScaleY         = 0D;
90
        private double                            stepX                  = 0D;
91
        private double                            stepY                  = 0D;
92
        public boolean                            isSupersampling        = false;
93
        private boolean                           open                   = false;
94
        /**
95
         * Estado de transparencia del raster.
96
         */
97
        protected DataStoreTransparency           fileTransparency       = null;
98
        protected DataStoreColorTable             palette                = null;
99
        protected DataStoreColorInterpretation    colorInterpr           = null;
100
        protected AffineTransform                 ownTransformation      = null;
101
        protected AffineTransform                 externalTransformation = new AffineTransform();
102
        
103
        
104
        /**
105
         * Overview usada en el ?ltimo setView
106
         */
107
        int currentOverview = -1;
108
        
109
        public GdalNative(String fName) throws GdalException, IOException {
110
                super();
111
                init(fName);
112
        }
113
        
114
        private void init(String fName) throws GdalException, IOException {
115
                fileName = fName;
116
                open(fName, GA_ReadOnly);
117
                open = true;
118
                if (getPtro() == -1)
119
                        throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
120
//                ext = RasterUtilities.getExtensionFromFileName(fName);
121
                width = getRasterXSize();
122
                height = getRasterYSize();
123

    
124
                int[] dt = new int[getRasterCount()];
125
                for (int i = 0; i < getRasterCount(); i++)
126
                        dt[i] = this.getRasterBand(i + 1).getRasterDataType();
127
                setDataType(dt);
128
                shortName = getDriverShortName();
129
                fileTransparency = new DataStoreTransparency();
130
                colorInterpr = new DataStoreColorInterpretation();
131
                metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
132

    
133
                // Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
134
                // nos sirve para saber que banda de la imagen va asignada a cada banda de
135
                // visualizaci?n (ARGB)
136
                colorInterpr.initColorInterpretation(getRasterCount());
137
                metadata.initNoDataByBand(getRasterCount());
138
                for (int i = 0; i < getRasterCount(); i++) {
139
                        GdalRasterBand rb = getRasterBand(i + 1);
140
                        String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
141
                        metadata.setNoDataEnabled(rb.existsNoDataValue());
142
                        if(rb.existsNoDataValue()) {
143
                                metadata.setNoDataValue(i, rb.getRasterNoDataValue());
144
                                metadata.setNoDataEnabled(rb.existsNoDataValue());
145
                        }
146
                        colorInterpr.setColorInterpValue(i, colorInt);
147
                        if (colorInt.equals("Alpha"))
148
                                fileTransparency.setTransparencyBand(i);
149

    
150
                        if (rb.getRasterColorTable() != null && palette == null) {
151
                                palette = new DataStoreColorTable();
152
                                palette.createPaletteFromGdalColorTable(rb.getRasterColorTable());
153
//                                fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
154
                        }
155
                }
156
                fileTransparency.setTransparencyByPixelFromMetadata(metadata);
157

    
158
                try {
159
                        trans = getGeoTransform();
160

    
161
                        boolean isCorrect = false;
162
                        for (int i = 0; i < trans.adfgeotransform.length; i++)
163
                                if (trans.adfgeotransform[i] != 0)
164
                                        isCorrect = true;
165
                        if (!isCorrect)
166
                                throw new GdalException("");
167

    
168
                        ownTransformation = new AffineTransform(trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
169
                        externalTransformation = (AffineTransform) ownTransformation.clone();
170
                        currentFullWidth = width;
171
                        currentFullHeight = height;
172

    
173
                        this.georeferenced = true;
174
                } catch (GdalException exc) {
175
                        // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
176
                        // ya que las WC decrecen de
177
                        // arriba a abajo y los pixeles crecen de arriba a abajo
178
                        ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
179
                        externalTransformation = (AffineTransform) ownTransformation.clone();
180
                        currentFullWidth = width;
181
                        currentFullHeight = height;
182
                        this.georeferenced = false;
183
                }
184
        }
185
        
186
        /**
187
         * Returns true if this provider is open and false if don't
188
         * @return
189
         */
190
        public boolean isOpen() {
191
                return open;
192
        }
193
        
194
        /**
195
         * Obtiene el flag que informa de si el raster tiene valor no data o no.
196
         * Consultar? todas las bandas del mismo y si alguna tiene valor no data
197
         * devuelve true sino devolver? false.
198
         * @return true si tiene valor no data y false si no lo tiene
199
         * @throws GdalException
200
         */
201
        public boolean existsNoDataValue() throws GdalException {
202
                for (int i = 0; i < getRasterCount(); i++) {
203
                        GdalRasterBand rb = getRasterBand(i + 1);
204
                        if (rb.existsNoDataValue())
205
                                return true;
206
                }
207
                return false;
208
        }
209
        
210
        /**
211
         * Obtiene el flag que informa de si el raster tiene valor no data o no
212
         * en una banda concreta.
213
         * @return true si tiene valor no data en esa banda y false si no lo tiene
214
         * @param band Posici?n de la banda a consultar (0..n)
215
         * @throws GdalException
216
         */
217
        public boolean existsNoDataValue(int band) throws GdalException {
218
                GdalRasterBand rb = getRasterBand(band + 1);
219
                return rb.existsNoDataValue();
220
        }
221

    
222
        /**
223
         * Gets nodata value
224
         * @return
225
         */
226
        public NoData getNoDataValue() {
227
                Number value = null;
228
                int type = RasterLocator.getManager().getRasterUtils().getRasterBufTypeFromGdalType(getDataType()[0]);
229
                if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
230
                        switch (type) {
231
                        case Buffer.TYPE_BYTE:
232
                                if (metadata == null || metadata.getNoDataValue().length == 0)
233
                                        value = new Byte(RasterLibrary.defaultByteNoDataValue);
234
                                else
235
                                        value = new Byte((byte)metadata.getNoDataValue()[0]);
236
                                break;
237
                        case Buffer.TYPE_SHORT:
238
                                if (metadata == null || metadata.getNoDataValue().length == 0)
239
                                        value = new Short(RasterLibrary.defaultShortNoDataValue);
240
                                else
241
                                        value = new Short((short)metadata.getNoDataValue()[0]);
242
                                break;
243
                        case Buffer.TYPE_INT:
244
                                if (metadata == null || metadata.getNoDataValue().length == 0)
245
                                        value = new Integer((int)RasterLibrary.defaultIntegerNoDataValue);
246
                                else
247
                                        value = new Integer((int)metadata.getNoDataValue()[0]);
248
                                break;
249
                        case Buffer.TYPE_FLOAT:
250
                                if (metadata == null || metadata.getNoDataValue().length == 0)
251
                                        value = new Float(RasterLibrary.defaultFloatNoDataValue);
252
                                else
253
                                        value = new Float(metadata.getNoDataValue()[0]);
254
                                break;
255
                        case Buffer.TYPE_DOUBLE:
256
                                if (metadata == null || metadata.getNoDataValue().length == 0)
257
                                        value = new Double(RasterLibrary.defaultFloatNoDataValue);
258
                                else
259
                                        value = new Double(metadata.getNoDataValue()[0]);
260
                                break;
261
                        }
262
                }
263

    
264
                return new DefaultNoData(value, value, fileName);
265
        }
266

    
267
        /**
268
         * Asigna el tipo de dato
269
         * @param dt entero que representa el tipo de dato
270
         */
271
        public void setDataType(int[] dt) { 
272
                dataType = dt; 
273
        }
274
        
275
        /**
276
         * Obtiene el tipo de dato
277
         * @return entero que representa el tipo de dato
278
         */
279
        public int[] getDataType() { 
280
                return dataType; 
281
        }
282
        
283
        /**
284
         * Gets the color interpretation
285
         * @return
286
         */
287
        public ColorInterpretation getColorInterpretation() { 
288
                return colorInterpr; 
289
        }
290
        
291
        /**
292
         * Gets the color table
293
         * @return
294
         */
295
        public ColorTable getColorTable() {
296
                return palette;
297
        }
298
        
299
        /**
300
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
301
         * del punto real.
302
         * Supone rasters no girados
303
         * @param pt        punto en coordenadas del punto real
304
         * @return        punto en coordenadas del raster
305
         */
306
        public Point2D worldToRasterWithoutRot(Point2D pt) {
307
                Point2D p = new Point2D.Double();
308
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
309
                                                                                                        0, externalTransformation.getScaleY(), 
310
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
311
                try {
312
                        at.inverseTransform(pt, p);
313
                } catch (NoninvertibleTransformException e) {
314
                        return pt;
315
                }
316
                return p;
317
        }
318
                
319
        /**
320
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
321
         * del punto real.
322
         * Supone rasters no girados
323
         * @param pt        punto en coordenadas del punto real
324
         * @return        punto en coordenadas del raster
325
         */
326
        public Point2D worldToRaster(Point2D pt) {
327
                Point2D p = new Point2D.Double();
328
                try {
329
                        externalTransformation.inverseTransform(pt, p);
330
                } catch (NoninvertibleTransformException e) {
331
                        return pt;
332
                }
333
                return p;
334
        }
335
        
336
        /**
337
         * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
338
         * reales. 
339
         * @param pt Punto en coordenadas reales
340
         * @return Punto en coordenadas pixel.
341
         */
342
        public Point2D rasterToWorld(Point2D pt) {
343
                Point2D p = new Point2D.Double();
344
                externalTransformation.transform(pt, p);
345
                return p;
346
        }
347
        
348
        /**
349
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
350
         * viewPortScale, currentFullWidth y currentFulHeight
351
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
352
         * @throws GdalException
353
         */
354
        private void calcOverview(Point2D tl, Point2D br) throws GdalException {
355
                gdalBands[0] = getRasterBand(1);
356
                currentOverview = -1;
357
                if (gdalBands[0].getOverviewCount() > 0) {
358
                        GdalRasterBand ovb = null;
359
                        for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
360
                                ovb = gdalBands[0].getOverview(i);
361
                                if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
362
                                        currentOverview = i;
363
                                        viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
364
                                        viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
365
                                        stepX = 1D / viewportScaleX;
366
                                        stepY = 1D / viewportScaleY;
367
                                        currentFullWidth = ovb.getRasterBandXSize();
368
                                        currentFullHeight = ovb.getRasterBandYSize();
369
                                        currentViewX = Math.min(tl.getX(), br.getX());
370
                                        lastReadLine = Math.min(tl.getY(), br.getY());
371
                                        break;
372
                                }
373
                        }
374
                }
375
        }
376
        
377
        public void setView(double dWorldTLX, double dWorldTLY,
378
                                                double dWorldBRX, double dWorldBRY,
379
                                                int nWidth, int nHeight) throws GdalException {
380
                currentFullWidth = width;
381
                currentFullHeight = height;
382
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
383
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
384
                // Calcula cual es la primera l?nea a leer;
385
                currentViewWidth = nWidth;
386
                currentViewHeight = nHeight;
387
//                wcWidth = Math.abs(br.getX() - tl.getX());
388

    
389
                currentViewX = Math.min(tl.getX(), br.getX());
390

    
391
                viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
392
                viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
393
                stepX = 1D / viewportScaleX;
394
                stepY = 1D / viewportScaleY;
395

    
396
                lastReadLine = Math.min(tl.getY(), br.getY());
397
                
398
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
399

    
400
                // calcula el overview a usar
401
                gdalBands = new GdalRasterBand[4];
402
                calcOverview(tl, br);
403

    
404
                // Selecciona las bandas y los overviews necesarios
405
                /*gdalBands[0] = getRasterBand(rBandNr);
406
                gdalBands[1] = gdalBands[0]; 
407
                gdalBands[2] = gdalBands[1]; 
408

409
                if(getRasterCount() >= 2) {
410
                        gdalBands[1] = getRasterBand(gBandNr);
411
                        gdalBands[2] = gdalBands[1]; 
412
                }
413
                if(this.getRasterCount() >= 3) 
414
                        gdalBands[2] = getRasterBand(bBandNr);
415
                if(colorInterpr.isAlphaBand())
416
                        gdalBands[3] = getRasterBand(aBandNr);                        
417

418
                assignDataTypeFromGdalRasterBands(gdalBands);
419

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

430
                }*/
431
        }
432
        
433
        /**
434
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
435
         * @param nbands N?mero de bandas solicitado.
436
         * @throws GdalException
437
         */
438
        public void selectGdalBands(int nbands) throws GdalException {
439
                gdalBands = new GdalRasterBand[nbands];
440
                // Selecciona las bandas y los overviews necesarios
441
                gdalBands[0] = getRasterBand(1);
442
                for (int i = 0; i < nbands; i++)
443
                        gdalBands[i] = gdalBands[0];
444

    
445
                assignDataTypeFromGdalRasterBands(gdalBands);
446
//                setDataType(gdalBands[0].getRasterDataType());
447

    
448
                for (int i = 2; i <= nbands; i++) {
449
                        if (getRasterCount() >= i) {
450
                                gdalBands[i - 1] = getRasterBand(i);
451
                                for (int j = i; j < nbands; j++)
452
                                        gdalBands[j] = gdalBands[i - 1];
453
                        }
454
                }
455

    
456
                if (currentOverview > 0) {
457
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
458
                        for (int i = 2; i <= nbands; i++) {
459
                                if (getRasterCount() >= i)
460
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
461
                        }
462
                }
463
        }
464
                
465
        int lastY = -1;
466
        
467
        /**
468
         * Lee una l?nea de bytes
469
         * @param line Buffer donde se cargan los datos
470
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
471
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
472
         * por la izquierda a mitad de pixel
473
         * @param gdalBuffer Buffer con la l?nea de datos original
474
         */
475
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
476
                double j = 0D;
477
                int i = 0;
478
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
479
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
480
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
481
                        }
482
                }
483
        }
484
        
485
        /**
486
         * Lee una l?nea de shorts
487
         * @param line Buffer donde se cargan los datos
488
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
489
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
490
         * por la izquierda a mitad de pixel
491
         * @param gdalBuffer Buffer con la l?nea de datos original
492
         */
493
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
494
                double j = 0D;
495
                int i = 0;
496
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
497
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
498
                                line[iBand][i] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
499
                        }
500
                }
501
        }
502

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

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

    
557
        /**
558
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
559
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
560
         * @param nLine N?mero de l?nea a leer
561
         * @param band Banda requerida
562
         * @return Object que es un array unidimendional del tipo de datos del raster
563
         * @throws GdalException
564
         */
565
        public Object readCompleteLine(int nLine, int band) throws GdalException {
566
                GdalRasterBand gdalBand = super.getRasterBand(band + 1);
567
                GdalBuffer gdalBuf = null;
568

    
569
                gdalBuf = gdalBand.readRaster(0, nLine, getRasterXSize(), 1, getRasterXSize(), 1, dataType[band]);
570

    
571
                if (dataType[band] == GDT_Byte)
572
                        return gdalBuf.buffByte;
573

    
574
                if (dataType[band] == GDT_Int16 || dataType[band] == GDT_UInt16)
575
                        return gdalBuf.buffShort;
576

    
577
                if (dataType[band] == GDT_Int32 || dataType[band] == GDT_UInt32)
578
                        return gdalBuf.buffInt;
579

    
580
                if (dataType[band] == GDT_Float32)
581
                        return gdalBuf.buffFloat;
582

    
583
                if (dataType[band] == GDT_Float64)
584
                        return gdalBuf.buffDouble;
585

    
586
                if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_CInt32 ||
587
                                dataType[band] == GDT_CFloat32 || dataType[band] == GDT_CFloat64)
588
                        return null;
589
                
590
                return null;
591
        }
592
        
593
        /**
594
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
595
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
596
         * @param nLine N?mero de l?nea a leer
597
         * @param band Banda requerida
598
         * @return Object que es un array unidimendional del tipo de datos del raster
599
         * @throws GdalException
600
         */
601
        public Object readBlock(int pos, int blockHeight, double scale) throws GdalException, ProcessInterruptedException {
602
                bBandNr = super.getRasterCount();
603
                int widthBuffer = (int)(getRasterXSize() * scale);
604
                int heightBuffer = (int)(blockHeight * scale);
605

    
606
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
607
                                
608
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
609
                for (int iBand = 0; iBand < gdalBand.length; iBand++) 
610
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
611
                                
612
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
613
                                
614
                if (dataType[0] == GDT_Byte) {
615
                        byte[][][] buf = new byte[bBandNr][heightBuffer][widthBuffer];
616
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
617
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
618
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
619
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
620
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * widthBuffer + iCol];
621
                                        if(task.getEvent() != null)
622
                                                task.manageEvent(task.getEvent());
623
                                }
624
                                gdalBuf[iBand].buffByte = null;
625
                        }        
626
                        return buf;
627
                } else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
628
                        short[][][] buf = new short[bBandNr][heightBuffer][widthBuffer];
629
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
630
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
631
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
632
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
633
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * widthBuffer + iCol];
634
                                        if(task.getEvent() != null)
635
                                                task.manageEvent(task.getEvent());
636
                                }
637
                                gdalBuf[iBand].buffShort = null;
638
                        }        
639
                        return buf;
640
                } else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
641
                        int[][][] buf = new int[bBandNr][heightBuffer][widthBuffer];
642
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
643
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
644
                                for (int iRow = 0; iRow < heightBuffer; iRow++) { 
645
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
646
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * widthBuffer + iCol];
647
                                        if(task.getEvent() != null)
648
                                                task.manageEvent(task.getEvent());
649
                                }
650
                                gdalBuf[iBand].buffInt = null;
651
                        }        
652
                        return buf;
653
                } else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
654
                        float[][][] buf = new float[bBandNr][heightBuffer][widthBuffer];
655
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
656
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
657
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
658
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
659
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * widthBuffer + iCol];
660
                                        if(task.getEvent() != null)
661
                                                task.manageEvent(task.getEvent());
662
                                }
663
                                gdalBuf[iBand].buffFloat = null;
664
                        }        
665
                        return buf;
666
                } else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
667
                        double[][][] buf = new double[bBandNr][heightBuffer][widthBuffer];
668
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
669
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
670
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
671
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
672
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * widthBuffer + iCol];
673
                                        if(task.getEvent() != null)
674
                                                task.manageEvent(task.getEvent());
675
                                }
676
                                gdalBuf[iBand].buffDouble = null;
677
                        }                
678
                        return buf;
679
                }
680
                                
681
                return null;
682
        }
683
        
684
        /**
685
         * Lectura de una l?nea de datos.
686
         * @param line
687
         * @throws GdalException
688
         */
689
        public void readLine(Object line) throws GdalException {
690
                int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
691
                int x = (int) (currentViewX);
692
                int y = (int) (lastReadLine);
693
                GdalBuffer r = null, g = null, b = null;
694
                GdalBuffer a = new GdalBuffer();
695

    
696
                while(y >= gdalBands[0].getRasterBandYSize())
697
                        y--;
698

    
699
                if (x+w > gdalBands[0].getRasterBandXSize()) 
700
                        w = gdalBands[0].getRasterBandXSize()-x;
701

    
702
                if(gdalBands[0].getRasterColorTable() != null) {
703
                        palette = new DataStoreColorTable();
704
                        palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
705
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
706
                } else {
707
                        a.buffByte = new byte[w];
708
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
709
                        g = b = r;
710
                        if (getRasterCount() > 1 && gdalBands[1] != null)
711
                                g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
712
                        if (getRasterCount() > 2 && gdalBands[2] != null)
713
                                b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
714
                }
715

    
716
                lastReadLine += stepY;
717

    
718
                double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
719
                GdalBuffer[] bands = {r, g, b};
720

    
721
                if (dataType[0] == GDT_Byte)
722
                        readLine((byte[][])line, initOffset, bands);
723
                else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
724
                        readLine((short[][])line, initOffset, bands);
725
                else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
726
                        readLine((int[][])line, initOffset, bands);
727
                else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
728
                        readLine((float[][])line, initOffset, bands);
729
                else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
730
                        readLine((double[][])line, initOffset, bands);
731

    
732
                return;
733
        }
734
                        
735
        /**
736
         * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede
737
         * estar ajustada a la extensi?n del raster o no estarlo. En caso de no
738
         * estarlo los pixeles del buffer que caen fuera de la extensi?n del raster
739
         * tendr?n valor de NoData. Esta funci?n calcula en que pixel del buffer hay
740
         * que empezar a escribir en caso de que este sea mayor que los datos a leer.
741
         * 
742
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
743
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
744
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
745
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
746
         * @param nWidth Ancho en pixeles del buffer
747
         * @param nHeight Alto en pixeles del buffer
748
         * @return desplazamiento dentro del buffer en X e Y
749
         */ 
750
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
751
                Extent imageExtent = getExtentWithoutRot();
752
                Extent ajustDataExtent = RasterLocator.getManager().getRasterUtils().calculateAdjustedView(dataExtent, imageExtent);
753
                if(!RasterLocator.getManager().getRasterUtils().compareExtents(dataExtent, ajustDataExtent)){
754
                        Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
755
                        Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
756
                        Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
757
                        //                    Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
758
                        //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
759
                        int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
760
                        int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
761

    
762
                        stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
763
                        stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
764
                        stpBuffer[2] = stpBuffer[0] + w; 
765
                        stpBuffer[3] = stpBuffer[1] + h;
766
                        return new int[]{w, h};
767
                }
768
                return new int[]{nWidth, nHeight};
769
        }
770
        
771
        /**
772
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
773
         * @param buf Buffer donde se almacenan los datos
774
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
775
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
776
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
777
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
778
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
779
         * @param nWidth Ancho en pixeles del buffer
780
         * @param nHeight Alto en pixeles del buffer
781
         * @throws GdalException
782
         */
783
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
784
                        int nWidth, int nHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
785
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
786
                setView(ulx, uly, lrx, lry, nWidth, nHeight);
787
                Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
788
                Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
789

    
790
                if(tl.getX() > br.getX())
791
                        tl.setLocation(tl.getX() - 1, tl.getY());
792
                else
793
                        br.setLocation(br.getX() - 1, br.getY());
794
                
795
                if(tl.getY() > br.getY())
796
                        tl.setLocation(tl.getX(), tl.getY() - 1);
797
                else
798
                        br.setLocation(br.getX(), br.getY() - 1);
799
                
800
                if(gdalBands.length == 0)
801
                        return;
802

    
803
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
804

    
805
                int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
806
                int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
807

    
808
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
809
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
810
                //ya que lo que cae fuera ser?n valores NoData
811
                if(!adjustToExtent){
812
                        int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
813
                        if(x < 0)
814
                                x  = 0;
815
                        if(y < 0)
816
                                y  = 0;
817
                        readDataCachedBuffer(buf, bandList, new int[]{x, y, wh[0], wh[1]}, 
818
                                        wh[0], wh[1], 0, 0, stpBuffer, status);
819
                        return;
820
                }
821

    
822
                readDataCachedBuffer(buf, bandList, new int[]{x, y, nWidth, nHeight}, 
823
                                nWidth, nHeight, 0, 0, stpBuffer, status);
824
        }
825
                        
826
        /**
827
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
828
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
829
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
830
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de 
831
         * mayor tama?o que el n?mero de pixels solicitado.
832
         * 
833
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor 
834
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer 
835
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
836
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del 
837
         * raster de disco completos sino que en los bordes del buffer quedan cortados.  
838
         *  
839
         * @param buf Buffer donde se almacenan los datos
840
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
841
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
842
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
843
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
844
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
845
         * @param nWidth Ancho en pixeles de la petici?n
846
         * @param nHeight Alto en pixeles de la petici?n
847
         * @param bufWidth Ancho del buffer
848
         * @param bufHeight Alto del buffer
849
         * @throws GdalException
850
         */
851
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
852
                                                        double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
853
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
854
                setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
855
                Point2D ul = worldToRaster(new Point2D.Double(ulx, uly));
856
                Point2D lr = worldToRaster(new Point2D.Double(lrx, lry));
857
                ul.setLocation(ul.getX() < 0 ? 1 : ul.getX(), ul.getY() < 0 ? 1 : ul.getY());
858
                lr.setLocation(lr.getX() < 0 ? 1 : lr.getX(), lr.getY() < 0 ? 1 : lr.getY());
859
                ul.setLocation(ul.getX() - 0.5, ul.getY() - 0.5);
860
                lr.setLocation(lr.getX() - 0.5, lr.getY() - 0.5);
861
                
862
                /*if(tl.getX() > br.getX())
863
                        tl.setLocation(tl.getX() - 1, tl.getY());
864
                else
865
                        br.setLocation(br.getX() - 1, br.getY());
866
                
867
                if(tl.getY() > br.getY())
868
                        tl.setLocation(tl.getX(), tl.getY() - 1);
869
                else
870
                        br.setLocation(br.getX(), br.getY() - 1);*/
871
                
872
                adjustPoints(ul, lr);
873
                
874
                if(gdalBands.length == 0)
875
                        return;
876
                
877
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
878
                                
879
                int x = (int) Math.min(ul.getX(), lr.getX());
880
                int y = (int) Math.min(ul.getY(), lr.getY());
881
                //int endX = (int) Math.ceil(Math.max(br.getX(), tl.getX()));
882
                //int endY = (int) Math.ceil(Math.max(br.getY(), tl.getY()));
883

    
884
                int stpX = 0;
885
                int stpY = 0;
886
                                
887
                /*if(bufWidth > Math.ceil(nWidth)){
888
                        stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
889
                        bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth);
890
                }
891
                if(bufHeight > Math.ceil(nHeight)){
892
                        stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
893
                        bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight);
894
                }
895

896
                nWidth = (int)Math.abs(endX - x);
897
                nHeight = (int)Math.abs(endY - y);*/
898

    
899
                nWidth = (nWidth * currentFullWidth) / width;
900
                nHeight = (nHeight * currentFullHeight) / height;
901
                x = (int)(((long)x * (long)currentFullWidth) / (long)width);
902
                y = (int) (((long)y * (long)currentFullHeight) / (long)height);
903

    
904
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
905
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
906
                //ya que lo que cae fuera ser?n valores NoData
907
                if(!adjustToExtent){
908
                        int[] wh = calcStepBuffer(petExtent, bufWidth, bufHeight, stpBuffer);
909
                        if(x < 0)
910
                                x  = 0;
911
                        if(y < 0)
912
                                y  = 0;
913
                        stpBuffer[0] = (int)((stpBuffer[0] * bufWidth) / nWidth);
914
                        stpBuffer[1] = (int)((stpBuffer[1] * bufHeight) / nHeight);
915
                        stpBuffer[2] = (int)((stpBuffer[2] * bufWidth) / nWidth);
916
                        stpBuffer[3] = (int)((stpBuffer[3] * bufHeight) / nHeight);
917
                        bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
918
                        bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
919
                        readDataCachedBuffer(buf, bandList, new int[]{x, y, wh[0], wh[1]}, bufWidth, bufHeight, 0, 0, stpBuffer, status);
920
                        return;
921
                }
922

    
923
                if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
924
                        nWidth = gdalBands[0].getRasterBandXSize() - x;
925

    
926
                if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
927
                        nHeight = gdalBands[0].getRasterBandYSize() - y;
928

    
929
                readDataCachedBuffer(buf, bandList, new int[]{x, y, (int)nWidth, (int)nHeight}, bufWidth, bufHeight, stpX, stpY, stpBuffer, status);
930
        }
931
        
932
        private void adjustPoints(Point2D ul, Point2D lr) {
933
                double a = (ul.getX() - (int)ul.getX());
934
                double b = (ul.getY() - (int)ul.getY());
935
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(), 
936
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
937
                lr.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(), 
938
                                                (b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
939
        }
940

    
941
        /**
942
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
943
         * @param buf Buffer donde se almacenan los datos
944
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
945
         * @param x Posici?n X en pixeles
946
         * @param y Posici?n Y en pixeles
947
         * @param w Ancho en pixeles
948
         * @param h Alto en pixeles
949
         * @throws GdalException
950
         */
951
//        public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h) 
952
//                throws GdalException, ProcessInterruptedException {
953
//                gdalBands = new GdalRasterBand[getRasterCount()];
954
//                isSupersampling = false;
955
//                if(gdalBands.length == 0)
956
//                        return;
957
//                
958
//                // Selecciona las bandas
959
//                gdalBands[0] = getRasterBand(1);
960
//                
961
//                for(int iBand = 1; iBand < gdalBands.length; iBand++)
962
//                        gdalBands[iBand] = getRasterBand(iBand + 1);
963
//
964
//                assignDataTypeFromGdalRasterBands(gdalBands);
965
//
966
//                int[] stepBuffer = new int[]{0, 0, w, h};
967
//                readDataCachedBuffer(buf, bandList, new int[]{x, y, w, h}, w, h, 0, 0, stepBuffer);
968
//        }
969

    
970
        
971
        
972
        /**
973
         * Lee una ventana de datos con resampleo a partir de coordenadas en pixeles. Este m?todo lee la
974
         * ventana de una vez cargando los datos de un golpe en el buffer.
975
         * @param buf Buffer donde se almacenan los datos
976
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
977
         * @param x Posici?n X en pixeles
978
         * @param y Posici?n Y en pixeles
979
         * @param w Ancho en pixeles
980
         * @param h Alto en pixeles
981
         * @param bufWidth Ancho del buffer
982
         * @param bufHeight Alto del buffer
983
         * @throws GdalException
984
         */
985
        public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h, TaskStatus status) throws GdalException, ProcessInterruptedException {
986
                gdalBands = new GdalRasterBand[getRasterCount()];
987
                
988
                if(buf.getWidth() == w && buf.getHeight() == h)
989
                        isSupersampling = false;
990
                
991
                if(gdalBands.length == 0)
992
                        return;
993
                
994
                // Selecciona las bandas
995
                gdalBands[0] = getRasterBand(1);
996
                
997
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
998
                        gdalBands[iBand] = getRasterBand(iBand + 1);
999
                
1000
                assignDataTypeFromGdalRasterBands(gdalBands);
1001
                
1002
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
1003
                readDataCachedBuffer(buf, bandList, new int[]{x, y, w, h}, buf.getWidth(), buf.getHeight(), 0, 0, stpBuffer, status);
1004
        }
1005
        
1006
        /**
1007
         * Asigna el tipo de datos de las bandas a partir de una lista de GdalRasterBands
1008
         * @param gdalBands
1009
         * @throws GdalException
1010
         */
1011
        private void assignDataTypeFromGdalRasterBands(GdalRasterBand[] gdalBands) throws GdalException {
1012
                int[] dt = new int[gdalBands.length];
1013
                for (int i = 0; i < gdalBands.length; i++) {
1014
                        if(gdalBands[i] != null)
1015
                                dt[i] = gdalBands[i].getRasterDataType();
1016
                }
1017
                setDataType(dt);
1018
        }
1019
        
1020
        /**
1021
         * Lee una ventana de datos. Esta funci?n es usuada por
1022
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. Esta es una versi?n de readData pero
1023
         * comprueba si el buffer es cacheado y si lo es pide por trozos para no intentar cargar desde gdal demasiados
1024
         * datos.
1025
         * @param buf Buffer donde se almacenan los datos
1026
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1027
         * @param inputWindow
1028
         * <UL>
1029
         * <LI>inputWindow[0]:Posici?n X en pixeles de la imagen de entrada</LI>
1030
         * <LI>inputWindow[1]:Posici?n Y en pixeles de la imagen de entrada</LI>
1031
         * <LI>inputWindow[2]:Ancho en p?xeles a leer de la imagen de entrada</LI>
1032
         * <LI>inputWindow[3]:Alto en p?xeles a leer de la imagen de entrada</LI>
1033
         * </UL>
1034
         * @param bufWidth Ancho del buffer de la imagen de entrada. Si no coincide con inputWindow[2] el propio gdal resamplea
1035
         * @param bufHeight Alto del buffer de la imagen de entrada. Si no coincide con inputWindow[3] el propio gdal resamplea
1036
         * @param stepX Desplazamiento en p?xeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un 
1037
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
1038
         * parte de ellos. 
1039
         * @param stepY Desplazamiento en p?xeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un 
1040
         * supersampleo ya que puede ser que de los p?xeles que est?n en el borde superior de la petici?n solo queramos una
1041
         * parte de ellos.
1042
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes 
1043
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1044
         * <UL>
1045
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1046
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1047
         * <LI>stepBuffer[2]:Posici?n X final m?s uno</LI>
1048
         * <LI>stepBuffer[3]:Posici?n Y final m?s uno</LI>
1049
         * </UL>
1050
         * @throws GdalException
1051
         */
1052
        private void readDataCachedBuffer(Buffer buf, 
1053
                        BandList bandList, 
1054
                        int[] inputWindow, 
1055
                        int bufWidth, 
1056
                        int bufHeight, 
1057
                        int stpX, 
1058
                        int stpY, 
1059
                        int[] stepBuffer,
1060
                        TaskStatus status) throws GdalException, ProcessInterruptedException {
1061
                if(buf.isCached()) {
1062
                        int nBlocks = (int)(buf.getHeight() / buf.getBlockHeight());
1063
                        int lastblock = buf.getHeight() - (nBlocks * buf.getBlockHeight());
1064
                        if(lastblock > 0)
1065
                                nBlocks ++;
1066
                        int initYSrc = inputWindow[1];
1067
                        int stepYSrc = (buf.getBlockHeight() * inputWindow[3]) / buf.getHeight();
1068
                        int lastBlockYSrc = (lastblock * inputWindow[3]) / buf.getHeight();
1069
                        int initYBuffer = 0;
1070
                        for (int i = 0; i < nBlocks; i++) {
1071
                                if(lastblock > 0 && i == (nBlocks - 1)) {
1072
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + lastblock};
1073
                                        int[] newWindow = new int[]{inputWindow[0], initYSrc, inputWindow[2], lastBlockYSrc};
1074
                                        readData(buf, 
1075
                                                        bandList, 
1076
                                                        newWindow, 
1077
                                                        bufWidth, lastblock, 0, 0, newStepBuffer);
1078
                                } else {
1079
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + buf.getBlockHeight()};
1080
                                        int[] newWindow = new int[]{inputWindow[0], initYSrc, inputWindow[2], stepYSrc};
1081
                                        readData(buf, 
1082
                                                        bandList, 
1083
                                                        newWindow, 
1084
                                                        bufWidth, buf.getBlockHeight(), 0, 0, newStepBuffer);
1085
                                        initYSrc += stepYSrc;
1086
                                        initYBuffer += buf.getBlockHeight();
1087
                                }
1088
                        }
1089
                } else {
1090
                        readData(buf, bandList, inputWindow, bufWidth, bufHeight, 0, 0, stepBuffer);
1091
                }
1092
        }
1093
                
1094
        /**
1095
         * Lee una ventana de datos. Esta funci?n es usuada por
1096
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1097
         * @param buf Buffer donde se almacenan los datos
1098
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1099
         * @param inputWindow
1100
         * <UL>
1101
         * <LI>inputWindow[0]:Posici?n X en pixeles de la imagen de entrada</LI>
1102
         * <LI>inputWindow[1]:Posici?n Y en pixeles de la imagen de entrada</LI>
1103
         * <LI>inputWindow[2]:Ancho en p?xeles a leer de la imagen de entrada</LI>
1104
         * <LI>inputWindow[3]:Alto en p?xeles a leer de la imagen de entrada</LI>
1105
         * </UL>
1106
         * @param bufWidth Ancho del buffer de la imagen de entrada. Si no coincide con inputWindow[2] el propio gdal resamplea
1107
         * @param bufHeight Alto del buffer de la imagen de entrada. Si no coincide con inputWindow[3] el propio gdal resamplea
1108
         * @param stepX Desplazamiento en p?xeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un 
1109
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
1110
         * parte de ellos. 
1111
         * @param stepY Desplazamiento en p?xeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un 
1112
         * supersampleo ya que puede ser que de los p?xeles que est?n en el borde superior de la petici?n solo queramos una
1113
         * parte de ellos.
1114
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes 
1115
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1116
         * <UL>
1117
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1118
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1119
         * <LI>stepBuffer[2]:Posici?n X final m?s uno</LI>
1120
         * <LI>stepBuffer[3]:Posici?n Y final m?s uno</LI>
1121
         * </UL>
1122
         * @throws GdalException
1123
         */
1124
        private void readData(Buffer buf, 
1125
                        BandList bandList, 
1126
                        int[] inputWindow, 
1127
                        int bufWidth, 
1128
                        int bufHeight, 
1129
                        int stpX, 
1130
                        int stpY, 
1131
                        int[] stepBuffer) throws GdalException, ProcessInterruptedException {
1132
                
1133
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + ""); 
1134
                FileUtils fUtil = RasterLocator.getManager().getFileUtils(); 
1135
                        
1136
                GdalBuffer gdalBuf = null;
1137
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1138
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1139
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1140
                                continue;        
1141
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
1142
                        int pos = init;
1143
                        gdalBuf = gdalBands[iBand].readRaster(        inputWindow[0], 
1144
                                                                                                        inputWindow[1], 
1145
                                                                                                        inputWindow[2], 
1146
                                                                                                        inputWindow[3], 
1147
                                                                                                        bufWidth, 
1148
                                                                                                        bufHeight, 
1149
                                                                                                        dataType[iBand]);
1150
                        int lineInputWindow = 0;
1151
                        if(dataType[iBand] == Gdal.GDT_Byte) {
1152
                                for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
1153
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1154
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++) {
1155
                                                for (int i = 0; i < drawableBands.length; i++) 
1156
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffByte[pos]);
1157
                                                pos ++;
1158
                                        }
1159
                                        lineInputWindow ++;
1160
                                        if(task.getEvent() != null)
1161
                                                task.manageEvent(task.getEvent());
1162
                                }
1163
                                gdalBuf.buffByte = null;
1164
                        } else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1165
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1166
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1167
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1168
                                                for (int i = 0; i < drawableBands.length; i++)
1169
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffShort[pos]);
1170
                                                pos ++;
1171
                                        }
1172
                                        lineInputWindow ++;
1173
                                        if(task.getEvent() != null)
1174
                                                task.manageEvent(task.getEvent());
1175
                                }
1176
                                gdalBuf.buffShort = null;
1177
                        } else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1178
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1179
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1180
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1181
                                                for (int i = 0; i < drawableBands.length; i++)
1182
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffInt[pos]);
1183
                                                pos ++;
1184
                                        }
1185
                                        lineInputWindow ++;
1186
                                        if(task.getEvent() != null)
1187
                                                task.manageEvent(task.getEvent());
1188
                                }
1189
                                gdalBuf.buffInt = null;
1190
                        } else if(dataType[iBand] == Gdal.GDT_Float32) {
1191
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1192
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1193
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1194
                                                for (int i = 0; i < drawableBands.length; i++)
1195
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffFloat[pos]);
1196
                                                pos ++;
1197
                                        }
1198
                                        lineInputWindow ++;
1199
                                        if(task.getEvent() != null)
1200
                                                task.manageEvent(task.getEvent());
1201
                                }
1202
                                gdalBuf.buffFloat = null;
1203
                        } else if(dataType[iBand] == Gdal.GDT_Float64) {
1204
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1205
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1206
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1207
                                                for (int i = 0; i < drawableBands.length; i++)
1208
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffDouble[pos]);
1209
                                                pos ++;
1210
                                        }
1211
                                        lineInputWindow ++;
1212
                                        if(task.getEvent() != null)
1213
                                                task.manageEvent(task.getEvent());
1214
                                }
1215
                                gdalBuf.buffDouble = null;
1216
                        }
1217
                }
1218
        }
1219
        
1220
        /**
1221
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1222
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1223
         * @param buf Buffer donde se almacenan los datos
1224
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1225
         * @param x Posici?n X en pixeles
1226
         * @param y Posici?n Y en pixeles
1227
         * @param w Ancho en pixeles
1228
         * @param yMax altura m?xima de y
1229
         * @throws GdalException
1230
         */
1231
        @SuppressWarnings("unused")
1232
        private void readDataByLine(Buffer buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException, ProcessInterruptedException {
1233
                GdalBuffer gdalBuf = null;
1234
                int rasterBufLine;
1235
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
1236
                FileUtils fUtil = RasterLocator.getManager().getFileUtils(); 
1237
                
1238
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1239
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1240
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1241
                                continue;        
1242
                        if(dataType[iBand] == Gdal.GDT_Byte) {
1243
                                for (int line = y; line < yMax; line++) {
1244
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1245
                                        rasterBufLine = line - y;
1246
                                        for (int i = 0; i < drawableBands.length; i++) {
1247
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[i]);
1248
                                        }
1249
                                        if(task.getEvent() != null)
1250
                                                task.manageEvent(task.getEvent());
1251
                                }
1252
                        }else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1253
                                for (int line = y; line < yMax; line++) {
1254
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1255
                                        rasterBufLine = line - y;
1256
                                        for (int i = 0; i < drawableBands.length; i++) {
1257
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[i]);
1258
                                        }
1259
                                        if(task.getEvent() != null)
1260
                                                task.manageEvent(task.getEvent());
1261
                                }
1262
                        }else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1263
                                for (int line = y; line < yMax; line++) {
1264
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1265
                                        rasterBufLine = line - y;
1266
                                        for (int i = 0; i < drawableBands.length; i++) {
1267
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[i]);
1268
                                        }
1269
                                        if(task.getEvent() != null)
1270
                                                task.manageEvent(task.getEvent());
1271
                                }
1272
                        }else if(dataType[iBand] == Gdal.GDT_Float32){
1273
                                for (int line = y; line < yMax; line++) {
1274
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1275
                                        rasterBufLine = line - y;
1276
                                        for (int i = 0; i < drawableBands.length; i++) {
1277
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[i]);
1278
                                        }
1279
                                        if(task.getEvent() != null)
1280
                                                task.manageEvent(task.getEvent());
1281
                                }
1282
                        }else if(dataType[iBand] == Gdal.GDT_Float64){
1283
                                for (int line = y; line < yMax; line++) {
1284
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1285
                                        rasterBufLine = line - y;
1286
                                        for (int i = 0; i < drawableBands.length; i++) {
1287
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[i]);
1288
                                        }
1289
                                        if(task.getEvent() != null)
1290
                                                task.manageEvent(task.getEvent());
1291
                                }
1292
                        }
1293
                }
1294
        }
1295
        
1296
        /**
1297
         * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
1298
         * por par?metro
1299
         * @param x Coordenada X del pixel
1300
         * @param y Coordenada Y del pixel
1301
         * @return Array de Object donde cada posici?n representa una banda y el valor ser? Integer
1302
         * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
1303
         */
1304
        public Object[] getData(int x, int y) {
1305
                try {
1306
                        Object[] data = new Object[getRasterCount()];
1307
                        for(int i = 0; i < getRasterCount(); i++){
1308
                                GdalRasterBand rb = getRasterBand(i + 1);
1309
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType[i]);
1310
                                switch(dataType[i]){
1311
                                case 0:        break;                                                                        //Sin tipo
1312
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1313
                                                break;
1314
                                case 2:                                                                                        //Buffer short (16)
1315
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1316
                                                break;
1317
                                case 4:                                                                                        //Buffer int (32)
1318
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1319
                                                break;
1320
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1321
                                                break;
1322
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1323
                                                break;
1324
                                }
1325
                        }
1326
                        return data;
1327
                } catch (GdalException e) {
1328
                        return null;
1329
                }
1330
        }
1331
        
1332
        public int getBlockSize(){
1333
                return this.getBlockSize();
1334
        }
1335

    
1336
        /**
1337
         * Devuelve la transformaci?n del fichero de georreferenciaci?n
1338
         * @return AffineTransform
1339
         */
1340
        public AffineTransform getOwnTransformation() {
1341
                return ownTransformation;
1342
        }
1343
                
1344
        /**
1345
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
1346
         * @return Extent
1347
         */
1348
        public Extent getExtentWithoutRot() {
1349
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
1350
                                                                                                        0, externalTransformation.getScaleY(), 
1351
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
1352
                Point2D p1 = new Point2D.Double(0, 0);
1353
                Point2D p2 = new Point2D.Double(width, height);
1354
                at.transform(p1, p1);
1355
                at.transform(p2, p2);
1356
                return new ExtentImpl(p1, p2);
1357
        }
1358
        
1359
        /**
1360
         * Asigna una transformaci?n que es aplicada sobre la que ya tiene el propio fichero
1361
         * @param t
1362
         */
1363
        public void setExternalTransform(AffineTransform t){
1364
                externalTransformation = t;
1365
        }
1366

    
1367
        /**
1368
         * Obtiene el nombre del driver de Gdal
1369
         * @return Cadena que representa el nombre del driver de gdal
1370
         */
1371
        public String getGdalShortName() {
1372
                return shortName;
1373
        }
1374
        
1375
        /*
1376
         * (non-Javadoc)
1377
         * @see org.gvsig.tools.dispose.Disposable#dispose()
1378
         */
1379
        public void dispose() {
1380
                open = false;
1381
                try {
1382
                        super.close();
1383
                } catch (GdalException e1) {
1384
                }
1385
                try {
1386
                        finalize();
1387
                } catch (Throwable e) {
1388
                }
1389
        }
1390
        
1391
        /*
1392
         * (non-Javadoc)
1393
         * @see java.lang.Object#finalize()
1394
         */
1395
        protected void finalize() throws Throwable {
1396
                fileTransparency       = null;
1397
                palette                = null;
1398
                colorInterpr           = null;
1399
                ownTransformation      = null;
1400
                externalTransformation = null;
1401
                stepArrayX             = null;
1402
                stepArrayY             = null;
1403
                fileName               = null;
1404
                shortName              = null;
1405
                trans                  = null;
1406
                version                = null;
1407
                dataType               = null;
1408
                metadata                = null;
1409
                
1410
                if(gdalBands != null) {
1411
                        for (int i = 0; i < gdalBands.length; i++) {
1412
                                gdalBands[i] = null;
1413
                        }
1414
                        gdalBands = null;
1415
                }
1416
                super.finalize();
1417
        }
1418
                
1419
}
1420

    
1421

    
1422

    
1423