Statistics
| Revision:

gvsig-raster / org.gvsig.raster.gdal / branches / org.gvsig.raster.gdal_dataaccess_refactoring / org.gvsig.raster.gdal.io / src / main / java / org / gvsig / raster / gdal / io / GdalNative.java @ 2305

History | View | Annotate | Download (57.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.Color;
25
import java.awt.Rectangle;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.NoninvertibleTransformException;
28
import java.awt.geom.Point2D;
29
import java.io.IOException;
30
import java.util.ArrayList;
31
import java.util.List;
32

    
33
import org.gvsig.fmap.dal.coverage.RasterLibrary;
34
import org.gvsig.fmap.dal.coverage.RasterLocator;
35
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
36
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
37
import org.gvsig.fmap.dal.coverage.datastruct.ColorItem;
38
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
39
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
40
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
41
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
42
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
43
import org.gvsig.fmap.dal.coverage.util.FileUtils;
44
import org.gvsig.jgdal.Gdal;
45
import org.gvsig.jgdal.GdalBuffer;
46
import org.gvsig.jgdal.GdalColorEntry;
47
import org.gvsig.jgdal.GdalColorTable;
48
import org.gvsig.jgdal.GdalException;
49
import org.gvsig.jgdal.GdalRasterBand;
50
import org.gvsig.jgdal.GeoTransform;
51
import org.gvsig.raster.impl.datastruct.ColorItemImpl;
52
import org.gvsig.raster.impl.datastruct.DefaultNoData;
53
import org.gvsig.raster.impl.datastruct.ExtentImpl;
54
import org.gvsig.raster.impl.process.RasterTask;
55
import org.gvsig.raster.impl.process.RasterTaskQueue;
56
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
57
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
58
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
59
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
60
import org.gvsig.tools.dispose.Disposable;
61
import org.gvsig.tools.task.TaskStatus;
62
/**
63
 * Soporte 'nativo' para ficheros desde GDAL.
64
 * 
65
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
66
 * @author Nacho Brodin (nachobrodin@gmail.com)
67
 */
68
public class GdalNative extends Gdal implements Disposable {
69
        private String                       fileName                = null;
70
        private String                       shortName               = "";
71
        public         GeoTransform                 trans                   = null;
72
        public int                           width                   = 0, height = 0;
73
        public double                        originX                 = 0D, originY = 0D;
74
        public String                        version                 = "";
75
        protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
76
        private int[]                        dataType                = null;
77
        DataStoreMetadata                    metadata                = null;
78
        protected boolean                    georeferenced           = true;
79
        
80
        /**
81
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
82
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
83
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
84
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
85
         * distinto tama?o que el resto.   
86
         */
87
        public int[]                              stepArrayX             = null;
88
        public int[]                              stepArrayY             = null;
89
        protected GdalRasterBand[]                gdalBands              = null;
90
        private double                            lastReadLine           = -1;
91
        private int                               overviewWidth          = -1;
92
        private int                               overviewHeight         = -1;
93
        private int                               currentViewWidth       = -1;
94
        private int                               currentViewHeight      = -1;
95
        private double                            currentViewX           = 0D;
96
        private double                            viewportScaleX         = 0D;
97
        private double                            viewportScaleY         = 0D;
98
        private double                            stepX                  = 0D;
99
        private double                            stepY                  = 0D;
100
        public boolean                            isSupersampling        = false;
101
        private boolean                           open                   = false;
102
        /**
103
         * Estado de transparencia del raster.
104
         */
105
        protected DataStoreTransparency           fileTransparency       = null;
106
        protected DataStoreColorTable             palette                = null;
107
        protected DataStoreColorInterpretation    colorInterpr           = null;
108
        protected AffineTransform                 ownTransformation      = null;
109
        protected AffineTransform                 externalTransformation = new AffineTransform();
110
        
111
        public static int getGdalTypeFromRasterBufType(int rasterBufType) {
112
                switch (rasterBufType) {
113
                        case Buffer.TYPE_BYTE: return Gdal.GDT_Byte;
114
                        case Buffer.TYPE_USHORT: return Gdal.GDT_UInt16;
115
                        case Buffer.TYPE_SHORT: return Gdal.GDT_Int16;
116
                        case Buffer.TYPE_INT: return Gdal.GDT_Int32;
117
                        case Buffer.TYPE_FLOAT: return Gdal.GDT_Float32;
118
                        case Buffer.TYPE_DOUBLE: return Gdal.GDT_Float64;
119
                        case Buffer.TYPE_UNDEFINED: return Gdal.GDT_Unknown;
120
                        case Buffer.TYPE_IMAGE: return Gdal.GDT_Byte;
121
                }
122
                return Gdal.GDT_Unknown;
123
        }
124
        
125
        /**
126
         * Conversi?n de los tipos de datos de gdal a los tipos de datos de RasterBuf
127
         * @param gdalType Tipo de dato de gdal
128
         * @return Tipo de dato de RasterBuf
129
         */
130
        public static int getRasterBufTypeFromGdalType(int gdalType) {
131
                switch (gdalType) {
132
                        case 1:// Eight bit unsigned integer GDT_Byte = 1
133
                                return Buffer.TYPE_BYTE;
134

    
135
                        case 3:// Sixteen bit signed integer GDT_Int16 = 3,
136
                                return Buffer.TYPE_SHORT;
137

    
138
                        case 2:// Sixteen bit unsigned integer GDT_UInt16 = 2
139
                                //return RasterBuffer.TYPE_USHORT;
140
                                return Buffer.TYPE_SHORT; //Apa?o para usar los tipos de datos que soportamos
141

    
142
                        case 5:// Thirty two bit signed integer GDT_Int32 = 5
143
                                return Buffer.TYPE_INT;
144

    
145
                        case 6:// Thirty two bit floating point GDT_Float32 = 6
146
                                return Buffer.TYPE_FLOAT;
147

    
148
                        case 7:// Sixty four bit floating point GDT_Float64 = 7
149
                                return Buffer.TYPE_DOUBLE;
150

    
151
                                // TODO:Estos tipos de datos no podemos gestionarlos. Habria que definir
152
                                // el tipo complejo y usar el tipo long que de momento no se gasta.
153
                        case 4:// Thirty two bit unsigned integer GDT_UInt32 = 4,
154
                                return Buffer.TYPE_INT;
155
                                //return RasterBuffer.TYPE_UNDEFINED; // Deberia devolver un Long
156

    
157
                        case 8:// Complex Int16 GDT_CInt16 = 8
158
                        case 9:// Complex Int32 GDT_CInt32 = 9
159
                        case 10:// Complex Float32 GDT_CFloat32 = 10
160
                        case 11:// Complex Float64 GDT_CFloat64 = 11
161
                                return Buffer.TYPE_UNDEFINED;
162
                }
163
                return Buffer.TYPE_UNDEFINED;
164
        }
165
        
166
        /**
167
         * Overview usada en el ?ltimo setView
168
         */
169
        int currentOverview = -1;
170
        
171
        public GdalNative(String fName) throws GdalException, IOException {
172
                super();
173
                init(fName);
174
        }
175
        
176
        private void init(String fName) throws GdalException, IOException {
177
                fileName = fName;
178
                open(fName, GA_ReadOnly);
179
                open = true;
180
                if (getPtro() == -1)
181
                        throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
182
//                ext = RasterUtilities.getExtensionFromFileName(fName);
183
                width = getRasterXSize();
184
                height = getRasterYSize();
185

    
186
                int[] dt = new int[getRasterCount()];
187
                for (int i = 0; i < getRasterCount(); i++)
188
                        dt[i] = this.getRasterBand(i + 1).getRasterDataType();
189
                setDataType(dt);
190
                shortName = getDriverShortName();
191
                fileTransparency = new DataStoreTransparency();
192
                colorInterpr = new DataStoreColorInterpretation();
193
                metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
194

    
195
                // Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
196
                // nos sirve para saber que banda de la imagen va asignada a cada banda de
197
                // visualizaci?n (ARGB)
198
                colorInterpr.initColorInterpretation(getRasterCount());
199
                metadata.initNoDataByBand(getRasterCount());
200
                for (int i = 0; i < getRasterCount(); i++) {
201
                        GdalRasterBand rb = getRasterBand(i + 1);
202
                        String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
203
                        metadata.setNoDataEnabled(rb.existsNoDataValue());
204
                        if(rb.existsNoDataValue()) {
205
                                metadata.setNoDataValue(i, rb.getRasterNoDataValue());
206
                                metadata.setNoDataEnabled(rb.existsNoDataValue());
207
                        }
208
                        colorInterpr.setColorInterpValue(i, colorInt);
209
                        if (colorInt.equals("Alpha"))
210
                                fileTransparency.setTransparencyBand(i);
211

    
212
                        if (rb.getRasterColorTable() != null && palette == null) {
213
                                palette = new DataStoreColorTable(gdalColorTable2ColorItems(rb.getRasterColorTable()), false);
214
//                                fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
215
                        }
216
                }
217
                fileTransparency.setTransparencyByPixelFromMetadata(metadata);
218

    
219
                try {
220
                        trans = getGeoTransform();
221

    
222
                        boolean isCorrect = false;
223
                        for (int i = 0; i < trans.adfgeotransform.length; i++)
224
                                if (trans.adfgeotransform[i] != 0)
225
                                        isCorrect = true;
226
                        if (!isCorrect)
227
                                throw new GdalException("");
228
                        
229
                        double psX = trans.adfgeotransform[1];
230
                        double psY = trans.adfgeotransform[5];
231
                        double rotX = trans.adfgeotransform[4];
232
                        double rotY = trans.adfgeotransform[2];
233
                        double offX = trans.adfgeotransform[0];
234
                        double offY = trans.adfgeotransform[3];
235
                        
236
                        ownTransformation = new AffineTransform(psX, rotX, rotY, psY, offX, offY);
237
                                        //trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
238
                        externalTransformation = (AffineTransform) ownTransformation.clone();
239
                        overviewWidth = width;
240
                        overviewHeight = height;
241

    
242
                        this.georeferenced = true;
243
                } catch (GdalException exc) {
244
                        // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
245
                        // ya que las WC decrecen de
246
                        // arriba a abajo y los pixeles crecen de arriba a abajo
247
                        ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
248
                        externalTransformation = (AffineTransform) ownTransformation.clone();
249
                        overviewWidth = width;
250
                        overviewHeight = height;
251
                        this.georeferenced = false;
252
                }
253
        }
254
        
255
        /**
256
         * Returns true if this provider is open and false if don't
257
         * @return
258
         */
259
        public boolean isOpen() {
260
                return open;
261
        }
262
        
263
        /**
264
         * Obtiene el flag que informa de si el raster tiene valor no data o no.
265
         * Consultar? todas las bandas del mismo y si alguna tiene valor no data
266
         * devuelve true sino devolver? false.
267
         * @return true si tiene valor no data y false si no lo tiene
268
         * @throws GdalException
269
         */
270
        public boolean existsNoDataValue() throws GdalException {
271
                for (int i = 0; i < getRasterCount(); i++) {
272
                        GdalRasterBand rb = getRasterBand(i + 1);
273
                        if (rb.existsNoDataValue())
274
                                return true;
275
                }
276
                return false;
277
        }
278
        
279
        /**
280
         * Obtiene el flag que informa de si el raster tiene valor no data o no
281
         * en una banda concreta.
282
         * @return true si tiene valor no data en esa banda y false si no lo tiene
283
         * @param band Posici?n de la banda a consultar (0..n)
284
         * @throws GdalException
285
         */
286
        public boolean existsNoDataValue(int band) throws GdalException {
287
                GdalRasterBand rb = getRasterBand(band + 1);
288
                return rb.existsNoDataValue();
289
        }
290

    
291
        /**
292
         * Gets nodata value
293
         * @return
294
         */
295
        public NoData getNoDataValue() {
296
                Number value = null;
297
                int type = getRasterBufTypeFromGdalType(getDataType()[0]);
298
                if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
299
                        switch (type) {
300
                        case Buffer.TYPE_BYTE:
301
                                if (metadata == null || metadata.getNoDataValue().length == 0)
302
                                        value = new Byte(RasterLibrary.defaultByteNoDataValue);
303
                                else
304
                                        value = new Byte((byte)metadata.getNoDataValue()[0]);
305
                                break;
306
                        case Buffer.TYPE_SHORT:
307
                                if (metadata == null || metadata.getNoDataValue().length == 0)
308
                                        value = new Short(RasterLibrary.defaultShortNoDataValue);
309
                                else
310
                                        value = new Short((short)metadata.getNoDataValue()[0]);
311
                                break;
312
                        case Buffer.TYPE_INT:
313
                                if (metadata == null || metadata.getNoDataValue().length == 0)
314
                                        value = new Integer((int)RasterLibrary.defaultIntegerNoDataValue);
315
                                else
316
                                        value = new Integer((int)metadata.getNoDataValue()[0]);
317
                                break;
318
                        case Buffer.TYPE_FLOAT:
319
                                if (metadata == null || metadata.getNoDataValue().length == 0)
320
                                        value = new Float(RasterLibrary.defaultFloatNoDataValue);
321
                                else
322
                                        value = new Float(metadata.getNoDataValue()[0]);
323
                                break;
324
                        case Buffer.TYPE_DOUBLE:
325
                                if (metadata == null || metadata.getNoDataValue().length == 0)
326
                                        value = new Double(RasterLibrary.defaultFloatNoDataValue);
327
                                else
328
                                        value = new Double(metadata.getNoDataValue()[0]);
329
                                break;
330
                        }
331
                }
332

    
333
                return new DefaultNoData(value, value, fileName);
334
        }
335

    
336
        /**
337
         * Asigna el tipo de dato
338
         * @param dt entero que representa el tipo de dato
339
         */
340
        public void setDataType(int[] dt) { 
341
                dataType = dt; 
342
        }
343
        
344
        /**
345
         * Obtiene el tipo de dato
346
         * @return entero que representa el tipo de dato
347
         */
348
        public int[] getDataType() { 
349
                return dataType; 
350
        }
351
        
352
        /**
353
         * Gets the color interpretation
354
         * @return
355
         */
356
        public ColorInterpretation getColorInterpretation() { 
357
                return colorInterpr; 
358
        }
359
        
360
        /**
361
         * Gets the color table
362
         * @return
363
         */
364
        public ColorTable getColorTable() {
365
                return palette;
366
        }
367
        
368
        /**
369
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
370
         * del punto real.
371
         * Supone rasters no girados
372
         * @param pt        punto en coordenadas del punto real
373
         * @return        punto en coordenadas del raster
374
         */
375
        public Point2D worldToRasterWithoutRot(Point2D pt) {
376
                Point2D p = new Point2D.Double();
377
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
378
                                                                                                        0, externalTransformation.getScaleY(), 
379
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
380
                try {
381
                        at.inverseTransform(pt, p);
382
                } catch (NoninvertibleTransformException e) {
383
                        return pt;
384
                }
385
                return p;
386
        }
387
                
388
        /**
389
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
390
         * del punto real.
391
         * Supone rasters no girados
392
         * @param pt        punto en coordenadas del punto real
393
         * @return        punto en coordenadas del raster
394
         */
395
        public Point2D worldToRaster(Point2D pt) {
396
                Point2D p = new Point2D.Double();
397
                try {
398
                        externalTransformation.inverseTransform(pt, p);
399
                } catch (NoninvertibleTransformException e) {
400
                        return pt;
401
                }
402
                return p;
403
        }
404
        
405
        /**
406
         * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
407
         * reales. 
408
         * @param pt Punto en coordenadas reales
409
         * @return Punto en coordenadas pixel.
410
         */
411
        public Point2D rasterToWorld(Point2D pt) {
412
                Point2D p = new Point2D.Double();
413
                externalTransformation.transform(pt, p);
414
                return p;
415
        }
416
        
417
        /**
418
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
419
         * viewPortScale, currentFullWidth y currentFulHeight
420
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
421
         * @throws GdalException
422
         */
423
        private void calcOverview(Point2D tl, Point2D br) throws GdalException {
424
                gdalBands[0] = getRasterBand(1);
425
                currentOverview = -1;
426
                if (gdalBands[0].getOverviewCount() > 0) {
427
                        GdalRasterBand ovb = null;
428
                        for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
429
                                ovb = gdalBands[0].getOverview(i);
430
                                if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
431
                                        currentOverview = i;
432
                                        viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
433
                                        viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
434
                                        stepX = 1D / viewportScaleX;
435
                                        stepY = 1D / viewportScaleY;
436
                                        overviewWidth = ovb.getRasterBandXSize();
437
                                        overviewHeight = ovb.getRasterBandYSize();
438
                                        currentViewX = Math.min(tl.getX(), br.getX());
439
                                        lastReadLine = Math.min(tl.getY(), br.getY());
440
                                        break;
441
                                }
442
                        }
443
                }
