Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_914 / libraries / libCq_CMS_praster / src / org / cresques / io / GdalWriter.java @ 11873

History | View | Annotate | Download (37.2 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.cresques.io;
25

    
26
import java.io.BufferedOutputStream;
27
import java.io.DataOutputStream;
28
import java.io.File;
29
import java.io.FileOutputStream;
30
import java.io.IOException;
31

    
32
import org.cresques.cts.IProjection;
33
import org.cresques.geo.ViewPortData;
34
import org.cresques.io.data.RasterBuf;
35
import org.cresques.io.exceptions.NotSupportedExtensionException;
36
import org.cresques.px.Extent;
37
import org.cresques.px.PxRaster;
38
import org.cresques.util.Utilities;
39

    
40
import es.gva.cit.jecwcompress.EcwException;
41
import es.gva.cit.jgdal.Gdal;
42
import es.gva.cit.jgdal.GdalBuffer;
43
import es.gva.cit.jgdal.GdalDriver;
44
import es.gva.cit.jgdal.GdalException;
45
import es.gva.cit.jgdal.GdalRasterBand;
46
import es.gva.cit.jgdal.GeoTransform;
47
import es.gva.cit.jogr.OGRSpatialReference;
48

    
49

    
50
/**
51
 * Driver para la escritura a trav?s de Gdal.
52
 * Puede exportar un fichero de un formato a otro desde un GeoRasterFile
53
 * en cualquier formato soportado por la lectura a un formato que este incluido
54
 * en la lista supportedDrv.
55
 *
56
 * Puede salvar a disco en un formato que este incluido en la lista supportedDrv
57
 * obteniendo los datos que van siendo servidos desde el cliente. Este cliente
58
 * debe implementar un IDataWriter o tener un objeto que lo implemente. Inicialmente
59
 * le pasar? los par?metros de la imagen de salida y cuando el driver comience a
60
 * escribir le ir? solicitando m?s a trav?s del m?todo readData de IDataWriter.
61
 * El cliente ser? el que lleve el control de lo que va sirviendo y lo que le queda
62
 * por servir.
63
 * @author Nacho Brodin (brodin_ign@gva.es)
64
 */
65
public class GdalWriter extends GeoRasterWriter {
66
        
67
        //Datos de registro de drivers
68
    static {
69
        GeoRasterWriter.registerWriterExtension("tif", GdalWriter.class);
70
        //GeoRasterWriter.registerWriterExtension("tiff", GdalWriter.class);
71
        typeList.put("tif", "GTiff");
72
        //typeList.put("tiff", "GTiff");
73
    }
74

    
75
    public final int                                 windowSizeX = 386;
76
    public final int                                 windowSizeY = 195;
77
    public final int                                 panelSizeX = 358;
78
    public final int                                 panelSizeY = 105;
79
    public final String                         panelLayout = "BorderLayout";
80
    private GdalDriver                                 drv;
81
    private Gdal                                         dset_destino = null;
82
    private GdalRasterBand                         rband = null;
83
    private GeoTransform                         geot = null; //Datos de georeferenciaci?n
84
    private OGRSpatialReference         oSRS; //Datos de proyecci?n                                                
85
    private GdalBuffer                                 buf = null; //Buffer de origen de gdal
86
    private GdalBuffer[]                        bufBands = null;
87
    private int                                         nBlocks = 0; //N?mero de bloques en Y en el que se divide la imagen para escribir
88
    private int                                         anchoResto = 0; //Tama?o del ?ltimo bloque de la imagen.
89
    private String[]                                 params = null; //Par?metros de creaci?n del dataset.
90
    private GdalSupportOptions                 support = null;
91
    private boolean                                 consulta = false;
92
    private        boolean                                        write = true; //Cuando est? a true se puede escribir en la imagen de salida. Si est? a false el proceso es interrumpido
93
    private int                                         dataType = RasterBuf.TYPE_UNDEFINED;
94

    
95
    /**
96
     * Constructor para la obtenci?n de par?metros del driver
97
     * @param drvType        Tipo de driver
98
     */
99
    public GdalWriter(String fileName) {
100
            ident = fileName.toLowerCase().substring(fileName.lastIndexOf(".") + 1); 
101
            driver = (String)typeList.get(ident);
102
        support = new GdalSupportOptions(driver);
103
        support.setBlockSize(blockSizeDefault);
104
        support.setPhotometric("RGB");
105
        support.setInterleave("BAND");
106
        support.setCompress("NONE");
107
        support.setWriteGeoref(true);
108
        support.setTfw(false);
109
        consulta = true;
110
    }
111

    
112
    /**
113
     * Constructor para salvar una sola imagen completa
114
     * @param raster        PxRaster de la imagen de  origen
115
     * @param outfilename        Nombre del fichero de salida
116
     * @param infilename        Nombre del fichero de entrada
117
     * @param drvType        Tipo de driver
118
     */
119
    public GdalWriter(PxRaster raster, String outFileName, String inFileName) throws GdalException, IOException {
120
            ident = outFileName.toLowerCase().substring(outFileName.lastIndexOf(".") + 1); 
121
            driver = (String)typeList.get(ident);
122
        support = new GdalSupportOptions(driver);   
123
        
124
        this.outFileName = outFileName;
125
        this.inFileName = inFileName;
126
        currentRaster = raster;
127

    
128
        sizeWindowX = raster.getFWidth();
129
        sizeWindowY = raster.getFHeight();
130

    
131
        //Obtenemos la georeferenciaci?n
132
        if (support.getGeoref()) {
133
            double maxX = currentRaster.getExtent().maxX();
134
            double minX = currentRaster.getExtent().minX();
135
            double maxY = currentRaster.getExtent().maxY();
136
            double minY = currentRaster.getExtent().minY();
137

    
138
            geot = new GeoTransform();
139
            geot.adfgeotransform[0] = minX;
140
            geot.adfgeotransform[3] = maxY;
141
            geot.adfgeotransform[1] = (maxX - minX) / currentRaster.getFWidth();
142
            geot.adfgeotransform[5] = (minY - maxY) / currentRaster.getFHeight();
143
        }
144

    
145
        nBands = currentRaster.getBandCount();
146

    
147
        this.support.setBlockSize(64/*currentRaster.getBlockSize()*/);
148

    
149
        if ((sizeWindowX < 0) || (sizeWindowY < 0)) {
150
            throw new IOException("Tama?o del fichero de salida erroneo.");
151
        }
152

    
153
        if (nBands == 3) {
154
            this.support.setPhotometric("PHOTOMETRIC=RGB");
155
        } else if (nBands == 1) {
156
            this.support.setPhotometric("PHOTOMETRIC=MINISBLACK");
157
        } else {
158
            this.support.setPhotometric("");
159
        }
160

    
161
        params = new String[2];
162
        params[0] = new String("TILED=YES");
163
        params[1] = new String(this.support.getPhotometric());
164

    
165
        init();
166

    
167
        /*oSRS = new OGRSpatialReference();
168
        try{
169
                oSRS.setUTM(currentRaster.geoFile.getUTM(), currentRaster.geoFile.getZone());
170
                  oSRS.setWellKnownGeogCS(currentRaster.geoFile.getGeogCS());
171
                  //System.out.println(currentRaster.geoFile.getGeogCS()+"Nueva Proyecci?n ==> "+oSRS.exportToWkt());
172
                  dset_destino.setProjection(oSRS.exportToWkt());
173
        }catch(Exception e){
174
                e.printStackTrace();
175
        }*/
176
    }
177

    
178
    /**
179
     * Constructor para salvar datos servidos por el cliente
180
     * @param dataWriter        Objeto servidor de datos para el driver de escritura
181
     * @param outSizeX        N?mero de pixels en X de la imagen de salida
182
     * @param outSizeY        N?mero de pixels en Y de la imagen de salida
183
     * @param outFilename        Fichero de salida
184
     * @param extentMaxX        Posici?n en X m?xima del extent
185
     * @param extentMinX        Posici?n en X m?nima del extent
186
     * @param extentMaxY        Posici?n en Y m?xima del extent
187
     * @param extentMinY        Posici?n en Y m?nima del extent
188
     * @param nBands        N?mero de bandas
189
     * @param drvType        Tipo de driver
190
     * @throws GdalException
191
     * @throws IOException
192
     */
193
    public GdalWriter(        IDataWriter dataWriter, 
194
                                             String outFileName, 
195
                                             Integer blockSize, 
196
                                             Integer nBands,
197
                                             ViewPortData vp,
198
                                             Integer compresion,
199
                                             Integer outSizeX,
200
                                             Integer outSizeY,
201
                                             Integer dataType)throws GdalException, IOException {
202
               
203
            ident = outFileName.toLowerCase().substring(outFileName.lastIndexOf(".") + 1); 
204
            driver = (String)typeList.get(ident);
205
        support = new GdalSupportOptions(driver);
206
        this.dataType = dataType.intValue();
207
        
208
        this.dataWriter = dataWriter;
209
        this.outFileName = outFileName;
210

    
211
        this.sizeWindowX = outSizeX.intValue();
212
        this.sizeWindowY = outSizeY.intValue();
213

    
214
        if ((sizeWindowX < 0) || (sizeWindowY < 0)) {
215
            throw new IOException("Tama?o del fichero de salida erroneo.");
216
        }
217

    
218
        this.nBands = nBands.intValue();
219

    
220
        //Calculamos la georeferenciaci?n a partir del extend pasado por el cliente.
221
        if (support.getGeoref()) {
222
                Extent ex = vp.getExtent();
223
            double maxX = ex.maxX();
224
            double minX = ex.minX();
225
            double maxY = ex.maxY();
226
            double minY = ex.minY();
227

    
228
            this.support.setBlockSize(blockSize.intValue());
229
            
230
            geot = new GeoTransform();
231
            geot.adfgeotransform[0] = minX;
232
            geot.adfgeotransform[3] = maxY; //-((pixelSizeY * outSizeY)-minY);
233
            geot.adfgeotransform[1] = (double) ((maxX - minX) / outSizeX.intValue()); //pixelSizeX;
234
            geot.adfgeotransform[5] = (double) ((minY - maxY) / outSizeY.intValue()); //pixelSizeY;
235
        }
236

    
237
        setParams();
238

    
239
        init();
240
    }
241
    
242
    /**
243
     * Constructor para salvar datos servidos por el cliente
244
     * @param dataWriter               Objeto servidor de datos para el driver de escritura
245
     * @param outFilename              Fichero de salida
246
     * @param blockSize                Tama?o de bloque
247
     * @param Extent                   extent
248
     * @param compresion                   Compresi?n si la tiene
249
     * @param outSizeX                          Tama?o de salida en X
250
     * @param outSizeY                        Tama?o de salida en Y
251
     * @param dataType                        Tipo de dato 
252
     * @throws GdalException
253
     * @throws IOException
254
     */
255
    public GdalWriter(        IDataWriter dataWriter, 
256
                                             String outFileName, 
257
                                             Integer blockSize, 
258
                                             Integer nBands,
259
                                             Extent ex,
260
                                             Integer compresion,
261
                                             Integer outSizeX,
262
                                             Integer outSizeY,
263
                                             Integer dataType)throws GdalException, IOException {
264
               
265
            ident = outFileName.toLowerCase().substring(outFileName.lastIndexOf(".") + 1); 
266
            driver = (String)typeList.get(ident);
267
        support = new GdalSupportOptions(driver);
268
        this.dataType = dataType.intValue();
269
        
270
        this.dataWriter = dataWriter;
271
        this.outFileName = outFileName;
272

    
273
        this.sizeWindowX = outSizeX.intValue();
274
        this.sizeWindowY = outSizeY.intValue();
275

    
276
        if ((sizeWindowX < 0) || (sizeWindowY < 0)) {
277
            throw new IOException("Tama?o del fichero de salida erroneo.");
278
        }
279

    
280
        this.nBands = nBands.intValue();
281

    
282
        //Calculamos la georeferenciaci?n a partir del extend pasado por el cliente.
283
        if (support.getGeoref()) {
284
            double maxX = ex.maxX();
285
            double minX = ex.minX();
286
            double maxY = ex.maxY();
287
            double minY = ex.minY();
288

    
289
            this.support.setBlockSize(blockSize.intValue());
290
            
291
            geot = new GeoTransform();
292
            geot.adfgeotransform[0] = minX;
293
            geot.adfgeotransform[3] = maxY; //-((pixelSizeY * outSizeY)-minY);
294
            geot.adfgeotransform[1] = (double) ((maxX - minX) / outSizeX.intValue()); //pixelSizeX;
295
            geot.adfgeotransform[5] = (double) ((minY - maxY) / outSizeY.intValue()); //pixelSizeY;
296
        }
297

    
298
        setParams();
299

    
300
        init();
301
    }
302

    
303
    /**
304
     *Asigna par?metros de creaci?n del dataset de Gdal
305
     */
306
    private void setParams() {
307
        params = new String[5];
308

    
309
        params[0] = new String("TILED=YES");
310
        params[1] = new String("PHOTOMETRIC=" + this.support.getPhotometric());
311
        params[2] = new String("INTERLEAVE=" + this.support.getInterleave());
312
        params[3] = new String("COMPRESS=" + this.support.getCompress());
313

    
314
        String tfw = null;
315

    
316
        if (this.support.getTfw()) {
317
            tfw = new String("YES");
318
        } else {
319
            tfw = new String("NO");
320
        }
321

    
322
        params[4] = new String("TFW=" + tfw);
323
    }
324

    
325
    /**
326
     * Asigna el tipo de driver con el que se salvar? la imagen
327
     * @param drvType        Tipo de driver
328
     */
329
    public void setDriverType(String drvType) {
330
        this.driver = drvType;
331
    }
332

    
333
    /**
334
     * Creaci?n del dataset de destino.
335
     * @throws EcwException
336
     */
337
    private void init() throws GdalException {
338
        //Controlamos que el tipo de driver sea correcto
339
        if (driver == null) {
340
            throw new GdalException("Tipo de driver sin especificar.");
341
        }
342

    
343
        boolean okdrvtype = false;
344

    
345
        String[] types = GeoRasterWriter.getDriversType();
346
        for (int i = 0; i < GeoRasterWriter.getNTypes(); i++)
347
            if (driver.equals(types[i])) {
348
                okdrvtype = true;
349
            }
350

    
351
        if (okdrvtype == false) {
352
            throw new GdalException("El tipo de driver "+driver+" no est? soportado por GdalWriter.");
353
        }
354

    
355
        //Obtenemos el driver y creamos el dataset del destino
356
        drv = Gdal.getDriverByName(driver);
357
        
358
        if (dset_destino != null) {
359
            dset_destino.close();
360
            dset_destino = null;
361
        }
362
                
363
        dset_destino = drv.create(outFileName, sizeWindowX, sizeWindowY,
364
                                  nBands, Utilities.getGdalTypeFromRasterBufType(dataType), params);
365

    
366
        if (this.support.getGeoref()) {
367
            dset_destino.setGeoTransform(geot);
368
        }
369

    
370
        nBlocks = (int) (sizeWindowY / this.support.getBlockSize());
371
        anchoResto = sizeWindowY - (nBlocks * this.support.getBlockSize());
372
    }
373

    
374
    /**
375
     * A partir de un elemento que contiene una propiedad y un valor
376
     * lo parsea y asigna el valor a su variable.
377
     * @param propValue        elemento con la forma propiedad=valor
378
     */
379
    private void readProperty(String propValue) {
380
        String prop = propValue.substring(0, propValue.indexOf("="));
381

    
382
        if (propValue.startsWith(prop)) {
383
            String value = propValue.substring(propValue.indexOf("=") + 1,
384
                                               propValue.length());
385

    
386
            if ((value != null) && !value.equals("")) {
387
                if (prop.equals("BLOCKSIZE")) {
388
                    this.support.setBlockSize(Integer.parseInt(value));
389
                }
390

    
391
                if (prop.equals("GEOREF")) {
392
                    boolean georef = true;
393

    
394
                    if (value.equals("yes")) {
395
                        georef = true;
396
                    } else {
397
                        georef = false;
398
                    }
399

    
400
                    this.support.setWriteGeoref(georef);
401
                }
402

    
403
                if (prop.equals("INTERLEAVE")) {
404
                    this.support.setInterleave(value);
405
                }
406

    
407
                if (prop.equals("PHOTOMETRIC")) {
408
                    this.support.setPhotometric(value);
409
                }
410

    
411
                if (prop.equals("COMPRESS")) {
412
                    this.support.setCompress(value);
413
                }
414

    
415
                if (prop.equals("TFW")) {
416
                    boolean tfw = true;
417

    
418
                    if (value.equals("yes")) {
419
                        tfw = true;
420
                    } else {
421
                        tfw = false;
422
                    }
423

    
424
                    this.support.setTfw(tfw);
425
                }
426
            }
427
        }
428
    }
429

    
430
    /**
431
     * Asigna propiedades al driver a partir de un vector de
432
     * strings donde cada elemento tiene la estructura de
433
     * propiedad=valor.
434
     * @param props        Propiedades
435
     */
436
    public void setProps(String[] props) {
437
        for (int iProps = 0; iProps < props.length; iProps++)
438
            readProperty(props[iProps]);
439

    
440
        setParams();
441

    
442
        try {
443
            if (!consulta) {
444
                init();
445
            }
446
        } catch (GdalException e) {
447
            e.printStackTrace();
448
        }
449
    }
450

    
451
    /**
452
     * Escritura de datos tipo Byte.
453
     * @param sizeY Alto del bloque que se escribe.
454
     * @param posicionY Posici?ny a partir desde donde se comienza.
455
     */
456
    public void writeByteBand(int sizeY, int posicionY){
457
            byte[][] buftmp = dataWriter.readByteData(sizeWindowX, sizeY);
458
            for(int iBand = 0; iBand < nBands; iBand ++)
459
                bufBands[iBand].buffByte = new byte[buftmp[iBand].length];        
460
  
461
            //Escribimos el bloque destino
462
            for (int iBand = 0; iBand < buftmp.length; iBand++)
463
                    for (int i = 0; i < buftmp[iBand].length; i++)
464
                            bufBands[iBand].buffByte[i] = buftmp[iBand][i];
465
            
466
        for (int iBand = 0; iBand < buftmp.length; iBand++){
467
                try {
468
                                rband = dset_destino.getRasterBand(iBand + 1);
469
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Byte);
470
                } catch (GdalException e) {
471
                                //No se est? escribiendo ...
472
                        }
473
        }
474
    }
475
    
476
    /**
477
     * Escritura de datos tipo Short.
478
     * @param sizeY Alto del bloque que se escribe.
479
     * @param posicionY Posici?ny a partir desde donde se comienza.
480
     */
481
    public void writeShortBand(int sizeY, int posicionY){
482
            short[][] buftmp = dataWriter.readShortData(sizeWindowX, sizeY);
483
            for(int iBand = 0; iBand < nBands; iBand ++)
484
                bufBands[iBand].buffShort = new short[buftmp[iBand].length];        
485
  
486
            //Escribimos el bloque destino
487
            for (int iBand = 0; iBand < buftmp.length; iBand++)
488
                    for (int i = 0; i < buftmp[iBand].length; i++)
489
                            bufBands[iBand].buffShort[i] = buftmp[iBand][i];
490
            
491
        for (int iBand = 0; iBand < buftmp.length; iBand++){
492
                try {
493
                                rband = dset_destino.getRasterBand(iBand + 1);
494
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Int16);
495
                } catch (GdalException e) {
496
                                //No se est? escribiendo ...
497
                        }
498
        }
499
    }
