Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / BufferFactory.java @ 16539

History | View | Annotate | Download (28.3 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.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
 * Clase que representa a una rejilla de datos que tiene como fuente
40
 * un RasterMultifile. Tiene m?todos para a?adir nuevos ficheros fuente a la
41
 * rejilla que podr?n ser consultados como bandas de uno solo. Estos deber?an tener
42
 * la misma extensi?n que el primero introducido.
43
 * </P>
44
 * <P>
45
 * Para la carga del buffer de datos habr? que asigna las bandas que queremos cargar
46
 * de todas las disponibles con addDrawableBands. Despu?s se seleccionar? el ?rea
47
 * que queremos cargar con setAreaOfInterest. Este ?rea se define con coordenadas
48
 * pixel o reales. Finalmente podemos recuperar el buffer con los datos usando la
49
 * funci?n getRasterBuf.
50
 * </P>
51
 * @author Nacho Brodin (nachobrodin@gmail.com)
52
 *
53
 */
54
public class BufferFactory {
55
        private IRasterDataSource                 mDataset = null;
56
        private IBuffer                                        rasterBuf = null;
57
        private int                                                width = 0;
58
        private int                                                height = 0;
59
        private boolean                                        adjustToExtent = true;
60

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

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

    
85
        /**
86
         * Constructor
87
         */
88
        public BufferFactory() {}
89

    
90
        /**
91
         * Constructor
92
         * @param MultiRasterDataset
93
         */
94
        public BufferFactory(IRasterDataSource rmd) {
95
                mDataset = rmd;
96
                width = (int)rmd.getWidth();
97
                height = (int)rmd.getHeight();
98
        }
99

    
100
        /**
101
         * Constructor
102
         * @param grf Lista de geoRasterFile
103
         */
104
        public BufferFactory(RasterDataset[] grf) {
105
                for(int i = 0; i< grf.length; i++)
106
                        addFile(grf[i]);
107
        }
108

    
109
        /**
110
         * Constructor
111
         * @param grf GeoRasterFile
112
         */
113
        public BufferFactory(RasterDataset grf) {
114
                addFile(grf);
115
        }
116

    
117
        /**
118
         * A?ade un MultiRasterDataset al Grid
119
         * @param grf MultiRasterDataset a a?adir
120
         */
121
        public void addFile(RasterDataset grf) {
122
                if(mDataset == null)
123
                        mDataset = new MultiRasterDataset();
124
                try{
125
                        mDataset.addDataset(new RasterDataset[]{grf});
126
                        width = grf.getWidth();
127
                        height = grf.getHeight();
128
                }catch(FileNotFoundInListException e) {
129
                        //El fichero est? en la lista por lo que no lo a?adimos
130
                }
131
        }
132

    
133
        /**
134
         * A?ade un GeoRasterFile al Grid
135
         * @param fileName Nombre del fichero a a?adir
136
         * @throws NotSupportedExtensionException
137
         * @throws RasterDriverException
138
         */
139
        public void addFile(String filename) throws NotSupportedExtensionException, RasterDriverException{
140
                try{
141
                        mDataset.addDataset(new String[]{filename});
142
                        width = (int)mDataset.getWidth();
143
                        height = (int)mDataset.getHeight();
144
                }catch(FileNotFoundInListException e) {
145
                        //El fichero est? en la lista por lo que no lo a?adimos
146
                }
147
        }
148

    
149
        /**
150
         * Elimina un GeoRasterFile del Grid
151
         * @param grf GeoRasterFile a eliminar
152
         */
153
        public void removeFile(RasterDataset grf) {
154
                mDataset.removeDataset(grf);
155
        }
156

    
157
        /**
158
         * Elimina un GeoRasterFile del Grid
159
         * @param fileName Nombre del fichero a eliminar su GeoRasterFile
160
         */
161
        public void removeFile(String fileName) {
162
                mDataset.removeDataset(fileName);
163
        }
164

    
165
        /**
166
         * Obtiene el n?mero de ficheros del que est? compuesta la fuente de datos.
167
         * @return
168
         */
169
        public int getFileCount() {
170
                return  mDataset.getDatasetCount();
171
        }
172

    
173
        /**
174
         * Obtiene la estructura que contiene la lista de ficheros del Grid
175
         * @return GeoRasterMultiFile
176
         */
177
        public IRasterDataSource getDataSource() {
178
                return mDataset;
179
        }
180

    
181
        /**
182
         * Libera el buffer de memoria
183
         */
184
        public void free() {
185
                rasterBuf.free();
186
                rasterBuf = null;
187
                mDataset = null;
188
        }
189

    
190
        /**
191
         * Resetea la asignaci?n de dibujado de las bandas de la imagen
192
         * sobre el DataImage cuando se hace un update para esta banda.
193
         */
194
        public void clearDrawableBand() {
195
                for(int i = 0; i < mDataset.getDatasetCount(); i++)
196
                        mDataset.getBands().clearDrawableBands();
197
                palette = null;
198
        }
199

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

    
213
                int[] files = new int[drawableBands.length];
214
                palette = new ColorTable[drawableBands.length];
215

    
216
                for(int i = 0; i< drawableBands.length; i++) {
217
                        if(drawableBands[i] < 0 || drawableBands[i] >= mDataset.getBandCount())
218
                                continue;
219
                        mDataset.addDrawableBand(i, drawableBands[i]);
220
                        String fileName = mDataset.getBands().getBand(drawableBands[i]).getFileName();
221
                        files[i] = mDataset.getBands().getFileNumber(fileName);
222
                        palette[i] = mDataset.getColorTable(fileName);
223
                }
224
                return files;
225
        }
226

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

    
246
                for(int i = 0; i< mDataset.getBandCount(); i++) {
247
                        mDataset.addDrawableBand(i, i);
248
                        String fileName = mDataset.getBands().getBand(i).getFileName();
249
                        files[i] = mDataset.getBands().getFileNumber(fileName);
250
                        palette[i] = mDataset.getColorTable(fileName);
251
                }
252
                return files;
253
        }
