Statistics
| Revision:

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

History | View | Annotate | Download (28.1 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.NotSupportedExtensionException;
30
import org.gvsig.raster.dataset.RasterDataset;
31
import org.gvsig.raster.dataset.RasterDriverException;
32
import org.gvsig.raster.datastruct.ColorTable;
33
import org.gvsig.raster.datastruct.Extent;
34
import org.gvsig.raster.hierarchy.ICancellable;
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 implements ICancellable {
55

    
56
        public static final int                        CANCEL_READ = 1;
57
        private boolean[]                                cancel = new boolean[1];
58

    
59
        private IRasterDataSource                 mDataset = null;
60
        private IBuffer                                        rasterBuf = null;
61
        private int                                                width = 0;
62
        private int                                                height = 0;
63
        private boolean                                        adjustToExtent = true;
64

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

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

    
89
        /**
90
         * Constructor
91
         */
92
        public BufferFactory() {}
93

    
94
        /**
95
         * Constructor
96
         * @param MultiRasterDataset
97
         */
98
        public BufferFactory(IRasterDataSource rmd) {
99
                mDataset = rmd;
100
                width = (int)rmd.getWidth()[0];
101
                height = (int)rmd.getHeight()[0];
102
        }
103

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

    
113
        /**
114
         * Constructor
115
         * @param grf GeoRasterFile
116
         */
117
        public BufferFactory(RasterDataset grf) {
118
                addFile(grf);
119
        }
120

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

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

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

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

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

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

    
183
        /**
184
         * Libera el buffer de memoria
185
         */
186
        public void free() {
187
                rasterBuf.free();
188
                rasterBuf = null;
189
                System.gc();
190
        }
191

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

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

    
215
                int[] files = new int[drawableBands.length];
216
                palette = new ColorTable[drawableBands.length];
217

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

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

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

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

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

    
275
                Extent adjustedDataExtent = RasterUtilities.calculateAdjustedView(dataExtent, mDataset.getAffineTransform(), new Dimension((int)mDataset.getWidth()[0], (int)mDataset.getHeight()[0]));
276
                
277
                rasterBuf = mDataset.getWindowRaster(adjustedDataExtent.getMin().getX(), adjustedDataExtent.getMax().getY(), adjustedDataExtent.width(), adjustedDataExtent.height(), adjustToExtent);
278
        }
279

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

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

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

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

    
356
                int copyX = (int)Math.abs(endPxX - initPxX);
357
                int copyY = (int)Math.abs(endPxY - initPxY);
358

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

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

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

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

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

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

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

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

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

    
523
        /**
524
         * Obtiene la altura del grid.
525
         * @return altura en celdas del grid.
526
         */
527
        public int getHeight() {
528
                return height;
529
        }
530

    
531
        /**
532
         * Obtiene la anchura del grid.
533
         * @return anchura en celdas del grid.
534
         */
535
        public int getWidth() {
536
                return width;
537
        }
538

    
539
        /**
540
         * Tama?o de celda en X
541
         * @return
542
         */
543
        public double getXCellSize() {
544

    
545
                Extent e = mDataset.getExtent();
546
                double dCellsize = (e.getMax().getX() - e.getMin().getX() ) / (double) width;
547

    
548
                return dCellsize;
549

    
550
        }
551

    
552
        /**
553
         * Tama?o de celda en Y
554
         * @return
555
         */
556
        public double getYCellSize() {
557

    
558
                return 0;
559
        }
560

    
561
        /**
562
         * Devuelve true si la celda contiene un valor de NODATA
563
         * @param x        coordenada X
564
         * @param y coordenada Y
565
         * @return
566
         */
567
        public boolean isNoData(int x, int y, int band) {
568

    
569
                return false;
570

    
571
        }
572

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

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

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

    
590
        }
591

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

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

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

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

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

    
639
        /**
640
         * Obtiene las coordenadas del fichero worldFile (o cabecera del raster) asociado
641
         * o el RMF en caso de que existan. Si la imagen no est? georreferenciada tendr?
642
         * las coordenadas pixel de la misma
643
         * @return Array de seis valores:
644
         *         <TABLE BORDER="1">
645
         *         <TR><TD><B>0:</B></TD><TD>Valor X de la esquina superior izquierda.</TD></TR>
646
         *         <TR><TD><B>1:</B></TD><TD>Tama?o de pixel en X.</TD></TR>
647
         *         <TR><TD><B>2:</B></TD><TD>Shearing en X.</TD></TR>
648
         *         <TR><TD><B>3:</B></TD><TD>Valor Y de la esquina superior izquierda.</TD></TR>
649
         *         <TR><TD><B>4:</B></TD><TD>Shearing en Y.</TD></TR>
650
         *         <TR><TD><B>5:</B></TD><TD>Tama?o de pixel en Y.</TD></TR>
651
         *         </TABLE>
652
         */
653
        /*public AffineTransform getCoordsGeoTransformFile() {
654
                return mDataset.getCoordsGeoTransformFile();
655
        }*/