500
        
501
    /**
502
     * Escritura de datos tipo Int.
503
     * @param sizeY Alto del bloque que se escribe.
504
     * @param posicionY Posici?ny a partir desde donde se comienza.
505
     */
506
    public void writeIntBand(int sizeY, int posicionY){
507
            int[][] buftmp = dataWriter.readIntData(sizeWindowX, sizeY);
508
            for(int iBand = 0; iBand < nBands; iBand ++)
509
                bufBands[iBand].buffInt = new int[buftmp[iBand].length];        
510
  
511
            //Escribimos el bloque destino
512
            for (int iBand = 0; iBand < buftmp.length; iBand++)
513
                    for (int i = 0; i < buftmp[iBand].length; i++)
514
                            bufBands[iBand].buffInt[i] = buftmp[iBand][i];
515
            
516
        for (int iBand = 0; iBand < buftmp.length; iBand++){
517
                try {
518
                                rband = dset_destino.getRasterBand(iBand + 1);
519
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Int32);
520
                } catch (GdalException e) {
521
                                //No se est? escribiendo ...
522
                        }
523
        }
524
    }
525
    
526
    /**
527
     * Escritura de datos tipo Float.
528
     * @param sizeY Alto del bloque que se escribe.
529
     * @param posicionY Posici?ny a partir desde donde se comienza.
530
     */
