Statistics
| Revision:

gvsig-raster / org.gvsig.raster.gdal / trunk / org.gvsig.raster.gdal / org.gvsig.raster.gdal.io / src / main / java / org / gvsig / raster / gdal / io / GdalNative.java @ 875

History | View | Annotate | Download (49.6 KB)

1
        /* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.gdal.io;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.io.IOException;
28

    
29
import org.gvsig.fmap.dal.coverage.RasterLibrary;
30
import org.gvsig.fmap.dal.coverage.RasterLocator;
31
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
32
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
33
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
34
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
35
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
36
import org.gvsig.fmap.dal.coverage.util.FileUtils;
37
import org.gvsig.jgdal.Gdal;
38
import org.gvsig.jgdal.GdalBuffer;
39
import org.gvsig.jgdal.GdalException;
40
import org.gvsig.jgdal.GdalRasterBand;
41
import org.gvsig.jgdal.GeoTransform;
42
import org.gvsig.raster.impl.datastruct.DefaultNoData;
43
import org.gvsig.raster.impl.datastruct.ExtentImpl;
44
import org.gvsig.raster.impl.process.RasterTask;
45
import org.gvsig.raster.impl.process.RasterTaskQueue;
46
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
47
import org.gvsig.raster.impl.store.properties.DataStoreColorTable;
48
import org.gvsig.raster.impl.store.properties.DataStoreMetadata;
49
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
50
/**
51
 * Soporte 'nativo' para ficheros desde GDAL.
52
 * 
53
 * @author Luis W. Sevilla (sevilla_lui@gva.es)
54
 * @author Nacho Brodin (nachobrodin@gmail.com)
55
 */
56
public class GdalNative extends Gdal {
57
        private String                       fileName                = null;
58
        private String                       shortName               = "";
59
        public         GeoTransform                 trans                   = null;
60
        public int                           width                   = 0, height = 0;
61
        public double                        originX                 = 0D, originY = 0D;
62
        public String                        version                 = "";
63
        protected int                        rBandNr                 = 1, gBandNr = 2, bBandNr = 3, aBandNr = 4;
64
        private int[]                        dataType                = null;
65
        DataStoreMetadata                    metadata                = null;
66
        protected boolean                    georeferenced           = true;
67
        
68
        /**
69
         * Vectores que contiene los desplazamientos de un pixel cuando hay supersampling.
70
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
71
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
72
         * una variable. Adem?s hay que tener en cuenta que el primer y ?ltimo pixel son de 
73
         * distinto tama?o que el resto.   
74
         */
75
        public int[]                          stepArrayX             = null;
76
        public int[]                          stepArrayY             = null;
77
        protected GdalRasterBand[]            gdalBands              = null;
78
        private double                        lastReadLine           = -1;
79
        private int                           currentFullWidth       = -1;
80
        private int                           currentFullHeight      = -1;
81
        private int                           currentViewWidth       = -1;
82
        private int                           currentViewHeight      = -1;
83
        private double                        currentViewX           = 0D;
84
        private double                        viewportScaleX         = 0D;
85
        private double                        viewportScaleY         = 0D;
86
        private double                        stepX                  = 0D;
87
        private double                        stepY                  = 0D;
88
        public boolean                        isSupersampling        = false;
89
        private boolean                       open                   = false;
90
        /**
91
         * Estado de transparencia del raster.
92
         */
93
        DataStoreTransparency                 fileTransparency       = null;
94
        DataStoreColorTable                   palette                = null;
95
        DataStoreColorInterpretation          colorInterpr           = null;
96
        AffineTransform                       ownTransformation      = null;
97
        AffineTransform                       externalTransformation = new AffineTransform();
98
        
99
        
100
        /**
101
         * Overview usada en el ?ltimo setView
102
         */
103
        int currentOverview = -1;
104
        
105
        
106
        public GdalNative(String fName) throws GdalException, IOException {
107
                super();
108
                init(fName);
109
        }
110
        
111
        private void init(String fName) throws GdalException, IOException {
112
                fileName = fName;
113
                open(fName, GA_ReadOnly);
114
                open = true;
115
                if (getPtro() == -1)
116
                        throw new GdalException("Error en la apertura del fichero. El fichero no tiene un formato v?lido.");
117
//                ext = RasterUtilities.getExtensionFromFileName(fName);
118
                width = getRasterXSize();
119
                height = getRasterYSize();
120
                int[] dt = new int[getRasterCount()];
121
                for (int i = 0; i < getRasterCount(); i++)
122
                        dt[i] = this.getRasterBand(i + 1).getRasterDataType();
123
                setDataType(dt);
124
                shortName = getDriverShortName();
125
                fileTransparency = new DataStoreTransparency();
126
                colorInterpr = new DataStoreColorInterpretation();
127
                metadata = new DataStoreMetadata(getMetadata(), colorInterpr);
128

    
129
                // Asignamos la interpretaci?n de color leida por gdal a cada banda. Esto
130
                // nos sirve para saber que banda de la imagen va asignada a cada banda de
131
                // visualizaci?n (ARGB)
132
                colorInterpr.initColorInterpretation(getRasterCount());
133
                metadata.initNoDataByBand(getRasterCount());
134
                for (int i = 0; i < getRasterCount(); i++) {
135
                        GdalRasterBand rb = getRasterBand(i + 1);
136
                        String colorInt = getColorInterpretationName(rb.getRasterColorInterpretation());
137
                        metadata.setNoDataEnabled(rb.existsNoDataValue());
138
                        if(rb.existsNoDataValue()) {
139
                                metadata.setNoDataValue(i, rb.getRasterNoDataValue());
140
                                metadata.setNoDataEnabled(rb.existsNoDataValue());
141
                        }
142
                        colorInterpr.setColorInterpValue(i, colorInt);
143
                        if (colorInt.equals("Alpha"))
144
                                fileTransparency.setTransparencyBand(i);
145

    
146
                        if (rb.getRasterColorTable() != null && palette == null) {
147
                                palette = new DataStoreColorTable();
148
                                palette.createPaletteFromGdalColorTable(rb.getRasterColorTable());
149
//                                fileTransparency.setTransparencyRangeList(palette.getTransparencyRange());
150
                        }
151
                }
152
                fileTransparency.setTransparencyByPixelFromMetadata(metadata);
153

    
154
                try {
155
                        trans = getGeoTransform();
156

    
157
                        boolean isCorrect = false;
158
                        for (int i = 0; i < trans.adfgeotransform.length; i++)
159
                                if (trans.adfgeotransform[i] != 0)
160
                                        isCorrect = true;
161
                        if (!isCorrect)
162
                                throw new GdalException("");
163

    
164
                        ownTransformation = new AffineTransform(trans.adfgeotransform[1], trans.adfgeotransform[4], trans.adfgeotransform[2], trans.adfgeotransform[5], trans.adfgeotransform[0], trans.adfgeotransform[3]);
165
                        externalTransformation = (AffineTransform) ownTransformation.clone();
166
                        currentFullWidth = width;
167
                        currentFullHeight = height;
168

    
169
                        this.georeferenced = true;
170
                } catch (GdalException exc) {
171
                        // Transformaci?n para ficheros sin georreferenciaci?n. Se invierte la Y
172
                        // ya que las WC decrecen de
173
                        // arriba a abajo y los pixeles crecen de arriba a abajo
174
                        ownTransformation = new AffineTransform(1, 0, 0, -1, 0, height);
175
                        externalTransformation = (AffineTransform) ownTransformation.clone();
176
                        currentFullWidth = width;
177
                        currentFullHeight = height;
178
                        this.georeferenced = false;
179
                }
180
        }
181
        
182
        /**
183
         * Returns true if this provider is open and false if don't
184
         * @return
185
         */
186
        public boolean isOpen() {
187
                return open;
188
        }
189
        
190
        /*
191
         * (non-Javadoc)
192
         * @see es.gva.cit.jgdal.Gdal#close()
193
         */
194
        public void close() throws GdalException {
195
                open = false;
196
                super.close();
197
        }
198
        
199
        /**
200
         * Obtiene el flag que informa de si el raster tiene valor no data o no.
201
         * Consultar? todas las bandas del mismo y si alguna tiene valor no data
202
         * devuelve true sino devolver? false.
203
         * @return true si tiene valor no data y false si no lo tiene
204
         * @throws GdalException
205
         */
206
        public boolean existsNoDataValue() throws GdalException {
207
                for (int i = 0; i < getRasterCount(); i++) {
208
                        GdalRasterBand rb = getRasterBand(i + 1);
209
                        if (rb.existsNoDataValue())
210
                                return true;
211
                }
212
                return false;
213
        }
214
        
215
        /**
216
         * Obtiene el flag que informa de si el raster tiene valor no data o no
217
         * en una banda concreta.
218
         * @return true si tiene valor no data en esa banda y false si no lo tiene
219
         * @param band Posici?n de la banda a consultar (0..n)
220
         * @throws GdalException
221
         */
222
        public boolean existsNoDataValue(int band) throws GdalException {
223
                GdalRasterBand rb = getRasterBand(band + 1);
224
                return rb.existsNoDataValue();
225
        }
226

    
227
        /**
228
         * Gets nodata value
229
         * @return
230
         */
231
        public NoData getNoDataValue() {
232
                Number value = null;
233
                int type = RasterLocator.getManager().getRasterUtils().getRasterBufTypeFromGdalType(getDataType()[0]);
234
                if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
235
                        switch (type) {
236
                        case Buffer.TYPE_BYTE:
237
                                if (metadata == null || metadata.getNoDataValue().length == 0)
238
                                        value = new Byte(RasterLibrary.defaultByteNoDataValue);
239
                                else
240
                                        value = new Byte((byte)metadata.getNoDataValue()[0]);
241
                                break;
242
                        case Buffer.TYPE_SHORT:
243
                                if (metadata == null || metadata.getNoDataValue().length == 0)
244
                                        value = new Short(RasterLibrary.defaultShortNoDataValue);
245
                                else
246
                                        value = new Short((short)metadata.getNoDataValue()[0]);
247
                                break;
248
                        case Buffer.TYPE_INT:
249
                                if (metadata == null || metadata.getNoDataValue().length == 0)
250
                                        value = new Integer((int)RasterLibrary.defaultIntegerNoDataValue);
251
                                else
252
                                        value = new Integer((int)metadata.getNoDataValue()[0]);
253
                                break;
254
                        case Buffer.TYPE_FLOAT:
255
                                if (metadata == null || metadata.getNoDataValue().length == 0)
256
                                        value = new Float(RasterLibrary.defaultFloatNoDataValue);
257
                                else
258
                                        value = new Float(metadata.getNoDataValue()[0]);
259
                                break;
260
                        case Buffer.TYPE_DOUBLE:
261
                                if (metadata == null || metadata.getNoDataValue().length == 0)
262
                                        value = new Double(RasterLibrary.defaultFloatNoDataValue);
263
                                else
264
                                        value = new Double(metadata.getNoDataValue()[0]);
265
                                break;
266
                        }
267
                }
268

    
269
                return new DefaultNoData(value, value, fileName);
270
        }
