Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataaccess / buffer / RasterBuffer.java @ 10883

History | View | Annotate | Download (12.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 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.dataaccess.buffer;
20

    
21
import java.io.FileNotFoundException;
22

    
23
import org.gvsig.raster.dataaccess.cache.RasterCache;
24
import org.gvsig.raster.dataaccess.cache.RasterReadOnlyHugeBuffer;
25
import org.gvsig.raster.driver.IBuffer;
26
import org.gvsig.raster.driver.NotSupportedExtensionException;
27
import org.gvsig.raster.driver.RasterDriverException;
28
import org.gvsig.raster.shared.RasterUtilities;
29

    
30
/**
31
 * Rectangulo de pixeles. Para cada tipo de datos java hay un buffer distinto donde cada elemento es
32
 * accedido de la siguiente forma: [banda][fila][columna]
33
 * m[1][2][0] = cte;-> Sustituye el elemento de la fila 2 de la banda 1 columna 0
34
 * m[1][0] = array; -> Sustituye la fila 0 de la banda 1 
35
 * m[0] = matriz cuadrada; -> Sustituye la banda entera.
36
 * 
37
 */
38
public abstract class RasterBuffer implements IBuffer {
39
        //Espacio en memoria (en Megas) que hay que sobrepasar para empezar a cachear.
40
        private static int                cacheMemorySize = 25;
41
        //Espacio en memoria (en Megas) que hay que sobrepasar para empezar a cachear en multipagina.
42
        private static int                multicacheMemorySize = 100;
43
        
44
        public double                         noDataValue = -99999;
45
        
46
    protected int                         width;
47
    protected int                         height;
48
    protected int                         nBands;
49
    protected int                         dataType;
50
    
51
    /**
52
     * Variable est?tica que si est? a false desactiva el uso de cach?. Puede ser usada por un cliente
53
     * para cargar siempre los datos en memoria. independientemente de su tama?o. 
54
     */
55
    public static boolean        cacheOn = true;
56
    /**
57
     * Fuerza la carga de los datos en cach? independientemente de su tama?o. Su
58
     * uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
59
     * es siempre false.
60
     */
61
    public static boolean         forceToLoadInCache = false;
62
    /**
63
     * Fuerza la carga de los datos en cach? de solo lectura independientemente de su tama?o. Su
64
     * uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
65
     * es siempre false.
66
     */
67
    public static boolean         forceToLoadInReadOnlyCache = false;
68
    /**
69
     * Valor con el que se rellena una banda no valida del buffer. Una banda no valida es la que 
70
     * no tiene datos asignados y tampoco puede ser null. Todas las bandas no validas de un buffer
71
     * apuntan por referencia a la misma banda.
72
     */
73
    protected double                notValidValue = 0D;
74

    
75
    /**
76
     * Genera instancias del buffer de datos adecuado al tama?o del raster. Si no hay muchos datos
77
     * (menos de cacheMemorySize) crear? un buffer en memoria. Si hay m?s de esta cantidad
78
     * entonces crearemos un buffer cacheado (RasterCache). A partir de la cantidad se?alada
79
     * por multicacheMemorySize haremos un buffer cacheado donde cada p?gina no ocupa todo
80
     * el ancho del raster ya que este ser? muy grande. La gesti?n de una cache donde cada
81
     * pagina ha de partir una l?nea lleva una complejidad a?adida.
82
     *  
83
     * @param dataType Tipo de dato
84
     * @param width Ancho
85
     * @param height Alto
86
     * @param bandNr Banda
87
     * @param malloc
88
     * @return
89
     * @throws RasterDriverException 
90
     * @throws NotSupportedExtensionException 
91
     * @throws FileNotFoundException 
92
     */
93
    public static RasterBuffer getBuffer(int dataType, int width, int height, int bandNr, boolean malloc, String filePath) 
94
            /*throws FileNotFoundException, NotSupportedExtensionException, RasterDriverException*/{
95
            //Opci?n de cachear siempre activada (Solo DEBUG)
96
            if(forceToLoadInCache)
97
                    return new RasterCache(dataType, width, height, bandNr);
98
            if(forceToLoadInReadOnlyCache && filePath != null){
99
                        try {
100
                                return new RasterReadOnlyHugeBuffer(dataType, width, height, bandNr, filePath);
101
                        } catch (FileNotFoundException e) {
102
                                //TODO: EXCEPTION: Modificar el lanzamiento de excepciones del RasterBuffer
103
                                e.printStackTrace();
104
                        } catch (NotSupportedExtensionException e) {
105
                                e.printStackTrace();
106
                        } catch (RasterDriverException e) {
107
                                e.printStackTrace();
108
                        }
109
            }
110
                    
111
            if(cacheOn){
112
                    long size = (RasterUtilities.getBytesFromRasterBufType(dataType) * width * height * bandNr) / 1024;
113
                    long ms1 = cacheMemorySize * 1024;
114
                    long ms2 = multicacheMemorySize * 1024;
115
                    if(size <= ms1)
116
                            return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc);
117
                    else{
118
                            //if(filePath == null)
119
                                    return new RasterCache(dataType, width, height, bandNr);
120
                            /*else 
121
                                    return new RasterReadOnlyHugeBuffer(dataType, width, height, bandNr, filePath);*/
122
                    }        
123
            }else
124
                    return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc);
125
    }
