Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / BufferFactory.java @ 20119

History | View | Annotate | Download (26.8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.buffer;
20

    
21

    
22
import java.awt.Dimension;
23
import java.awt.geom.Point2D;
24

    
25
import org.gvsig.raster.dataset.FileNotFoundInListException;
26
import org.gvsig.raster.dataset.IBuffer;
27
import org.gvsig.raster.dataset.IRasterDataSource;
28
import org.gvsig.raster.dataset.InvalidSetViewException;
29
import org.gvsig.raster.dataset.MultiRasterDataset;
30
import org.gvsig.raster.dataset.NotSupportedExtensionException;
31
import org.gvsig.raster.dataset.RasterDataset;
32
import org.gvsig.raster.dataset.io.RasterDriverException;
33
import org.gvsig.raster.datastruct.ColorTable;
34
import org.gvsig.raster.datastruct.Extent;
35
import org.gvsig.raster.util.RasterUtilities;
36

    
37
/**
38
 * <P>
39
 * Factoria de buffers de datos. Esta clase devuelve al usuario buffers cargados con datos
40
 * a partir de uno o varios datasets y unos par?metros de selecci?n de ?rea.
41
 * </P>
42
 * <P>
43
 * Para la carga del buffer de datos habr? que asigna las bandas que queremos cargar
44
 * de todas las disponibles con addDrawableBands. Despu?s se seleccionar? el ?rea
45
 * que queremos cargar con setAreaOfInterest. Este ?rea se define con coordenadas
46
 * pixel o reales. Finalmente podemos recuperar el buffer con los datos usando la
47
 * funci?n getRasterBuf.
48
 * </P>
49
 * @author Nacho Brodin (nachobrodin@gmail.com)
50
 *
51
 */
52
public class BufferFactory {
53
        private IRasterDataSource                 mDataset = null;
54
        private IBuffer                                        rasterBuf = null;
55
        private boolean                                        adjustToExtent = true;
56

    
57
        /**
58
         * Extensi?n de los datos del buffer
59
         */
60
        private Extent                                        dataExtent = null;
61
        /**
62
         * Lista de paletas asociadas a las bandas cargadas en el DataSource. Estas son calculadas
63
         * en las funciones que asignan las bandas a dibujar (addDrawableBands)
64
         */
65
        private ColorTable[]                        palette = null;
66
        /**
67
         * Activa o desactiva el supersampleo en la carga del buffer.
68
         */
69
        private boolean                                        supersamplingLoadingBuffer = true;
70

    
71
        /**
72
         * Ancho y alto en pixeles del ?ltimo buffer asignado
73
         */
74
        private double                                         nWidth = 0;
75
        private double                                         nHeight = 0;
76
        /**
77
         * Valor NoData con el que se rellenan las celdas cuando adjustToExtent es false
78
         */
79
        private double                  noDataValueToFill = -99999;
80

    
81
        /**
82
         * Constructor
83
         */
84
        public BufferFactory() {}
85

    
86
        /**
87
         * Constructor
88
         * @param MultiRasterDataset
89
         */
90
        public BufferFactory(IRasterDataSource rmd) {
91
                mDataset = rmd;
92
        }
93

    
94
        /**
95
         * Constructor
96
         * @param grf Lista de geoRasterFile
97
         */
98
        public BufferFactory(RasterDataset[] grf) {
99
                for(int i = 0; i< grf.length; i++)
100
                        addFile(grf[i]);
101
        }
102

    
103
        /**
104
         * Constructor
105
         * @param grf GeoRasterFile
106
         */
107
        public BufferFactory(RasterDataset grf) {
108
                addFile(grf);
109
        }
110

    
111
        /**
112
         * A?ade un MultiRasterDataset al Grid
113
         * @param grf MultiRasterDataset a a?adir
114
         */
115
        public void addFile(RasterDataset grf) {
116
                if(mDataset == null)
117
                        mDataset = new MultiRasterDataset();
118
                try{
119
                        mDataset.addDataset(new RasterDataset[]{grf});
120
                }catch(FileNotFoundInListException e) {
121
                        //El fichero est? en la lista por lo que no lo a?adimos
122
                }
123
        }
124

    
125
        /**
126
         * A?ade un GeoRasterFile al Grid
127
         * @param fileName Nombre del fichero a a?adir
128
         * @throws NotSupportedExtensionException
129
         * @throws RasterDriverException
130
         */
131
        public void addFile(String filename) throws NotSupportedExtensionException, RasterDriverException{
132
                try{
133
                        mDataset.addDataset(new String[]{filename});
134
                }catch(FileNotFoundInListException e) {
135
                        //El fichero est? en la lista por lo que no lo a?adimos
136
                }
137
        }
138

    
139
        /**
140
         * Elimina un GeoRasterFile del Grid
141
         * @param grf GeoRasterFile a eliminar
142
         */
143
        public void removeFile(RasterDataset grf) {
144
                mDataset.removeDataset(grf);
145
        }
146

    
147
        /**
148
         * Elimina un GeoRasterFile del Grid
149
         * @param fileName Nombre del fichero a eliminar su GeoRasterFile
150
         */
151
        public void removeFile(String fileName) {
152
                mDataset.removeDataset(fileName);
153
        }
154

    
155
        /**
156
         * Obtiene el n?mero de ficheros del que est? compuesta la fuente de datos.
157
         * @return
158
         */
159
        public int getFileCount() {
160
                return  mDataset.getDatasetCount();
161
        }
162

    
163
        /**
164
         * Obtiene la estructura que contiene la lista de ficheros del Grid
165
         * @return GeoRasterMultiFile
166
         */
167
        public IRasterDataSource getDataSource() {
168
                return mDataset;
169
        }
170

    
171
        /**
172
         * Libera el buffer de memoria
173
         */
174
        public void free() {
175
                if(rasterBuf != null) {
176
                        rasterBuf.free();
177
                        rasterBuf = null;
178
                }
179
                mDataset = null;
180
        }
181

    
182
        /**
183
         * Resetea la asignaci?n de dibujado de las bandas de la imagen
184
         * sobre el DataImage cuando se hace un update para esta banda.
185
         */
186
        public void clearDrawableBand() {
187
                for(int i = 0; i < mDataset.getDatasetCount(); i++)
188
                        mDataset.getBands().clearDrawableBands();
189
                palette = null;
190
        }
191

    
192
        /**
193
         * Para este GeoRasterFile asigna que bandas se pintaran
194
         * sobre el RasterBuf cuando se haga un update. Cada posici?n del vector es una banda
195
         * del rasterBuf y el contenido de esa posici?n es la banda de la imagen que se dibujar?
196
         * sobre ese RasterBuf.
197
         * @param drawableBands        Array con las bandas a dibujar.
198
         * @return array con tantos elementos como bandas a dibujar. El valor contenido es el fichero del
199
         * dataset multifichero al que corresponde la banda.
200
         */
201
        public int[] setDrawableBands(int[] drawableBands) {
202
                clearDrawableBand();
203
                mDataset.setDrawableBands(drawableBands);
204

    
205
                int[] files = new int[drawableBands.length];
206
                palette = new ColorTable[drawableBands.length];
207

    
208
                for(int i = 0; i< drawableBands.length; i++) {
209
                        if(drawableBands[i] < 0 || drawableBands[i] >= mDataset.getBandCount())
210
                                continue;
211
                        mDataset.addDrawableBand(i, drawableBands[i]);
212
                        String fileName = mDataset.getBands().getBand(drawableBands[i]).getFileName();
213
                        files[i] = mDataset.getBands().getFileNumber(fileName);
214
                        palette[i] = mDataset.getColorTable(fileName);
215
                }
216
                return files;
217
        }
218

    
219
        /**
220
         * Para este GeoRasterFile asigna que bandas se pintaran
221
         * sobre el RasterBuf cuando se haga un update. Cada posici?n del vector es una banda
222
         * del rasterBuf y el contenido de esa posici?n es la banda de la imagen que se dibujar?
223
         * sobre ese RasterBuf. Esta llamada asigna todas las bandas dibujables en su orden natural.
224
         * @return array con tantos elementos como bandas a dibujar. El valor contenido es el fichero del
225
         * dataset multifichero al que corresponde la banda.
226
         */
227
        public int[] setAllDrawableBands() {
228
                clearDrawableBand();
229
                
230
                int[] list = new int[mDataset.getBandCount()];
231
                for(int i = 0; i< mDataset.getBandCount(); i++)
232
                        list[i] = i;
233
                mDataset.setDrawableBands(list);
234
                
235
                int[] files = new int[mDataset.getBandCount()];
236
                palette = new ColorTable[mDataset.getBandCount()];
237

    
238
                for(int i = 0; i< mDataset.getBandCount(); i++) {
239
                        mDataset.addDrawableBand(i, i);
240
                        String fileName = mDataset.getBands().getBand(i).getFileName();
241
                        files[i] = mDataset.getBands().getFileNumber(fileName);
242
                        palette[i] = mDataset.getColorTable(fileName);
243
                }
244
                return files;
245
        }
246

    
247
        /**
248
         * Obtiene el array que contiene el orden de bandas. Cada posici?n del vector es una banda
249
         * del rasterBuf y el contenido de esa posici?n es la banda de la imagen que se dibujar?
250
         * sobre ese RasterBuf.
251
         * @return Array de enteros con el orden de las badas
252
         */
253
        public int[] getDrawableBands() {
254
                return mDataset.getBands().getDrawableBands();
255
        }
256

    
257
        /**
258
         * Asigna el ?rea de interes en coordenadas del mundo real. Si las coordenadas exceden del tama?o de la imagen
259
         * estas coordenadas son ajustadas el extent.
260
         * @param x Coordenada X, esquina superior izquierda
261
         * @param y Coordenada Y, esquina superior izquierda
262
         * @param w Ancho del ?rea
263
         * @param h Alto del ?rea
264
         * @throws ArrayIndexOutOfBoundsException
265
         * @throws InvalidSetViewException 
266
         */
267
        public void setAreaOfInterest(double x, double y, double w, double h)
268
                throws RasterDriverException, InvalidSetViewException, InterruptedException {
269
                dataExtent = new Extent(x, y, x + w, y - h);
270

    
271
                Extent adjustedDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, mDataset.getAffineTransform(), new Dimension((int)mDataset.getWidth(), (int)mDataset.getHeight()));
272
                
273
                rasterBuf = mDataset.getWindowRaster(adjustedDataExtent.getMin().getX(), adjustedDataExtent.getMax().getY(), adjustedDataExtent.width(), adjustedDataExtent.height(), adjustToExtent);
274
        }
275

    
276
        /**
277
         * Asigna el ?rea de interes en coordenadas del mundo real. Si las coordenadas exceden del tama?o de la imagen
278
         * estas coordenadas son ajustadas el extent.
279
         * @param x Coordenada X, esquina superior izquierda
280
         * @param y Coordenada Y, esquina superior izquierda
281
         * @param w Ancho del ?rea
282
         * @param h Alto del ?rea
283
         * @param bufWidth Ancho del buffer
284
         * @param bufHeight Alto del buffer
285
         * @return En caso de que el buffer sea mayor que el tama?o seleccionado de raster se produce supersampleo. La funci?n devuelve
286
         * un array de dos elementos que representan el desplazamiento en pixels de X e Y de la esquina superior izquierda.
287
         * @throws ArrayIndexOutOfBoundsException
288
         * @throws InvalidSetViewException 
289
         */
290
        public double[] setAreaOfInterest(double ulx, double uly, double lrx, double lry, int bufWidth, int bufHeight)
291
                throws RasterDriverException, InvalidSetViewException, InterruptedException {
292
                dataExtent = new Extent(ulx, uly, lrx, lry);
293
                Extent adjustedDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, mDataset.getAffineTransform(), new Dimension((int)mDataset.getWidth(), (int)mDataset.getHeight()));
294

    
295
                //Caso 3D: La petici?n no se ajusta al ?rea y se rellena el exterior con NoData
296
                if(!adjustToExtent && !RasterUtilities.isInside(dataExtent, mDataset.getExtent())) 
297
                        return requestFillingWithNoData(dataExtent, adjustedDataExtent, bufWidth, bufHeight);
298
                
299
                //Esta secci?n es para que no supersamplee el driver y pueda hacerse en el cliente
300
                if(!isSupersamplingLoadingBuffer()) {
301
                        //nWidth = ((adjustedDataExtent.width() * mDataset.getDataset(0).getWidth()) / mDataset.getExtentForRequest().width());
302
                        //nHeight = ((adjustedDataExtent.height() * mDataset.getDataset(0).getHeight()) / mDataset.getExtentForRequest().height());
303
                        Point2D p1 = mDataset.worldToRaster(new Point2D.Double(adjustedDataExtent.getULX(), adjustedDataExtent.getULY()));
304
                        Point2D p2 = mDataset.worldToRaster(new Point2D.Double(adjustedDataExtent.getLRX(), adjustedDataExtent.getLRY()));
305
                        nWidth = Math.abs(p1.getX() - p2.getX());
306
                        nHeight = Math.abs(p1.getY() - p2.getY());
307

    
308
                        if(bufWidth > Math.ceil(nWidth) && bufHeight > Math.ceil(nHeight)) {
309
                                rasterBuf = mDataset.getWindowRaster(adjustedDataExtent.getULX(), adjustedDataExtent.getULY(), adjustedDataExtent.getLRX(), adjustedDataExtent.getLRY());
310
                                double[] step = mDataset.calcSteps(adjustedDataExtent.getULX(), adjustedDataExtent.getULY(), adjustedDataExtent.getLRX(), adjustedDataExtent.getLRY(), nWidth, nHeight, bufWidth, bufHeight);
311
                                return step;
312
                        }
313
                }
314
                rasterBuf = mDataset.getWindowRaster(adjustedDataExtent.getULX(), adjustedDataExtent.getULY(), adjustedDataExtent.getLRX(), adjustedDataExtent.getLRY(), bufWidth, bufHeight, true /*Siempre ajustado*/);
315
                return null;
316
        }
