Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / io / MemoryRasterDriver.java @ 11207

History | View | Annotate | Download (27.8 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 * 
4
 * Copyright (C) 2004-5. 
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 * 
22
 * cresques@gmail.com
23
 */
24
package org.gvsig.raster.dataset.io;
25

    
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28

    
29
import org.cresques.cts.ICoordTrans;
30
import org.cresques.cts.IProjection;
31
import org.gvsig.raster.dataset.BandList;
32
import org.gvsig.raster.dataset.FileNotOpenException;
33
import org.gvsig.raster.dataset.GeoInfo;
34
import org.gvsig.raster.dataset.IBuffer;
35
import org.gvsig.raster.dataset.InvalidSetViewException;
36
import org.gvsig.raster.dataset.NotSupportedExtensionException;
37
import org.gvsig.raster.dataset.RasterDataset;
38
import org.gvsig.raster.dataset.RasterDriverException;
39
import org.gvsig.raster.shared.Extent;
40
import org.gvsig.raster.util.RasterUtilities;
41
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
42
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
43

    
44
/**
45
 * Driver para datos cargados en un objeto IBuffer
46
 * @author Nacho Brodin (nachobrodin@gmail.com)
47
 *
48
 */
49
public class MemoryRasterDriver extends RasterDataset {
50

    
51
        private Extent v = null;
52
        private IBuffer buffer = null;
53
        
54
        static {
55
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
56
                extensionPoints.add("RasterDriver", new MemoryRasterDriverParam().getFormatID(), MemoryRasterDriver.class);
57
        }
58
        
59
        /**
60
         * Constructor. Asigna el buffer de datos y la extensi?n 
61
         * @param proj Proyecci?n
62
         * @param buf Buffer
63
         * @throws NotSupportedExtensionException
64
         */
65
        public MemoryRasterDriver(IProjection proj, Object buf)throws NotSupportedExtensionException {
66
                super(null, null);
67
                if(!(buf instanceof MemoryRasterDriverParam))
68
                        throw new NotSupportedExtensionException("Buffer not supported");
69
                
70
                this.extent = this.requestExtent = ((MemoryRasterDriverParam)buf).getExtent();
71
                this.buffer = ((MemoryRasterDriverParam)buf).getBuffer();
72
                
73
                if(buffer == null)
74
                        throw new NotSupportedExtensionException("Buffer invalid");
75
                
76
                if(extent == null) {
77
                        extent = requestExtent = new Extent(0, buffer.getHeight(), buffer.getWidth(), 0);
78
                }
79
                                
80
                load();
81
                bandCount = buffer.getBandCount(); 
82
                
83
                //Obtenemos el tipo de dato de gdal y lo convertimos el de RasterBuf
84
                setDataType(buffer.getDataType());
85
        }
86
        
87
        /*
88
         *  (non-Javadoc)
89
         * @see org.gvsig.raster.dataset.GeoInfo#load()
90
         */
91
        public GeoInfo load() {
92
                return this;
93
        }
94
        
95
        /*
96
         *  (non-Javadoc)
97
         * @see org.gvsig.raster.dataset.GeoInfo#close()
98
         */
99
        public void close() {
100
                
101
        }
102
        
103
        /**
104
         * Asigna el extent de la vista actual. 
105
         */
106
        public void setView(Extent e) { 
107
                v = new Extent(e.minX(), e.minY(), e.maxX(), e.maxY());        
108
        }
109
                
110
         /**
111
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
112
         * asociado. En Gdal el origen de coordenadas en Y es el valor m?nimo y crece hasta el m?ximo. De la
113
         * misma forma calcula la matriz de transformaci?n de la cabecera del fichero o del world file asociado
114
         * @param originX Origen de la imagen en la coordenada X
115
         * @param originY Origen de la imagen en la coordenada Y
116
         */
117
        public void setExtentTransform(double originX, double originY, double psX, double psY) {                
118
                transformRMF.setToTranslation(originX, originY);
119
                transformRMF.scale(psX, psY);
120
        }
121
        
122
        /**
123
         * Obtiene extent de la vista actual
124
         */
125
        public Extent getView() { 
126
                return v; 
127
        }
128
        
129
        /**
130
         * Obtiene la anchura del fichero
131
         */
132
        public int getWidth() {        
133
                return buffer.getWidth(); 
134
        }
135
        
136
        /**
137
         * Obtiene la altura del fichero
138
         */
139
        public int getHeight() { 
140
                return buffer.getHeight();
141
        }
142

    
143
        /*
144
         *  (non-Javadoc)
145
         * @see org.cresques.geo.Projected#reProject(org.cresques.cts.ICoordTrans)
146
         */
147
        public void reProject(ICoordTrans rp) {
148
        }
149
        
150
        /**
151
         * Obtiene la orientaci?n de la imagen a partir del signo del tama?o de pixel para poder
152
         * asignarlo en el setView. Esto es util para poder conocer como debe leerse la image, 
153
         * de abajo a arriba, de arriba a abajo, de izquierda a derecha o de derecha a izquierda. 
154
         * La posici?n habitual es la que el pixel size en X es positivo y en Y negativo leyendose 
155
         * en este caso las X de menor a mayor y las Y de mayor a menor. Los casos posibles son:
156
         * <UL>
157
         * <LI><B>X > 0; Y < 0;</B> {true, false}</LI>
158
         * <LI><B>X > 0; Y > 0;</B> {true, true}</LI>
159
         * <LI><B>X < 0; Y > 0;</B> {false, true}</LI>
160
         * <LI><B>X < 0; Y < 0;</B> {false, false}</LI>
161
         * </UL>
162
         *  
163
         * @return
164
         */
165
        private boolean[] getOrientation(){
166
                boolean[] orientation = {true, false};
167
                return orientation;
168
        }
169
        
170
        /* (non-Javadoc)
171
         * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
172
         */
173
        public Object getData(int x, int y, int band) {
174
                if(buffer.getDataType() == IBuffer.TYPE_BYTE){
175
                        return new Byte(buffer.getElemByte(y, x, band));
176
                }else if(buffer.getDataType() == IBuffer.TYPE_SHORT){
177
                        return new Short(buffer.getElemShort(y, x, band));
178
                }else if(buffer.getDataType() == IBuffer.TYPE_INT){
179
                        return new Integer(buffer.getElemInt(y, x, band));
180
                }else if(buffer.getDataType() == IBuffer.TYPE_FLOAT){
181
                        return new Float(buffer.getElemFloat(y, x, band));
182
                }else if(buffer.getDataType() == IBuffer.TYPE_DOUBLE){
183
                        return new Double(buffer.getElemDouble(y, x, band));
184
                }
185
                return null;
186
        }
187
                
188
        
189
        /**
190
         * Devuelve el tama?o de bloque
191
         * @return Tama?o de bloque
192
         */
193
        public int getBlockSize(){
194
                return 0;
195
        }
196
        
197
        /**
198
         * Obtiene el flag que dice si la imagen est? o no georreferenciada
199
         * @return true si est? georreferenciada y false si no lo est?.
200
         */
201
        public boolean isGeoreferenced() {
202
                return (this.extent != null);
203
        }
204
    
205
        /**
206
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
207
         * el valor de esta variable cada vez que dibuja. 
208
         * @return true si se ha supersampleado y false si no se ha hecho.
209
         */
210
        public boolean isSupersampling() {
211
                return false;
212
        }
213
        
214
        /**
215
         * Obtiene los par?metros de la transformaci?n af?n
216
         * <UL> 
217
         * <LI>[1]tama?o de pixel en X</LI>
218
         * <LI>[2]rotaci?n en X</LI>
219
         * <LI>[4]rotaci?n en Y</LI>
220
         * <LI>[5]tama?o de pixel en Y</LI>
221
         * <LI>[0]origen en X</LI>
222
         * <LI>[3]origen en Y</LI>
223
         * </UL>
224
         * Este m?todo debe ser reimplementado por el driver si tiene esta informaci?n.
225
         * @return vector de double con los elementos de la transformaci?n af?n.
226
         */
227
        public double[] getTransform(){
228
                return new double[]{extent.minX(), 
229
                                                        extent.width() / buffer.getWidth(), 
230
                                                        0.0, 
231
                                                        extent.maxY(), 
232
                                                        0.0, 
233
                                                        extent.height() / buffer.getHeight()};
234
        }
235
        
236
        /*
237
         *  (non-Javadoc)
238
         * @see org.gvsig.fmap.driver.GeoRasterFile#rasterToWorld(java.awt.geom.Point2D)
239
         */
240
        public Point2D rasterToWorld(Point2D pt) {
241
                double x = extent.minX() + ((pt.getX() * (extent.maxX() - extent.minX())) / ((double) buffer.getWidth()));
242
                double y = extent.maxY() - ((pt.getY() * (extent.maxY() - extent.minY())) / ((double) buffer.getHeight()));
243
                Point2D ptRes = new Point2D.Double(x, y);
244
                return ptRes;
245
        }
246
        
247
        /*
248
         *  (non-Javadoc)
249
         * @see org.gvsig.fmap.driver.GeoRasterFile#worldToRaster(java.awt.geom.Point2D)
250
         */
251
        public Point2D worldToRaster(Point2D pt) {
252
                double x = (((double) buffer.getWidth()) / (extent.maxX() - extent.minX())) * (pt.getX() - extent.minX());
253
                double y = (((double) buffer.getHeight()) / (extent.maxY() - extent.minY())) * (extent.maxY() - pt.getY());
254
                Point2D ptRes = new Point2D.Double(x, y);
255
                return ptRes;
256
        }
257
        
258
        /**
259
         * @return Returns the dataType.
260
         */
261
        public int getDataType() {
262
                return buffer.getDataType();
263
        }
264

    
265
        /**
266
         * Ajusta los puntos pasados por par?metro a los l?mites del buffer. Es decir si alguno excede
267
         * los l?mites por arriba o por abajo los ajusta.
268
         * @param begin Punto inicial
269
         * @param end Punto final
270
         */
271
        private void adjustPointsToBufferLimits(Point2D begin, Point2D end) {
272
                if(begin.getX() < 0)
273
                        begin.setLocation(0, begin.getY());
274
                if(begin.getY() > buffer.getHeight())
275
                        begin.setLocation(begin.getX(), buffer.getHeight());
276
                if(end.getY() < 0)
277
                        end.setLocation(begin.getX(), 0);
278
                if(end.getX() > buffer.getWidth())
279
                        begin.setLocation(buffer.getWidth(), begin.getY());
280
        }
281
        
282
        /*
283
         *  (non-Javadoc)
284
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer, boolean)
285
         */
286
        public IBuffer getWindowRaster(double x, double y, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) {
287
                Point2D begin = worldToRaster(new Point2D.Double(x, y));
288
                Point2D end = worldToRaster(new Point2D.Double(x + w, y - h));
289
                setView(new Extent(x, y, x + w, y - h));
290
                
291
                adjustPointsToBufferLimits(begin, end);
292
                
293
                switch(buffer.getDataType()){
294
                case IBuffer.TYPE_BYTE: writeByteBuffer(rasterBuf, 1, 1, begin, bandList); break;
295
                case IBuffer.TYPE_SHORT: writeShortBuffer(rasterBuf, 1, 1, begin, bandList); break;
296
                case IBuffer.TYPE_INT: writeIntBuffer(rasterBuf, 1, 1, begin, bandList); break;
297
                case IBuffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, 1, 1, begin, bandList); break;
298
                case IBuffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, 1, 1, begin, bandList); break;
299
                }
300
                return rasterBuf;
301
        }
