Statistics
| Revision:

gvsig-raster / org.gvsig.raster.gdal / trunk / org.gvsig.raster.gdal / org.gvsig.raster.gdal.io / src / main / java / org / gvsig / raster / gdal / io / GdalDataSource.java @ 4437

History | View | Annotate | Download (58.2 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.gdal.gdal.gdal;
34
import org.gdal.ogr.ogr;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.fmap.dal.coverage.RasterLibrary;
39
import org.gvsig.fmap.dal.coverage.RasterLocator;
40
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
41
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
42
import org.gvsig.fmap.dal.coverage.datastruct.ColorItem;
43
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
44
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
45
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
46
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
47
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
48
import org.gvsig.fmap.dal.coverage.util.FileUtils;
49
import org.gvsig.jgdal.GdalBuffer;
50
import org.gvsig.jgdal.GdalColorEntry;
51
import org.gvsig.jgdal.GdalColorTable;
52
import org.gvsig.jgdal.GdalDataset;
53
import org.gvsig.jgdal.GdalException;
54
import org.gvsig.jgdal.GdalRasterBand;
55
import org.gvsig.jgdal.GeoTransform;
56
import org.gvsig.raster.impl.datastruct.ColorItemImpl;
57
import org.gvsig.raster.impl.datastruct.DefaultNoData;
58
import org.gvsig.raster.impl.datastruct.ExtentImpl;
59
import org.gvsig.raster.impl.process.RasterTask;
60
import org.gvsig.raster.impl.process.RasterTaskQueue;
61
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
62
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
63
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
64
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
65
import org.gvsig.tools.dispose.Disposable;
66
import org.gvsig.tools.task.TaskStatus;
67
/**
68
 * Soporte 'nativo' para ficheros desde GDAL.
69
 */
70
public class GdalDataSource extends GdalDataset implements Disposable {
71
        private String                       fileName                = null;
72
        private String                       shortName               = "";
73
        public         GeoTransform                 trans                   = null;
74
        public int                           width                   = 0, height = 0;
75
        public double                        originX                 = 0D, originY = 0D;
76
        public String                        version                 = "";
77
        protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
78
        private int[]                        dataType                = null;
79
        DataStoreMetadata                    metadata                = null;
80
        protected boolean                    georeferenced           = true;
81

    
82
        private static final Logger logger = LoggerFactory.getLogger(GdalDataSource.class);
83

    
84
        /**
85
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
86
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
87
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
88
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de
89
         * distinto tama?o que el resto.
90
         */
91
        public int[]                              stepArrayX             = null;
92
        public int[]                              stepArrayY             = null;
93
        protected GdalRasterBand[]                gdalBands              = null;
94
        private double                            lastReadLine           = -1;
95
        private int                               overviewWidth          = -1;
96
        private int                               overviewHeight         = -1;
97
        private int                               currentViewWidth       = -1;
98
        private int                               currentViewHeight      = -1;
99
        private double                            currentViewX           = 0D;
100
        private double                            viewportScaleX         = 0D;
101
        private double                            viewportScaleY         = 0D;
102
        private double                            stepX                  = 0D;
103
        private double                            stepY                  = 0D;
104
        public boolean                            isSupersampling        = false;
105
        private boolean                           open                   = false;
106
        /**
107
         * Estado de transparencia del raster.
108
         */
109
        protected DataStoreTransparency           fileTransparency       = null;
110
        protected DataStoreColorTable             palette                = null;
111
        protected DataStoreColorInterpretation    colorInterpr           = null;
112
        protected AffineTransform                 ownTransformation      = null;
113
        protected AffineTransform                 externalTransformation = new AffineTransform();
114

    
115
        public static int getGdalTypeFromRasterBufType(int rasterBufType) {
116
                switch (rasterBufType) {
117
                        case Buffer.TYPE_BYTE: return GdalDataset.GDT_Byte;
118
                        case Buffer.TYPE_USHORT: return GdalDataset.GDT_UInt16;
119
                        case Buffer.TYPE_SHORT: return GdalDataset.GDT_Int16;
120
                        case Buffer.TYPE_INT: return GdalDataset.GDT_Int32;
121
                        case Buffer.TYPE_FLOAT: return GdalDataset.GDT_Float32;
122
                        case Buffer.TYPE_DOUBLE: return GdalDataset.GDT_Float64;
123
                        case Buffer.TYPE_UNDEFINED: return GdalDataset.GDT_Unknown;
124
                        case Buffer.TYPE_IMAGE: return GdalDataset.GDT_Byte;
125
                }
126
                return GdalDataset.GDT_Unknown;
127
        }
128

    
129
        /**
130
         * Conversi?n de los tipos de datos de gdal a los tipos de datos de RasterBuf
131
         * @param gdalType Tipo de dato de gdal
132
         * @return Tipo de dato de RasterBuf
133
         */
134
        public static int getRasterBufTypeFromGdalType(int gdalType) {
135
                switch (gdalType) {
136
                        case 1:// Eight bit unsigned integer GDT_Byte = 1
137
                                return Buffer.TYPE_BYTE;
138

    
139
                        case 3:// Sixteen bit signed integer GDT_Int16 = 3,
140
                                return Buffer.TYPE_SHORT;
141

    
142
                        case 2:// Sixteen bit unsigned integer GDT_UInt16 = 2
143
                                //return RasterBuffer.TYPE_USHORT;
144
                                return Buffer.TYPE_SHORT; //Apa?o para usar los tipos de datos que soportamos
145

    
146
                        case 5:// Thirty two bit signed integer GDT_Int32 = 5
147
                                return Buffer.TYPE_INT;
148

    
149
                        case 6:// Thirty two bit floating point GDT_Float32 = 6
150
                                return Buffer.TYPE_FLOAT;
151

    
152
                        case 7:// Sixty four bit floating point GDT_Float64 = 7
153
                                return Buffer.TYPE_DOUBLE;
154

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

    
161
                        case 8:// Complex Int16 GDT_CInt16 = 8
162
                        case 9:// Complex Int32 GDT_CInt32 = 9
163
                        case 10:// Complex Float32 GDT_CFloat32 = 10
164
                        case 11:// Complex Float64 GDT_CFloat64 = 11
165
                                return Buffer.TYPE_UNDEFINED;
166
                }
167
                return Buffer.TYPE_UNDEFINED;
168
        }
169

    
170
        /**
171
         * Overview usada en el ?ltimo setView
172
         */
173
        int currentOverview = -1;
174

    
175
        public GdalDataSource(String fName) throws GdalException, IOException {
176
                super();
177
                init(fName);
178
        }
179

    
180
//        private static Dataset initializeGdal(String fName) throws GdalException {
181
//                gdal.AllRegister();
182
//                ogr.RegisterAll();
183
//                Dataset data = gdal.Open(fName, 1);
184
//                if (data == null)
185
//                        throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
186
//
187
//                return data;
188
//        }
189

    
190
        private void init(String fName) throws GdalException, IOException {
191
                gdal.AllRegister();
192
                ogr.RegisterAll();
193
                fileName = fName;
194
                open(fName, GA_ReadOnly);
195
                open = true;
196
                if (getDataset() == null)
197
                        throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
198
                width = getRasterXSize();
199
                height = getRasterYSize();
200

    
201
                int[] dt = new int[getRasterCount()];
202
                for (int i = 0; i < getRasterCount(); i++)
203
                        dt[i] = this.getRasterBand(i + 1).getRasterDataType();
204
                setDataType(dt);
205
                shortName = getDriverShortName();
206
                colorInterpr = new DataStoreColorInterpretation(getRasterCount());
207
                fileTransparency = new DataStoreTransparency(colorInterpr);
208
                metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
209

    
210
                // Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
211
                // nos sirve para saber que banda de la imagen va asignada a cada banda de
212
                // visualizaci?n (ARGB)
213
                metadata.initNoDataByBand(getRasterCount());
214
                for (int i = 0; i < getRasterCount(); i++) {
215
                        GdalRasterBand rb = getRasterBand(i + 1);
216
                        String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
217
                        metadata.setNoDataEnabled(rb.existsNoDataValue());
218
                        if(rb.existsNoDataValue()) {
219
                                metadata.setNoDataValue(i, rb.getRasterNoDataValue());
220
                                metadata.setNoDataEnabled(rb.existsNoDataValue());
221
                        }
222
                        colorInterpr.setColorInterpValue(i, colorInt);
223
                        if (colorInt.equals("Alpha"))
224
                                fileTransparency.setTransparencyBand(i);
225

    
226
                        if (rb.getRasterColorTable() != null && palette == null) {
227
                                palette = new DataStoreColorTable(gdalColorTable2ColorItems(rb.getRasterColorTable()), false);
228
//                                fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
229
                        }
230
                }
231
                fileTransparency.setTransparencyByPixelFromMetadata(metadata);
232

    
233
                try {
234
                        trans = getGeoTransform();
235

    
236
                        boolean isCorrect = false;
237
                        for (int i = 0; i < trans.adfgeotransform.length; i++)
238
                                if (trans.adfgeotransform[i] != 0)
239
                                        isCorrect = true;
240
                        if (!isCorrect)
241
                                throw new GdalException("");
242

    
243
                        double psX = trans.adfgeotransform[1];
244
                        double psY = trans.adfgeotransform[5];
245
                        double rotX = trans.adfgeotransform[4];
246
                        double rotY = trans.adfgeotransform[2];
247
                        double offX = trans.adfgeotransform[0];
248
                        double offY = trans.adfgeotransform[3];
249

    
250
                        ownTransformation = new AffineTransform(psX, rotX, rotY, psY, offX, offY);
251
                                        //trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
252
                        externalTransformation = (AffineTransform) ownTransformation.clone();
253
                        overviewWidth = width;
254
                        overviewHeight = height;
255

    
256
                        this.georeferenced = true;
257
                } catch (GdalException exc) {
258
                        // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
259
                        // ya que las WC decrecen de
260
                        // arriba a abajo y los pixeles crecen de arriba a abajo
261
                    logger.warn("Can't retrieve transformation from file '"+fName+"' use default.", exc);
262
                        ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
263
                        externalTransformation = (AffineTransform) ownTransformation.clone();
264
                        overviewWidth = width;
265
                        overviewHeight = height;
266
                        this.georeferenced = false;
267
                }
268
        }
269

    
270
        /**
271
         * Returns true if this provider is open and false if don't
272
         * @return
273
         */
274
        public boolean isOpen() {
275
                return open;
276
        }
277

    
278
        /**
279
         * Obtiene el flag que informa de si el raster tiene valor no data o no.
280
         * Consultar? todas las bandas del mismo y si alguna tiene valor no data
281
         * devuelve true sino devolver? false.
282
         * @return true si tiene valor no data y false si no lo tiene
283
         * @throws GdalException
284
         */
285
        public boolean existsNoDataValue() throws GdalException {
286
                for (int i = 0; i < getRasterCount(); i++) {
287
                        GdalRasterBand rb = getRasterBand(i + 1);
288
                        if (rb.existsNoDataValue())
289
                                return true;
290
                }
291
                return false;
292
        }
293

    
294
        /**
295
         * Obtiene el flag que informa de si el raster tiene valor no data o no
296
         * en una banda concreta.
297
         * @return true si tiene valor no data en esa banda y false si no lo tiene
298
         * @param band Posici?n de la banda a consultar (0..n)
299
         * @throws GdalException
300
         */
301
        public boolean existsNoDataValue(int band) throws GdalException {
302
                GdalRasterBand rb = getRasterBand(band + 1);
303
                return rb.existsNoDataValue();
304
        }
305

    
306
        /**
307
         * Gets nodata value
308
         * @return
309
         */
310
        public NoData getNoDataValue() {
311
                Number value = null;
312
                int type = getRasterBufTypeFromGdalType(getDataType()[0]);
313
                if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
314
                        switch (type) {
315
                        case Buffer.TYPE_BYTE:
316
                                if (metadata == null || metadata.getNoDataValue().length == 0)
317
                                        value = new Byte(RasterLibrary.defaultByteNoDataValue);
318
                                else
319
                                        value = new Byte((byte)metadata.getNoDataValue()[0]);
320
                                break;
321
                        case Buffer.TYPE_SHORT:
322
                                if (metadata == null || metadata.getNoDataValue().length == 0)
323
                                        value = new Short(RasterLibrary.defaultShortNoDataValue);
324
                                else
325
                                        value = new Short((short)metadata.getNoDataValue()[0]);
326
                                break;
327
                        case Buffer.TYPE_INT:
328
                                if (metadata == null || metadata.getNoDataValue().length == 0)
329
                                        value = new Integer((int)RasterLibrary.defaultIntegerNoDataValue);
330
                                else
331
                                        value = new Integer((int)metadata.getNoDataValue()[0]);
332
                                break;
333
                        case Buffer.TYPE_FLOAT:
334
                                if (metadata == null || metadata.getNoDataValue().length == 0)
335
                                        value = new Float(RasterLibrary.defaultFloatNoDataValue);
336
                                else
337
                                        value = new Float(metadata.getNoDataValue()[0]);
338
                                break;
339
                        case Buffer.TYPE_DOUBLE:
340
                                if (metadata == null || metadata.getNoDataValue().length == 0)
341
                                        value = new Double(RasterLibrary.defaultFloatNoDataValue);
342
                                else
343
                                        value = new Double(metadata.getNoDataValue()[0]);
344
                                break;
345
                        }
346
                }
347

    
348
                NoData nodata = new DefaultNoData(value, value, fileName);
349
                nodata.setNoDataTransparent(false);
350
                return nodata;
351
        }
352

    
353
        /**
354
         * Asigna el tipo de dato
355
         * @param dt entero que representa el tipo de dato
356
         */
357
        public void setDataType(int[] dt) {
358
                dataType = dt;
359
        }
360

    
361
        /**
362
         * Obtiene el tipo de dato
363
         * @return entero que representa el tipo de dato
364
         */
365
        public int[] getDataType() {
366
                return dataType;
367
        }
368

    
369
        /**
370
         * Gets the color interpretation
371
         * @return
372
         */
373
        public ColorInterpretation getColorInterpretation() {
374
                return colorInterpr;
375
        }
376

    
377
        /**
378
         * Gets the color table
379
         * @return
380
         */
381
        public ColorTable getColorTable() {
382
                return palette;
383
        }
384

    
385
        /**
386
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
387
         * del punto real.
388
         * Supone rasters no girados
389
         * @param pt        punto en coordenadas del punto real
390
         * @return        punto en coordenadas del raster
391
         */
392
        public Point2D worldToRasterWithoutRot(Point2D pt) {
393
                Point2D p = new Point2D.Double();
394
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0,
395
                                                                                                        0, externalTransformation.getScaleY(),
396
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
397
                try {
398
                        at.inverseTransform(pt, p);
399
                } catch (NoninvertibleTransformException e) {
400
                        return pt;
401
                }
402
                return p;
403
        }
404

    
405
        /**
406
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
407
         * del punto real.
408
         * Supone rasters no girados
409
         * @param pt        punto en coordenadas del punto real
410
         * @return        punto en coordenadas del raster
411
         */
412
        public Point2D worldToRaster(Point2D pt) {
413
                Point2D p = new Point2D.Double();
414
                try {
415
                        externalTransformation.inverseTransform(pt, p);
416
                } catch (NoninvertibleTransformException e) {
417
                        return pt;
418
                }
419
                return p;
420
        }
421

    
422
        /**
423
         * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
424
         * reales.
425
         * @param pt Punto en coordenadas reales
426
         * @return Punto en coordenadas pixel.
427
         */
428
        public Point2D rasterToWorld(Point2D pt) {
429
                Point2D p = new Point2D.Double();
430
                externalTransformation.transform(pt, p);
431
                return p;
432
        }
433

    
434
        /**
435
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
436
         * viewPortScale, currentFullWidth y currentFulHeight
437
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
438
         * @throws GdalException
439
         */
440
        private void calcOverview(Point2D tl, Point2D br) throws GdalException {
441
                gdalBands[0] = getRasterBand(1);
442
                currentOverview = -1;
443
                if (gdalBands[0].getOverviewCount() > 0) {
444
                        GdalRasterBand ovb = null;
445
                        for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
446
                                ovb = gdalBands[0].getOverview(i);
447
                                if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
448
                                        currentOverview = i;
449
                                        viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
450
                                        viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
451
                                        stepX = 1D / viewportScaleX;
452
                                        stepY = 1D / viewportScaleY;
453
                                        overviewWidth = ovb.getRasterBandXSize();
454
                                        overviewHeight = ovb.getRasterBandYSize();
455
                                        currentViewX = Math.min(tl.getX(), br.getX());
456
                                        lastReadLine = Math.min(tl.getY(), br.getY());
457
                                        break;
458
                                }
459
                        }
460
                }