444
        }
445
        
446
        public void setView(double dWorldTLX, double dWorldTLY,
447
                                                double dWorldBRX, double dWorldBRY,
448
                                                int nWidth, int nHeight) throws GdalException {
449
                overviewWidth = width;
450
                overviewHeight = height;
451
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
452
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
453
                // Calcula cual es la primera l?nea a leer;
454
                currentViewWidth = nWidth;
455
                currentViewHeight = nHeight;
456
//                wcWidth = Math.abs(br.getX() - tl.getX());
457

    
458
                currentViewX = Math.min(tl.getX(), br.getX());
459

    
460
                viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
461
                viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
462
                stepX = 1D / viewportScaleX;
463
                stepY = 1D / viewportScaleY;
464

    
465
                lastReadLine = Math.min(tl.getY(), br.getY());
466
                
467
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
468

    
469
                // calcula el overview a usar
470
                gdalBands = new GdalRasterBand[4];
471
                calcOverview(tl, br);
472
        }
473
        
474
        /**
475
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
476
         * @param nbands N?mero de bandas solicitado.
477
         * @throws GdalException
478
         */
479
        public void selectGdalBands(int nbands) throws GdalException {
480
                gdalBands = new GdalRasterBand[nbands];
481
                // Selecciona las bandas y los overviews necesarios
482
                gdalBands[0] = getRasterBand(1);
483
                for (int i = 0; i < nbands; i++)
484
                        gdalBands[i] = gdalBands[0];
485

    
486
                assignDataTypeFromGdalRasterBands(gdalBands);
487
//                setDataType(gdalBands[0].getRasterDataType());
488

    
489
                for (int i = 2; i <= nbands; i++) {
490
                        if (getRasterCount() >= i) {
491
                                gdalBands[i - 1] = getRasterBand(i);
492
                                for (int j = i; j < nbands; j++)
493
                                        gdalBands[j] = gdalBands[i - 1];
494
                        }
495
                }
496

    
497
                if (currentOverview > 0) {
498
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
499
                        for (int i = 2; i <= nbands; i++) {
500
                                if (getRasterCount() >= i)
501
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
502
                        }
503
                }
504
        }