302

    
303
        /*
304
         *  (non-Javadoc)
305
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer, boolean)
306
         */
307
        public IBuffer getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) {
308
                Point2D begin = worldToRaster(new Point2D.Double(minX, maxY));
309
                Point2D end = worldToRaster(new Point2D.Double(maxX, minY));
310
                setView(new Extent(minX, minY, maxX, maxY));
311
                
312
                adjustPointsToBufferLimits(begin, end);                
313
                
314
                //Ancho y alto en pixels (double) del area seleccionada.
315
                double w = Math.abs(end.getX() - begin.getX());
316
                double h = Math.abs(end.getY() - begin.getY());
317
                
318
                //Relaci?n entre el n?mero de pixels del buffer origen (area seleccionada) y el destino 
319
                double stepX = w / ((double)bufWidth);
320
                double stepY = h / ((double)bufHeight);
321
                
322
                //Escritura separada en 5 llamadas para mejorar el rendimiento
323
                switch(buffer.getDataType()){
324
                case IBuffer.TYPE_BYTE: writeByteBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
325
                case IBuffer.TYPE_SHORT: writeShortBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
326
                case IBuffer.TYPE_INT: writeIntBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
327
                case IBuffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
328
                case IBuffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, stepX, stepY, begin, bandList); break;
329
                }