461
        }
462

    
463
        public void setView(double dWorldTLX, double dWorldTLY,
464
                                                double dWorldBRX, double dWorldBRY,
465
                                                int nWidth, int nHeight) throws GdalException {
466
                overviewWidth = width;
467
                overviewHeight = height;
468
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
469
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
470
                // Calcula cual es la primera l?nea a leer;
471
                currentViewWidth = nWidth;
472
                currentViewHeight = nHeight;
473
//                wcWidth = Math.abs(br.getX() - tl.getX());
474

    
475
                currentViewX = Math.min(tl.getX(), br.getX());
476

    
477
                viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
478
                viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
479
                stepX = 1D / viewportScaleX;
480
                stepY = 1D / viewportScaleY;
481

    
482
                lastReadLine = Math.min(tl.getY(), br.getY());
483

    
484
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
485

    
486
                // calcula el overview a usar
487
                gdalBands = new GdalRasterBand[4];
488
                calcOverview(tl, br);
489
        }
490

    
491
        /**
492
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
493
         * @param nbands N?mero de bandas solicitado.
494
         * @throws GdalException
495
         */
496
        public void selectGdalBands(int nbands) throws GdalException {
497
                gdalBands = new GdalRasterBand[nbands];
498
                // Selecciona las bandas y los overviews necesarios
499
                gdalBands[0] = getRasterBand(1);
500
                for (int i = 0; i < nbands; i++)
501
                        gdalBands[i] = gdalBands[0];
502

    
503
                assignDataTypeFromGdalRasterBands(gdalBands);
504
//                setDataType(gdalBands[0].getRasterDataType());
505

    
506
                for (int i = 2; i <= nbands; i++) {
507
                        if (getRasterCount() >= i) {
508
                                gdalBands[i - 1] = getRasterBand(i);
509
                                for (int j = i; j < nbands; j++)
510
                                        gdalBands[j] = gdalBands[i - 1];
511
                        }
512
                }
513

    
514
                if (currentOverview > 0) {
515
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
516
                        for (int i = 2; i <= nbands; i++) {
517
                                if (getRasterCount() >= i)
518
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
519
                        }
520
                }
521
        }