254

    
255
        /**
256
         * Obtiene el array que contiene el orden de bandas. Cada posici?n del vector es una banda
257
         * del rasterBuf y el contenido de esa posici?n es la banda de la imagen que se dibujar?
258
         * sobre ese RasterBuf.
259
         * @return Array de enteros con el orden de las badas
260
         */
261
        public int[] getDrawableBands() {
262
                return mDataset.getBands().getDrawableBands();
263
        }
264

    
265
        /**
266
         * Asigna el ?rea de interes en coordenadas del mundo real. Si las coordenadas exceden del tama?o de la imagen
267
         * estas coordenadas son ajustadas el extent.
268
         * @param x Coordenada X, esquina superior izquierda
269
         * @param y Coordenada Y, esquina superior izquierda
270
         * @param w Ancho del ?rea
271
         * @param h Alto del ?rea
272
         * @throws ArrayIndexOutOfBoundsException
273
         * @throws InvalidSetViewException 
274
         */
275
        public void setAreaOfInterest(double x, double y, double w, double h)
276
                throws ArrayIndexOutOfBoundsException, InvalidSetViewException, InterruptedException {
277
                dataExtent = new Extent(x, y, x + w, y - h);
278

    
279
                Extent adjustedDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, mDataset.getAffineTransform(), new Dimension((int)mDataset.getWidth(), (int)mDataset.getHeight()));
280
                
281
                rasterBuf = mDataset.getWindowRaster(adjustedDataExtent.getMin().getX(), adjustedDataExtent.getMax().getY(), adjustedDataExtent.width(), adjustedDataExtent.height(), adjustToExtent);
282
        }
283

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

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

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

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

    
360
                int copyX = (int)Math.abs(endPxX - initPxX);
361
                int copyY = (int)Math.abs(endPxY - initPxY);
362

    
363
                rasterBuf = mDataset.getWindowRaster(wcXInit, wcYEnd, wcXEnd, wcYInit, copyX, copyY, true);
364
                IBuffer buf = RasterBuffer.getBuffer(mDataset.getDataType()[0], bufWidth, bufHeight, rasterBuf.getBandCount(), true);
365
                buf.setNoDataValue(noDataValue);
366
                for(int i = 0; i < buf.getBandCount(); i++) {
367
                        switch(buf.getDataType()) {
368
                        case IBuffer.TYPE_BYTE:buf.assign(i, rasterBuf.getByteNoDataValue());break;
369
                        case IBuffer.TYPE_SHORT:buf.assign(i, rasterBuf.getShortNoDataValue());break;
370
                        case IBuffer.TYPE_INT:buf.assign(i, rasterBuf.getIntNoDataValue());break;
371
                        case IBuffer.TYPE_FLOAT:buf.assign(i, rasterBuf.getFloatNoDataValue());break;
372
                        case IBuffer.TYPE_DOUBLE:buf.assign(i, rasterBuf.getNoDataValue());break;
373
                        }
374
                }        
375

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

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

    
472
                dataExtent = new Extent(mDataset.rasterToWorld(new Point2D.Double(x, y)),
473
                                                                mDataset.rasterToWorld(new Point2D.Double(x + w, y + h)));
474
                rasterBuf = mDataset.getWindowRaster(x, y, w, h);