330
                
331
                /*int xPx = 0, yPx = 0;
332
                for (int iBand = 0; iBand < rasterBuf.getBandCount(); iBand++) {
333
                        yPx = 0;
334
                        for(double row = begin.getY(); yPx < bufHeight; row += stepY) {
335
                                xPx = 0;
336
                                for(double col = begin.getX(); xPx < bufWidth; col += stepX) {
337
                                        switch(buffer.getDataType()){
338
                                        case IBuffer.TYPE_BYTE: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemByte((int)row, (int)col, iBand)); break;
339
                                        case IBuffer.TYPE_SHORT: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemShort((int)row, (int)col, iBand)); break;
340
                                        case IBuffer.TYPE_INT: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemInt((int)row, (int)col, iBand)); break;
341
                                        case IBuffer.TYPE_FLOAT: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemFloat((int)row, (int)col, iBand)); break;
342
                                        case IBuffer.TYPE_DOUBLE: rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemDouble((int)row, (int)col, iBand)); break;
343
                                        }
344
                                        xPx ++;
345
                                }
346
                                yPx ++;
347
                        }
348
                }*/
349
                return rasterBuf;
350
        }
351

    
352
        /**
353
         * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
354
         * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a 
355
         * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
356
         * @param rasterBuf Buffer donde se escriben los datos 
357
         * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
358
         * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
359
         * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
360
         * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
361
         * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
362
         * del pixel. Esto es util cuando se supersamplea.
363
         */