522

    
523
        int lastY = -1;
524

    
525
        /**
526
         * Lee una l?nea de bytes
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(byte[][] 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] = gdalBuffer[iBand].buffByte[(int) j];
539
                        }
540
                }
541
        }
542

    
543
        /**
544
         * Lee una l?nea de shorts
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(short[][] 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] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
557
                        }
558
                }
559
        }
560

    
561
        /**
562
         * Lee una l?nea de ints
563
         * @param line Buffer donde se cargan los datos
564
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. 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(int[][] 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].buffInt[(int) j] & 0xffffffff);
575
                        }
576
                }
577
        }
578

    
579
        /**
580
         * Lee una l?nea de float
581
         * @param line Buffer donde se cargan los datos
582
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. 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(float[][] 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].buffFloat[(int) j];
593
                        }
594
                }
595
        }
596

    
597
        /**
598
         * Lee una l?nea de doubles
599
         * @param line Buffer donde se cargan los datos
600
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
601
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
602
         * por la izquierda a mitad de pixel
603
         * @param gdalBuffer Buffer con la l?nea de datos original
604
         */
605
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
606
                double j = 0D;
607
                int i = 0;
608
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
609
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
610
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
611
                        }
612
                }
613
        }
614

    
615
        /**
616
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
617
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista.
618
         * @param nLine N?mero de l?nea a leer
619
         * @param band Banda requerida
620
         * @return Object que es un array unidimendional del tipo de datos del raster
621
         * @throws GdalException
622
         */