475
        }
476

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

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

    
513
                dataExtent = new Extent(mDataset.rasterToWorld(new Point2D.Double(x, y)),
514
                                                                mDataset.rasterToWorld(new Point2D.Double(x + w, y + h)));
515

    
516
                rasterBuf = mDataset.getWindowRaster(x, y, w, h, bufWidth, bufHeight);
517
        }
518

    
519
        /**
520
         * Obtiene el tipo de datos del grid.
521
         * @return entero que representa el tipo de dato de las celdas del grid.
522
         */
523
        public int getDataType() {
524
                return mDataset.getDataType()[0];
525
        }
526

    
527
        /**
528
         * Obtiene la altura del grid.
529
         * @return altura en celdas del grid.
530
         */
531
        public int getHeight() {
532
                return height;
533
        }
534

    
535
        /**
536
         * Obtiene la anchura del grid.
537
         * @return anchura en celdas del grid.
538
         */
539
        public int getWidth() {
540
                return width;
541
        }
542

    
543
        /**
544
         * Tama?o de celda en X
545
         * @return
546
         */
547
        public double getXCellSize() {
548
                try {
549
                        Extent e = mDataset.getExtent();
550
                        double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
551
                        return dCellsize;
552
                } catch (NullPointerException e) {
553
                        return 0;
554
                }
555
        }
556

    
557
        /**
558
         * Tama?o de celda en Y
559
         * @return
560
         */
561
        public double getYCellSize() {
562
                return 0;
563
        }
564

    
565
        /**
566
         * Devuelve true si la celda contiene un valor de NODATA
567
         * @param x        coordenada X
568
         * @param y coordenada Y
569
         * @return
570
         */
571
        public boolean isNoData(int x, int y, int band) {
572
                return false;
573
        }
574

    
575
        public void setNoDataValue(double dNoDataValue) {
576
                if(rasterBuf instanceof RasterBuffer)
577
                        ((RasterBuffer)rasterBuf).setNoDataValue(dNoDataValue);
578
        }
579

    
580
        public double getNoDataValue() {
581
                if(rasterBuf instanceof RasterBuffer)
582
                        return ((RasterBuffer)rasterBuf).getNoDataValue();
583
                return 0D;
584
        }
585

    
586
        /**
587
         * Asigna tipo de datos del raster
588
         * @see java.awt.image.DataBuffer
589
         */
590
        public void setDataType(int dt) {
591

    
592
        }
593

    
594
        /**
595
         * Obtiene el n?mero de bandas
596
         * @return N?mero de bandas
597
         */
598
        public int getBandCount() {
599
                if(rasterBuf != null)
600
                        return rasterBuf.getBandCount();
601
                else
602
                        return this.getDataSource().getBandCount();
603
        }
604

    
605
        /**
606
         * Obtiene el buffer de datos del grid
607
         * @return RasterBuf
608
         */
609
        public IBuffer getRasterBuf() {
610
                return rasterBuf;
611
        }
612

    
613
        /**
614
         * Evalua si una coordenada pixel cae dentro de la imagen.
615
         * @param x coordenada pixel X
616
         * @param y coordenada pixel Y
617
         */
618
        public boolean isPixelInGrid(int x, int y) {
619
                return (x >= 0 && y >= 0 && x <= getWidth() && y <= getHeight());
620
        }
621

    
622
        /**
623
         * Extent de todo el raster asociado a la fuente de datos.
624
         */
625
        public Extent getExtent() {
626
                return mDataset.getExtent();
627
        }
628

    
629
        /**
630
         * Obtiene un buffer desde la posici?n x,y en pixeles de ancho w y alto h
631
         * @param x Coordenada x de la esquina superior izquierda
632
         * @param y Coordenada y de la esquina superior izquierda
633
         * @param w Ancho del grid
634
         * @param h Alto del grid
635
         * @return Buffer de datos
636
         */
637
        public RasterBuffer getData(int x, int y, int w, int h) {
638
                return null;
639
        }
640

    
641
        /**
642
         * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
643
         * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
644
         * que se hayan aplicado sobre el/los dataset.
645
         * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
646
         * solicitada.
647
         */
648
        public Extent getLastSelectedView() {
649
                return mDataset.getLastSelectedView();
650
        }
651

    
652
        /**
653
         * Obtiene el extent correspondiente a los datos cargados en el buffer
654
         * @return Extent
655
         */
656
        public Extent getDataExtent() {
657
                return dataExtent;
658
        }
659

    
660
        /**
661
         * Obtiene la lista de paletas asociadas a las bandas cargadas en el DataSource
662
         * @return Lista con las paletas o null si no hay ninguna asocida. Un nulo en una
663
         * posici?n del array tambi?n indicar? que para esa banda no hay paletas asociadas.
664
         */