271

    
272
        /**
273
         * Asigna el tipo de dato
274
         * @param dt entero que representa el tipo de dato
275
         */
276
        public void setDataType(int[] dt) { 
277
                dataType = dt; 
278
        }
279
        
280
        /**
281
         * Obtiene el tipo de dato
282
         * @return entero que representa el tipo de dato
283
         */
284
        public int[] getDataType() { 
285
                return dataType; 
286
        }
287
        
288
        /**
289
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
290
         * del punto real.
291
         * Supone rasters no girados
292
         * @param pt        punto en coordenadas del punto real
293
         * @return        punto en coordenadas del raster
294
         */
295
        public Point2D worldToRasterWithoutRot(Point2D pt) {
296
                Point2D p = new Point2D.Double();
297
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
298
                                                                                                        0, externalTransformation.getScaleY(), 
299
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
300
                try {
301
                        at.inverseTransform(pt, p);
302
                } catch (NoninvertibleTransformException e) {
303
                        return pt;
304
                }
305
                return p;
306
        }
307
                
308
        /**
309
         * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
310
         * del punto real.
311
         * Supone rasters no girados
312
         * @param pt        punto en coordenadas del punto real
313
         * @return        punto en coordenadas del raster
314
         */
315
        public Point2D worldToRaster(Point2D pt) {
316
                Point2D p = new Point2D.Double();
317
                try {
318
                        externalTransformation.inverseTransform(pt, p);
319
                } catch (NoninvertibleTransformException e) {
320
                        return pt;
321
                }
322
                return p;
323
        }
324
        
325
        /**
326
         * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
327
         * reales. 
328
         * @param pt Punto en coordenadas reales
329
         * @return Punto en coordenadas pixel.
330
         */
331
        public Point2D rasterToWorld(Point2D pt) {
332
                Point2D p = new Point2D.Double();
333
                externalTransformation.transform(pt, p);
334
                return p;
335
        }
336
        
337
        /**
338
         * Calcula el overview a usar. Hay que tener en cuenta que tenemos que tener calculadas las variables
339
         * viewPortScale, currentFullWidth y currentFulHeight
340
         * @param coordenada pixel expresada en double que indica la posici?n superior izquierda
341
         * @throws GdalException
342
         */