531
    public void writeFloatBand(int sizeY, int posicionY){
532
            float[][] buftmp = dataWriter.readFloatData(sizeWindowX, sizeY);
533
            for(int iBand = 0; iBand < nBands; iBand ++)
534
                bufBands[iBand].buffFloat = new float[buftmp[iBand].length];        
535
  
536
            //Escribimos el bloque destino
537
            for (int iBand = 0; iBand < buftmp.length; iBand++)
538
                    for (int i = 0; i < buftmp[iBand].length; i++)
539
                            bufBands[iBand].buffFloat[i] = buftmp[iBand][i];
540
            
541
        for (int iBand = 0; iBand < buftmp.length; iBand++){
542
                try {
543
                                rband = dset_destino.getRasterBand(iBand + 1);
544
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Float32);
545
                } catch (GdalException e) {
546
                                //No se est? escribiendo ...
547
                        }
548
        }
549
    }
550
    
551
    /**
552
     * Escritura de datos tipo Double.
553
     * @param sizeY Alto del bloque que se escribe.
554
     * @param posicionY Posici?ny a partir desde donde se comienza.
555
     */
556
    public void writeDoubleBand(int sizeY, int posicionY){
557
            double[][] buftmp = dataWriter.readDoubleData(sizeWindowX, sizeY);
558
            for(int iBand = 0; iBand < nBands; iBand ++)
559
                bufBands[iBand].buffDouble = new double[buftmp[iBand].length];        
560
  
561
            //Escribimos el bloque destino
562
            for (int iBand = 0; iBand < buftmp.length; iBand++)
563
                    for (int i = 0; i < buftmp[iBand].length; i++)
564
                            bufBands[iBand].buffDouble[i] = buftmp[iBand][i];
565
            
566
        for (int iBand = 0; iBand < buftmp.length; iBand++){
567
                try {
568
                                rband = dset_destino.getRasterBand(iBand + 1);
569
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Float64);
570
                } catch (GdalException e) {
571
                                //No se est? escribiendo ...
572
                        }
573
        }