665
        public ColorTable[] getColorTables() {
666
                return palette;
667
        }
668

    
669
        /**
670
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
671
         * @return true si est? georreferenciada y false si no lo est?.
672
         */
673
        public boolean isGeoreferenced() {
674
                return mDataset.isGeoreferenced();
675
        }
676

    
677
        /**
678
         * Consulta el flag de supersampleo en la carga del buffer.
679
         * <P>
680
         * Si este flag es false
681
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la
682
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos
683
         * en el ?rea.
684
         * </P>
685
         * <P>
686
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe
687
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta
688
         * variable es true el buffer lo generar? de 500x400.
689
         * </P>
690
         *
691
         * @return true si el supersampleo en la carga del buffer est? activado y false si no lo est?.
692
         */
693
        public boolean isSupersamplingLoadingBuffer() {
694
                return supersamplingLoadingBuffer;
695
        }
696

    
697
        /**
698
         * Activa o desactiva el supersampling en la carga del buffer.
699
         * <P>
700
         * Si este flag es false
701
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la
702
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos
703
         * en el ?rea.
704
         * </P>
705
         * <P>
706
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe
707
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta
708
         * variable es true el buffer lo generar? de 500x400.
709
         * </P>
710
         *
711
         * @param supersamplingLoadingBuffer true o false para activar o desactivar el supersampling en la
712
         * carga del buffer.
713
         */
714
        public void setSupersamplingLoadingBuffer(boolean supersamplingLoadingBuffer) {
715
                this.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
716
        }
717

    
718
        public double getNHeight() {
719
                return nHeight;
720
        }
721

    
722
        public double getNWidth() {
723
                return nWidth;
724
        }
725

    
726
        /**
727
         * Obtiene el flag que ajusta el extent de la petici?n al del raster. Si est? a
728
         * true en caso de que el extent de la petici?n sea mayor lo ajustar? a los limites
729
         * de este. Si est? a false no lo ajustar? rellenando los valores con NoData. Por defecto
730
         * estar? a true.
731
         * @return true si ajusta y false si no lo hace
732
         */
733
        public boolean isAdjustToExtent() {
734
                return adjustToExtent;
735
        }
736

    
737
        /**
738
         * Asigna el flag que ajusta el extent de la petici?n al del raster. Si est? a
739
         * true en caso de que el extent de la petici?n sea mayor lo ajustar? a los limites
740
         * de este. Si est? a false no lo ajustar? rellenando los valores con NoData
741
         * @param adjustToExtent true para ajustar y false si no queremos que lo haga. Por defecto
742
         * estar? a true.
743
         */
744
        public void setAdjustToExtent(boolean adjustToExtent) {
745
                this.adjustToExtent = adjustToExtent;
746
        }
747
        
748
        /**
749
         * Asigna el valor noData con el que se rellenan las celdas cuando se hace una petici?n
750
         * en la que no se quiere que se ajuste al ?rea del raster. Por defecto noData tendr? el valor
751
         * que aparece en IBuffer.
752
         * @param noData
753
         */
754
        public void setNoDataToFill(double noData) {
755
                this.noDataValue = noData;
756
        }
757

    
758
        /**
759
         * Consulta si el buffer siguiente a pedir es de solo lectura o lectura y escritura.
760
         * La asignaci?n del flag de solo lectura a true debe hacerse para cada consulta.
761
         * @return true si la siguiente carga de buffer se hace de solo lectura y false si es de lectura/escritura 
762
         */
763
        public boolean isReadOnly() {
764
                if(mDataset != null)
765
                        return mDataset.isReadOnly();
766
                return false;
767
        }
768
        
769
        /**
770
         * Asigna el flag que dice si la carga del siguiente buffer es de solo lectura o lectura/escritura.
771
         * La asignaci?n del flag de solo lectura a true debe hacerse para cada consulta.
772
         * @param readOnly true si la siguiente carga de buffer se hace de solo lectura y false si es de lectura/escritura
773
         */
774
        public void setReadOnly(boolean readOnly) {
775
                if(mDataset != null)
776
                        mDataset.setReadOnly(readOnly);
777
        }
778
        
779
        /**
780
         * Asigna el flag que dice si la carga del siguiente buffer es en memoria
781
         * @param memory true si la siguiente carga de buffer se hace en memoria y false se deja decidir al dataset 
782
         * el tipo de buffer
783
         */
784
        public void setMemoryBuffer(boolean readOnly) {
785
                if(mDataset != null)
786
                        mDataset.setMemoryBuffer(readOnly);
787
        }
788
}
789