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 488 nbrodin
        /* 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 1745 nbrodin
import java.awt.Color;
25 2232 nbrodin
import java.awt.Rectangle;
26 488 nbrodin
import java.awt.geom.AffineTransform;
27
import java.awt.geom.NoninvertibleTransformException;
28
import java.awt.geom.Point2D;
29
import java.io.IOException;
30 1745 nbrodin
import java.util.ArrayList;
31
import java.util.List;
32 488 nbrodin
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 1745 nbrodin
import org.gvsig.fmap.dal.coverage.datastruct.ColorItem;
38 488 nbrodin
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
39 859 nbrodin
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
40 488 nbrodin
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
41 906 nbrodin
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
42
import org.gvsig.fmap.dal.coverage.store.props.ColorTable;
43 620 nbrodin
import org.gvsig.fmap.dal.coverage.util.FileUtils;
44 805 nbrodin
import org.gvsig.jgdal.Gdal;
45
import org.gvsig.jgdal.GdalBuffer;
46 1745 nbrodin
import org.gvsig.jgdal.GdalColorEntry;
47
import org.gvsig.jgdal.GdalColorTable;
48 805 nbrodin
import org.gvsig.jgdal.GdalException;
49
import org.gvsig.jgdal.GdalRasterBand;
50
import org.gvsig.jgdal.GeoTransform;
51 1745 nbrodin
import org.gvsig.raster.impl.datastruct.ColorItemImpl;
52 859 nbrodin
import org.gvsig.raster.impl.datastruct.DefaultNoData;
53 488 nbrodin
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 1054 nbrodin
import org.gvsig.tools.dispose.Disposable;
61
import org.gvsig.tools.task.TaskStatus;
62 488 nbrodin
/**
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 1054 nbrodin
public class GdalNative extends Gdal implements Disposable {
69 488 nbrodin
        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 906 nbrodin
         * , es decir el n?mero de pixels de pantalla que tiene un pixel de imagen. Como todos
83 488 nbrodin
         * los pixeles no tienen el mismo ancho y alto ha de meterse en un array y no puede ser
84 906 nbrodin
         * 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 488 nbrodin
         */
87 906 nbrodin
        public int[]                              stepArrayX             = null;
88
        public int[]                              stepArrayY             = null;
89
        protected GdalRasterBand[]                gdalBands              = null;
90
        private double                            lastReadLine           = -1;
91 2239 nbrodin
        private int                               overviewWidth          = -1;
92
        private int                               overviewHeight         = -1;
93 906 nbrodin
        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 488 nbrodin
        /**
103
         * Estado de transparencia del raster.
104
         */
105 906 nbrodin
        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 488 nbrodin
111 1749 nbrodin
        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 488 nbrodin
125
        /**
126 1749 nbrodin
         * 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 488 nbrodin
         * 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 937 nbrodin
186 488 nbrodin
                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 2308 nbrodin
                colorInterpr = new DataStoreColorInterpretation(getRasterCount());
192
                fileTransparency = new DataStoreTransparency(colorInterpr);
193 488 nbrodin
                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 859 nbrodin
                        if(rb.existsNoDataValue()) {
204
                                metadata.setNoDataValue(i, rb.getRasterNoDataValue());
205
                                metadata.setNoDataEnabled(rb.existsNoDataValue());
206
                        }
207 488 nbrodin
                        colorInterpr.setColorInterpValue(i, colorInt);
208
                        if (colorInt.equals("Alpha"))
209
                                fileTransparency.setTransparencyBand(i);
210
211
                        if (rb.getRasterColorTable() != null && palette == null) {
212 1745 nbrodin
                                palette = new DataStoreColorTable(gdalColorTable2ColorItems(rb.getRasterColorTable()), false);
213 488 nbrodin
//                                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 2303 nbrodin
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 488 nbrodin
                        externalTransformation = (AffineTransform) ownTransformation.clone();
238 2239 nbrodin
                        overviewWidth = width;
239
                        overviewHeight = height;
240 488 nbrodin
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 2239 nbrodin
                        overviewWidth = width;
249
                        overviewHeight = height;
250 488 nbrodin
                        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 859 nbrodin
         * Gets nodata value
292 488 nbrodin
         * @return
293
         */