574
    }
575
    /**
576
     * Escritura para tipo de dato ARGB.
577
     * @param sizeY Alto del bloque que se escribe.
578
     * @param posicionY Posici?ny a partir desde donde se comienza.
579
     */
580
    public void writeARGBBand(int sizeY, int posicionY){
581
            int[] buftmp = dataWriter.readARGBData(sizeWindowX, sizeY, 0);
582
             for(int iBand = 0; iBand < nBands; iBand ++)
583
                 bufBands[iBand].buffByte = new byte[buftmp.length];        
584
             
585
         //Escribimos el bloque destino
586
         for (int i = 0; i < buftmp.length; i++) {
587
             bufBands[0].buffByte[i] = (byte) (((buftmp[i] & 0xff0000) >> 16) &
588
                                    0xff);
589
             bufBands[1].buffByte[i] = (byte) (((buftmp[i] & 0xff00) >> 8) & 0xff);
590
             bufBands[2].buffByte[i] = (byte) ((buftmp[i] & 0xff) & 0xff);
591
         }
592

    
593
         try {
594
             rband = dset_destino.getRasterBand(1);
595
             rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[0],
596
                               Gdal.GDT_Byte);
597
             rband = dset_destino.getRasterBand(2);
598
             rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[1],
599
                               Gdal.GDT_Byte);
