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

History | View | Annotate | Download (57.8 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
                NoData nodata = new DefaultNoData(value, value, fileName);
333
                nodata.setNoDataTransparent(false);
334
                return nodata;
335
        }
336

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
757
                lastReadLine += stepY;
758

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

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

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

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

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

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

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

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

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

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

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

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

    
897
                selectGdalBands(getRasterCount());
898

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

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

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

    
974
                requestWindow = getAdjustedWindowInOverviewCoordinates(requestWindow); 
975

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

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

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

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

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

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

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

    
1458

    
1459

    
1460