505
                
506
        int lastY = -1;
507
        
508
        /**
509
         * Lee una l?nea de bytes
510
         * @param line Buffer donde se cargan los datos
511
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
512
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
513
         * por la izquierda a mitad de pixel
514
         * @param gdalBuffer Buffer con la l?nea de datos original
515
         */
516
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
517
                double j = 0D;
518
                int i = 0;
519
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
520
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
521
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
522
                        }
523
                }
524
        }
525
        
526
        /**
527
         * Lee una l?nea de shorts
528
         * @param line Buffer donde se cargan los datos
529
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
530
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
531
         * por la izquierda a mitad de pixel
532
         * @param gdalBuffer Buffer con la l?nea de datos original
533
         */
534
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
535
                double j = 0D;
536
                int i = 0;
537
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
538
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
539
                                line[iBand][i] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
540
                        }
541
                }
542
        }
543

    
544
        /**
545
         * Lee una l?nea de ints
546
         * @param line Buffer donde se cargan los datos
547
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
548
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
549
         * por la izquierda a mitad de pixel
550
         * @param gdalBuffer Buffer con la l?nea de datos original
551
         */
552
        private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
553
                double j = 0D;
554
                int i = 0;
555
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
556
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
557
                                line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
558
                        }
559
                }
560
        }