600
             rband = dset_destino.getRasterBand(3);
601
             rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[2],
602
                               Gdal.GDT_Byte);
603
         } catch (GdalException e) {
604
             e.printStackTrace();
605
         }
606
    }
607
    
608
    /**
609
     * Escribe tres bandas en el GDALRasterBand desde el IDataWriter con una
610
     * altura definida por sizeY.
611
     * @param buftmp        Buffer
612
     * @param sizeY        Altura en pixels del bloque leido
613
     * @param posicionY        Posici?n y a partir de la cual se escribe en el GDALRasterBand destino
614
     */
615
    private void writeBands(int sizeY, int posicionY) {
616
        //leemos el bloque origen
617
        
618
        switch(dataType){
619
        case RasterBuf.TYPE_IMAGE: 
620
                writeARGBBand(sizeY, posicionY);
621
                break;
622
        case RasterBuf.TYPE_BYTE:
623
                writeByteBand(sizeY, posicionY);
624
                break;
625
        case RasterBuf.TYPE_SHORT:
626
                writeShortBand(sizeY, posicionY);
627
                break;
628
        case RasterBuf.TYPE_INT:
629
                writeIntBand(sizeY, posicionY);
630
                break;
631
        case RasterBuf.TYPE_FLOAT:
632
                writeFloatBand(sizeY, posicionY);
633
                break;
634
        case RasterBuf.TYPE_DOUBLE:
635
                writeDoubleBand(sizeY, posicionY);
636
                break;
637
        }
638
    }