343
        private void calcOverview(Point2D tl, Point2D br) throws GdalException {
344
                gdalBands[0] = getRasterBand(1);
345
                currentOverview = -1;
346
                if (gdalBands[0].getOverviewCount() > 0) {
347
                        GdalRasterBand ovb = null;
348
                        for (int i = gdalBands[0].getOverviewCount() - 1; i > 0; i--) {
349
                                ovb = gdalBands[0].getOverview(i);
350
                                if (ovb.getRasterBandXSize() > getRasterXSize() * viewportScaleX) {
351
                                        currentOverview = i;
352
                                        viewportScaleX *= ((double) width / (double) ovb.getRasterBandXSize());
353
                                        viewportScaleY *= ((double) height / (double) ovb.getRasterBandYSize());
354
                                        stepX = 1D / viewportScaleX;
355
                                        stepY = 1D / viewportScaleY;
356
                                        currentFullWidth = ovb.getRasterBandXSize();
357
                                        currentFullHeight = ovb.getRasterBandYSize();
358
                                        currentViewX = Math.min(tl.getX(), br.getX());
359
                                        lastReadLine = Math.min(tl.getY(), br.getY());
360
                                        break;
361
                                }
362
                        }
363
                }
364
        }
365
        
366
        public void setView(double dWorldTLX, double dWorldTLY,
367
                                                double dWorldBRX, double dWorldBRY,
368
                                                int nWidth, int nHeight) throws GdalException {
369
                currentFullWidth = width;
370
                currentFullHeight = height;
371
                Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
372
                Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
373
                // Calcula cual es la primera l?nea a leer;
374
                currentViewWidth = nWidth;
375
                currentViewHeight = nHeight;
376
//                wcWidth = Math.abs(br.getX() - tl.getX());
377

    
378
                currentViewX = Math.min(tl.getX(), br.getX());
379

    
380
                viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
381
                viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
382
                stepX = 1D / viewportScaleX;
383
                stepY = 1D / viewportScaleY;
384

    
385
                lastReadLine = Math.min(tl.getY(), br.getY());
386
                
387
                //Para lectura del renderizado (ARGB). readWindow selecciona las bandas que necesita.
388

    
389
                // calcula el overview a usar
390
                gdalBands = new GdalRasterBand[4];
391
                calcOverview(tl, br);
392

    
393
                // Selecciona las bandas y los overviews necesarios
394
                /*gdalBands[0] = getRasterBand(rBandNr);
395
                gdalBands[1] = gdalBands[0]; 
396
                gdalBands[2] = gdalBands[1]; 
397

398
                if(getRasterCount() >= 2) {
399
                        gdalBands[1] = getRasterBand(gBandNr);
400
                        gdalBands[2] = gdalBands[1]; 
401
                }
402
                if(this.getRasterCount() >= 3) 
403
                        gdalBands[2] = getRasterBand(bBandNr);
404
                if(colorInterpr.isAlphaBand())
405
                        gdalBands[3] = getRasterBand(aBandNr);                        
406

407
                assignDataTypeFromGdalRasterBands(gdalBands);
408

409
                if (currentOverview > 0) {
410
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
411
                        if(getRasterCount() >= 2) {
412
                                gdalBands[1] = gdalBands[1].getOverview(currentOverview);
413
                        }
414
                        if(this.getRasterCount() >= 3) 
415
                                gdalBands[2] = gdalBands[2].getOverview(currentOverview);
416
                        if(colorInterpr.isAlphaBand())
417
                                gdalBands[3] = gdalBands[3].getOverview(currentOverview);                        
418

419
                }*/
420
        }
421
        
422
        /**
423
         * Selecciona bandas y overview en el objeto GdalRasterBand[] para el n?mero de bandas solicitado.
424
         * @param nbands N?mero de bandas solicitado.
425
         * @throws GdalException
426
         */
427
        public void selectGdalBands(int nbands) throws GdalException {
428
                gdalBands = new GdalRasterBand[nbands];
429
                // Selecciona las bandas y los overviews necesarios
430
                gdalBands[0] = getRasterBand(1);
431
                for (int i = 0; i < nbands; i++)
432
                        gdalBands[i] = gdalBands[0];
433

    
434
                assignDataTypeFromGdalRasterBands(gdalBands);
435
//                setDataType(gdalBands[0].getRasterDataType());
436

    
437
                for (int i = 2; i <= nbands; i++) {
438
                        if (getRasterCount() >= i) {
439
                                gdalBands[i - 1] = getRasterBand(i);
440
                                for (int j = i; j < nbands; j++)
441
                                        gdalBands[j] = gdalBands[i - 1];
442
                        }
443
                }
444

    
445
                if (currentOverview > 0) {
446
                        gdalBands[0] = gdalBands[0].getOverview(currentOverview);
447
                        for (int i = 2; i <= nbands; i++) {
448
                                if (getRasterCount() >= i)
449
                                        gdalBands[i - 1] = gdalBands[i - 1].getOverview(currentOverview);
450
                        }
451
                }
452
        }
453
                
454
        int lastY = -1;
455
        
456
        /**
457
         * Lee una l?nea de bytes
458
         * @param line Buffer donde se cargan los datos
459
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
460
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
461
         * por la izquierda a mitad de pixel
462
         * @param gdalBuffer Buffer con la l?nea de datos original
463
         */
464
        private void readLine(byte[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
465
                double j = 0D;
466
                int i = 0;
467
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
468
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
469
                                line[iBand][i] = gdalBuffer[iBand].buffByte[(int) j];
470
                        }
471
                }
472
        }
473
        
474
        /**
475
         * Lee una l?nea de shorts
476
         * @param line Buffer donde se cargan los datos
477
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
478
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
479
         * por la izquierda a mitad de pixel
480
         * @param gdalBuffer Buffer con la l?nea de datos original
481
         */
482
        private void readLine(short[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
483
                double j = 0D;
484
                int i = 0;
485
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
486
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
487
                                line[iBand][i] = (short) (gdalBuffer[iBand].buffShort[(int) j] & 0xffff);
488
                        }
489
                }
490
        }
491

    
492
        /**
493
         * Lee una l?nea de ints
494
         * @param line Buffer donde se cargan los datos
495
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
496
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
497
         * por la izquierda a mitad de pixel
498
         * @param gdalBuffer Buffer con la l?nea de datos original
499
         */
500
        private void readLine(int[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
501
                double j = 0D;
502
                int i = 0;
503
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
504
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
505
                                line[iBand][i] = (gdalBuffer[iBand].buffInt[(int) j] & 0xffffffff);
506
                        }
507
                }