561

    
562
        /**
563
         * Lee una l?nea de float
564
         * @param line Buffer donde se cargan los datos
565
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
566
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
567
         * por la izquierda a mitad de pixel
568
         * @param gdalBuffer Buffer con la l?nea de datos original
569
         */
570
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
571
                double j = 0D;
572
                int i = 0;
573
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
574
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
575
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
576
                        }
577
                }
578
        }
579
        
580
        /**
581
         * Lee una l?nea de doubles
582
         * @param line Buffer donde se cargan los datos
583
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
584
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
585
         * por la izquierda a mitad de pixel
586
         * @param gdalBuffer Buffer con la l?nea de datos original
587
         */
588
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
589
                double j = 0D;
590
                int i = 0;
591
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
592
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
593
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
594
                        }
595
                }
596
        }
597

    
598
        /**
599
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
600
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
601
         * @param nLine N?mero de l?nea a leer
602
         * @param band Banda requerida
603
         * @return Object que es un array unidimendional del tipo de datos del raster
604
         * @throws GdalException
605
         */
606
        public Object readCompleteLine(int nLine, int band) throws GdalException {
607
                GdalRasterBand gdalBand = super.getRasterBand(band + 1);
608
                GdalBuffer gdalBuf = null;
609

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

    
612
                if (dataType[band] == GDT_Byte)
613
                        return gdalBuf.buffByte;
614

    
615
                if (dataType[band] == GDT_Int16 || dataType[band] == GDT_UInt16)
616
                        return gdalBuf.buffShort;
617

    
618
                if (dataType[band] == GDT_Int32 || dataType[band] == GDT_UInt32)
619
                        return gdalBuf.buffInt;
620

    
621
                if (dataType[band] == GDT_Float32)
622
                        return gdalBuf.buffFloat;
623

    
624
                if (dataType[band] == GDT_Float64)
625
                        return gdalBuf.buffDouble;
626

    
627
                if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_CInt32 ||
628
                                dataType[band] == GDT_CFloat32 || dataType[band] == GDT_CFloat64)