639

    
640
    /**
641
     * Funci?n que gestiona la lectura desde el origen y la escritura
642
     * de Gdal sobre el fichero destino.
643
     * @param mode        Modo de escritura
644
     * @throws IOException
645
     */
646
    private void write(int mode) throws IOException {
647
        buf = new GdalBuffer();
648
        bufBands = new GdalBuffer[nBands];
649
        for(int iBand = 0; iBand < nBands; iBand ++)
650
                bufBands[iBand] = new GdalBuffer();
651
        
652
       // int[] buftmp = null;
653

    
654
        //long t1 = System.currentTimeMillis();
655
        try {
656
            if (mode == Mode.fileWrite) {
657
                for (int iBand = 0; iBand < this.nBands; iBand++) {
658
                    rband = dset_destino.getRasterBand(iBand + 1);
659

    
660
                    for (int iBlock = 0; iBlock < nBlocks; iBlock++) {
661
                            if(write){
662
                                //leemos el bloque origen
663
                                buf.buffByte = currentRaster.getGeoFile().getWindow(0,
664
                                                                                    iBlock * this.support.getBlockSize(),
665
                                                                                    sizeWindowX,
666
                                                                                    this.support.getBlockSize(),
667
                                                                                    iBand +
668
                                                                                    1);
669
        
670
                                //Escribimos el bloque destino
671
                                rband.writeRaster(0,
672
                                                  iBlock * this.support.getBlockSize(),
673
                                                  sizeWindowX,
674
                                                  this.support.getBlockSize(), buf,
675
                                                  Gdal.GDT_Byte);
676
                            }/*else
677
                                    this.writeClose();*/
678
                    }
679
                }
680
            } else if (mode == Mode.dataWrite) {
681
                //for(int iBlock=1;iBlock<=nBlocks;iBlock++){
682
                for (int iBlock = 0; iBlock < nBlocks; iBlock++) {
683
                    int posicionY = iBlock * this.support.getBlockSize();
684
                    if(write)
685
                            writeBands( this.support.getBlockSize(), posicionY);
686
                    /*else
687
                            this.writeClose();*/
688
                }
689
            }
690

    
691
            if (anchoResto != 0) {
692
                if (mode == Mode.fileWrite) {
693
                    for (int iBand = 0; iBand < this.nBands; iBand++) {
694
                        rband = dset_destino.getRasterBand(iBand + 1);
695
                        if(write){
696
                                //leemos el bloque origen
697
                                buf.buffByte = currentRaster.getGeoFile().getWindow(0,
698
                                                                                    nBlocks * this.support.getBlockSize(),
699
                                                                                    sizeWindowX,
700
                                                                                    anchoResto,
701
                                                                                    iBand +
702
                                                                                    1);
703
        
704
                                //Escribimos el bloque destino
705
                                rband.writeRaster(0,
706
                                                  nBlocks * this.support.getBlockSize(),
707
                                                  sizeWindowX, anchoResto, buf,
708
                                                  Gdal.GDT_Byte);
709
                        }/*else
710
                                this.writeClose();*/
711
                    }
712
                } else if (mode == Mode.dataWrite) {
713
                    int posicionY = nBlocks * this.support.getBlockSize();
714
                    if(write)
715
                            writeBands(anchoResto, posicionY);
716
                    /*else
717
                            this.writeClose();*/
718
                }
719
            }
720
        } catch (GdalException e) {
721
            e.printStackTrace();
722
        }
723
    }
724

    
725
    /**
726
     * Realiza la funci?n de compresi?n a partir de un GeoRasterFile.
727
     * @throws IOException
728
     */
729
    public void fileWrite() throws IOException {
730
        if (currentRaster == null) {
731
            throw new IOException("No se ha asignado un fichero de entrada.");
732
        }
733

    
734
        this.write(Mode.fileWrite);
735
    }
736

    
737
    /**
738
     * Realiza una copia en el formato especificado.
739
     * @throws IOException
740
     */
741
    public static void createCopy(GdalDriver driverDst, String dst, String src, 
742
                    boolean bstrict, String[] params, IProjection proj) throws IOException, GdalException {
743
        if (dst == null || src == null) {
744
            throw new IOException("No se ha asignado un fichero de entrada.");
745
        }
746

    
747
        GdalFile gdalFile;
748
                try {
749
                        gdalFile = new GdalFile(proj, src);
750
                driverDst.createCopy(dst, gdalFile.file, bstrict, params);
751
                if(dst.endsWith(".jpg") || dst.endsWith(".jpeg"))
752
                        GdalWriter.createWorldFile(dst, gdalFile);
753
                gdalFile.close();
754
                } catch (NotSupportedExtensionException e) {
755
                        e.printStackTrace();
756
                }
757
    }
758
    