294 859 nbrodin
        public NoData getNoDataValue() {
295
                Number value = null;
296 1749 nbrodin
                int type = getRasterBufTypeFromGdalType(getDataType()[0]);
297 864 nbrodin
                if (metadata != null && metadata.isNoDataEnabled() && metadata.getNoDataValue().length > 0) {
298 859 nbrodin
                        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 488 nbrodin
332 2434 nbrodin
                NoData nodata = new DefaultNoData(value, value, fileName);
333
                nodata.setNoDataTransparent(false);
334
                return nodata;
335 488 nbrodin
        }
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 906 nbrodin
         * 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 488 nbrodin
         * 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 2239 nbrodin
                                        overviewWidth = ovb.getRasterBandXSize();
438
                                        overviewHeight = ovb.getRasterBandYSize();
439 488 nbrodin
                                        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 2239 nbrodin
                overviewWidth = width;
451
                overviewHeight = height;
452 488 nbrodin
                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 771 nbrodin
        public Object readBlock(int pos, int blockHeight, double scale) throws GdalException, ProcessInterruptedException {
644 488 nbrodin
                bBandNr = super.getRasterCount();
645 771 nbrodin
                int widthBuffer = (int)(getRasterXSize() * scale);
646
                int heightBuffer = (int)(blockHeight * scale);
647 488 nbrodin
648 1419 nbrodin
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
649 488 nbrodin
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 771 nbrodin
                        byte[][][] buf = new byte[bBandNr][heightBuffer][widthBuffer];
658 488 nbrodin
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
659 771 nbrodin
                                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 488 nbrodin
                                        if(task.getEvent() != null)
664
                                                task.manageEvent(task.getEvent());
665
                                }
666 1054 nbrodin
                                gdalBuf[iBand].buffByte = null;
667 488 nbrodin
                        }
668
                        return buf;
669
                } else if (dataType[0] == GDT_CInt16 || dataType[0] == GDT_Int16  || dataType[0] == GDT_UInt16) {
670 771 nbrodin
                        short[][][] buf = new short[bBandNr][heightBuffer][widthBuffer];
671 488 nbrodin
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
672 771 nbrodin
                                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 488 nbrodin
                                        if(task.getEvent() != null)
677
                                                task.manageEvent(task.getEvent());
678
                                }
679 1054 nbrodin
                                gdalBuf[iBand].buffShort = null;
680 488 nbrodin
                        }
681
                        return buf;
682
                } else if (dataType[0] == GDT_CInt32 || dataType[0] == GDT_Int32  || dataType[0] == GDT_UInt32) {
683 771 nbrodin
                        int[][][] buf = new int[bBandNr][heightBuffer][widthBuffer];
684 488 nbrodin
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
685 771 nbrodin
                                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 488 nbrodin
                                        if(task.getEvent() != null)
690
                                                task.manageEvent(task.getEvent());
691
                                }
692 1054 nbrodin
                                gdalBuf[iBand].buffInt = null;
693 488 nbrodin
                        }
694
                        return buf;
695
                } else if(dataType[0] == GDT_Float32 || dataType[0] == GDT_CFloat32) {
696 771 nbrodin
                        float[][][] buf = new float[bBandNr][heightBuffer][widthBuffer];
697 488 nbrodin
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
698 771 nbrodin
                                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 488 nbrodin
                                        if(task.getEvent() != null)
703
                                                task.manageEvent(task.getEvent());
704
                                }
705 1054 nbrodin
                                gdalBuf[iBand].buffFloat = null;
706 488 nbrodin
                        }
707
                        return buf;
708
                } else if(dataType[0] == GDT_Float64 || dataType[0] == GDT_CFloat64) {
709 771 nbrodin
                        double[][][] buf = new double[bBandNr][heightBuffer][widthBuffer];
710 488 nbrodin
                        for (int iBand = 0; iBand < gdalBuf.length; iBand++) {
711 771 nbrodin
                                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 488 nbrodin
                                        if(task.getEvent() != null)
716
                                                task.manageEvent(task.getEvent());
717
                                }
718 1054 nbrodin
                                gdalBuf[iBand].buffDouble = null;
719 488 nbrodin
                        }