629
                        return null;
630
                
631
                return null;
632
        }
633
        
634
        /**
635
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
636
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
637
         * @param nLine N?mero de l?nea a leer
638
         * @param band Banda requerida
639
         * @return Object que es un array unidimendional del tipo de datos del raster
640
         * @throws GdalException
641
         */
642
        public Object readBlock(int pos, int blockHeight, double scale) throws GdalException, ProcessInterruptedException {
643
                bBandNr = super.getRasterCount();
644
                int widthBuffer = (int)(getRasterXSize() * scale);
645
                int heightBuffer = (int)(blockHeight * scale);
646

    
647
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
648
                                
649
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
650
                for (int iBand = 0; iBand < gdalBand.length; iBand++) 
651
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
652
                                
653
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
654
                                
655
                if (dataType[0] == GDT_Byte) {
656
                        byte[][][] buf = new byte[bBandNr][heightBuffer][widthBuffer];
657
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
658
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
659
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
660
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
661
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * widthBuffer + iCol];
662
                                        if(task.getEvent() != null)
663
                                                task.manageEvent(task.getEvent());
664
                                }
665
                                gdalBuf[iBand].buffByte = null;
666
                        }        
667
                        return buf;
668
                } else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
669
                        short[][][] buf = new short[bBandNr][heightBuffer][widthBuffer];
670
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
671
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
672
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
673
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
674
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * widthBuffer + iCol];
675
                                        if(task.getEvent() != null)
676
                                                task.manageEvent(task.getEvent());
677
                                }
678
                                gdalBuf[iBand].buffShort = null;
679
                        }        
680
                        return buf;
681
                } else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
682
                        int[][][] buf = new int[bBandNr][heightBuffer][widthBuffer];
683
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
684
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
685
                                for (int iRow = 0; iRow < heightBuffer; iRow++) { 
686
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
687
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * widthBuffer + iCol];
688
                                        if(task.getEvent() != null)
689
                                                task.manageEvent(task.getEvent());
690
                                }
691
                                gdalBuf[iBand].buffInt = null;
692
                        }        
693
                        return buf;
694
                } else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
695
                        float[][][] buf = new float[bBandNr][heightBuffer][widthBuffer];
696
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
697
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
698
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
699
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
700
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * widthBuffer + iCol];
701
                                        if(task.getEvent() != null)