317
        
318
        /**
319
         * M?todo que crea un buffer con la extensi?n que se ha pedido completa y sin ajustar
320
         * a la extensi?n del raster. La zona que tenga informaci?n del raster se rellenara con 
321
         * esta y la que quede vacia se rellenar? con valores NoData.
322
         * 
323
         * @param rasterBuf Buffer de salida.
324
         * @throws InvalidSetViewException 
325
         */
326
        private double[] requestFillingWithNoData(Extent requestExtent, Extent fitExtent, int bufWidth, int bufHeight) 
327
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
328
                double error = 0.01;
329
                //Upper Left
330
                double distWcX = Math.abs(fitExtent.getMin().getX() - dataExtent.getMin().getX());
331
                distWcX = (distWcX > error) ? distWcX : 0;
332
                double distWcY = Math.abs(fitExtent.getMax().getY() - dataExtent.getMax().getY());
333
                distWcY = (distWcY > error) ? distWcY : 0;
334
                //Pixel inicial del buffer donde se empieza a dibujar. Redondeamos por arriba pq lo que sobra se pone NoData
335
                double initPxX = Math.ceil((distWcX * bufWidth) / requestExtent.width()); 
336
                double initPxY = Math.ceil((distWcY * bufHeight) / requestExtent.height());
337
                //Obtenemos la coordenada real para el pixel inicial
