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

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
                colorInterpr = new DataStoreColorInterpretation(getRasterCount());
192
                fileTransparency = new DataStoreTransparency(colorInterpr);
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
                metadata.initNoDataByBand(getRasterCount());
199
                for (int i = 0; i < getRasterCount(); i++) {
200
                        GdalRasterBand rb = getRasterBand(i + 1);
201
                        String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
202
                        metadata.setNoDataEnabled(rb.existsNoDataValue());
203
                        if(rb.existsNoDataValue()) {
204
                                metadata.setNoDataValue(i, rb.getRasterNoDataValue());
205
                                metadata.setNoDataEnabled(rb.existsNoDataValue());
206
                        }
207
                        colorInterpr.setColorInterpValue(i, colorInt);
208
                        if (colorInt.equals("Alpha"))
209
                                fileTransparency.setTransparencyBand(i);
210

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

    
218
                try {
219
                        trans = getGeoTransform();
220

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
755
                lastReadLine += stepY;
756

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

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

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

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

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

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

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

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

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

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

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

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

    
895
                selectGdalBands(getRasterCount());
896

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

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

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

    
972
                requestWindow = getAdjustedWindowInOverviewCoordinates(requestWindow); 
973

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

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

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

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

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

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

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

    
1456

    
1457

    
1458