702
                                                task.manageEvent(task.getEvent());
703
                                }
704
                                gdalBuf[iBand].buffFloat = null;
705
                        }        
706
                        return buf;
707
                } else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
708
                        double[][][] buf = new double[bBandNr][heightBuffer][widthBuffer];
709
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
710
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
711
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
712
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
713
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * widthBuffer + iCol];
714
                                        if(task.getEvent() != null)
715
                                                task.manageEvent(task.getEvent());
716
                                }
717
                                gdalBuf[iBand].buffDouble = null;
718
                        }                
719
                        return buf;
720
                }
721
                                
722
                return null;
723
        }
724
        
725
        /**
726
         * Lectura de una l?nea de datos.
727
         * @param line
728
         * @throws GdalException
729
         */
730
        public void readLine(Object line) throws GdalException {
731
                int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
732
                int x = (int) (currentViewX);
733
                int y = (int) (lastReadLine);
734
                GdalBuffer r = null, g = null, b = null;
735
                GdalBuffer a = new GdalBuffer();
736

    
737
                while(y >= gdalBands[0].getRasterBandYSize())
738
                        y--;
739

    
740
                if (x+w > gdalBands[0].getRasterBandXSize()) 
741
                        w = gdalBands[0].getRasterBandXSize()-x;
742

    
743
                if(gdalBands[0].getRasterColorTable() != null) {
744
                        palette = new DataStoreColorTable(gdalColorTable2ColorItems(gdalBands[0].getRasterColorTable()), false);
745
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
746
                } else {
747
                        a.buffByte = new byte[w];
748
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
749
                        g = b = r;
750
                        if (getRasterCount() > 1 && gdalBands[1] != null)
751
                                g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
752
                        if (getRasterCount() > 2 && gdalBands[2] != null)
753
                                b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
754
                }
755

    
756
                lastReadLine += stepY;
757

    
758
                double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
759
                GdalBuffer[] bands = {r, g, b};
760

    
761
                if (dataType[0] == GDT_Byte)
762
                        readLine((byte[][])line, initOffset, bands);
763
                else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
764
                        readLine((short[][])line, initOffset, bands);
765
                else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
766
                        readLine((int[][])line, initOffset, bands);
767
                else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
768
                        readLine((float[][])line, initOffset, bands);
769
                else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
770
                        readLine((double[][])line, initOffset, bands);
771

    
772
                return;
773
        }
774
        
775
        private List<ColorItem> gdalColorTable2ColorItems(GdalColorTable table) {
776
                try {
777
                        List<ColorItem> colorItems = new ArrayList<ColorItem>();
778
                        for (int iEntry = 0; iEntry < table.getColorEntryCount(); iEntry++) {
779
                                GdalColorEntry entry = table.getColorEntryAsRGB(iEntry);
780

    
781
                                ColorItem colorItem = new ColorItemImpl();
782
                                colorItem.setNameClass("");
783
                                colorItem.setValue(iEntry);
784
                                colorItem.setColor(new Color(        (int) (entry.c1 & 0xff),
785
                                                                                                                                                        (int) (entry.c2 & 0xff),
786
                                                                                                                                                        (int) (entry.c3 & 0xff),
787
                                                                                                                                                        (int) (entry.c4 & 0xff)));
788

    
789
                                colorItems.add(colorItem);
790
                        }
791
                        return colorItems;
792
                } catch (GdalException ex) {
793
                        // No se crea la paleta
794
                }
795
                return null;
796
        }
797
        
798
                        
799
        /**
800
         * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede
801
         * estar ajustada a la extensi?n del raster o no estarlo. En caso de no
802
         * estarlo los pixeles del buffer que caen fuera de la extensi?n del raster
803
         * tendr?n valor de NoData. Esta funci?n calcula en que pixel del buffer hay
804
         * que empezar a escribir en caso de que este sea mayor que los datos a leer.
805
         * 
806
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
807
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
808
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
809
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
810
         * @param nWidth Ancho en pixeles del buffer
811
         * @param nHeight Alto en pixeles del buffer
812
         * @return desplazamiento dentro del buffer en X e Y
813
         */ 
814
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
815
                Extent imageExtent = getExtentWithoutRot();
816
                Extent ajustDataExtent = RasterLocator.getManager().getRasterUtils().calculateAdjustedView(dataExtent, imageExtent);
817
                if(!RasterLocator.getManager().getRasterUtils().compareExtents(dataExtent, ajustDataExtent)){
818
                        Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
819
                        Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
820
                        Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
821
                        //                    Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
822
                        //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
823
                        int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
824
                        int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
825

    
826
                        stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
827
                        stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
828
                        stpBuffer[2] = stpBuffer[0] + w; 
829
                        stpBuffer[3] = stpBuffer[1] + h;
830
                        return new int[]{w, h};
831
                }
832
                return new int[]{nWidth, nHeight};
833
        }
834
        