338
                double wcXInit = (requestExtent.minX() < mDataset.getExtent().minX()) ? mDataset.getExtent().minX() : requestExtent.minX();
339
                double wcYInit = (requestExtent.maxY() > mDataset.getExtent().maxY()) ? mDataset.getExtent().maxY() : requestExtent.maxY();
340

    
341
                //Lower Right
342
                distWcX = Math.abs(fitExtent.getMax().getX() - dataExtent.getMin().getX());
343
                distWcX = (distWcX > error) ? distWcX : 0;
344
                distWcY = Math.abs(fitExtent.getMin().getY() - dataExtent.getMax().getY());
345
                distWcY = (distWcY > error) ? distWcY : 0;
346
                //Pixel final del buffer donde se dibuja. Redondeamos por abajo pq lo que sobra se pone NoData
347
                double endPxX = Math.floor((distWcX * bufWidth) / requestExtent.width()); 
348
                double endPxY = Math.floor((distWcY * bufHeight) / requestExtent.height());
349
                //Obtenemos la coordenada real para el pixel
350
                double wcXEnd = (requestExtent.maxX() > mDataset.getExtent().maxX()) ? mDataset.getExtent().maxX() : requestExtent.maxX();
351
                double wcYEnd = (requestExtent.minY() < mDataset.getExtent().minY()) ? mDataset.getExtent().minY() : requestExtent.minY();