720
                        return buf;
721
                }
722
723 771 nbrodin
                return null;
724 488 nbrodin
        }
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 1745 nbrodin
                        palette = new DataStoreColorTable(gdalColorTable2ColorItems(gdalBands[0].getRasterColorTable()), false);
746 488 nbrodin
                        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 1745 nbrodin
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 488 nbrodin
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 1054 nbrodin
                        int nWidth, int nHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
850 488 nbrodin
                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 1054 nbrodin
                        readDataCachedBuffer(buf, bandList, new int[]{x, y, wh[0], wh[1]},
883
                                        wh[0], wh[1], 0, 0, stpBuffer, status);
884 488 nbrodin
                        return;
885
                }
886
887 1054 nbrodin
                readDataCachedBuffer(buf, bandList, new int[]{x, y, nWidth, nHeight},
888
                                nWidth, nHeight, 0, 0, stpBuffer, status);
889 488 nbrodin
        }
890 2232 nbrodin
891 2234 nbrodin
        public void readWindow(Buffer buf, BandList bandList, Extent ext, Rectangle adjustedWindow, TaskStatus status) throws GdalException, ProcessInterruptedException {
892 2232 nbrodin
                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 2239 nbrodin
901
                adjustedWindow = getAdjustedWindowInOverviewCoordinates(adjustedWindow);
902 2232 nbrodin
903
                readDataCachedBuffer(buf,
904
                                bandList,
905 2234 nbrodin
                                new int[]{(int)adjustedWindow.getX(), (int)adjustedWindow.getY(), (int)adjustedWindow.getWidth(), (int)adjustedWindow.getHeight()},
906 2232 nbrodin
                                buf.getWidth(),
907
                                buf.getHeight(),
908
                                0, 0, stpBuffer, status);
909
        }
910 2239 nbrodin
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 2433 nbrodin
                int nWidth = (int)(((long)adjustedWindow.getWidth() * overviewWidth) / width);
919
                int nHeight = (int)(((long)adjustedWindow.getHeight() * overviewHeight) / height);
920 2239 nbrodin
                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 488 nbrodin
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 1054 nbrodin
                                                        double nWidth, double nHeight, int bufWidth, int bufHeight, boolean adjustToExtent, TaskStatus status) throws GdalException, ProcessInterruptedException {
952 488 nbrodin
                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 2239 nbrodin
                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 488 nbrodin
974 2239 nbrodin
                requestWindow = getAdjustedWindowInOverviewCoordinates(requestWindow);
975
976 488 nbrodin
                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 2239 nbrodin
                        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 488 nbrodin
                        bufWidth = (int)Math.abs(stpBuffer[2] - stpBuffer[0]);
990
                        bufHeight = (int)Math.abs(stpBuffer[3] - stpBuffer[1]);
991 2239 nbrodin
                        readDataCachedBuffer(buf, bandList,
992
                                        new int[]{(int)requestWindow.getX(), (int)requestWindow.getY(), wh[0], wh[1]},
993
                                                bufWidth, bufHeight, 0, 0, stpBuffer, status);
994 488 nbrodin
                        return;
995
                }
996
997 2239 nbrodin
                if ((requestWindow.getX() + requestWindow.getWidth()) > gdalBands[0].getRasterBandXSize())
998
                        requestWindow.setSize((int)(gdalBands[0].getRasterBandXSize() - requestWindow.getX()), (int)requestWindow.getHeight());
999 488 nbrodin
1000 2239 nbrodin
                if ((requestWindow.getY() + requestWindow.getHeight()) > gdalBands[0].getRasterBandYSize())
1001
                        requestWindow.setSize((int)requestWindow.getWidth(), (int)(gdalBands[0].getRasterBandYSize() - requestWindow.getY()));