508
        }
509

    
510
        /**
511
         * Lee una l?nea de float
512
         * @param line Buffer donde se cargan los datos
513
         * @param initOffset Desplazamiento inicial desde el margen izquierdo. Esto es necesario para cuando
514
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
515
         * por la izquierda a mitad de pixel
516
         * @param gdalBuffer Buffer con la l?nea de datos original
517
         */
518
        private void readLine(float[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
519
                double j = 0D;
520
                int i = 0;
521
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
522
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
523
                                line[iBand][i] = gdalBuffer[iBand].buffFloat[(int) j];
524
                        }
525
                }
526
        }
527
        
528
        /**
529
         * Lee una l?nea de doubles
530
         * @param line Buffer donde se cargan los datos
531
         * @param initOffset Desplazamiento inicial desde el margen inzquierdo. Esto es necesario para cuando
532
         * se supersamplea ya que cada pixel de imagen ocupa muchos pixeles de pantalla y puede empezar a dibujarse
533
         * por la izquierda a mitad de pixel
534
         * @param gdalBuffer Buffer con la l?nea de datos original
535
         */
536
        private void readLine(double[][] line, double initOffset, GdalBuffer[] gdalBuffer) {
537
                double j = 0D;
538
                int i = 0;
539
                for (int iBand = 0; iBand < gdalBuffer.length; iBand++) {
540
                        for (i = 0, j = initOffset; i < currentViewWidth && j < gdalBuffer[0].getSize(); i++, j += stepX) {
541
                                line[iBand][i] = gdalBuffer[iBand].buffDouble[(int) j];
542
                        }
543
                }
544
        }
545

    
546
        /**
547
         * Lee una l?nea completa del raster y devuelve un array del tipo correcto. Esta funci?n es util
548
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
549
         * @param nLine N?mero de l?nea a leer
550
         * @param band Banda requerida
551
         * @return Object que es un array unidimendional del tipo de datos del raster
552
         * @throws GdalException
553
         */
554
        public Object readCompleteLine(int nLine, int band) throws GdalException {
555
                GdalRasterBand gdalBand = super.getRasterBand(band + 1);
556
                GdalBuffer gdalBuf = null;
557

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

    
560
                if (dataType[band] == GDT_Byte)
561
                        return gdalBuf.buffByte;
562

    
563
                if (dataType[band] == GDT_Int16 || dataType[band] == GDT_UInt16)
564
                        return gdalBuf.buffShort;
565

    
566
                if (dataType[band] == GDT_Int32 || dataType[band] == GDT_UInt32)
567
                        return gdalBuf.buffInt;
568

    
569
                if (dataType[band] == GDT_Float32)
570
                        return gdalBuf.buffFloat;
571

    
572
                if (dataType[band] == GDT_Float64)
573
                        return gdalBuf.buffDouble;
574

    
575
                if (dataType[band] == GDT_CInt16 || dataType[band] == GDT_CInt32 ||
576
                                dataType[band] == GDT_CFloat32 || dataType[band] == GDT_CFloat64)
577
                        return null;
578
                
579
                return null;
580
        }
581
        
582
        /**
583
         * Lee una bloque completo del raster y devuelve un array tridimensional del tipo correcto. Esta funci?n es util
584
         * para una lectura rapida de todo el fichero sin necesidad de asignar vista. 
585
         * @param nLine N?mero de l?nea a leer
586
         * @param band Banda requerida
587
         * @return Object que es un array unidimendional del tipo de datos del raster
588
         * @throws GdalException
589
         */
590
        public Object readBlock(int pos, int blockHeight, double scale) throws GdalException, ProcessInterruptedException {
591
                bBandNr = super.getRasterCount();
592
                int widthBuffer = (int)(getRasterXSize() * scale);
593
                int heightBuffer = (int)(blockHeight * scale);
594

    
595
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
596
                                
597
                GdalRasterBand[] gdalBand = new GdalRasterBand[bBandNr];
598
                for (int iBand = 0; iBand < gdalBand.length; iBand++) 
599
                        gdalBand[iBand] = super.getRasterBand(iBand + 1);
600
                                
601
                GdalBuffer[] gdalBuf = new GdalBuffer[bBandNr];
602
                                
603
                if (dataType[0] == GDT_Byte) {
604
                        byte[][][] buf = new byte[bBandNr][heightBuffer][widthBuffer];
605
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
606
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
607
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
608
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
609
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffByte[iRow * widthBuffer + iCol];
610
                                        if(task.getEvent() != null)
611
                                                task.manageEvent(task.getEvent());
612
                                }
613
                        }        
614
                        return buf;
615
                } else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
616
                        short[][][] buf = new short[bBandNr][heightBuffer][widthBuffer];
617
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
618
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
619
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
620
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
621
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffShort[iRow * widthBuffer + iCol];
622
                                        if(task.getEvent() != null)
623
                                                task.manageEvent(task.getEvent());
624
                                }
625
                        }        
626
                        return buf;
627
                } else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
628
                        int[][][] buf = new int[bBandNr][heightBuffer][widthBuffer];
629
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
630
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
631
                                for (int iRow = 0; iRow < heightBuffer; iRow++) { 
632
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
633
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffInt[iRow * widthBuffer + iCol];
634
                                        if(task.getEvent() != null)
635
                                                task.manageEvent(task.getEvent());
636
                                }
637
                        }        
638
                        return buf;
639
                } else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
640
                        float[][][] buf = new float[bBandNr][heightBuffer][widthBuffer];
641
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
642
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
643
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
644
                                        for (int iCol = 0; iCol < widthBuffer; iCol++)
645
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffFloat[iRow * widthBuffer + iCol];
646
                                        if(task.getEvent() != null)
647
                                                task.manageEvent(task.getEvent());
648
                                }
649
                        }        
650
                        return buf;
651
                } else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
652
                        double[][][] buf = new double[bBandNr][heightBuffer][widthBuffer];
653
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
654
                                gdalBuf[iBand] = gdalBand[iBand].readRaster(0, pos, getRasterXSize(), blockHeight, widthBuffer, heightBuffer, dataType[0]);
655
                                for (int iRow = 0; iRow < heightBuffer; iRow++) {
656
                                        for (int iCol = 0; iCol < widthBuffer; iCol++) 
657
                                                buf[iBand][iRow][iCol] = gdalBuf[iBand].buffDouble[iRow * widthBuffer + iCol];
658
                                        if(task.getEvent() != null)
659
                                                task.manageEvent(task.getEvent());
660
                                }
661
                        }                
662
                        return buf;
663
                }
664
                                
665
                return null;
666
        }
667
        
