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 @ 1419

History | View | Annotate | Download (55.5 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 initYBuffer = 0;
1068
                        for (int i = 0; i < nBlocks; i++) {
1069
                                if(lastblock > 0 && i == (nBlocks - 1)) {
1070
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + lastblock};
1071
                                        readData(buf, 
1072
                                                        bandList, 
1073
                                                        new int[]{inputWindow[0], initYSrc, inputWindow[2], lastblock}, 
1074
                                                        bufWidth, lastblock, 0, 0, newStepBuffer);
1075
                                } else {
1076
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + buf.getBlockHeight()};
1077
                                        readData(buf, 
1078
                                                        bandList, 
1079
                                                        new int[]{inputWindow[0], initYSrc, inputWindow[2], buf.getBlockHeight()}, 
1080
                                                        bufWidth, buf.getBlockHeight(), 0, 0, newStepBuffer);
1081
                                        initYSrc += buf.getBlockHeight();
1082
                                        initYBuffer += buf.getBlockHeight();
1083
                                }
1084
                        }
1085
                } else {
1086
                        readData(buf, bandList, inputWindow, bufWidth, bufHeight, 0, 0, stepBuffer);
1087
                }
1088
        }
1089
                
1090
        /**
1091
         * Lee una ventana de datos. Esta funci?n es usuada por
1092
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1093
         * @param buf Buffer donde se almacenan los datos
1094
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1095
         * @param inputWindow
1096
         * <UL>
1097
         * <LI>inputWindow[0]:Posici?n X en pixeles de la imagen de entrada</LI>
1098
         * <LI>inputWindow[1]:Posici?n Y en pixeles de la imagen de entrada</LI>
1099
         * <LI>inputWindow[2]:Ancho en p?xeles a leer de la imagen de entrada</LI>
1100
         * <LI>inputWindow[3]:Alto en p?xeles a leer de la imagen de entrada</LI>
1101
         * </UL>
1102
         * @param bufWidth Ancho del buffer de la imagen de entrada. Si no coincide con inputWindow[2] el propio gdal resamplea
1103
         * @param bufHeight Alto del buffer de la imagen de entrada. Si no coincide con inputWindow[3] el propio gdal resamplea
1104
         * @param stepX Desplazamiento en p?xeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un 
1105
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
1106
         * parte de ellos. 
1107
         * @param stepY Desplazamiento en p?xeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un 
1108
         * supersampleo ya que puede ser que de los p?xeles que est?n en el borde superior de la petici?n solo queramos una
1109
         * parte de ellos.
1110
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes 
1111
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1112
         * <UL>
1113
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1114
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1115
         * <LI>stepBuffer[2]:Posici?n X final m?s uno</LI>
1116
         * <LI>stepBuffer[3]:Posici?n Y final m?s uno</LI>
1117
         * </UL>
1118
         * @throws GdalException
1119
         */
1120
        private void readData(Buffer buf, 
1121
                        BandList bandList, 
1122
                        int[] inputWindow, 
1123
                        int bufWidth, 
1124
                        int bufHeight, 
1125
                        int stpX, 
1126
                        int stpY, 
1127
                        int[] stepBuffer) throws GdalException, ProcessInterruptedException {
1128
                
1129
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + ""); 
1130
                FileUtils fUtil = RasterLocator.getManager().getFileUtils(); 
1131
                        
1132
                GdalBuffer gdalBuf = null;
1133
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1134
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1135
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1136
                                continue;        
1137
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
1138
                        int pos = init;
1139
                        gdalBuf = gdalBands[iBand].readRaster(        inputWindow[0], 
1140
                                                                                                        inputWindow[1], 
1141
                                                                                                        inputWindow[2], 
1142
                                                                                                        inputWindow[3], 
1143
                                                                                                        bufWidth, 
1144
                                                                                                        bufHeight, 
1145
                                                                                                        dataType[iBand]);
1146
                        int lineInputWindow = 0;
1147
                        if(dataType[iBand] == Gdal.GDT_Byte) {
1148
                                for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
1149
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1150
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++) {
1151
                                                for (int i = 0; i < drawableBands.length; i++) 
1152
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffByte[pos]);
1153
                                                pos ++;
1154
                                        }
1155
                                        lineInputWindow ++;
1156
                                        if(task.getEvent() != null)
1157
                                                task.manageEvent(task.getEvent());
1158
                                }
1159
                                gdalBuf.buffByte = null;
1160
                        } else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1161
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1162
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1163
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1164
                                                for (int i = 0; i < drawableBands.length; i++)
1165
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffShort[pos]);
1166
                                                pos ++;
1167
                                        }
1168
                                        lineInputWindow ++;
1169
                                        if(task.getEvent() != null)
1170
                                                task.manageEvent(task.getEvent());
1171
                                }
1172
                                gdalBuf.buffShort = null;
1173
                        } else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1174
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1175
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1176
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1177
                                                for (int i = 0; i < drawableBands.length; i++)
1178
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffInt[pos]);
1179
                                                pos ++;
1180
                                        }
1181
                                        lineInputWindow ++;
1182
                                        if(task.getEvent() != null)
1183
                                                task.manageEvent(task.getEvent());
1184
                                }