623
        public Object readCompleteLine(int nLine, int band) throws GdalException {
624
                GdalRasterBand gdalBand = super.getRasterBand(band + 1);
625
                GdalBuffer gdalBuf = null;
626

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

    
629
                if (dataType[band] == GDT_Byte)
630
                        return gdalBuf.buffByte;
631

    
632
                if (dataType[band] == GDT_Int16 || dataType[band] == GDT_UInt16)
633
                        return gdalBuf.buffShort;
634

    
635
                if (dataType[band] == GDT_Int32 || dataType[band] == GDT_UInt32)
636
                        return gdalBuf.buffInt;
637

    
638
                if (dataType[band] == GDT_Float32)
639
                        return gdalBuf.buffFloat;
640

    
641
                if (dataType[band] == GDT_Float64)
642
                        return gdalBuf.buffDouble;
643

    
644
                if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_CInt32 ||
645
                                dataType[band] == GDT_CFloat32 || dataType[band] == GDT_CFloat64)
646
                        return null;
647

    
648
                return null;
649
        }
650

    
651
        /**
652
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
653
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista.
654
         * @param nLine N?mero de l?nea a leer
655
         * @param band Banda requerida
656
         * @return Object que es un array unidimendional del tipo de datos del raster
657
         * @throws GdalException
658
         */
659
        public Object readBlock(int pos, int blockHeight, double scale) throws GdalException, ProcessInterruptedException {
660
                bBandNr = super.getRasterCount();
661
                int widthBuffer = (int)(getRasterXSize() * scale);
662
                int heightBuffer = (int)(blockHeight * scale);
663

    
664
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
665

    
666
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
667
                for (int iBand = 0; iBand < gdalBand.length; iBand++)
668
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
669

    
670
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
671

    
672
                if (dataType[0] == GDT_Byte) {
673
                        byte[][][] buf = new byte[bBandNr][heightBuffer][widthBuffer];
674
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
675
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
676
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
677
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
678
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * widthBuffer + iCol];
679
                                        if(task.getEvent() != null)
680
                                                task.manageEvent(task.getEvent());
681
                                }
682
                                gdalBuf[iBand].buffByte = null;
683
                        }
684
                        return buf;
685
                } else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
686
                        short[][][] buf = new short[bBandNr][heightBuffer][widthBuffer];
687
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
688
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
689
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
690
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
691
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * widthBuffer + iCol];
692
                                        if(task.getEvent() != null)
693
                                                task.manageEvent(task.getEvent());
694
                                }
695
                                gdalBuf[iBand].buffShort = null;
696
                        }
697
                        return buf;
698
                } else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
699
                        int[][][] buf = new int[bBandNr][heightBuffer][widthBuffer];
700
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
701
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
702
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
703
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
704
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * widthBuffer + iCol];
705
                                        if(task.getEvent() != null)
706
                                                task.manageEvent(task.getEvent());
707
                                }
708
                                gdalBuf[iBand].buffInt = null;
709
                        }
710
                        return buf;
711
                } else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
712
                        float[][][] buf = new float[bBandNr][heightBuffer][widthBuffer];
713
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
714
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
715
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
716
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
717
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * widthBuffer + iCol];
718
                                        if(task.getEvent() != null)
719
                                                task.manageEvent(task.getEvent());
720
                                }
721
                                gdalBuf[iBand].buffFloat = null;
722
                        }
723
                        return buf;
724
                } else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
725
                        double[][][] buf = new double[bBandNr][heightBuffer][widthBuffer];
726
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
727
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
728
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
729
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
730
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * widthBuffer + iCol];
731
                                        if(task.getEvent() != null)
732
                                                task.manageEvent(task.getEvent());
733
                                }
734
                                gdalBuf[iBand].buffDouble = null;
735
                        }
736
                        return buf;
737
                }
738

    
739
                return null;
740
        }
741

    
742
        /**
743
         * Lectura de una l?nea de datos.
744
         * @param line
745
         * @throws GdalException
746
         */
747
        public void readLine(Object line) throws GdalException {
748
                int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
749
                int x = (int) (currentViewX);
750
                int y = (int) (lastReadLine);
751
                GdalBuffer r = null, g = null, b = null;
752
                GdalBuffer a = new GdalBuffer();
753

    
754
                while(y >= gdalBands[0].getRasterBandYSize())
755
                        y--;
756

    
757
                if (x+w > gdalBands[0].getRasterBandXSize())
758
                        w = gdalBands[0].getRasterBandXSize()-x;
759

    
760
                if(gdalBands[0].getRasterColorTable() != null) {
761
                        palette = new DataStoreColorTable(gdalColorTable2ColorItems(gdalBands[0].getRasterColorTable()), false);
762
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
763
                } else {
764
                        a.buffByte = new byte[w];
765
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
766
                        g = b = r;
767
                        if (getRasterCount() > 1 && gdalBands[1] != null)
768
                                g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
769
                        if (getRasterCount() > 2 && gdalBands[2] != null)
770
                                b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
771
                }
772

    
773
                lastReadLine += stepY;
774

    
775
                double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
776
                GdalBuffer[] bands = {r, g, b};
777

    
778
                if (dataType[0] == GDT_Byte)
779
                        readLine((byte[][])line, initOffset, bands);
780
                else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
781
                        readLine((short[][])line, initOffset, bands);
782
                else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
783
                        readLine((int[][])line, initOffset, bands);
784
                else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
785
                        readLine((float[][])line, initOffset, bands);
786
                else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
787
                        readLine((double[][])line, initOffset, bands);
788

    
789
                return;
790
        }
791

    
792
        private List<ColorItem> gdalColorTable2ColorItems(GdalColorTable table) {
793
                try {
794
                        List<ColorItem> colorItems = new ArrayList<ColorItem>();
795
                        for (int iEntry = 0; iEntry < table.getColorEntryCount(); iEntry++) {
796
                                GdalColorEntry entry = table.getColorEntryAsRGB(iEntry);
797

    
798
                                ColorItem colorItem = new ColorItemImpl();
799
                                colorItem.setNameClass("");
800
                                colorItem.setValue(iEntry);
801
                                colorItem.setColor(new Color(        (int) (entry.c1 & 0xff),
802
                                                                                                                                                        (int) (entry.c2 & 0xff),
803
                                                                                                                                                        (int) (entry.c3 & 0xff),
804
                                                                                                                                                        (int) (entry.c4 & 0xff)));
805

    
806
                                colorItems.add(colorItem);
807
                        }
808
                        return colorItems;
809
                } catch (GdalException ex) {
810
                        // No se crea la paleta
811
                }
812
                return null;
813
        }