668
        /**
669
         * Lectura de una l?nea de datos.
670
         * @param line
671
         * @throws GdalException
672
         */
673
        public void readLine(Object line) throws GdalException {
674
                int w = (int) (Math.ceil(((double)currentViewWidth)*stepX) + 1);
675
                int x = (int) (currentViewX);
676
                int y = (int) (lastReadLine);
677
                GdalBuffer r = null, g = null, b = null;
678
                GdalBuffer a = new GdalBuffer();
679

    
680
                while(y >= gdalBands[0].getRasterBandYSize())
681
                        y--;
682

    
683
                if (x+w > gdalBands[0].getRasterBandXSize()) 
684
                        w = gdalBands[0].getRasterBandXSize()-x;
685

    
686
                if(gdalBands[0].getRasterColorTable() != null) {
687
                        palette = new DataStoreColorTable();
688
                        palette.createPaletteFromGdalColorTable(gdalBands[0].getRasterColorTable());
689
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
690
                } else {
691
                        a.buffByte = new byte[w];
692
                        r = gdalBands[0].readRaster(x, y, w, 1, w, 1, dataType[0]);
693
                        g = b = r;
694
                        if (getRasterCount() > 1 && gdalBands[1] != null)
695
                                g = gdalBands[1].readRaster(x, y, w, 1, w, 1, dataType[0]);
696
                        if (getRasterCount() > 2 && gdalBands[2] != null)
697
                                b = gdalBands[2].readRaster(x, y, w, 1, w, 1, dataType[0]);
698
                }
699

    
700
                lastReadLine += stepY;
701

    
702
                double initOffset =  Math.abs(currentViewX - ((int)currentViewX));
703
                GdalBuffer[] bands = {r, g, b};
704

    
705
                if (dataType[0] == GDT_Byte)
706
                        readLine((byte[][])line, initOffset, bands);
707
                else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16)
708
                        readLine((short[][])line, initOffset, bands);
709
                else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32)
710
                        readLine((int[][])line, initOffset, bands);
711
                else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32)
712
                        readLine((float[][])line, initOffset, bands);
713
                else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64)
714
                        readLine((double[][])line, initOffset, bands);
715

    
716
                return;
717
        }
718
                        
719
        /**
720
         * Cuando se hace una petici?n de carga de buffer la extensi?n pedida puede
721
         * estar ajustada a la extensi?n del raster o no estarlo. En caso de no
722
         * estarlo los pixeles del buffer que caen fuera de la extensi?n del raster
723
         * tendr?n valor de NoData. Esta funci?n calcula en que pixel del buffer hay
724
         * que empezar a escribir en caso de que este sea mayor que los datos a leer.
725
         * 
726
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
727
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
728
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
729
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
730
         * @param nWidth Ancho en pixeles del buffer
731
         * @param nHeight Alto en pixeles del buffer
732
         * @return desplazamiento dentro del buffer en X e Y
733
         */ 
734
        private int[] calcStepBuffer(Extent dataExtent, int nWidth, int nHeight, int[] stpBuffer) {
735
                Extent imageExtent = getExtentWithoutRot();
736
                Extent ajustDataExtent = RasterLocator.getManager().getRasterUtils().calculateAdjustedView(dataExtent, imageExtent);
737
                if(!RasterLocator.getManager().getRasterUtils().compareExtents(dataExtent, ajustDataExtent)){
738
                        Point2D p1 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.minX(), ajustDataExtent.maxY()));
739
                        Point2D p2 = worldToRasterWithoutRot(new Point2D.Double(ajustDataExtent.maxX(), ajustDataExtent.minY()));
740
                        Point2D p3 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.minX(), dataExtent.maxY()));
741
                        //                    Point2D p4 = worldToRasterWithoutRot(new Point2D.Double(dataExtent.maxX(), dataExtent.minY()));
742
                        //Ese es el ancho y alto q tendr?a el buffer en caso de haberse ajustado
743
                        int w = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
744
                        int h = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
745

    
746
                        stpBuffer[0] = (int)(p1.getX() + (-p3.getX()));
747
                        stpBuffer[1] = (int)(p1.getY() + (-p3.getY()));
748
                        stpBuffer[2] = stpBuffer[0] + w; 
749
                        stpBuffer[3] = stpBuffer[1] + h;
750
                        return new int[]{w, h};
751
                }
752
                return new int[]{nWidth, nHeight};
753
        }
754
        
755
        /**
756
         * Lee una ventana de datos sin resampleo a partir de coordenadas reales.
757
         * @param buf Buffer donde se almacenan los datos
758
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
759
         * @param dWorldTLX Posici?n X superior izquierda en coord reales
760
         * @param dWorldTLY Posici?n Y superior izquierda en coord reales
761
         * @param dWorldBRX Posici?n X inferior derecha en coord reales
762
         * @param dWorldBRY Posici?n Y inferior derecha en coord reales
763
         * @param nWidth Ancho en pixeles del buffer
764
         * @param nHeight Alto en pixeles del buffer
765
         * @throws GdalException
766
         */
767
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly,double lrx, double lry,
768
                        int nWidth, int nHeight, boolean adjustToExtent) throws GdalException, ProcessInterruptedException {
769
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
770
                setView(ulx, uly, lrx, lry, nWidth, nHeight);
771
                Point2D tl = worldToRaster(new Point2D.Double(ulx, uly));
772
                Point2D br = worldToRaster(new Point2D.Double(lrx, lry));
773

    
774
                if(tl.getX() > br.getX())
775
                        tl.setLocation(tl.getX() - 1, tl.getY());
776
                else
777
                        br.setLocation(br.getX() - 1, br.getY());
778
                
779
                if(tl.getY() > br.getY())
780
                        tl.setLocation(tl.getX(), tl.getY() - 1);
781
                else
782
                        br.setLocation(br.getX(), br.getY() - 1);
783
                
784
                if(gdalBands.length == 0)
785
                        return;
786

    
787
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
788

    
789
                int x = (int) Math.round(Math.min(tl.getX(), br.getX()));
790
                int y = (int) Math.round(Math.min(tl.getY(), br.getY()));
791

    
792
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
793
                //Si el buffer no se ajusta al extent entonces calculamos en que posici?n comienza a escribirse dentro del buffer
794
                //ya que lo que cae fuera ser?n valores NoData
795
                if(!adjustToExtent){
796
                        int[] wh = calcStepBuffer(petExtent, nWidth, nHeight, stpBuffer);
797
                        if(x < 0)
798
                                x  = 0;
799
                        if(y < 0)
800
                                y  = 0;
801
                        readData(buf, bandList, x, y, wh[0], wh[1], wh[0], wh[1], 0, 0, stpBuffer);
802
                        return;
803
                }
804

    
805
                readData(buf, bandList, x, y, nWidth, nHeight, nWidth, nHeight, 0, 0, stpBuffer);
806
        }