352

    
353
                int copyX = (int)Math.abs(endPxX - initPxX);
354
                int copyY = (int)Math.abs(endPxY - initPxY);
355

    
356
                rasterBuf = mDataset.getWindowRaster(wcXInit, wcYEnd, wcXEnd, wcYInit, copyX, copyY, true);
357
                IBuffer buf = RasterBuffer.getBuffer(mDataset.getDataType()[0], bufWidth, bufHeight, rasterBuf.getBandCount(), true);
358
                buf.setNoDataValue(noDataValueToFill);
359
                for(int i = 0; i < buf.getBandCount(); i++) {
360
                        switch(buf.getDataType()) {
361
                        case IBuffer.TYPE_BYTE:buf.assign(i, rasterBuf.getByteNoDataValue());break;
362
                        case IBuffer.TYPE_SHORT:buf.assign(i, rasterBuf.getShortNoDataValue());break;
363
                        case IBuffer.TYPE_INT:buf.assign(i, rasterBuf.getIntNoDataValue());break;
364
                        case IBuffer.TYPE_FLOAT:buf.assign(i, rasterBuf.getFloatNoDataValue());break;
365
                        case IBuffer.TYPE_DOUBLE:buf.assign(i, rasterBuf.getNoDataValue());break;
366
                        }
367
                }        