656

    
657
        /**
658
         * Obtiene el extent de la ?ltima selecci?n hecha con alguna de las llamadas
659
         * setAreaOfInterest. Este extent es devuelto en coordenadas reales con las transformaciones
660
         * que se hayan aplicado sobre el/los dataset.
661
         * @return Extent Coordenadas reales que representan el ?ltimo ?rea de datos
662
         * solicitada.
663
         */
664
        public Extent getLastSelectedView() {
665
                return mDataset.getLastSelectedView();
666
        }
667

    
668
        /**
669
         * Obtiene el extent correspondiente a los datos cargados en el buffer
670
         * @return Extent
671
         */
672
        public Extent getDataExtent() {
673
                return dataExtent;
674
        }
675

    
676
        /**
677
         * Obtiene la lista de paletas asociadas a las bandas cargadas en el DataSource
678
         * @return Lista con las paletas o null si no hay ninguna asocida. Un nulo en una
679
         * posici?n del array tambi?n indicar? que para esa banda no hay paletas asociadas.
680
         */
681
        public ColorTable[] getColorTables() {
682
                return palette;
683
        }
684

    
685
        /**
686
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
687
         * @return true si est? georreferenciada y false si no lo est?.
688
         */
689
        public boolean isGeoreferenced() {
690
                return mDataset.isGeoreferenced();
691
        }
692

    
693
        /**
694
         * Consulta el flag de supersampleo en la carga del buffer.
695
         * <P>
696
         * Si este flag es false
697
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la
698
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos
699
         * en el ?rea.
700
         * </P>
701
         * <P>
702
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe
703
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta
704
         * variable es true el buffer lo generar? de 500x400.
705
         * </P>
706
         *
707
         * @return true si el supersampleo en la carga del buffer est? activado y false si no lo est?.
708
         */
709
        public boolean isSupersamplingLoadingBuffer() {
710
                return supersamplingLoadingBuffer;
711
        }
712

    
713
        /**
714
         * Activa o desactiva el supersampling en la carga del buffer.
715
         * <P>
716
         * Si este flag es false
717
         * y pasamos un buffer de tama?o mayor que el n?mero de pixels del ?rea requerida en la
718
         * llamada setAreaOfInterest entonces se ajustar? este buffer al n?mero de pixeles contenidos
719
         * en el ?rea.
720
         * </P>
721
         * <P>
722
         * Por ejemplo, si solicitamos un ?rea de 5x4 pixels de un raster y pedimos que nos los grabe
723
         * en un buffer de 500x400, si esta variable es false el buffer lo generar? de 5x4. Si esta
724
         * variable es true el buffer lo generar? de 500x400.
725
         * </P>
726
         *
727
         * @param supersamplingLoadingBuffer true o false para activar o desactivar el supersampling en la
728
         * carga del buffer.
729
         */
730
        public void setSupersamplingLoadingBuffer(boolean supersamplingLoadingBuffer) {
731
                this.supersamplingLoadingBuffer = supersamplingLoadingBuffer;
732
        }
733

    
734
        public double getNHeight() {
735
                return nHeight;
736
        }
737

    
738
        public double getNWidth() {
739
                return nWidth;
740
        }
741

    
742
        /*
743
         * (non-Javadoc)
744
         * @see org.gvsig.raster.util.ICancellable#isCanceled(int)
745
         */
746
        public boolean isCanceled(int process) {
747
                if (process == CANCEL_READ)
748
                        return cancel[0];
749
                return false;
750
        }
751

    
752
        /*
753
         * (non-Javadoc)
754
         * @see org.gvsig.raster.util.ICancellable#setCanceled(boolean, int)
755
         */
756
        public void setCanceled(boolean value, int process) {
757
                if(process == CANCEL_READ || process == 0)
758
                        cancel[0] = value;
759
        }
760

    
761
        /**
762
         * Obtiene el flag que ajusta el extent de la petici?n al del raster. Si est? a
763
         * true en caso de que el extent de la petici?n sea mayor lo ajustar? a los limites
764
         * de este. Si est? a false no lo ajustar? rellenando los valores con NoData. Por defecto
765
         * estar? a true.
766
         * @return true si ajusta y false si no lo hace
767
         */
768
        public boolean isAdjustToExtent() {
769
                return adjustToExtent;
770
        }
771

    
772
        /**
773
         * Asigna el flag que ajusta el extent de la petici?n al del raster. Si est? a
774
         * true en caso de que el extent de la petici?n sea mayor lo ajustar? a los limites
775
         * de este. Si est? a false no lo ajustar? rellenando los valores con NoData
776
         * @param adjustToExtent true para ajustar y false si no queremos que lo haga. Por defecto
777
         * estar? a true.
778
         */
779
        public void setAdjustToExtent(boolean adjustToExtent) {
780
                this.adjustToExtent = adjustToExtent;
781
        }
782
        
783
        /**
784
         * Asigna el valor noData con el que se rellenan las celdas cuando se hace una petici?n
785
         * en la que no se quiere que se ajuste al ?rea del raster. Por defecto noData tendr? el valor
786
         * que aparece en IBuffer.
787
         * @param noData
788
         */
789
        public void setNoDataToFill(double noData) {
790
                this.noDataValue = noData;
791
        }
792

    
793
}
794