807
                        
808
        /**
809
         * Lee una ventana de datos con resampleo a partir de coordenadas reales. Este m?todo lee la
810
         * ventana de una vez cargando los datos de un golpe en el buffer. Las coordenadas se solicitan
811
         * en coordenadas del mundo real por lo que estas pueden caer en cualquier parte de un pixel.
812
         * Esto se hace m?s evidente cuando supersampleamos en la petici?n, es decir el buffer de de 
813
         * mayor tama?o que el n?mero de pixels solicitado.
814
         * 
815
         * Para resolver esto escribiremos con la funci?n readRaster los datos sobre un buffer mayor 
816
         * que el solicitado. Despu?s calcularemos el desplazamiento en pixels dentro de este buffer 
817
         * de mayor tama?o hasta llegar a la coordenada real donde comienza la petici?n real que ha
818
         * hecho el usuario. Esto es as? porque cuando supersampleamos no queremos los pixeles del 
819
         * raster de disco completos sino que en los bordes del buffer quedan cortados.  
820
         *  
821
         * @param buf Buffer donde se almacenan los datos
822
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
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 de la petici?n
828
         * @param nHeight Alto en pixeles de la petici?n
829
         * @param bufWidth Ancho del buffer
830
         * @param bufHeight Alto del buffer
831
         * @throws GdalException
832
         */
833
        public void readWindow(Buffer buf, BandList bandList, double ulx, double uly, double lrx, double lry,
834
                                                                                double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent) throws GdalException, ProcessInterruptedException {
835
                Extent petExtent = new ExtentImpl(ulx, uly, lrx, lry);
836
                setView(ulx, uly, lrx, lry, bufWidth, bufHeight);
837
                Point2D ul = worldToRaster(new Point2D.Double(ulx, uly));
838
                Point2D lr = worldToRaster(new Point2D.Double(lrx, lry));
839
                ul.setLocation(ul.getX() < 0 ? 1 : ul.getX(), ul.getY() < 0 ? 1 : ul.getY());
840
                lr.setLocation(lr.getX() < 0 ? 1 : lr.getX(), lr.getY() < 0 ? 1 : lr.getY());
841
                ul.setLocation(ul.getX() - 0.5, ul.getY() - 0.5);
842
                lr.setLocation(lr.getX() - 0.5, lr.getY() - 0.5);
843
                
844
                /*if(tl.getX() > br.getX())
845
                        tl.setLocation(tl.getX() - 1, tl.getY());
846
                else
847
                        br.setLocation(br.getX() - 1, br.getY());
848
                
849
                if(tl.getY() > br.getY())
850
                        tl.setLocation(tl.getX(), tl.getY() - 1);
851
                else
852
                        br.setLocation(br.getX(), br.getY() - 1);*/
853
                
854
                adjustPoints(ul, lr);
855
                
856
                if(gdalBands.length == 0)
857
                        return;
858
                
859
                selectGdalBands(/*buf.getBandCount()*/getRasterCount());
860
                                
861
                int x = (int) Math.min(ul.getX(), lr.getX());
862
                int y = (int) Math.min(ul.getY(), lr.getY());
863
                //int endX = (int) Math.ceil(Math.max(br.getX(), tl.getX()));
864
                //int endY = (int) Math.ceil(Math.max(br.getY(), tl.getY()));
865

    
866
                int stpX = 0;
867
                int stpY = 0;
868
                                
869
                /*if(bufWidth > Math.ceil(nWidth)){
870
                        stpX = (int)(((tl.getX() - x) * bufWidth) / nWidth);
871
                        bufWidth = (int)((Math.abs(endX - x) * bufWidth) / nWidth);
872
                }
873
                if(bufHeight > Math.ceil(nHeight)){
874
                        stpY = (int)(((tl.getY() - y) * bufHeight) / nHeight);
875
                        bufHeight = (int)((Math.abs(endY - y) * bufHeight) / nHeight);
876
                }
877

878
                nWidth = (int)Math.abs(endX - x);
879
                nHeight = (int)Math.abs(endY - y);*/
880

    
881
                nWidth = (nWidth * currentFullWidth) / width;
882
                nHeight = (nHeight * currentFullHeight) / height;
883
                x = (int)(((long)x * (long)currentFullWidth) / (long)width);
884
                y = (int) (((long)y * (long)currentFullHeight) / (long)height);
885

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

    
905
                if ((x + nWidth) > gdalBands[0].getRasterBandXSize()) 
906
                        nWidth = gdalBands[0].getRasterBandXSize() - x;
907

    
908
                if ((y + nHeight) > gdalBands[0].getRasterBandYSize()) 
909
                        nHeight = gdalBands[0].getRasterBandYSize() - y;
910

    
911
                readData(buf, bandList, x, y, (int)nWidth, (int)nHeight, bufWidth, bufHeight, stpX, stpY, stpBuffer);
912
        }
913
        
914
        private void adjustPoints(Point2D ul, Point2D lr) {
915
                double a = (ul.getX() - (int)ul.getX());
916
                double b = (ul.getY() - (int)ul.getY());
917
                ul.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(ul.getX()) : ul.getX(), 
918
                                                (b > 0.95 || b < 0.05) ? Math.round(ul.getY()) : ul.getY());
919
                lr.setLocation(        (a > 0.95 || a < 0.05) ? Math.round(lr.getX()) : lr.getX(), 
920
                                                (b > 0.95 || b < 0.05) ? Math.round(lr.getY()) : lr.getY());
921
        }
922

    
923
        /**
924
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
925
         * @param buf Buffer donde se almacenan los datos
926
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
927
         * @param x Posici?n X en pixeles
928
         * @param y Posici?n Y en pixeles
929
         * @param w Ancho en pixeles
930
         * @param h Alto en pixeles
931
         * @throws GdalException
932
         */
933
        public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h) 
934
                throws GdalException, ProcessInterruptedException {
935
                gdalBands = new GdalRasterBand[getRasterCount()];
936
                isSupersampling = false;
937
                if(gdalBands.length == 0)
938
                        return;
939
                
940
                // Selecciona las bandas
941
                gdalBands[0] = getRasterBand(1);
942
                
943
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
944
                        gdalBands[iBand] = getRasterBand(iBand + 1);
945
                
946
                assignDataTypeFromGdalRasterBands(gdalBands);
947
                
948
                int[] stepBuffer = new int[]{0, 0, w, h};
949
                readData(buf, bandList, x, y, w, h, w, h, 0, 0, stepBuffer);
950
                //int yMax = y + h;
951
                //readDataByLine(buf, bandList, x, y, w, yMax);
952
        }