1185
                                gdalBuf.buffInt = null;
1186
                        } else if(dataType[iBand] == Gdal.GDT_Float32) {
1187
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1188
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1189
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1190
                                                for (int i = 0; i < drawableBands.length; i++)
1191
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffFloat[pos]);
1192
                                                pos ++;
1193
                                        }
1194
                                        lineInputWindow ++;
1195
                                        if(task.getEvent() != null)
1196
                                                task.manageEvent(task.getEvent());
1197
                                }
1198
                                gdalBuf.buffFloat = null;
1199
                        } else if(dataType[iBand] == Gdal.GDT_Float64) {
1200
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1201
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1202
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1203
                                                for (int i = 0; i < drawableBands.length; i++)
1204
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffDouble[pos]);
1205
                                                pos ++;
1206
                                        }
1207
                                        lineInputWindow ++;
1208
                                        if(task.getEvent() != null)
1209
                                                task.manageEvent(task.getEvent());
1210
                                }
1211
                                gdalBuf.buffDouble = null;
1212
                        }
1213
                }
1214
        }
1215
        
1216
        /**
1217
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1218
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1219
         * @param buf Buffer donde se almacenan los datos
1220
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1221
         * @param x Posici?n X en pixeles
1222
         * @param y Posici?n Y en pixeles
1223
         * @param w Ancho en pixeles
1224
         * @param yMax altura m?xima de y
1225
         * @throws GdalException
1226
         */
1227
        @SuppressWarnings("unused")
1228
        private void readDataByLine(Buffer buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException, ProcessInterruptedException {
1229
                GdalBuffer gdalBuf = null;
1230
                int rasterBufLine;
1231
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
1232
                FileUtils fUtil = RasterLocator.getManager().getFileUtils(); 
1233
                
1234
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1235
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1236
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1237
                                continue;        
1238
                        if(dataType[iBand] == Gdal.GDT_Byte) {
1239
                                for (int line = y; line < yMax; line++) {
1240
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1241
                                        rasterBufLine = line - y;
1242
                                        for (int i = 0; i < drawableBands.length; i++) {
1243
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[i]);
1244
                                        }
1245
                                        if(task.getEvent() != null)
1246
                                                task.manageEvent(task.getEvent());
1247
                                }
1248
                        }else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1249
                                for (int line = y; line < yMax; line++) {
1250
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1251
                                        rasterBufLine = line - y;
1252
                                        for (int i = 0; i < drawableBands.length; i++) {
1253
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[i]);
1254
                                        }
1255
                                        if(task.getEvent() != null)
1256
                                                task.manageEvent(task.getEvent());
1257
                                }
1258
                        }else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1259
                                for (int line = y; line < yMax; line++) {
1260
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1261
                                        rasterBufLine = line - y;
1262
                                        for (int i = 0; i < drawableBands.length; i++) {
1263
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[i]);
1264
                                        }
1265
                                        if(task.getEvent() != null)
1266
                                                task.manageEvent(task.getEvent());
1267
                                }
1268
                        }else if(dataType[iBand] == Gdal.GDT_Float32){
1269
                                for (int line = y; line < yMax; line++) {
1270
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1271
                                        rasterBufLine = line - y;
1272
                                        for (int i = 0; i < drawableBands.length; i++) {
1273
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[i]);
1274
                                        }
1275
                                        if(task.getEvent() != null)
1276
                                                task.manageEvent(task.getEvent());
1277
                                }
1278
                        }else if(dataType[iBand] == Gdal.GDT_Float64){
1279
                                for (int line = y; line < yMax; line++) {
1280
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1281
                                        rasterBufLine = line - y;
1282
                                        for (int i = 0; i < drawableBands.length; i++) {
1283
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[i]);
1284
                                        }
1285
                                        if(task.getEvent() != null)
1286
                                                task.manageEvent(task.getEvent());
1287
                                }
1288
                        }
1289
                }
1290
        }
1291
        
1292
        /**
1293
         * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
1294
         * por par?metro
1295
         * @param x Coordenada X del pixel
1296
         * @param y Coordenada Y del pixel
1297
         * @return Array de Object donde cada posici?n representa una banda y el valor ser? Integer
1298
         * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
1299
         */
1300
        public Object[] getData(int x, int y) {
1301
                try {
1302
                        Object[] data = new Object[getRasterCount()];
1303
                        for(int i = 0; i < getRasterCount(); i++){
1304
                                GdalRasterBand rb = getRasterBand(i + 1);
1305
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType[i]);
1306
                                switch(dataType[i]){
1307
                                case 0:        break;                                                                        //Sin tipo
1308
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1309
                                                break;
1310
                                case 2:                                                                                        //Buffer short (16)
1311
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1312
                                                break;
1313
                                case 4:                                                                                        //Buffer int (32)
1314
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1315
                                                break;
1316
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1317
                                                break;
1318
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1319
                                                break;
1320
                                }
1321
                        }
1322
                        return data;
1323
                } catch (GdalException e) {
1324
                        return null;
1325
                }
1326
        }
1327
        
1328
        public int getBlockSize(){
1329
                return this.getBlockSize();
1330
        }
1331

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

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

    
1417

    
1418

    
1419