364
        private void writeByteBuffer(IBuffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
365
                int xPx = 0, yPx = 0;
366
                for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
367
                        int[] drawableBands = bandList.getBufferBandToDraw(this.getFName(), iBand);
368
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
369
                                continue;
370
                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
371
                                yPx = 0;
372
                                for(double row = begin.getY(); (yPx < rasterBuf.getHeight() && row < buffer.getHeight()); row += stepY) {
373
                                        xPx = 0;
374
                                        for(double col = begin.getX(); (xPx < rasterBuf.getWidth() && col < buffer.getWidth()); col += stepX) {
375
                                                rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemByte((int)row, (int)col, iBand));
376
                                                xPx ++;
377
                                        }
378
                                        yPx ++;
379
                                }
380
                        }
381
                }
382
        }
383
        
384
        /**
385
         * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
386
         * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a 
387
         * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
388
         * @param rasterBuf Buffer donde se escriben los datos 
389
         * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
390
         * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
391
         * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
392
         * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
393
         * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
394
         * del pixel. Esto es util cuando se supersamplea.
395
         */
396
        private void writeShortBuffer(IBuffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
397
                int xPx = 0, yPx = 0;
398
                for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
399
                        int[] drawableBands = bandList.getBufferBandToDraw(this.getFName(), iBand);
400
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
401
                                continue;
402
                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
403
                                yPx = 0;
404
                                for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
405
                                        xPx = 0;
406
                                        for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
407
                                                rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemShort((int)row, (int)col, iBand));
408
                                                xPx ++;
409
                                        }
410
                                        yPx ++;
411
                                }
412
                        }
413
                }
414
        }
415
        
416
        /**
417
         * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
418
         * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a 
419
         * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
420
         * @param rasterBuf Buffer donde se escriben los datos 
421
         * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
422
         * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
423
         * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
424
         * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
425
         * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
426
         * del pixel. Esto es util cuando se supersamplea.
427
         */
428
        private void writeIntBuffer(IBuffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
429
                int xPx = 0, yPx = 0;
430
                for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
431
                        int[] drawableBands = bandList.getBufferBandToDraw(this.getFName(), iBand);
432
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
433
                                continue;
434
                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
435
                                yPx = 0;
436
                                for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
437
                                        xPx = 0;
438
                                        for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
439
                                                rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemInt((int)row, (int)col, iBand));
440
                                                xPx ++;
441
                                        }
442
                                        yPx ++;
443
                                }
444
                        }
445
                }
446
        }
447
        
448
        /**
449
         * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
450
         * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a 
451
         * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
452
         * @param rasterBuf Buffer donde se escriben los datos 
453
         * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
454
         * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
455
         * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
456
         * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
457
         * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
458
         * del pixel. Esto es util cuando se supersamplea.
459
         */
460
        private void writeFloatBuffer(IBuffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
461
                int xPx = 0, yPx = 0;
462
                for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
463
                        int[] drawableBands = bandList.getBufferBandToDraw(this.getFName(), iBand);
464
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
465
                                continue;
466
                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
467
                                yPx = 0;
468
                                for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
469
                                        xPx = 0;
470
                                        for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
471
                                                rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemFloat((int)row, (int)col, iBand));
472
                                                xPx ++;
473
                                        }
474
                                        yPx ++;
475
                                }
476
                        }