835
        /**
836
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
837
         * @param buf Buffer donde se almacenan los datos
838
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
839
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
840
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
841
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
842
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
843
         * @param nWidth Ancho en pixeles del buffer
844
         * @param nHeight Alto en pixeles del buffer
845
         * @throws GdalException
846
         */
847
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
848
                        int nWidth, int nHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
849
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
850
                setView(ulx, uly, lrx, lry, nWidth, nHeight);
851
                Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
852
                Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
853

    
854
                if(tl.getX() > br.getX())
855
                        tl.setLocation(tl.getX() - 1, tl.getY());
856
                else
857
                        br.setLocation(br.getX() - 1, br.getY());
858
                
859
                if(tl.getY() > br.getY())
860
                        tl.setLocation(tl.getX(), tl.getY() - 1);
861
                else
862
                        br.setLocation(br.getX(), br.getY() - 1);
863
                
864
                if(gdalBands.length == 0)
865
                        return;
866

    
867
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
868

    
869
                int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
870
                int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
871

    
872
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
873
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
874
                //ya que lo que cae fuera ser?n valores NoData
875
                if(!adjustToExtent){
876
                        int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
877
                        if(x < 0)
878
                                x  = 0;
879
                        if(y < 0)
880
                                y  = 0;
881
                        readDataCachedBuffer(buf, bandList, new int[]{x, y, wh[0], wh[1]}, 
882
                                        wh[0], wh[1], 0, 0, stpBuffer, status);
883
                        return;
884
                }
885

    
886
                readDataCachedBuffer(buf, bandList, new int[]{x, y, nWidth, nHeight}, 
887
                                nWidth, nHeight, 0, 0, stpBuffer, status);
888
        }
889
        
890
        public void readWindow(Buffer buf, BandList bandList, Extent ext, Rectangle adjustedWindow, TaskStatus status) throws GdalException, ProcessInterruptedException {
891
                setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), buf.getHeight());
892

    
893
                if(gdalBands.length == 0)
894
                        return;
895

    
896
                selectGdalBands(getRasterCount());
897

    
898
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
899
                
900
                adjustedWindow = getAdjustedWindowInOverviewCoordinates(adjustedWindow);
901

    
902
                readDataCachedBuffer(buf, 
903
                                bandList, 
904
                                new int[]{(int)adjustedWindow.getX(), (int)adjustedWindow.getY(), (int)adjustedWindow.getWidth(), (int)adjustedWindow.getHeight()}, 
905
                                buf.getWidth(), 
906
                                buf.getHeight(), 
907
                                0, 0, stpBuffer, status);
908
        }
909
        
910
        /**
911
         * Adjust the request rectangle to the overview size. The requests in Gdal have to be
912
         * in the overview scale
913
         * @param adjustedWindow
914
         * @return
915
         */
916
        private Rectangle getAdjustedWindowInOverviewCoordinates(Rectangle adjustedWindow) {
917
                int nWidth = ((int)adjustedWindow.getWidth() * overviewWidth) / width;
918
                int nHeight = ((int)adjustedWindow.getHeight() * overviewHeight) / height;
919
                int x = (int)(((long)adjustedWindow.getX() * (long)overviewWidth) / (long)width);
920
                int y = (int) (((long)adjustedWindow.getY() * (long)overviewHeight) / (long)height);
921
                return new Rectangle(x, y, nWidth, nHeight);
922
        }
923
                        
924
        /**
925
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
926
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
927
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
928
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de 
929
         * mayor tama?o que el n?mero de pixels solicitado.
930
         * 
931
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor 
932
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer 
933
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
934
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del 
935
         * raster de disco completos sino que en los bordes del buffer quedan cortados.  
936
         *  
937
         * @param buf Buffer donde se almacenan los datos
938
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
939
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
940
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
941
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
942
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
943
         * @param nWidth Ancho en pixeles de la petici?n
944
         * @param nHeight Alto en pixeles de la petici?n
945
         * @param bufWidth Ancho del buffer
946
         * @param bufHeight Alto del buffer
947
         * @throws GdalException
948
         */
949
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
950
                                                        double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
951
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
952
                setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
953
                Point2D ul = worldToRaster(new Point2D.Double(ulx, uly));
954
                Point2D lr = worldToRaster(new Point2D.Double(lrx, lry));
955
                ul.setLocation(ul.getX() < 0 ? 1 : ul.getX(), ul.getY() < 0 ? 1 : ul.getY());
956
                lr.setLocation(lr.getX() < 0 ? 1 : lr.getX(), lr.getY() < 0 ? 1 : lr.getY());
957
                ul.setLocation(ul.getX() - 0.5, ul.getY() - 0.5);
958
                lr.setLocation(lr.getX() - 0.5, lr.getY() - 0.5);
959
                
960
                adjustPoints(ul, lr);
961
                
962
                if(gdalBands.length == 0)
963
                        return;
964
                
965
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
966

    
967
                Rectangle requestWindow = new Rectangle(
968
                                (int) Math.min(ul.getX(), lr.getX()), 
969
                                (int) Math.min(ul.getY(), lr.getY()), 
970
                                (int)nWidth, 
971
                                (int)nHeight);