953
        
954
        /**
955
         * Lee una ventana de datos con resampleo a partir de coordenadas en pixeles. Este m?todo lee la
956
         * ventana de una vez cargando los datos de un golpe en el buffer.
957
         * @param buf Buffer donde se almacenan los datos
958
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
959
         * @param x Posici?n X en pixeles
960
         * @param y Posici?n Y en pixeles
961
         * @param w Ancho en pixeles
962
         * @param h Alto en pixeles
963
         * @param bufWidth Ancho del buffer
964
         * @param bufHeight Alto del buffer
965
         * @throws GdalException
966
         */
967
        public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h, int bufWidth, int bufHeight) throws GdalException, ProcessInterruptedException {
968
                gdalBands = new GdalRasterBand[getRasterCount()];
969
                
970
                if(gdalBands.length == 0)
971
                        return;
972
                
973
                // Selecciona las bandas
974
                gdalBands[0] = getRasterBand(1);
975
                
976
                for(int iBand = 1; iBand < gdalBands.length; iBand++)
977
                        gdalBands[iBand] = getRasterBand(iBand + 1);
978
                
979
                assignDataTypeFromGdalRasterBands(gdalBands);
980
                
981
                int[] stpBuffer = new int[]{0, 0 , buf.getWidth(), buf.getHeight()};
982
                readData(buf, bandList, x, y, w, h, bufWidth, bufHeight, 0, 0, stpBuffer);
983
        }
984
        
985
        /**
986
         * Asigna el tipo de datos de las bandas a partir de una lista de GdalRasterBands
987
         * @param gdalBands
988
         * @throws GdalException
989
         */
990
        private void assignDataTypeFromGdalRasterBands(GdalRasterBand[] gdalBands) throws GdalException {
991
                int[] dt = new int[gdalBands.length];
992
                for (int i = 0; i < gdalBands.length; i++) {
993
                        if(gdalBands[i] != null)
994
                                dt[i] = gdalBands[i].getRasterDataType();
995
                }
996
                setDataType(dt);
997
        }
998
                
999
        /**
1000
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1001
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1002
         * @param buf Buffer donde se almacenan los datos
1003
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1004
         * @param x Posici?n X en pixeles
1005
         * @param y Posici?n Y en pixeles
1006
         * @param w Ancho en pixeles
1007
         * @param h Alto en pixeles
1008
         * @param bufWidth Ancho del buffer
1009
         * @param bufHeight Alto del buffer
1010
         * @param stepX Desplazamiento en pixeles en X a partir de la posici?n x. Este desplazamiento es util cuando hay un 
1011
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde izquierdo de la petici?n solo queramos una
1012
         * parte de ellos. 
1013
         * @param stepY Desplazamiento en pixeles en Y a partir de la posici?n y. Este desplazamiento es util cuando hay un 
1014
         * supersampleo ya que puede ser que de los pixeles que est?n en el borde superior de la petici?n solo queramos una
1015
         * parte de ellos.
1016
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes 
1017
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1018
         * <UL>
1019
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1020
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1021
         * <LI>stepBuffer[2]:Posici?n X final</LI>
1022
         * <LI>stepBuffer[3]:Posici?n Y final</LI>
1023
         * </UL>
1024
         * @throws GdalException
1025
         */
1026
        private void readData(Buffer buf, BandList bandList, int x, int y, int w, int h, 
1027
                        int bufWidth, int bufHeight, int stpX, int stpY, int[] stepBuffer) throws GdalException, ProcessInterruptedException {
1028
                
1029
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString()); 
1030
                FileUtils fUtil = RasterLocator.getManager().getFileUtils(); 
1031
                        
1032
                GdalBuffer gdalBuf = null;
1033
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1034
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1035
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1036
                                continue;        
1037
                        int init = (int)((bufWidth * stpY) + stpX); //Pos inicial. Desplazamos stpX pixels hacia la derecha y bajamos stpY lineas
1038
                        int pos = init;
1039
                        gdalBuf = gdalBands[iBand].readRaster(x, y, w, h, bufWidth, bufHeight, dataType[iBand]);
1040
                        if(dataType[iBand] == Gdal.GDT_Byte){
1041
                                for (int line = stepBuffer[1]; line < stepBuffer[3]/*buf.getHeight()*/; line++) {
1042
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1043
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]/*buf.getWidth()*/; col ++) {
1044
                                                for (int i = 0; i < drawableBands.length; i++) 
1045
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffByte[pos]);
1046
                                                pos ++;
1047
                                        }
1048
                                        if(task.getEvent() != null)
1049
                                                task.manageEvent(task.getEvent());
1050
                                }
1051
                        }else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)){
1052
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1053
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1054
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1055
                                                for (int i = 0; i < drawableBands.length; i++)
1056
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffShort[pos]);
1057
                                                pos ++;
1058
                                        }
1059
                                        if(task.getEvent() != null)
1060
                                                task.manageEvent(task.getEvent());
1061
                                }
1062
                        }else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)){
1063
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1064
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1065
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1066
                                                for (int i = 0; i < drawableBands.length; i++)
1067
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffInt[pos]);
1068
                                                pos ++;
1069
                                        }
1070
                                        if(task.getEvent() != null)
1071
                                                task.manageEvent(task.getEvent());
1072
                                }
1073
                        }else if(dataType[iBand] == Gdal.GDT_Float32){
1074
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1075
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1076
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1077
                                                for (int i = 0; i < drawableBands.length; i++)
1078
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffFloat[pos]);
1079
                                                pos ++;
1080
                                        }
1081
                                        if(task.getEvent() != null)
1082
                                                task.manageEvent(task.getEvent());
1083
                                }
1084
                        }else if(dataType[iBand] == Gdal.GDT_Float64){
1085
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1086
                                        pos = (int)((bufWidth * (line - stepBuffer[0])) + init);
1087
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1088
                                                for (int i = 0; i < drawableBands.length; i++)
1089
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffDouble[pos]);
1090
                                                pos ++;
1091
                                        }
1092
                                        if(task.getEvent() != null)
1093
                                                task.manageEvent(task.getEvent());
1094
                                }
1095
                        }
1096
                }
1097
        }
1098
        
1099
        /**
1100
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles. Esta funci?n es usuada por
1101
         * readWindow para coordenadas reales y readWindow en coordenadas pixel. 
1102
         * @param buf Buffer donde se almacenan los datos
1103
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
1104
         * @param x Posici?n X en pixeles
1105
         * @param y Posici?n Y en pixeles
1106
         * @param w Ancho en pixeles
1107
         * @param yMax altura m?xima de y
1108
         * @throws GdalException
1109
         */