814

    
815

    
816
        /**
817
         * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede
818
         * estar ajustada a la extensi?n del raster o no estarlo. En caso de no
819
         * estarlo los pixeles del buffer que caen fuera de la extensi?n del raster
820
         * tendr?n valor de NoData. Esta funci?n calcula en que pixel del buffer hay
821
         * que empezar a escribir en caso de que este sea mayor que los datos a leer.
822
         *
823
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
824
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
825
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
826
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
827
         * @param nWidth Ancho en pixeles del buffer
828
         * @param nHeight Alto en pixeles del buffer
829
         * @return desplazamiento dentro del buffer en X e Y
830
         */
831
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
832
                Extent imageExtent = getExtentWithoutRot();
833
                Extent ajustDataExtent = RasterLocator.getManager().getRasterUtils().calculateAdjustedView(dataExtent, imageExtent);
834
                if(!RasterLocator.getManager().getRasterUtils().compareExtents(dataExtent, ajustDataExtent)){
835
                        Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
836
                        Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
837
                        Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
838
                        //                    Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
839
                        //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
840
                        int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX()));
841
                        int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
842

    
843
                        stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
844
                        stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
845
                        stpBuffer[2] = stpBuffer[0] + w;
846
                        stpBuffer[3] = stpBuffer[1] + h;
847
                        return new int[]{w, h};
848
                }
849
                return new int[]{nWidth, nHeight};
850
        }
851

    
852
        /**
853
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
854
         * @param buf Buffer donde se almacenan los datos
855
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
856
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
857
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
858
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
859
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
860
         * @param nWidth Ancho en pixeles del buffer
861
         * @param nHeight Alto en pixeles del buffer
862
         * @throws GdalException
863
         */
864
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
865
                        int nWidth, int nHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
866
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
867
                setView(ulx, uly, lrx, lry, nWidth, nHeight);
868
                Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
869
                Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
870

    
871
                if(tl.getX() > br.getX())
872
                        tl.setLocation(tl.getX() - 1, tl.getY());
873
                else
874
                        br.setLocation(br.getX() - 1, br.getY());
875

    
876
                if(tl.getY() > br.getY())
877
                        tl.setLocation(tl.getX(), tl.getY() - 1);
878
                else
879
                        br.setLocation(br.getX(), br.getY() - 1);
880

    
881
                if(gdalBands.length == 0)
882
                        return;
883

    
884
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
885

    
886
                int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
887
                int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
888

    
889
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
890
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
891
                //ya que lo que cae fuera ser?n valores NoData
892
                if(!adjustToExtent){
893
                        int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
894
                        if(x < 0)
895
                                x  = 0;
896
                        if(y < 0)
897
                                y  = 0;
898
                        readDataCachedBuffer(buf, bandList, new int[]{x, y, wh[0], wh[1]},
899
                                        wh[0], wh[1], 0, 0, stpBuffer, status);
900
                        return;
901
                }
902

    
903
                readDataCachedBuffer(buf, bandList, new int[]{x, y, nWidth, nHeight},
904
                                nWidth, nHeight, 0, 0, stpBuffer, status);
905
        }
906

    
907
        public void readWindow(Buffer buf, BandList bandList, Extent ext, Rectangle adjustedWindow, TaskStatus status) throws GdalException, ProcessInterruptedException {
908
                setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), buf.getHeight());
909

    
910
                if(gdalBands.length == 0)
911
                        return;
912

    
913
                selectGdalBands(getRasterCount());
914

    
915
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
916

    
917
                adjustedWindow = getAdjustedWindowInOverviewCoordinates(adjustedWindow);
918

    
919
                readDataCachedBuffer(buf,
920
                                bandList,
921
                                new int[]{(int)adjustedWindow.getX(), (int)adjustedWindow.getY(), (int)adjustedWindow.getWidth(), (int)adjustedWindow.getHeight()},
922
                                buf.getWidth(),
923
                                buf.getHeight(),
924
                                0, 0, stpBuffer, status);
925
        }
926

    
927
        /**
928
         * Adjust the request rectangle to the overview size. The requests in Gdal have to be
929
         * in the overview scale
930
         * @param adjustedWindow
931
         * @return
932
         */
933
        private Rectangle getAdjustedWindowInOverviewCoordinates(Rectangle adjustedWindow) {
934
                int nWidth = (int)(((long)adjustedWindow.getWidth() * overviewWidth) / width);
935
                int nHeight = (int)(((long)adjustedWindow.getHeight() * overviewHeight) / height);
936
                int x = (int)(((long)adjustedWindow.getX() * (long)overviewWidth) / (long)width);
937
                int y = (int) (((long)adjustedWindow.getY() * (long)overviewHeight) / (long)height);
938
                return new Rectangle(x, y, nWidth, nHeight);
939
        }
940

    
941
        /**
942
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
943
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
944
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
945
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de
946
         * mayor tama?o que el n?mero de pixels solicitado.
947
         *
948
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor
949
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer
950
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
951
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del
952
         * raster de disco completos sino que en los bordes del buffer quedan cortados.
953
         *
954
         * @param buf Buffer donde se almacenan los datos
955
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
956
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
957
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
958
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
959
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
960
         * @param nWidth Ancho en pixeles de la petici?n
961
         * @param nHeight Alto en pixeles de la petici?n
962
         * @param bufWidth Ancho del buffer
963
         * @param bufHeight Alto del buffer
964
         * @throws GdalException
965
         */
966
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
967
                                                        double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
968
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
969
                setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
970
                Point2D ul = worldToRaster(new Point2D.Double(ulx, uly));
971
                Point2D lr = worldToRaster(new Point2D.Double(lrx, lry));
972
                ul.setLocation(ul.getX() < 0 ? 1 : ul.getX(), ul.getY() < 0 ? 1 : ul.getY());
973
                lr.setLocation(lr.getX() < 0 ? 1 : lr.getX(), lr.getY() < 0 ? 1 : lr.getY());
974
                ul.setLocation(ul.getX() - 0.5, ul.getY() - 0.5);
975
                lr.setLocation(lr.getX() - 0.5, lr.getY() - 0.5);
976

    
977
                adjustPoints(ul, lr);
978

    
979
                if(gdalBands.length == 0)
980
                        return;
981

    
982
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
983

    
984
                Rectangle requestWindow = new Rectangle(
985
                                (int) Math.min(ul.getX(), lr.getX()),
986
                                (int) Math.min(ul.getY(), lr.getY()),
987
                                (int)nWidth,
988
                                (int)nHeight);
989

    
990
                requestWindow = getAdjustedWindowInOverviewCoordinates(requestWindow);
991

    
992
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
993
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
994
                //ya que lo que cae fuera ser?n valores NoData
