Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / io / MemoryRasterDriver.java @ 11076

History | View | Annotate | Download (25.5 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.Image;
27
import java.awt.geom.Point2D;
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.extensionPoints.ExtensionPoints;
41
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
42

    
43
import es.gva.cit.jgdal.Gdal;
44
import es.gva.cit.jgdal.GdalBuffer;
45
import es.gva.cit.jgdal.GdalException;
46

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

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

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

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

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

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

    
575
        /*
576
         *  (non-Javadoc)
577
         * @see org.gvsig.raster.dataset.RasterDataset#readCompleteLine(int, int)
578
         */
579
        public Object readCompleteLine(int line, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
580
                switch(buffer.getDataType()){
581
                case IBuffer.TYPE_BYTE: return buffer.getLineFromBandByte(line, band);
582
                case IBuffer.TYPE_SHORT: return buffer.getLineFromBandShort(line, band);
583
                case IBuffer.TYPE_INT: return buffer.getLineFromBandInt(line, band);
584
                case IBuffer.TYPE_FLOAT: return buffer.getLineFromBandFloat(line, band);
585
                case IBuffer.TYPE_DOUBLE: return buffer.getLineFromBandDouble(line, band);
586
                }
587
                return null;
588
        }
589
        
590
}
591

    
592

    
593