759
    /**
760
         * Crea un fichero de georeferenciaci?n
761
         * @param img
762
         * @param name
763
         * @return
764
         * @throws IOException
765
         */
766
        private static void createWorldFile(String name, GdalFile gdalFile) throws IOException{
767
            File tfw = null;
768
            
769
            String extWorldFile = ".wld";
770
            if(name.endsWith("tif"))
771
                    extWorldFile = ".tfw";
772
            if(name.endsWith("jpg") || name.endsWith("jpeg"))
773
                    extWorldFile = ".jpgw";
774
                                
775
            tfw = new File(name.substring(0, name.lastIndexOf(".")) + extWorldFile);
776
            
777
            //Generamos un world file para gdal
778
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(tfw)) );
779
            dos.writeBytes((gdalFile.getExtent().getMax().getX() - gdalFile.getExtent().getMin().getX())/gdalFile.getWidth()+"\n");
780
            dos.writeBytes("0.0\n");
781
            dos.writeBytes("0.0\n");
782
            dos.writeBytes((gdalFile.getExtent().getMax().getY() - gdalFile.getExtent().getMin().getY())/gdalFile.getHeight()+"\n");
783
            dos.writeBytes(""+gdalFile.getExtent().getMin().getX()+"\n");
784
            dos.writeBytes(""+gdalFile.getExtent().getMin().getY()+"\n");
785
            dos.close();    
786
        }
787

    
788
    
789
    /**
790
     * Realiza la escritura de datos con los datos que le pasa el cliente.
791
     * @throws IOException
792
     */
793
    public void dataWrite() throws IOException {
794
        if (dataWriter == null) {
795
            throw new IOException("No se ha obtenido un objeto de entrada para la escritura valido.");
796
        }
797

    
798
        this.write(Mode.dataWrite);
799
    }
800

    
801
    /**
802
     * Cancela el salvado de datos.
803
     * @throws GdalException
804
     */
805
    public void writeClose() {
806
        try {
807
                if(dset_destino != null)
808
                        dset_destino.close();
809
            oSRS = null;
810
        } catch (GdalException e) {
811
            e.printStackTrace();
812
        }
813
    }
814

    
815
    /**
816
     * Cancela el salvado de datos.
817
     */
818
    public void writeCancel() {
819
       write = false; 
820
    }
821
    
822
    /**
823
     * Devuelve la configuraci?n de la ventana de dialogo
824
     * para las propiedades del driver de escritura de Gdal.
825
     * @return XML de configuraci?n del dialogo.
826
     */
827
    public String getXMLPropertiesDialog() {
828
        StringBuffer options = null;
829
        options = new StringBuffer();
830
        options.append("<window sizex=\"" + this.windowSizeX + "\" sizey=\"" +
831
                       this.windowSizeY + "\">");
832
        options.append("<panel sizex=\"" + this.panelSizeX + "\" sizey=\"" +
833
                       this.panelSizeY + "\" layout=\"" + this.panelLayout +
834
                       "\" border=\"yes\">");
835

    
836
        options.append("<panel layout=\"FlowLayout\" position=\"North\" align=\"left\">");
837
        options.append("<label>Block Size:</label>");
838
        options.append("<combo ident=\"BLOCKSIZE\" selected=\"" +
839
                       this.support.getBlockSize() + "\">");
840

    
841
        for (int i = 0; i < this.support.getBlockSizeList().length; i++)
842
            options.append("<elem>" + this.support.getBlockSizeList()[i] +
843
                           "</elem>");
844

    
845
        options.append("</combo>");
846
        //options.append("<label>Georef Si/No:</label>");
847

    
848
        String sel = null;
849

    
850
        if (this.support.getGeoref()) {
851
            sel = new String("yes");
852
        } else {
853
            sel = new String("no");
854
        }
855

    
856
        /*options.append("<check ident=\"GEOREF\" selected=\"" + sel +
857
                       "\" text=\"\">");
858
        options.append("</check>");*/
859
        options.append("</panel>");
860

    
861
        options.append("<panel layout=\"FlowLayout\" position=\"Center\" align=\"left\">");
862
        options.append("<label>Photometric:</label>");
863
        options.append("<combo ident=\"PHOTOMETRIC\" selected=\"" +
864
                       this.support.getPhotometric() + "\">");
865

    
866
        for (int i = 0; i < this.support.getPhotometricList().length; i++)
867
            options.append("<elem>" + this.support.getPhotometricList()[i] +
868
                           "</elem>");
869

    
870
        options.append("</combo>");
871
        options.append("<label>Interleave:</label>");
872
        options.append("<combo ident=\"INTERLEAVE\" selected=\"" +
873
                       this.support.getInterleave() + "\">");
874

    
875
        for (int i = 0; i < this.support.getInterleaveList().length; i++)
876
            options.append("<elem>" + this.support.getInterleaveList()[i] +
877
                           "</elem>");
878

    
879
        options.append("</combo>");
880
        options.append("</panel>");
881

    
882
        options.append("<panel layout=\"FlowLayout\" position=\"South\" align=\"left\">");
883
        options.append("<label>Compresi?n:</label>");
884
        options.append("<combo ident=\"COMPRESS\" selected=\"" +
885
                       this.support.getCompress() + "\">");
886

    
887
        for (int i = 0; i < this.support.getCompressList().length; i++)
888
            options.append("<elem>" + this.support.getCompressList()[i] +
889
                           "</elem>");
890

    
891
        options.append("</combo>");
892
        options.append("<label>Generar Tfw:</label>");
893
        sel = null;
894

    
895
        if (this.support.getTfw()) {
896
            sel = new String("yes");
897
        } else {
898
            sel = new String("no");
899
        }
900

    
901
        options.append("<check ident=\"TFW\" selected=\"" + sel +
902
                       "\" text=\"\">");
903
        options.append("</check>");
904
        options.append("</panel>");
905

    
906
        options.append("</panel>");
907
        options.append("</window>");
908

    
909
        return options.toString();
910
    }