995
                if(!adjustToExtent){
996
                        int[] wh = calcStepBuffer(petExtent, bufWidth, bufHeight, stpBuffer);
997
                        if(requestWindow.getX() < 0)
998
                                requestWindow.setLocation(0, (int)requestWindow.getY());
999
                        if(requestWindow.getY() < 0)
1000
                                requestWindow.setLocation((int)requestWindow.getX(), 0);
1001
                        stpBuffer[0] = (int)((stpBuffer[0] * bufWidth) / requestWindow.getWidth());
1002
                        stpBuffer[1] = (int)((stpBuffer[1] * bufHeight) / requestWindow.getHeight());
1003
                        stpBuffer[2] = (int)((stpBuffer[2] * bufWidth) / requestWindow.getWidth());
1004
                        stpBuffer[3] = (int)((stpBuffer[3] * bufHeight) / requestWindow.getHeight());
1005
                        bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
1006
                        bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
1007
                        readDataCachedBuffer(buf, bandList,
1008
                                        new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), wh[0], wh[1]},
1009
                                                bufWidth, bufHeight, 0, 0, stpBuffer, status);
1010
                        return;
1011
                }
1012

    
1013
                if ((requestWindow.getX() + requestWindow.getWidth()) > gdalBands[0].getRasterBandXSize())
1014
                        requestWindow.setSize((int)(gdalBands[0].getRasterBandXSize() - requestWindow.getX()), (int)requestWindow.getHeight());
1015

    
1016
                if ((requestWindow.getY() + requestWindow.getHeight()) > gdalBands[0].getRasterBandYSize())
1017
                        requestWindow.setSize((int)requestWindow.getWidth(), (int)(gdalBands[0].getRasterBandYSize() - requestWindow.getY()));
1018

    
1019
                readDataCachedBuffer(buf, bandList,
1020
                                new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), (int)requestWindow.getWidth(), (int)requestWindow.getHeight()},
1021
                                bufWidth, bufHeight, 0, 0, stpBuffer, status);
1022
        }
1023

    
1024
        private void adjustPoints(Point2D ul, Point2D lr) {
1025
                double a = (ul.getX() - (int)ul.getX());
1026
                double b = (ul.getY() - (int)ul.getY());
1027
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(),
1028
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
1029
                lr.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(),
1030
                                                (b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
1031
        }
1032

    
1033
        /**
1034
         * Lee una ventana de datos con resampleo a partir de coordenadas en pixeles. Este m?todo lee la
1035
         * ventana de una vez cargando los datos de un golpe en el buffer.
1036
         * @param buf Buffer donde se almacenan los datos
1037
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1038
         * @param x Posici?n X en pixeles
1039
         * @param y Posici?n Y en pixeles
1040
         * @param w Ancho en pixeles
1041
         * @param h Alto en pixeles
1042
         * @param bufWidth Ancho del buffer
1043
         * @param bufHeight Alto del buffer
1044
         * @throws GdalException
1045
         */
1046
        public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h, TaskStatus status) throws GdalException, ProcessInterruptedException {
1047
                gdalBands = new GdalRasterBand[getRasterCount()];
1048

    
1049
                if(buf.getWidth() == w && buf.getHeight() == h)
1050
                        isSupersampling = false;
1051

    
1052
                if(gdalBands.length == 0)
1053
                        return;
1054

    
1055
                // Selecciona las bandas
1056
                gdalBands[0] = getRasterBand(1);
1057

    
1058
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
1059
                        gdalBands[iBand] = getRasterBand(iBand + 1);
1060

    
1061
                assignDataTypeFromGdalRasterBands(gdalBands);
1062

    
1063
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
1064
                readDataCachedBuffer(buf, bandList, new int[]{x, y, w, h}, buf.getWidth(), buf.getHeight(), 0, 0, stpBuffer, status);
1065
        }
1066

    
1067
        /**
1068
         * Asigna el tipo de datos de las bandas a partir de una lista de GdalRasterBands
1069
         * @param gdalBands
1070
         * @throws GdalException
1071
         */
1072
        private void assignDataTypeFromGdalRasterBands(GdalRasterBand[] gdalBands) throws GdalException {
1073
                int[] dt = new int[gdalBands.length];
1074
                for (int i = 0; i < gdalBands.length; i++) {
1075
                        if(gdalBands[i] != null)
1076
                                dt[i] = gdalBands[i].getRasterDataType();
1077
                }
1078
                setDataType(dt);
1079
        }
1080

    
1081
        /**
1082
         * Lee una ventana de datos. Esta funci?n es usuada por
1083
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. Esta es una versi?n de readData pero
1084
         * comprueba si el buffer es cacheado y si lo es pide por trozos para no intentar cargar desde gdal demasiados
1085
         * datos.
1086
         * @param buf Buffer donde se almacenan los datos
1087
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1088
         * @param inputWindow
1089
         * <UL>
1090
         * <LI>inputWindow[0]:Posici?n X en pixeles de la imagen de entrada</LI>
1091
         * <LI>inputWindow[1]:Posici?n Y en pixeles de la imagen de entrada</LI>
1092
         * <LI>inputWindow[2]:Ancho en p?xeles a leer de la imagen de entrada</LI>
1093
         * <LI>inputWindow[3]:Alto en p?xeles a leer de la imagen de entrada</LI>
1094
         * </UL>
1095
         * @param bufWidth Ancho del buffer de la imagen de entrada. Si no coincide con inputWindow[2] el propio gdal resamplea
1096
         * @param bufHeight Alto del buffer de la imagen de entrada. Si no coincide con inputWindow[3] el propio gdal resamplea
1097
         * @param stepX Desplazamiento en p?xeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un
1098
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
1099
         * parte de ellos.
1100
         * @param stepY Desplazamiento en p?xeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un
1101
         * supersampleo ya que puede ser que de los p?xeles que est?n en el borde superior de la petici?n solo queramos una
1102
         * parte de ellos.
1103
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes
1104
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1105
         * <UL>
1106
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1107
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1108
         * <LI>stepBuffer[2]:Posici?n X final m?s uno</LI>
1109
         * <LI>stepBuffer[3]:Posici?n Y final m?s uno</LI>
1110
         * </UL>
1111
         * @throws GdalException
1112
         */