477
                }
478
        }
479
        
480
        /**
481
         * Escribe sobre el buffer pasado por par?metro los valores solicitados, desde el buffer de la clase. Los valores
482
         * se solicitan a trav?s de los par?metros. En ellos se especifica el tama?o del buffer de destino, las bandas a 
483
         * escribir, el punto inicial en coordenadas pixel (double) y el incremento.
484
         * @param rasterBuf Buffer donde se escriben los datos 
485
         * @param stepX Incremento en X. Cada vez que se escribe un pixel en X se incrementa el contador en stepX pixels. Esto es necesario
486
         * ya que el buffer destino no tiene porque tener el mismo ancho que el de origen. Este valor suele ser ancho_buffer_origen / ancho_buffer_destino.
487
         * @param stepY Incremento en Y. Cada vez que se escribe un pixel en Y se incrementa el contador en stepY pixels. Esto es necesario
488
         * ya que el buffer destino no tiene porque tener el mismo alto que el de origen. Este valor suele ser alto_buffer_origen / alto_buffer_destino.
489
         * @param begin pixel donde se comienza a leer en el buffer de origen. Este valor es decimal ya que no tiene porque empezar a leerse al principio
490
         * del pixel. Esto es util cuando se supersamplea.
491
         */
492
        private void writeDoubleBuffer(IBuffer rasterBuf, double stepX, double stepY, Point2D begin, BandList bandList) {
493
                int xPx = 0, yPx = 0;
494
                for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
495
                        int[] drawableBands = bandList.getBufferBandToDraw(this.getFName(), iBand);
496
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
497
                                continue;
498
                        for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
499
                                yPx = 0;
500
                                for(double row = begin.getY(); yPx < rasterBuf.getHeight(); row += stepY) {
501
                                        xPx = 0;
502
                                        for(double col = begin.getX(); xPx < rasterBuf.getWidth(); col += stepX) {
503
                                                rasterBuf.setElem(yPx, xPx, iBand, buffer.getElemDouble((int)row, (int)col, iBand));
504
                                                xPx ++;
505
                                        }
506
                                        yPx ++;
507
                                }
508
                        }
509
                }
510
        }
511
        
512
        /*
513
         *  (non-Javadoc)
514
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
515
         */
516
        public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf) {
517
                setView(
518
                                new Extent( RasterUtilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
519
                                                        getWidth(), 
520
                                                        getHeight(),
521
                                                        new Rectangle2D.Double(x, y, w, h)))
522
                                );
523
                
524
                for(int iBand = 0; iBand < buffer.getBandCount(); iBand ++){
525
                        int[] drawableBands = bandList.getBufferBandToDraw(this.getFName(), iBand);
526
                        if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
527
                                continue;        
528
                        if(buffer.getDataType() == IBuffer.TYPE_BYTE) {
529
                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++) {
530
                                        for(int line = y; line < (y + h); line ++)
531
                                                for(int col = x; col < (x + w); col ++)
532
                                                        rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemByte(line, col, drawableBands[drawBands]));
533
                                }
534
                        }else if(buffer.getDataType() == IBuffer.TYPE_SHORT){
535
                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
536
                                        for(int line = y; line < (y + h); line ++)
537
                                                for(int col = x; col < (x + w); col ++)
538
                                                        rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemShort(line, col, drawableBands[drawBands]));
539
                                }
540
                        }else if(buffer.getDataType() == IBuffer.TYPE_INT){
541
                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
542
                                        for(int line = y; line < (y + h); line ++)
543
                                                for(int col = x; col < (x + w); col ++)
544
                                                        rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemInt(line, col, drawableBands[drawBands]));
545
                                }
546
                        }else if(buffer.getDataType() == IBuffer.TYPE_FLOAT){
547
                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
548
                                        for(int line = y; line < (y + h); line ++)
549
                                                for(int col = x; col < (x + w); col ++)
550
                                                        rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemFloat(line, col, drawableBands[drawBands]));
551
                                }
552
                        }else if(buffer.getDataType() == IBuffer.TYPE_DOUBLE){
553
                                for(int drawBands = 0; drawBands < drawableBands.length; drawBands++){
554
                                        for(int line = y; line < (y + h); line ++)
555
                                                for(int col = x; col < (x + w); col ++)
556
                                                        rasterBuf.setElem((line - y), (col - x), drawableBands[drawBands], buffer.getElemDouble(line, col, drawableBands[drawBands]));
557
                                }
558
                        }