126
    
127
    /**
128
     * Reserva de memoria para el rasterbuf
129
     * @param dataType Tipo de dato
130
     * @param width Ancho
131
     * @param height Alto
132
     * @param bandNr Numero de bandas
133
     * @param orig
134
     */
135
    public abstract void malloc(int dataType, int width, int height, int bandNr);
136
   
137
    /*
138
     *  (non-Javadoc)
139
     * @see org.gvsig.fmap.driver.IBuffer#getWidth()
140
     */
141
    public int getWidth() {
142
        return width;
143
    }
144

    
145
   /*
146
    *  (non-Javadoc)
147
    * @see org.gvsig.fmap.driver.IBuffer#getHeight()
148
    */
149
    public int getHeight() {
150
        return height;
151
    }
152

    
153
    /*
154
     *  (non-Javadoc)
155
     * @see org.gvsig.fmap.driver.IBuffer#getBandCount()
156
     */
157
    public int getBandCount() {
158
        return nBands;
159
    }
160

    
161
    /**
162
     * Obtiene el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
163
     * @return tipo de datos
164
     */
165
        public int getDataType() {
166
                return dataType;
167
        }
168
        
169
        /**
170
         * Asigna el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
171
         * @param dataType Tipo de dato del buffer
172
         */
173
        public void setDataType(int dataType) {
174
                this.dataType = dataType;
175
        }
176

    
177
    /**
178
     * Obtiene el tama?o del tipo de dato en bytes
179
     * @return Tipo de dato
180
     */
181
    public int getDataSize() {
182
        if (dataType == TYPE_BYTE) {
183
            return 1;
184
        } else if ((dataType == TYPE_SHORT) | (dataType == TYPE_USHORT)) {
185
            return 2;
186
        } else if (dataType == TYPE_INT) {
187
            return 4;
188
        }else if (dataType == TYPE_FLOAT) {
189
            return 8;
190
        }else if (dataType == TYPE_DOUBLE) {
191
            return 16;
192
        }
193

    
194
        return 0;
195
    }
196

    
197
    /**
198
     * Obtiene el tama?o del buffer
199
     * @return tama?o del buffer
200
     */
201
    public long sizeof() {
202
        return getDataSize() * width * height * nBands;
203
    }
204
    
205
    /**
206
     * Replica la banda de una posici?n sobre otra. Si la banda de destino no existe
207
     * se crea nueva. Si la posici?n de la banda de destino est? intercalada entre bandas 
208
     * que ya existen las otras se desplazan hacia abajo, NO se machacan los datos de ninguna.
209
     * Los datos se replican por referencia por lo que al modificar la banda original las
210
     * del resto quedar?n afectadas.
211
     * @param orig. Posici?n de la banda de origen. 
212
     * @param dest. Posici?n de la banda destino
213
     */   
214
    public abstract void replicateBand(int orig, int dest);
215
    
216
    /**
217
     * Cambia bandas de posici?n. Las posiciones deben existir como bandas del raster. 
218
     * Cada elemento del array representa una banda existente en el buffer (de longitud
219
     * rasterBuf.length) y el valor contenido dentro la banda que le corresponde. Por ejemplo
220
     * si pasamos un array {1, 0, 3, 2} significa que el buffer tiene cuatro bandas y que 
221
     * cambiamos la 0 por la 1 y la 2 por la 3. Un array {0, 1, 2, 3} en el mismo 
222
     * caso no producir?a nig?n cambio.
223
     * 
224
     * Si quisieramos asignar en un buffer monobanda su banda a la segunda posici?n habria
225
     * que insertar una vacia, por ejemplo con addBandFloat(0, null) se insertaria una 
226
     * banda nula en la posici?n 0 y la banda que estaba en la 0 pasar?a a la segunda.
227
     * 
228
     */
229
    public abstract void switchBands(int[] bandPosition);
230
            
231
    /**
232
     * Convierte un tipo de dato a cadena
233
     * @param type Tipo de dato
234
     * @return cadena  que representa el tipo de dato
235
     */