1002 488 nbrodin
1003 2239 nbrodin
                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 488 nbrodin
        }
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 1054 nbrodin
        public void readWindow(Buffer buf, BandList bandList, int x, int y, int w, int h, TaskStatus status) throws GdalException, ProcessInterruptedException {
1031 488 nbrodin
                gdalBands = new GdalRasterBand[getRasterCount()];
1032
1033 1043 nbrodin
                if(buf.getWidth() == w && buf.getHeight() == h)
1034
                        isSupersampling = false;
1035
1036 488 nbrodin
                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 1054 nbrodin
                readDataCachedBuffer(buf, bandList, new int[]{x, y, w, h}, buf.getWidth(), buf.getHeight(), 0, 0, stpBuffer, status);
1049 488 nbrodin
        }
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 1032 nbrodin
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 1054 nbrodin
                        int[] stepBuffer,
1105
                        TaskStatus status) throws GdalException, ProcessInterruptedException {
1106 1032 nbrodin
                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 1043 nbrodin
                        int initYSrc = inputWindow[1];
1112 1678 nbrodin
                        int stepYSrc = (buf.getBlockHeight() * inputWindow[3]) / buf.getHeight();
1113
                        int lastBlockYSrc = (lastblock * inputWindow[3]) / buf.getHeight();
1114 1043 nbrodin
                        int initYBuffer = 0;
1115 1032 nbrodin
                        for (int i = 0; i < nBlocks; i++) {
1116
                                if(lastblock > 0 && i == (nBlocks - 1)) {
1117 1043 nbrodin
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + lastblock};
1118 1678 nbrodin
                                        int[] newWindow = new int[]{inputWindow[0], initYSrc, inputWindow[2], lastBlockYSrc};
1119 1032 nbrodin
                                        readData(buf,
1120
                                                        bandList,
1121 1678 nbrodin
                                                        newWindow,
1122 1032 nbrodin
                                                        bufWidth, lastblock, 0, 0, newStepBuffer);
1123
                                } else {
1124 1043 nbrodin
                                        int[] newStepBuffer = new int[]{0, initYBuffer, stepBuffer[2], initYBuffer + buf.getBlockHeight()};
1125 1678 nbrodin
                                        int[] newWindow = new int[]{inputWindow[0], initYSrc, inputWindow[2], stepYSrc};
1126 1032 nbrodin
                                        readData(buf,
1127
                                                        bandList,
1128 1678 nbrodin
                                                        newWindow,
1129 1032 nbrodin
                                                        bufWidth, buf.getBlockHeight(), 0, 0, newStepBuffer);
1130 1678 nbrodin
                                        initYSrc += stepYSrc;
1131 1043 nbrodin
                                        initYBuffer += buf.getBlockHeight();
1132 1032 nbrodin
                                }
1133
                        }
1134
                } else {
1135
                        readData(buf, bandList, inputWindow, bufWidth, bufHeight, 0, 0, stepBuffer);
1136
                }
1137
        }
1138 488 nbrodin
1139
        /**
1140 1032 nbrodin
         * Lee una ventana de datos. Esta funci?n es usuada por
1141 488 nbrodin
         * 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 1032 nbrodin
         * @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 488 nbrodin
         * parte de ellos.
1156 1032 nbrodin
         * @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 488 nbrodin
         * parte de ellos.
1159
         * @param stepBuffer El buffer puede empezar a escribirse a partir de un pixel determinado y acabar de escribir antes
1160 1032 nbrodin
         * de fin de buffer. Este par?metro indica el desplazamiento desde el inicio del buffer y la posici?n final.
1161 488 nbrodin
         * <UL>
1162
         * <LI>stepBuffer[0]:Desplazamiento en X desde el inicio</LI>
1163
         * <LI>stepBuffer[1]:Desplazamiento en Y desde el inicio</LI>
1164 1032 nbrodin
         * <LI>stepBuffer[2]:Posici?n X final m?s uno</LI>
1165
         * <LI>stepBuffer[3]:Posici?n Y final m?s uno</LI>
1166 488 nbrodin
         * </UL>
1167
         * @throws GdalException
1168
         */