368

    
369
                switch(rasterBuf.getDataType()) {
370
                case IBuffer.TYPE_BYTE:
371
                        for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
372
                                for (int row = 0; row < copyY; row++) 
373
                                        for (int col = 0; col < copyX; col++) 
374
                                                buf.setElem((int)(row + initPxY), (int)(col + initPxX), 
375
                                                                iBand, 
376
                                                                rasterBuf.getElemByte(row, col, iBand));
377
                        break;
378
                case IBuffer.TYPE_SHORT:
379
                case IBuffer.TYPE_USHORT:
380
                        for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
381
                                for (int row = 0; row < copyY; row++) 
382
                                        for (int col = 0; col < copyX; col++) 
383
                                                buf.setElem((int)(row + initPxY), (int)(col + initPxX), 
384
                                                                iBand, 
385
                                                                rasterBuf.getElemShort(row, col, iBand));
386
                        break;
387
                case IBuffer.TYPE_INT:
388
                        for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
389
                                for (int row = 0; row < copyY; row++) 
390
                                        for (int col = 0; col < copyX; col++) 
391
                                                buf.setElem((int)(row + initPxY), (int)(col + initPxX), 
392
                                                                iBand, 
393
                                                                rasterBuf.getElemInt(row, col, iBand));
394
                        break;
395
                case IBuffer.TYPE_FLOAT:
396
                        for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
397
                                for (int row = 0; row < copyY; row++) 
398
                                        for (int col = 0; col < copyX; col++) 
399
                                                buf.setElem((int)(row + initPxY), (int)(col + initPxX), 
400
                                                                iBand, 
401
                                                                rasterBuf.getElemFloat(row, col, iBand));
402
                        break;
403
                case IBuffer.TYPE_DOUBLE:
404
                        for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++)        
405
                                for (int row = 0; row < copyY; row++) 
406
                                        for (int col = 0; col < copyX; col++) 
407
                                                buf.setElem((int)(row + initPxY), (int)(col + initPxX), 
408
                                                                iBand, 
409
                                                                rasterBuf.getElemDouble(row, col, iBand));
410
                        break;
411
                }
412
                rasterBuf = buf;
413
                return null;
414
        }
415
        