1113
        private void readDataCachedBuffer(Buffer buf,
1114
                        BandList bandList,
1115
                        int[] inputWindow,
1116
                        int bufWidth,
1117
                        int bufHeight,
1118
                        int stpX,
1119
                        int stpY,
1120
                        int[] stepBuffer,
1121
                        TaskStatus status) throws GdalException, ProcessInterruptedException {
1122
                if(buf.isCached()) {
1123
                        int nBlocks = (int)(buf.getHeight() / buf.getBlockHeight());
1124
                        int lastblock = buf.getHeight() - (nBlocks * buf.getBlockHeight());
1125
                        if(lastblock > 0)
1126
                                nBlocks ++;
1127
                        int initYSrc = inputWindow[1];
1128
                        int stepYSrc = (buf.getBlockHeight() * inputWindow[3]) / buf.getHeight();
1129
                        int lastBlockYSrc = (lastblock * inputWindow[3]) / buf.getHeight();
1130
                        int initYBuffer = 0;
1131
                        for (int i = 0; i < nBlocks; i++) {
1132
                                if(lastblock > 0 && i == (nBlocks - 1)) {
1133
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + lastblock};
1134
                                        int[] newWindow = new int[]{inputWindow[0], initYSrc, inputWindow[2], lastBlockYSrc};
1135
                                        readData(buf,
1136
                                                        bandList,
1137
                                                        newWindow,
1138
                                                        bufWidth, lastblock, 0, 0, newStepBuffer);
1139
                                } else {
1140
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + buf.getBlockHeight()};
1141
                                        int[] newWindow = new int[]{inputWindow[0], initYSrc, inputWindow[2], stepYSrc};
1142
                                        readData(buf,
1143
                                                        bandList,
1144
                                                        newWindow,
1145
                                                        bufWidth, buf.getBlockHeight(), 0, 0, newStepBuffer);
1146
                                        initYSrc += stepYSrc;
1147
                                        initYBuffer += buf.getBlockHeight();
1148
                                }
1149
                        }
1150
                } else {
1151
                        readData(buf, bandList, inputWindow, bufWidth, bufHeight, 0, 0, stepBuffer);
1152
                }
1153
        }
1154

    
1155
        /**
1156
         * Lee una ventana de datos. Esta funci?n es usuada por
1157
         * readWindow para coordenadas reales y readWindow en coordenadas pixel.
1158
         * @param buf Buffer donde se almacenan los datos
1159
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1160
         * @param inputWindow
1161
         * <UL>
1162
         * <LI>inputWindow[0]:Posici?n X en pixeles de la imagen de entrada</LI>
1163
         * <LI>inputWindow[1]:Posici?n Y en pixeles de la imagen de entrada</LI>
1164
         * <LI>inputWindow[2]:Ancho en p?xeles a leer de la imagen de entrada</LI>
1165
         * <LI>inputWindow[3]:Alto en p?xeles a leer de la imagen de entrada</LI>
1166
         * </UL>
1167
         * @param bufWidth Ancho del buffer de la imagen de entrada. Si no coincide con inputWindow[2] el propio gdal resamplea
1168
         * @param bufHeight Alto del buffer de la imagen de entrada. Si no coincide con inputWindow[3] el propio gdal resamplea
1169
         * @param stepX Desplazamiento en p?xeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un
1170
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
1171
         * parte de ellos.
1172
         * @param stepY Desplazamiento en p?xeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un
1173
         * supersampleo ya que puede ser que de los p?xeles que est?n en el borde superior de la petici?n solo queramos una
1174
         * parte de ellos.
1175
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes
1176
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1177
         * <UL>
1178
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1179
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1180
         * <LI>stepBuffer[2]:Posici?n X final m?s uno</LI>
1181
         * <LI>stepBuffer[3]:Posici?n Y final m?s uno</LI>
1182
         * </UL>
1183
         * @throws GdalException
1184
         */
1185
        private void readData(Buffer buf,
1186
                        BandList bandList,
1187
                        int[] inputWindow,
1188
                        int bufWidth,
1189
                        int bufHeight,
1190
                        int stpX,
1191
                        int stpY,
1192
                        int[] stepBuffer) throws GdalException, ProcessInterruptedException {
1193

    
1194
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
1195
                FileUtils fUtil = RasterLocator.getManager().getFileUtils();
1196

    
1197
                GdalBuffer gdalBuf = null;
1198
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1199
                        int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
1200
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1201
                                continue;
1202
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
1203
                        int pos = init;
1204
                        gdalBuf = gdalBands[iBand].readRaster(        inputWindow[0],
1205
                                                                                                        inputWindow[1],
1206
                                                                                                        inputWindow[2],
1207
                                                                                                        inputWindow[3],
1208
                                                                                                        bufWidth,
1209
                                                                                                        bufHeight,
1210
                                                                                                        dataType[iBand]);
1211
                        int lineInputWindow = 0;
1212
                        if(dataType[iBand] == GdalDataset.GDT_Byte) {
1213
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1214
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1215
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1216
                                                for (int i = 0; i < drawableBands.length; i++)
1217
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffByte[pos]);
1218
                                                pos ++;
1219
                                        }
1220
                                        lineInputWindow ++;
1221
                                        if(task.getEvent() != null)
1222
                                                task.manageEvent(task.getEvent());
1223
                                }
1224
                                gdalBuf.buffByte = null;
1225
                        } else if((dataType[iBand] == GdalDataset.GDT_UInt16) || (dataType[iBand] == GdalDataset.GDT_Int16) || (dataType[iBand] == GdalDataset.GDT_CInt16)) {
1226
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1227
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1228
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1229
                                                for (int i = 0; i < drawableBands.length; i++)
1230
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffShort[pos]);
1231
                                                pos ++;
1232
                                        }
1233
                                        lineInputWindow ++;
1234
                                        if(task.getEvent() != null)
1235
                                                task.manageEvent(task.getEvent());
1236
                                }
1237
                                gdalBuf.buffShort = null;
1238
                        } else if((dataType[iBand] == GdalDataset.GDT_UInt32) || (dataType[iBand] == GdalDataset.GDT_Int32) || (dataType[iBand] == GdalDataset.GDT_CInt32)) {
1239
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1240
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1241
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1242
                                                for (int i = 0; i < drawableBands.length; i++)
1243
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffInt[pos]);
1244
                                                pos ++;
1245
                                        }
1246
                                        lineInputWindow ++;
1247
                                        if(task.getEvent() != null)
1248
                                                task.manageEvent(task.getEvent());
1249
                                }
1250
                                gdalBuf.buffInt = null;
1251
                        } else if(dataType[iBand] == GdalDataset.GDT_Float32) {
1252
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1253
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1254
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1255
                                                for (int i = 0; i < drawableBands.length; i++)
1256
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffFloat[pos]);
1257
                                                pos ++;
1258
                                        }
1259
                                        lineInputWindow ++;
1260
                                        if(task.getEvent() != null)
1261
                                                task.manageEvent(task.getEvent());
1262
                                }
1263
                                gdalBuf.buffFloat = null;
1264
                        } else if(dataType[iBand] == GdalDataset.GDT_Float64) {
1265
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1266
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1267
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1268
                                                for (int i = 0; i < drawableBands.length; i++)
1269
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffDouble[pos]);
1270
                                                pos ++;
1271
                                        }
1272
                                        lineInputWindow ++;
1273
                                        if(task.getEvent() != null)
1274
                                                task.manageEvent(task.getEvent());
1275
                                }
1276
                                gdalBuf.buffDouble = null;
1277
                        }
1278
                }
1279
        }