1169 1032 nbrodin
        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 488 nbrodin
1178 1419 nbrodin
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
1179 620 nbrodin
                FileUtils fUtil = RasterLocator.getManager().getFileUtils();
1180
1181 488 nbrodin
                GdalBuffer gdalBuf = null;
1182
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1183 620 nbrodin
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1184 488 nbrodin
                        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 1032 nbrodin
                        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 937 nbrodin
                        if(dataType[iBand] == Gdal.GDT_Byte) {
1197 2305 nbrodin
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1198 1032 nbrodin
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1199 2305 nbrodin
                                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col ++) {
1200 488 nbrodin
                                                for (int i = 0; i < drawableBands.length; i++)
1201
                                                        buf.setElem(line, col, drawableBands[i], gdalBuf.buffByte[pos]);
1202
                                                pos ++;
1203
                                        }
1204 1032 nbrodin
                                        lineInputWindow ++;
1205 488 nbrodin
                                        if(task.getEvent() != null)
1206
                                                task.manageEvent(task.getEvent());
1207
                                }
1208 1054 nbrodin
                                gdalBuf.buffByte = null;
1209 1015 nbrodin
                        } else if((dataType[iBand] == Gdal.GDT_UInt16) || (dataType[iBand] == Gdal.GDT_Int16) || (dataType[iBand] == Gdal.GDT_CInt16)) {
1210 488 nbrodin
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1211 1032 nbrodin
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1212 488 nbrodin
                                        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 1032 nbrodin
                                        lineInputWindow ++;
1218 488 nbrodin
                                        if(task.getEvent() != null)
1219
                                                task.manageEvent(task.getEvent());
1220
                                }
1221 1054 nbrodin
                                gdalBuf.buffShort = null;
1222 1015 nbrodin
                        } else if((dataType[iBand] == Gdal.GDT_UInt32) || (dataType[iBand] == Gdal.GDT_Int32) || (dataType[iBand] == Gdal.GDT_CInt32)) {
1223 488 nbrodin
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1224 1032 nbrodin
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1225 488 nbrodin
                                        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 1032 nbrodin
                                        lineInputWindow ++;
1231 488 nbrodin
                                        if(task.getEvent() != null)
1232
                                                task.manageEvent(task.getEvent());
1233
                                }
1234 1054 nbrodin
                                gdalBuf.buffInt = null;
1235 1015 nbrodin
                        } else if(dataType[iBand] == Gdal.GDT_Float32) {
1236 488 nbrodin
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1237 1032 nbrodin
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1238 488 nbrodin
                                        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 1032 nbrodin
                                        lineInputWindow ++;
1244 488 nbrodin
                                        if(task.getEvent() != null)
1245
                                                task.manageEvent(task.getEvent());
1246
                                }
1247 1054 nbrodin
                                gdalBuf.buffFloat = null;
1248 1015 nbrodin
                        } else if(dataType[iBand] == Gdal.GDT_Float64) {
1249 488 nbrodin
                                for (int line = stepBuffer[1]; line < stepBuffer[3]; line++) {
1250 1032 nbrodin
                                        pos = (int)((bufWidth * (lineInputWindow - stepBuffer[0])) + init);
1251 488 nbrodin
                                        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 1032 nbrodin
                                        lineInputWindow ++;
1257 488 nbrodin
                                        if(task.getEvent() != null)
1258
                                                task.manageEvent(task.getEvent());
1259
                                }
1260 1054 nbrodin
                                gdalBuf.buffDouble = null;
1261 488 nbrodin
                        }
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 1419 nbrodin
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
1281 620 nbrodin
                FileUtils fUtil = RasterLocator.getManager().getFileUtils();
1282 488 nbrodin
1283
                for(int iBand = 0; iBand < gdalBands.length; iBand++) {
1284 620 nbrodin
                        int[] drawableBands = bandList.getBufferBandToDraw(fUtil.getFormatedRasterFileName(fileName), iBand);
1285 488 nbrodin
                        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 1054 nbrodin
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 488 nbrodin
1447 1054 nbrodin
                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 488 nbrodin
}
1457
1458
1459