416
        /**
417
         * Dado unas coordenadas reales, un tama?o de buffer y un tama?o de raster. 
418
         * Si el buffer es de mayor tama?o que el raster (supersampleo) quiere decir que 
419
         * por cada pixel de buffer se repiten varios del raster. Esta funci?n calcula el 
420
         * n?mero de pixels de desplazamiento en X e Y que corresponden al primer pixel del
421
         * buffer en la esquina superior izquierda. Esto es necesario porque la coordenada
422
         * solicitada es real y puede no caer sobre un pixel completo. Este calculo es
423
         * util cuando un cliente quiere supersamplear sobre un buffer y que no se lo haga
424
         * el driver autom?ticamente.
425
         * @param dWorldTLX Coordenada real X superior izquierda
426
         * @param dWorldTLY Coordenada real Y superior izquierda
427
         * @param dWorldBRX Coordenada real X inferior derecha
428
         * @param dWorldBRY Coordenada real Y inferior derecha
429
         * @param nWidth Ancho del raster
430
         * @param nHeight Alto del raster
431
         * @param bufWidth Ancho del buffer
432
         * @param bufHeight Alto del buffer
433
         * @return Array de dos elementos con el desplazamiento en X e Y. 
434
         */
435
        public double[] calcSteps(double ulx, double uly, double lrx, double lry, 
436
                        double nWidth, double nHeight, int bufWidth, int bufHeight) {
437
                Point2D p1 = mDataset.worldToRaster(new Point2D.Double(ulx, uly));
438
                Point2D p2 = mDataset.worldToRaster(new Point2D.Double(lrx, lry));
439
                int width = (int)Math.abs(Math.ceil(p2.getX()) - Math.floor(p1.getX())); 
440
                int height = (int)Math.abs(Math.floor(p1.getY()) - Math.ceil(p2.getY()));
441
                Point2D wc1 = mDataset.rasterToWorld(new Point2D.Double(Math.floor(p1.getX()), Math.floor(p1.getY())));
442
                Point2D wc2 = mDataset.rasterToWorld(new Point2D.Double(Math.ceil(p2.getX()), Math.ceil(p2.getY())));
443
                
444
                return mDataset.calcSteps(wc1.getX(), wc1.getY(), wc2.getX(), wc2.getY(), width, height, bufWidth, bufHeight);
445
        }
446

    
447
        /**
448
         * Asigna el ?rea de interes en coordenadas pixel. Si las coordenadas exceden del tama?o de la imagen
449
         * lanza una excepci?n.
450
         * @param x Coordenada X, esquina superior izquierda
451
         * @param y Coordenada Y, esquina superior izquierda
452
         * @param w Ancho del ?rea
453
         * @param h Alto del ?rea
454
         * @throws InvalidSetViewException  
455
         * @throws ArrayIndexOutOfBoundsException
456
         */
457
        public void setAreaOfInterest(int x, int y, int w, int h) 
458
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
459
                if(x > getSourceWidth() || y > getSourceHeight())
460
                        throw new InvalidSetViewException("Par?metros incorrectos en setAreaOfInterest");
461
                x = (x < 0) ? 0 : x;
462
                y = (y < 0) ? 0 : y;
463
                w = (w > getSourceWidth()) ? getSourceWidth() : w;
464
                h = (h > getSourceHeight()) ? getSourceHeight() : h;
465

    
466
                dataExtent = new Extent(mDataset.rasterToWorld(new Point2D.Double(x, y)),
467
                                                                mDataset.rasterToWorld(new Point2D.Double(x + w, y + h)));
468
                rasterBuf = mDataset.getWindowRaster(x, y, w, h);
469
        }
470

    
471
        /**
472
         * Asigna el ?rea de inter?s a toda la extensi?n del raster.
473
         */
474
        public void setAreaOfInterest() 
475
                throws InterruptedException, RasterDriverException {
476
                dataExtent = mDataset.getExtent();
477
                try {
478
                        rasterBuf = mDataset.getWindowRaster(0, 0, (int)mDataset.getWidth(), (int)mDataset.getHeight());
479
                } catch (InvalidSetViewException e) {
480
                        //Esta excepci?n no deber?a darse ya que las coordenadas se asignan autom?ticamente por lo que no
481
                        //tiene sentido lanzarla hacia arriba
482
                        e.printStackTrace();
483
                }
484
        }