1110
        @SuppressWarnings("unused")
1111
        private void readDataByLine(Buffer buf, BandList bandList, int x, int y, int w, int yMax) throws GdalException, ProcessInterruptedException {
1112
                GdalBuffer gdalBuf = null;
1113
                int rasterBufLine;
1114
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
1115
                FileUtils fUtil = RasterLocator.getManager().getFileUtils(); 
1116
                
1117
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1118
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1119
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
1120
                                continue;        
1121
                        if(dataType[iBand] == Gdal.GDT_Byte) {
1122
                                for (int line = y; line < yMax; line++) {
1123
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1124
                                        rasterBufLine = line - y;
1125
                                        for (int i = 0; i < drawableBands.length; i++) {
1126
                                                buf.setLineInBandByte(gdalBuf.buffByte, rasterBufLine, drawableBands[i]);
1127
                                        }
1128
                                        if(task.getEvent() != null)
1129
                                                task.manageEvent(task.getEvent());
1130
                                }
1131
                        }else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1132
                                for (int line = y; line < yMax; line++) {
1133
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1134
                                        rasterBufLine = line - y;
1135
                                        for (int i = 0; i < drawableBands.length; i++) {
1136
                                                buf.setLineInBandShort(gdalBuf.buffShort, rasterBufLine, drawableBands[i]);
1137
                                        }
1138
                                        if(task.getEvent() != null)
1139
                                                task.manageEvent(task.getEvent());
1140
                                }
1141
                        }else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1142
                                for (int line = y; line < yMax; line++) {
1143
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1144
                                        rasterBufLine = line - y;
1145
                                        for (int i = 0; i < drawableBands.length; i++) {
1146
                                                buf.setLineInBandInt(gdalBuf.buffInt, rasterBufLine, drawableBands[i]);
1147
                                        }
1148
                                        if(task.getEvent() != null)
1149
                                                task.manageEvent(task.getEvent());
1150
                                }
1151
                        }else if(dataType[iBand] == Gdal.GDT_Float32){
1152
                                for (int line = y; line < yMax; line++) {
1153
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1154
                                        rasterBufLine = line - y;
1155
                                        for (int i = 0; i < drawableBands.length; i++) {
1156
                                                buf.setLineInBandFloat(gdalBuf.buffFloat, rasterBufLine, drawableBands[i]);
1157
                                        }
1158
                                        if(task.getEvent() != null)
1159
                                                task.manageEvent(task.getEvent());
1160
                                }
1161
                        }else if(dataType[iBand] == Gdal.GDT_Float64){
1162
                                for (int line = y; line < yMax; line++) {
1163
                                        gdalBuf = gdalBands[iBand].readRaster(x, line, w, 1, w, 1, dataType[iBand]);
1164
                                        rasterBufLine = line - y;
1165
                                        for (int i = 0; i < drawableBands.length; i++) {
1166
                                                buf.setLineInBandDouble(gdalBuf.buffDouble, rasterBufLine, drawableBands[i]);
1167
                                        }
1168
                                        if(task.getEvent() != null)
1169
                                                task.manageEvent(task.getEvent());
1170
                                }
1171
                        }
1172
                }
1173
        }
1174
        
1175
        /**
1176
         * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
1177
         * por par?metro
1178
         * @param x Coordenada X del pixel
1179
         * @param y Coordenada Y del pixel
1180
         * @return Array de Object donde cada posici?n representa una banda y el valor ser? Integer
1181
         * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
1182
         */
1183
        public Object[] getData(int x, int y) {
1184
                try {
1185
                        Object[] data = new Object[getRasterCount()];
1186
                        for(int i = 0; i < getRasterCount(); i++){
1187
                                GdalRasterBand rb = getRasterBand(i + 1);
1188
                                GdalBuffer r = rb.readRaster(x, y, 1, 1, 1, 1, dataType[i]);
1189
                                switch(dataType[i]){
1190
                                case 0:        break;                                                                        //Sin tipo
1191
                                case 1:        data[i] = new Integer(r.buffByte[0]);         //Buffer byte (8)
1192
                                                break;
1193
                                case 2:                                                                                        //Buffer short (16)
1194
                                case 3:        data[i] = new Integer(r.buffShort[0]);        //Buffer short (16)
1195
                                                break;
1196
                                case 4:                                                                                        //Buffer int (32)
1197
                                case 5: data[i] = new Integer(r.buffInt[0]);        //Buffer int (32)
1198
                                                break;
1199
                                case 6:        data[i] = new Float(r.buffFloat[0]);        //Buffer float (32)
1200
                                                break;
1201
                                case 7:        data[i] = new Double(r.buffDouble[0]);        //Buffer double (64)
1202
                                                break;
1203
                                }
1204
                        }
1205
                        return data;
1206
                } catch (GdalException e) {
1207
                        return null;
1208
                }
1209
        }
1210
        
1211
        public int getBlockSize(){
1212
                return this.getBlockSize();
1213
        }
1214

    
1215
        /**
1216
         * Devuelve la transformaci?n del fichero de georreferenciaci?n
1217
         * @return AffineTransform
1218
         */
1219
        public AffineTransform getOwnTransformation() {
1220
                return ownTransformation;
1221
        }
1222
                
1223
        /**
1224
         * Calcula el extent en coordenadas del mundo real sin rotaci?n. Solo coordenadas y tama?o de pixel
1225
         * @return Extent
1226
         */
1227
        public Extent getExtentWithoutRot() {
1228
                AffineTransform at = new AffineTransform(        externalTransformation.getScaleX(), 0, 
1229
                                                                                                        0, externalTransformation.getScaleY(), 
1230
                                                                                                        externalTransformation.getTranslateX(), externalTransformation.getTranslateY());
1231
                Point2D p1 = new Point2D.Double(0, 0);
1232
                Point2D p2 = new Point2D.Double(width, height);
1233
                at.transform(p1, p1);
1234
                at.transform(p2, p2);
1235
                return new ExtentImpl(p1, p2);
1236
        }
1237
        
1238
        /**
1239
         * Asigna una transformaci?n que es aplicada sobre la que ya tiene el propio fichero
1240
         * @param t
1241
         */
1242
        public void setExternalTransform(AffineTransform t){
1243
                externalTransformation = t;
1244
        }
1245

    
1246
        /**
1247
         * Obtiene el nombre del driver de Gdal
1248
         * @return Cadena que representa el nombre del driver de gdal
1249
         */
1250
        public String getGdalShortName() {
1251
                return shortName;
1252
        }
1253
                
1254
}
1255

    
1256

    
1257

    
1258