972

    
973
                requestWindow = getAdjustedWindowInOverviewCoordinates(requestWindow); 
974

    
975
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
976
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
977
                //ya que lo que cae fuera ser?n valores NoData
978
                if(!adjustToExtent){
979
                        int[] wh = calcStepBuffer(petExtent, bufWidth, bufHeight, stpBuffer);
980
                        if(requestWindow.getX() < 0)
981
                                requestWindow.setLocation(0, (int)requestWindow.getY());
982
                        if(requestWindow.getY() < 0)
983
                                requestWindow.setLocation((int)requestWindow.getX(), 0);
984
                        stpBuffer[0] = (int)((stpBuffer[0] * bufWidth) / requestWindow.getWidth());
985
                        stpBuffer[1] = (int)((stpBuffer[1] * bufHeight) / requestWindow.getHeight());
986
                        stpBuffer[2] = (int)((stpBuffer[2] * bufWidth) / requestWindow.getWidth());
987
                        stpBuffer[3] = (int)((stpBuffer[3] * bufHeight) / requestWindow.getHeight());
988
                        bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
989
                        bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
990
                        readDataCachedBuffer(buf, bandList, 
991
                                        new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), wh[0], wh[1]}, 
992
                                                bufWidth, bufHeight, 0, 0, stpBuffer, status);
993
                        return;
994
                }
995

    
996
                if ((requestWindow.getX() + requestWindow.getWidth()) > gdalBands[0].getRasterBandXSize()) 
997
                        requestWindow.setSize((int)(gdalBands[0].getRasterBandXSize() - requestWindow.getX()), (int)requestWindow.getHeight());
998

    
999
                if ((requestWindow.getY() + requestWindow.getHeight()) > gdalBands[0].getRasterBandYSize()) 
1000
                        requestWindow.setSize((int)requestWindow.getWidth(), (int)(gdalBands[0].getRasterBandYSize() - requestWindow.getY()));
1001

    
1002
                readDataCachedBuffer(buf, bandList, 
1003
                                new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), (int)requestWindow.getWidth(), (int)requestWindow.getHeight()}, 
1004
                                bufWidth, bufHeight, 0, 0, stpBuffer, status);
1005
        }
1006
        
1007
        private void adjustPoints(Point2D ul, Point2D lr) {
1008
                double a = (ul.getX() - (int)ul.getX());
1009
                double b = (ul.getY() - (int)ul.getY());
1010
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(), 
1011
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
1012
                lr.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(), 
1013
                                                (b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
1014
        }
1015

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

    
1380
        /**
1381
         * Devuelve la transformaci?n del fichero de georreferenciaci?n
1382
         * @return AffineTransform
1383
         */
1384
        public AffineTransform getOwnTransformation() {
1385
                return ownTransformation;
1386
        }
1387
                
1388
        /**
1389
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
1390
         * @return Extent
1391
         */
1392
        public Extent getExtentWithoutRot() {
1393
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
1394
                                                                                                        0, externalTransformation.getScaleY(), 
1395
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
1396
                Point2D p1 = new Point2D.Double(0, 0);
1397
                Point2D p2 = new Point2D.Double(width, height);
1398
                at.transform(p1, p1);
1399
                at.transform(p2, p2);
1400
                return new ExtentImpl(p1, p2);
1401
        }
1402
        
1403
        /**
1404
         * Asigna una transformaci?n que es aplicada sobre la que ya tiene el propio fichero
1405
         * @param t
1406
         */
1407
        public void setExternalTransform(AffineTransform t){
1408
                externalTransformation = t;
1409
        }
1410

    
1411
        /**
1412
         * Obtiene el nombre del driver de Gdal
1413
         * @return Cadena que representa el nombre del driver de gdal
1414
         */
1415
        public String getGdalShortName() {
1416
                return shortName;
1417
        }
1418
        
1419
        public void dispose() {
1420
                open = false;
1421
                try {
1422
                        super.close();
1423
                } catch (GdalException e1) {
1424
                }
1425
                try {
1426
                        finalize();
1427
                } catch (Throwable e) {
1428
                }
1429
        }
1430
        
1431
        protected void finalize() throws Throwable {
1432
                fileTransparency       = null;
1433
                palette                = null;
1434
                colorInterpr           = null;
1435
                ownTransformation      = null;
1436
                externalTransformation = null;
1437
                stepArrayX             = null;
1438
                stepArrayY             = null;
1439
                fileName               = null;
1440
                shortName              = null;
1441
                trans                  = null;
1442
                version                = null;
1443
                dataType               = null;
1444
                metadata                = null;
1445
                
1446
                if(gdalBands != null) {
1447
                        for (int i = 0; i < gdalBands.length; i++) {
1448
                                gdalBands[i] = null;
1449
                        }
1450
                        gdalBands = null;
1451
                }
1452
                super.finalize();
1453
        }
1454
                
1455
}
1456

    
1457

    
1458

    
1459