485

    
486
        /**
487
         * Asigna el ?rea de interes en coordenadas pixel. Esta operaci?n cargar? un RasterBuffer con los datos solicitados por
488
         * lo que, si al acabar hacemos getRasterBuf obtendremos la matriz de datos. Si las coordenadas exceden del tama?o
489
         * de la imagen lanza una excepci?n.
490
         * @param x Coordenada X, esquina superior izquierda
491
         * @param y Coordenada Y, esquina superior izquierda
492
         * @param w Ancho del ?rea
493
         * @param h Alto del ?rea
494
         * @param bufWidth Ancho del buffer
495
         * @param bufHeight Alto del buffer
496
         * @throws ArrayIndexOutOfBoundsException
497
         */
498
        public void setAreaOfInterest(int x, int y, int w, int h, int bufWidth, int bufHeight)
499
                throws InvalidSetViewException, InterruptedException, RasterDriverException {
500
                if(x > getSourceWidth() || y > getSourceHeight())
501
                        throw new InvalidSetViewException("Par?metros incorrectos en setAreaOfInterest");
502
                
503
                x = (x < 0) ? 0 : x;
504
                y = (y < 0) ? 0 : y;
505
                w = (w > getSourceWidth()) ? getSourceWidth() : w;
506
                h = (h > getSourceHeight()) ? getSourceHeight() : h;
507

    
508
                dataExtent = new Extent(mDataset.rasterToWorld(new Point2D.Double(x, y)),
509
                                                                mDataset.rasterToWorld(new Point2D.Double(x + w, y + h)));
510

    
511
                rasterBuf = mDataset.getWindowRaster(x, y, w, h, bufWidth, bufHeight);
512
        }
513

    
514
        /**
515
         * Obtiene la altura de la fuente de datos.
516
         * @return altura en celdas del grid.
517
         */
518
        public int getSourceHeight() {
519
                return (mDataset != null) ? (int)mDataset.getHeight() : 0;
520
        }
521

    
522
        /**
523
         * Obtiene la anchura de la fuente de datos.
524
         * @return anchura en celdas del grid.
525
         */
526
        public int getSourceWidth() {
527
                return (mDataset != null) ? (int)mDataset.getWidth() : 0;
528
        }
529

    
530
        /**
531
         * Tama?o de celda en X
532
         * @return
533
         */
534
        /*public double getXCellSize() {
535
                try {
536
                        Extent e = mDataset.getExtent();
537
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / getSourceWidth();
538
                        return dCellsize;
539
                } catch (NullPointerException e) {
540
                        return 0;
541
                }
542
        }*/
543

    
544
        /**
545
         * Obtiene el n?mero de bandas
546
         * @return N?mero de bandas
547
         */
548
        public int getBandCount() {
549
                if(rasterBuf != null)
550
                        return rasterBuf.getBandCount();
551
                else
552
                        return this.getDataSource().getBandCount();
553
        }
554

    
555
        /**
556
         * Obtiene el buffer de datos del grid
557
         * @return RasterBuf
558
         */
559
        public IBuffer getRasterBuf() {
560
                if (rasterBuf != null && mDataset != null)
561
                        rasterBuf.setNoDataValue(mDataset.getNoDataValue());
562
                return rasterBuf;
563
        }
564

    
565
        /**
566
         * Obtiene un buffer desde la posici?n x,y en pixeles de ancho w y alto h
567
         * @param x Coordenada x de la esquina superior izquierda
568
         * @param y Coordenada y de la esquina superior izquierda
569
         * @param w Ancho del grid
570
         * @param h Alto del grid
571
         * @return Buffer de datos
572
         */
573
        public RasterBuffer getData(int x, int y, int w, int h) {
574
                return null;
575
        }
576

    
577
        /**
578
         * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
579
         * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
580
         * que se hayan aplicado sobre el/los dataset.
581
         * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
582
         * solicitada.
583
         */
584
        public Extent getLastSelectedView() {
585
                return mDataset.getLastSelectedView();
586
        }
587

    
588
        /**
589
         * Obtiene el extent correspondiente a los datos cargados en el buffer
590
         * @return Extent
591
         */
592
        public Extent getDataExtent() {
593
                return dataExtent;
594
        }
595

    
596
        /**
597
         * Obtiene la lista de paletas asociadas a las bandas cargadas en el DataSource
598
         * @return Lista con las paletas o null si no hay ninguna asocida. Un nulo en una
599
         * posici?n del array tambi?n indicar? que para esa banda no hay paletas asociadas.
600
         */