559
                }
560
                return rasterBuf;
561
        }
562
        
563
        /*
564
         *  (non-Javadoc)
565
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
566
         */
567
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf) {
568
                setView(
569
                                new Extent( RasterUtilities.getMapRectFromPxRect(getExtent().toRectangle2D(), 
570
                                                        getWidth(), 
571
                                                        getHeight(),
572
                                                        new Rectangle2D.Double(x, y, w, h)))
573
                                );
574
                
575
                //Relaci?n entre el n?mero de pixels del buffer origen (area seleccionada) y el destino 
576
                double stepX = w / ((double)bufWidth);
577
                double stepY = h / ((double)bufHeight);
578
                switch(buffer.getDataType()){
579
                case IBuffer.TYPE_BYTE: writeByteBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
580
                case IBuffer.TYPE_SHORT: writeShortBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
581
                case IBuffer.TYPE_INT: writeIntBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
582
                case IBuffer.TYPE_FLOAT: writeFloatBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
583
                case IBuffer.TYPE_DOUBLE: writeDoubleBuffer(rasterBuf, stepX, stepY, new Point2D.Double(x, y), bandList); break;
584
                }
585
                return rasterBuf;
586
        }
587

    
588
        /*
589
         *  (non-Javadoc)
590
         * @see org.gvsig.raster.dataset.RasterDataset#readCompleteLine(int, int)
591
         */
592
        public Object readCompleteLine(int line, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
593
                switch(buffer.getDataType()){
594
                case IBuffer.TYPE_BYTE: return buffer.getLineFromBandByte(line, band);
595
                case IBuffer.TYPE_SHORT: return buffer.getLineFromBandShort(line, band);
596
                case IBuffer.TYPE_INT: return buffer.getLineFromBandInt(line, band);
597
                case IBuffer.TYPE_FLOAT: return buffer.getLineFromBandFloat(line, band);
598
                case IBuffer.TYPE_DOUBLE: return buffer.getLineFromBandDouble(line, band);
599
                }
600
                return null;
601
        }
602

    
603
        /*
604
         *  (non-Javadoc)
605
         * @see org.gvsig.raster.dataset.RasterDataset#readBlock(int, int)
606
         */
607
        public Object readBlock(int pos, int blockHeight) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
608
                if(pos < 0)
609
                        throw new InvalidSetViewException("Request out of grid");
610
                
611
                if((pos + blockHeight) > buffer.getHeight())
612
                        blockHeight = Math.abs(buffer.getHeight() - pos);
613
                
614
                switch(buffer.getDataType()){
615
                case IBuffer.TYPE_BYTE:
616
                        byte[][][] bufb = new byte[getBandCount()][][];
617
                        for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
618
                                for (int row = 0; row < blockHeight; row++) {
619
                                        bufb[iBand][row] = buffer.getLineFromBandByte(row, iBand);
620
                                }        
621
                        }
622
                        return bufb;
623
                case IBuffer.TYPE_SHORT:
624
                        short[][][] bufs = new short[getBandCount()][][];
625
                        for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
626
                                for (int row = 0; row < blockHeight; row++) {
627
                                        bufs[iBand][row] = buffer.getLineFromBandShort(row, iBand);
628
                                }        
629
                        }
630
                        return bufs;
631
                case IBuffer.TYPE_INT:
632
                        int[][][] bufi = new int[getBandCount()][][];
633
                        for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
634
                                for (int row = 0; row < blockHeight; row++) {
635
                                        bufi[iBand][row] = buffer.getLineFromBandInt(row, iBand);
636
                                }        
637
                        }
638
                        return bufi;
639
                case IBuffer.TYPE_FLOAT: 
640
                        float[][][] buff = new float[getBandCount()][][];
641
                        for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
642
                                for (int row = 0; row < blockHeight; row++) {
643
                                        buff[iBand][row] = buffer.getLineFromBandFloat(row, iBand);
644
                                }        
645
                        }
646
                        return buff;
647
                case IBuffer.TYPE_DOUBLE: 
648
                        double[][][] bufd = new double[getBandCount()][][];
649
                        for (int iBand = 0; iBand < buffer.getBandCount(); iBand++) {
650
                                for (int row = 0; row < blockHeight; row++) {
651
                                        bufd[iBand][row] = buffer.getLineFromBandDouble(row, iBand);
652
                                }        
653
                        }
654
                        return bufd;
655
                }
656
                return null;
657
        }
658
        
659
}
660

    
661

    
662