911

    
912
    /**
913
     * Obtiene el valor a la variable write que estar? a true cuando se est? escribiendo
914
     *  o puede escribirse la imagen de salida. El cancelar la operaci?n de escritura
915
     * pondr? esta variable a false deteniendose la escritura y cerrandose el dataset
916
     * de salida. 
917
     * @return True si puede escribirse y false si no puede
918
     */
919
    public boolean isWrite() {
920
                return write;
921
        }
922

    
923
    /**
924
     * Asigna el valor a la variable write que estar? a true cuando se est? escribiendo
925
     *  o puede escribirse la imagen de salida. El cancelar la operaci?n de escritura
926
     * pondr? esta variable a false deteniendose la escritura y cerrandose el dataset
927
     * de salida. 
928
     * @param write Variable booleana. True si puede escribirse y false si no puede
929
     */
930
        public void setWrite(boolean write) {
931
                this.write = write;
932
        }
933
        
934
        /**
935
         * Obtiene las opciones de salvado.
936
         * @return GdalSupportOptions
937
         */
938
        public GdalSupportOptions getSupport(){
939
            return this.support; 
940
    }
941
        
942
    /**
943
     *
944
     * @author Nacho Brodin (brodin_ign@gva.es)
945
     *
946
     * Opciones que soporta el driver de escritura de Gdal.
947
     */
948
    public class GdalSupportOptions extends WriterSupportOptions {
949
        private String[]         photometric = {
950
                                           "YCBR", "MINISBLACK", "MINISWHITE",
951
                                           "RGB", "CMYK", "CIELAB", "ICCLAB",
952
                                           "ITULAB", "CBCR"
953
                                       };
954
        private String[]         interleave = { "BAND", "PIXEL" };
955
        private String[]         compress = { "LZW", "PACKBITS", "DEFLATE", "NONE" };
956
        private String                 photometricDefault = "RGB";
957
        private String                 interleaveDefault = "BAND";
958
        private String                 compressDefault = "NONE";
959
       
960
        private boolean tfw = false;
961

    
962
        public GdalSupportOptions(String ext) {
963
            super(ext);
964
        }
965

    
966
        /**
967
         * @param defaultPhot        Tipo de imagen
968
         */
969
        public void setPhotometric(String defaultPhot) {
970
            this.photometricDefault = defaultPhot;
971
        }
972

    
973
        /**
974
         * @param defaultInt
975
         */
976
        public void setInterleave(String defaultInt) {
977
            this.interleaveDefault = defaultInt;
978
        }
979

    
980
        /**
981
         * @param defaultComp
982
         */
983
        public void setCompress(String defaultComp) {
984
            this.compressDefault = defaultComp;
985
        }
986

    
987
        /**
988
         * Asigna true o false si se desea generar un fichero tfw con la
989
         * georeferenciaci?n o no;
990
         * @param tfw true se genera el fichero tfw y false no se genera
991
         */
992
        public void setTfw(boolean tfw) {
993
            this.tfw = tfw;
994
        }
995

    
996
        /**
997
         * @return
998
         */
999
        public String[] getPhotometricList() {
1000
            return photometric;
1001
        }
1002

    
1003
        /**
1004
         * @return
1005
         */
1006
        public String[] getInterleaveList() {
1007
            return interleave;
1008
        }
1009

    
1010
        /**
1011
         * @return
1012
         */
1013
        public String[] getCompressList() {
1014
            return compress;
1015
        }
1016

    
1017
        /**
1018
         * @return
1019
         */
1020
        public String getPhotometric() {
1021
            return photometricDefault;
1022
        }
1023

    
1024
        /**
1025
         * @return
1026
         */
1027
        public String getInterleave() {
1028
            return interleaveDefault;
1029
        }
1030

    
1031
        /**
1032
         * Obtiene el par?metro de compresi?n
1033
         * @return
1034
         */
1035
        public String getCompress() {
1036
            return compressDefault;
1037
        }
1038

    
1039
        /**
1040
         * Devuelve true o false si se genera un fichero tfw con la
1041
         * georeferenciaci?n o no;
1042
         * @param tfw true se genera el fichero tfw y false no se genera
1043
         */
1044
        public boolean getTfw() {
1045
            return tfw;
1046
        }
1047
    }
1048

    
1049
    private class Mode {
1050
        public final static int fileWrite = 0;
1051
        public final static int dataWrite = 1;
1052
    }
1053
}