601
        public ColorTable[] getColorTables() {
602
                return palette;
603
        }
604

    
605
        /**
606
         * Consulta el flag de supersampleo en la carga del buffer.
607
         * <P>
608
         * Si este flag es false
609
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la
610
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos
611
         * en el ?rea.
612
         * </P>
613
         * <P>
614
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe
615
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta
616
         * variable es true el buffer lo generar? de 500x400.
617
         * </P>
618
         *
619
         * @return true si el supersampleo en la carga del buffer est? activado y false si no lo est?.
620
         */
621
        public boolean isSupersamplingLoadingBuffer() {
622
                return supersamplingLoadingBuffer;
623
        }
624

    
625
        /**
626
         * Activa o desactiva el supersampling en la carga del buffer.
627
         * <P>
628
         * Si este flag es false
629
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la
630
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos
631
         * en el ?rea.
632
         * </P>
633
         * <P>
634
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe
635
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta
636
         * variable es true el buffer lo generar? de 500x400.
637
         * </P>
638
         *
639
         * @param supersamplingLoadingBuffer true o false para activar o desactivar el supersampling en la
640
         * carga del buffer.
641
         */
642
        public void setSupersamplingLoadingBuffer(boolean supersamplingLoadingBuffer) {
643
                this.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
644
        }
645

    
646
        /**
647
         * Obtiene el flag que ajusta el extent de la petici?n al del raster. Si est? a
648
         * true en caso de que el extent de la petici?n sea mayor lo ajustar? a los limites
649
         * de este. Si est? a false no lo ajustar? rellenando los valores con NoData. Por defecto
650
         * estar? a true.
651
         * @return true si ajusta y false si no lo hace
652
         */
653
        public boolean isAdjustToExtent() {
654
                return adjustToExtent;
655
        }
656

    
657
        /**
658
         * Asigna el flag que ajusta el extent de la petici?n al del raster. Si est? a
659
         * true en caso de que el extent de la petici?n sea mayor lo ajustar? a los limites
660
         * de este. Si est? a false no lo ajustar? rellenando los valores con NoData
661
         * @param adjustToExtent true para ajustar y false si no queremos que lo haga. Por defecto
662
         * estar? a true.
663
         */
664
        public void setAdjustToExtent(boolean adjustToExtent) {
665
                this.adjustToExtent = adjustToExtent;
666
        }
667
        
668
        /**
669
         * Asigna el valor noData con el que se rellenan las celdas cuando se hace una petici?n
670
         * en la que no se quiere que se ajuste al ?rea del raster. Por defecto noData tendr? el valor
671
         * que aparece en IBuffer.
672
         * @param noData
673
         */
674
        public void setNoDataToFill(double noData) {
675
                this.noDataValueToFill = noData;
676
        }
677

    
678
        /**
679
         * Consulta si el buffer siguiente a pedir es de solo lectura o lectura y escritura.
680
         * La asignaci?n del flag de solo lectura a true debe hacerse para cada consulta.
681
         * @return true si la siguiente carga de buffer se hace de solo lectura y false si es de lectura/escritura 
682
         */
683
        public boolean isReadOnly() {
684
                if(mDataset != null)
685
                        return mDataset.isReadOnly();
686
                return false;
687
        }
688
        
689
        /**
690
         * Asigna el flag que dice si la carga del siguiente buffer es de solo lectura o lectura/escritura.
691
         * La asignaci?n del flag de solo lectura a true debe hacerse para cada consulta.
692
         * @param readOnly true si la siguiente carga de buffer se hace de solo lectura y false si es de lectura/escritura
693
         */
694
        public void setReadOnly(boolean readOnly) {
695
                if(mDataset != null)
696
                        mDataset.setReadOnly(readOnly);
697
        }
698
        
699
        /**
700
         * Asigna el flag que dice si la carga del siguiente buffer es en memoria
701
         * @param memory true si la siguiente carga de buffer se hace en memoria y false se deja decidir al dataset 
702
         * el tipo de buffer
703
         */
704
        public void setMemoryBuffer(boolean readOnly) {
705
                if(mDataset != null)
706
                        mDataset.setMemoryBuffer(readOnly);
707
        }
708
}
709