1280

    
1281
        /**
1282
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1283
         * readWindow para coordenadas reales y readWindow en coordenadas pixel.
1284
         * @param buf Buffer donde se almacenan los datos
1285
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1286
         * @param x Posici?n X en pixeles
1287
         * @param y Posici?n Y en pixeles
1288
         * @param w Ancho en pixeles
1289
         * @param yMax altura m?xima de y
1290
         * @throws GdalException
1291
         */
1292
        @SuppressWarnings("unused")
1293
        private void readDataByLine(Buffer buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException, ProcessInterruptedException {
1294
                GdalBuffer gdalBuf = null;
1295
                int rasterBufLine;
1296
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
1297
                FileUtils fUtil = RasterLocator.getManager().getFileUtils();
1298

    
1299
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1300
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1301
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1302
                                continue;
1303
                        if(dataType[iBand] == GdalDataset.GDT_Byte) {
1304
                                for (int line = y; line < yMax; line++) {
1305
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1306
                                        rasterBufLine = line - y;
1307
                                        for (int i = 0; i < drawableBands.length; i++) {
1308
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[i]);
1309
                                        }
1310
                                        if(task.getEvent() != null)
1311
                                                task.manageEvent(task.getEvent());
1312
                                }
1313
                        }else if((dataType[iBand] == GdalDataset.GDT_UInt16) || (dataType[iBand] == GdalDataset.GDT_Int16) || (dataType[iBand] == GdalDataset.GDT_CInt16)) {
1314
                                for (int line = y; line < yMax; line++) {
1315
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1316
                                        rasterBufLine = line - y;
1317
                                        for (int i = 0; i < drawableBands.length; i++) {
1318
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[i]);
1319
                                        }
1320
                                        if(task.getEvent() != null)
1321
                                                task.manageEvent(task.getEvent());
1322
                                }
1323
                        }else if((dataType[iBand] == GdalDataset.GDT_UInt32) || (dataType[iBand] == GdalDataset.GDT_Int32) || (dataType[iBand] == GdalDataset.GDT_CInt32)) {
1324
                                for (int line = y; line < yMax; line++) {
1325
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1326
                                        rasterBufLine = line - y;
1327
                                        for (int i = 0; i < drawableBands.length; i++) {
1328
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[i]);
1329
                                        }
1330
                                        if(task.getEvent() != null)
1331
                                                task.manageEvent(task.getEvent());
1332
                                }
1333
                        }else if(dataType[iBand] == GdalDataset.GDT_Float32){
1334
                                for (int line = y; line < yMax; line++) {
1335
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1336
                                        rasterBufLine = line - y;
1337
                                        for (int i = 0; i < drawableBands.length; i++) {
1338
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[i]);
1339
                                        }
1340
                                        if(task.getEvent() != null)
1341
                                                task.manageEvent(task.getEvent());
1342
                                }
1343
                        }else if(dataType[iBand] == GdalDataset.GDT_Float64){
1344
                                for (int line = y; line < yMax; line++) {
1345
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1346
                                        rasterBufLine = line - y;
1347
                                        for (int i = 0; i < drawableBands.length; i++) {
1348
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[i]);
1349
                                        }
1350
                                        if(task.getEvent() != null)
1351
                                                task.manageEvent(task.getEvent());
1352
                                }
1353
                        }
1354
                }
1355
        }
1356

    
1357
        /**
1358
         * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
1359
         * por par?metro
1360
         * @param x Coordenada X del pixel
1361
         * @param y Coordenada Y del pixel
1362
         * @return Array de Object donde cada posici?n representa una banda y el valor ser? Integer
1363
         * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
1364
         */
1365
        public Object[] getData(int x, int y) {
1366
                try {
1367
                        Object[] data = new Object[getRasterCount()];
1368
                        for(int i = 0; i < getRasterCount(); i++){
1369
                                GdalRasterBand rb = getRasterBand(i + 1);
1370
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType[i]);
1371
                                switch(dataType[i]){
1372
                                case 0:        break;                                                                        //Sin tipo
1373
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1374
                                                break;
1375
                                case 2:                                                                                        //Buffer short (16)
1376
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1377
                                                break;
1378
                                case 4:                                                                                        //Buffer int (32)
1379
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1380
                                                break;
1381
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1382
                                                break;
1383
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1384
                                                break;
1385
                                }
1386
                        }
1387
                        return data;
1388
                } catch (GdalException e) {
1389
                        return null;
1390
                }
1391
        }
1392

    
1393
        public int getBlockSize(){
1394
                return this.getBlockSize();
1395
        }
1396

    
1397
        /**
1398
         * Devuelve la transformaci?n del fichero de georreferenciaci?n
1399
         * @return AffineTransform
1400
         */
1401
        public AffineTransform getOwnTransformation() {
1402
                return ownTransformation;
1403
        }
1404

    
1405
        /**
1406
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
1407
         * @return Extent
1408
         */
1409
        public Extent getExtentWithoutRot() {
1410
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0,
1411
                                                                                                        0, externalTransformation.getScaleY(),
1412
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
1413
                Point2D p1 = new Point2D.Double(0, 0);
1414
                Point2D p2 = new Point2D.Double(width, height);
1415
                at.transform(p1, p1);
1416
                at.transform(p2, p2);
1417
                return new ExtentImpl(p1, p2);
1418
        }
1419

    
1420
        /**
1421
         * Asigna una transformaci?n que es aplicada sobre la que ya tiene el propio fichero
1422
         * @param t
1423
         */
1424
        public void setExternalTransform(AffineTransform t){
1425
                externalTransformation = t;
1426
        }
1427

    
1428
        /**
1429
         * Obtiene el nombre del driver de Gdal
1430
         * @return Cadena que representa el nombre del driver de gdal
1431
         */
1432
        public String getGdalShortName() {
1433
                return shortName;
1434
        }
1435

    
1436
        public void dispose() {
1437
                open = false;
1438
                try {
1439
                        super.close();
1440
                } catch (GdalException e1) {
1441
                }
1442
                try {
1443
                        finalize();
1444
                } catch (Throwable e) {
1445
                }
1446
        }
1447

    
1448
        protected void finalize() {
1449
                fileTransparency       = null;
1450
                palette                = null;
1451
                colorInterpr           = null;
1452
                ownTransformation      = null;
1453
                externalTransformation = null;
1454
                stepArrayX             = null;
1455
                stepArrayY             = null;
1456
                fileName               = null;
1457
                shortName              = null;
1458
                trans                  = null;
1459
                version                = null;
1460
                dataType               = null;
1461
                metadata                = null;
1462

    
1463
                if(gdalBands != null) {
1464
                        for (int i = 0; i < gdalBands.length; i++) {
1465
                                gdalBands[i] = null;
1466
                        }
1467
                        gdalBands = null;
1468
                }
1469
                this.finalize();
1470
        }
1471

    
1472
}
1473

    
1474

    
1475

    
1476