236
    public static String typesToString(int type) {
237
        switch (type) {
238
        case RasterBuffer.TYPE_IMAGE:
239
            return new String("Image");
240

    
241
        case RasterBuffer.TYPE_BYTE:
242
            return new String("Byte");
243

    
244
        case RasterBuffer.TYPE_DOUBLE:
245
            return new String("Double");
246

    
247
        case RasterBuffer.TYPE_FLOAT:
248
            return new String("Float");
249

    
250
        case RasterBuffer.TYPE_INT:
251
                return new String("Integer");
252
                
253
        case RasterBuffer.TYPE_USHORT:
254
        case RasterBuffer.TYPE_SHORT:
255
            return new String("Short");
256
        }
257

    
258
        return null;
259
    }
260
    
261
    /**
262
     * Ajusta el raster al ancho y alto solicitado por el vecino m?s cercano. Promedia el valor de dos
263
     * pixeles contiguos.
264
     * @param w Nuevo ancho
265
     * @param h Nuevo alto
266
     */
267
    public abstract RasterBuffer adjustRasterNearestNeighbourInterpolation(int w, int h, int[] bands);
268
    
269
    /**
270
     * Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n bilineal. Promedia
271
     * el valor de cuatro pixeles adyacentes.
272
     * @param w Nuevo ancho
273
     * @param h Nuevo alto
274
     */
275
    public abstract RasterBuffer adjustRasterBilinearInterpolation(int w, int h, int[] bands);
276
    
277
    /**
278
     * Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n de distancia inversa.
279
     * Asigna el valor de un pixel en funci?n inversa de la distancia.
280
     * 
281
     * @param w Nuevo ancho
282
     * @param h Nuevo alto
283
     */
284
    public abstract RasterBuffer adjustRasterInverseDistanceInterpolation(int w, int h, int[] bands);
285
    
286
    /**
287
     * Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n de spline bicubica.
288
     * @param w Nuevo ancho
289
     * @param h Nuevo alto
290
     */
291
    public abstract RasterBuffer adjustRasterBicubicSplineInterpolation(int w, int h, int[] bands);
292
    
293
    /**
294
     * Ajusta el raster al ancho y alto solicitado ajustando con una interpolaci?n BSpline.
295
     * @param w Nuevo ancho
296
     * @param h Nuevo alto
297
     */
298
    public abstract RasterBuffer adjustRasterBSplineInterpolation(int w, int h, int[] bands);
299
    
300
    /*
301
     *  (non-Javadoc)
302
     * @see org.gvsig.fmap.driver.IBuffer#getNoDataValue()
303
     */
304
    public double getNoDataValue(){
305
            return noDataValue;
306
    }
307
    
308
    /*
309
     *  (non-Javadoc)
310
     * @see org.gvsig.fmap.driver.IBuffer#getByteNoDataValue()
311
     */
312
    public byte getByteNoDataValue(){
313
            return (byte)noDataValue;
314
    }
315
    
316
    /*
317
     *  (non-Javadoc)
318
     * @see org.gvsig.fmap.driver.IBuffer#getShortNoDataValue()
319
     */
320
    public short getShortNoDataValue(){
321
            return (short)noDataValue;
322
    }
323
    
324
    /*
325
     *  (non-Javadoc)
326
     * @see org.gvsig.fmap.driver.IBuffer#getIntNoDataValue()
327
     */
328
    public int getIntNoDataValue(){
329
            return (int)noDataValue;
330
    }
331
    
332
    /*
333
     *  (non-Javadoc)
334
     * @see org.gvsig.fmap.driver.IBuffer#getFloatNoDataValue()
335
     */
336
    public float getFloatNoDataValue(){
337
            return (float)noDataValue;
338
    }
339
    
340
    /*
341
     *  (non-Javadoc)
342
     * @see org.gvsig.fmap.driver.IBuffer#setNoDataValue(double)
343
     */
344
    public void setNoDataValue(double nd){
345
            noDataValue = nd;
346
    }
347
    
348
    /*
349
     *  (non-Javadoc)
350
     * @see org.gvsig.fmap.driver.IBuffer#getNotValidValue()
351
     */
352
    public double getNotValidValue(){
353
            return notValidValue;
354
    }
355
    
356
    /*
357
         *  (non-Javadoc)
358
         * @see org.gvsig.fmap.driver.IBuffer#setNotValidValue(java.lang.Object)
359
         */
360
    public void setNotValidValue(double value){
361
            this.notValidValue = value;
362
    }
363
    
364
    /*
365
     *  (non-Javadoc)
366
     * @see org.gvsig.fmap.driver.IBuffer#cloneBuffer()
367
     */
368
    public abstract IBuffer cloneBuffer();
369
}