Statistics
| Revision:

root / trunk / libraries / libCq_CMS_praster / src / org / cresques / io / GdalWriter.java @ 8026

History | View | Annotate | Download (35 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
     *Asigna par?metros de creaci?n del dataset de Gdal
244
     */
245
    private void setParams() {
246
        params = new String[5];
247

    
248
        params[0] = new String("TILED=YES");
249
        params[1] = new String("PHOTOMETRIC=" + this.support.getPhotometric());
250
        params[2] = new String("INTERLEAVE=" + this.support.getInterleave());
251
        params[3] = new String("COMPRESS=" + this.support.getCompress());
252

    
253
        String tfw = null;
254

    
255
        if (this.support.getTfw()) {
256
            tfw = new String("YES");
257
        } else {
258
            tfw = new String("NO");
259
        }
260

    
261
        params[4] = new String("TFW=" + tfw);
262
    }
263

    
264
    /**
265
     * Asigna el tipo de driver con el que se salvar? la imagen
266
     * @param drvType        Tipo de driver
267
     */
268
    public void setDriverType(String drvType) {
269
        this.driver = drvType;
270
    }
271

    
272
    /**
273
     * Creaci?n del dataset de destino.
274
     * @throws EcwException
275
     */
276
    private void init() throws GdalException {
277
        //Controlamos que el tipo de driver sea correcto
278
        if (driver == null) {
279
            throw new GdalException("Tipo de driver sin especificar.");
280
        }
281

    
282
        boolean okdrvtype = false;
283

    
284
        String[] types = GeoRasterWriter.getDriversType();
285
        for (int i = 0; i < GeoRasterWriter.getNTypes(); i++)
286
            if (driver.equals(types[i])) {
287
                okdrvtype = true;
288
            }
289

    
290
        if (okdrvtype == false) {
291
            throw new GdalException("El tipo de driver "+driver+" no est? soportado por GdalWriter.");
292
        }
293

    
294
        //Obtenemos el driver y creamos el dataset del destino
295
        drv = Gdal.getDriverByName(driver);
296
        
297
        if (dset_destino != null) {
298
            dset_destino.close();
299
            dset_destino = null;
300
        }
301
                
302
        dset_destino = drv.create(outFileName, sizeWindowX, sizeWindowY,
303
                                  nBands, Utilities.getGdalTypeFromRasterBufType(dataType), params);
304

    
305
        if (this.support.getGeoref()) {
306
            dset_destino.setGeoTransform(geot);
307
        }
308

    
309
        nBlocks = (int) (sizeWindowY / this.support.getBlockSize());
310
        anchoResto = sizeWindowY - (nBlocks * this.support.getBlockSize());
311
    }
312

    
313
    /**
314
     * A partir de un elemento que contiene una propiedad y un valor
315
     * lo parsea y asigna el valor a su variable.
316
     * @param propValue        elemento con la forma propiedad=valor
317
     */
318
    private void readProperty(String propValue) {
319
        String prop = propValue.substring(0, propValue.indexOf("="));
320

    
321
        if (propValue.startsWith(prop)) {
322
            String value = propValue.substring(propValue.indexOf("=") + 1,
323
                                               propValue.length());
324

    
325
            if ((value != null) && !value.equals("")) {
326
                if (prop.equals("BLOCKSIZE")) {
327
                    this.support.setBlockSize(Integer.parseInt(value));
328
                }
329

    
330
                if (prop.equals("GEOREF")) {
331
                    boolean georef = true;
332

    
333
                    if (value.equals("yes")) {
334
                        georef = true;
335
                    } else {
336
                        georef = false;
337
                    }
338

    
339
                    this.support.setWriteGeoref(georef);
340
                }
341

    
342
                if (prop.equals("INTERLEAVE")) {
343
                    this.support.setInterleave(value);
344
                }
345

    
346
                if (prop.equals("PHOTOMETRIC")) {
347
                    this.support.setPhotometric(value);
348
                }
349

    
350
                if (prop.equals("COMPRESS")) {
351
                    this.support.setCompress(value);
352
                }
353

    
354
                if (prop.equals("TFW")) {
355
                    boolean tfw = true;
356

    
357
                    if (value.equals("yes")) {
358
                        tfw = true;
359
                    } else {
360
                        tfw = false;
361
                    }
362

    
363
                    this.support.setTfw(tfw);
364
                }
365
            }
366
        }
367
    }
368

    
369
    /**
370
     * Asigna propiedades al driver a partir de un vector de
371
     * strings donde cada elemento tiene la estructura de
372
     * propiedad=valor.
373
     * @param props        Propiedades
374
     */
375
    public void setProps(String[] props) {
376
        for (int iProps = 0; iProps < props.length; iProps++)
377
            readProperty(props[iProps]);
378

    
379
        setParams();
380

    
381
        try {
382
            if (!consulta) {
383
                init();
384
            }
385
        } catch (GdalException e) {
386
            e.printStackTrace();
387
        }
388
    }
389

    
390
    /**
391
     * Escritura de datos tipo Byte.
392
     * @param sizeY Alto del bloque que se escribe.
393
     * @param posicionY Posici?ny a partir desde donde se comienza.
394
     */
395
    public void writeByteBand(int sizeY, int posicionY){
396
            byte[][] buftmp = dataWriter.readByteData(sizeWindowX, sizeY);
397
            for(int iBand = 0; iBand < nBands; iBand ++)
398
                bufBands[iBand].buffByte = new byte[buftmp[iBand].length];        
399
  
400
            //Escribimos el bloque destino
401
            for (int iBand = 0; iBand < buftmp.length; iBand++)
402
                    for (int i = 0; i < buftmp[iBand].length; i++)
403
                            bufBands[iBand].buffByte[i] = buftmp[iBand][i];
404
            
405
        for (int iBand = 0; iBand < buftmp.length; iBand++){
406
                try {
407
                                rband = dset_destino.getRasterBand(iBand + 1);
408
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Byte);
409
                } catch (GdalException e) {
410
                                //No se est? escribiendo ...
411
                        }
412
        }
413
    }
414
    
415
    /**
416
     * Escritura de datos tipo Short.
417
     * @param sizeY Alto del bloque que se escribe.
418
     * @param posicionY Posici?ny a partir desde donde se comienza.
419
     */
420
    public void writeShortBand(int sizeY, int posicionY){
421
            short[][] buftmp = dataWriter.readShortData(sizeWindowX, sizeY);
422
            for(int iBand = 0; iBand < nBands; iBand ++)
423
                bufBands[iBand].buffShort = new short[buftmp[iBand].length];        
424
  
425
            //Escribimos el bloque destino
426
            for (int iBand = 0; iBand < buftmp.length; iBand++)
427
                    for (int i = 0; i < buftmp[iBand].length; i++)
428
                            bufBands[iBand].buffShort[i] = buftmp[iBand][i];
429
            
430
        for (int iBand = 0; iBand < buftmp.length; iBand++){
431
                try {
432
                                rband = dset_destino.getRasterBand(iBand + 1);
433
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Int16);
434
                } catch (GdalException e) {
435
                                //No se est? escribiendo ...
436
                        }
437
        }
438
    }
439
        
440
    /**
441
     * Escritura de datos tipo Int.
442
     * @param sizeY Alto del bloque que se escribe.
443
     * @param posicionY Posici?ny a partir desde donde se comienza.
444
     */
445
    public void writeIntBand(int sizeY, int posicionY){
446
            int[][] buftmp = dataWriter.readIntData(sizeWindowX, sizeY);
447
            for(int iBand = 0; iBand < nBands; iBand ++)
448
                bufBands[iBand].buffInt = new int[buftmp[iBand].length];        
449
  
450
            //Escribimos el bloque destino
451
            for (int iBand = 0; iBand < buftmp.length; iBand++)
452
                    for (int i = 0; i < buftmp[iBand].length; i++)
453
                            bufBands[iBand].buffInt[i] = buftmp[iBand][i];
454
            
455
        for (int iBand = 0; iBand < buftmp.length; iBand++){
456
                try {
457
                                rband = dset_destino.getRasterBand(iBand + 1);
458
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Int32);
459
                } catch (GdalException e) {
460
                                //No se est? escribiendo ...
461
                        }
462
        }
463
    }
464
    
465
    /**
466
     * Escritura de datos tipo Float.
467
     * @param sizeY Alto del bloque que se escribe.
468
     * @param posicionY Posici?ny a partir desde donde se comienza.
469
     */
470
    public void writeFloatBand(int sizeY, int posicionY){
471
            float[][] buftmp = dataWriter.readFloatData(sizeWindowX, sizeY);
472
            for(int iBand = 0; iBand < nBands; iBand ++)
473
                bufBands[iBand].buffFloat = new float[buftmp[iBand].length];        
474
  
475
            //Escribimos el bloque destino
476
            for (int iBand = 0; iBand < buftmp.length; iBand++)
477
                    for (int i = 0; i < buftmp[iBand].length; i++)
478
                            bufBands[iBand].buffFloat[i] = buftmp[iBand][i];
479
            
480
        for (int iBand = 0; iBand < buftmp.length; iBand++){
481
                try {
482
                                rband = dset_destino.getRasterBand(iBand + 1);
483
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Float32);
484
                } catch (GdalException e) {
485
                                //No se est? escribiendo ...
486
                        }
487
        }
488
    }
489
    
490
    /**
491
     * Escritura de datos tipo Double.
492
     * @param sizeY Alto del bloque que se escribe.
493
     * @param posicionY Posici?ny a partir desde donde se comienza.
494
     */
495
    public void writeDoubleBand(int sizeY, int posicionY){
496
            double[][] buftmp = dataWriter.readDoubleData(sizeWindowX, sizeY);
497
            for(int iBand = 0; iBand < nBands; iBand ++)
498
                bufBands[iBand].buffDouble = new double[buftmp[iBand].length];        
499
  
500
            //Escribimos el bloque destino
501
            for (int iBand = 0; iBand < buftmp.length; iBand++)
502
                    for (int i = 0; i < buftmp[iBand].length; i++)
503
                            bufBands[iBand].buffDouble[i] = buftmp[iBand][i];
504
            
505
        for (int iBand = 0; iBand < buftmp.length; iBand++){
506
                try {
507
                                rband = dset_destino.getRasterBand(iBand + 1);
508
                                rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[iBand], Gdal.GDT_Float64);
509
                } catch (GdalException e) {
510
                                //No se est? escribiendo ...
511
                        }
512
        }
513
    }
514
    /**
515
     * Escritura para tipo de dato ARGB.
516
     * @param sizeY Alto del bloque que se escribe.
517
     * @param posicionY Posici?ny a partir desde donde se comienza.
518
     */
519
    public void writeARGBBand(int sizeY, int posicionY){
520
            int[] buftmp = dataWriter.readARGBData(sizeWindowX, sizeY, 0);
521
             for(int iBand = 0; iBand < nBands; iBand ++)
522
                 bufBands[iBand].buffByte = new byte[buftmp.length];        
523
             
524
         //Escribimos el bloque destino
525
         for (int i = 0; i < buftmp.length; i++) {
526
             bufBands[0].buffByte[i] = (byte) (((buftmp[i] & 0xff0000) >> 16) &
527
                                    0xff);
528
             bufBands[1].buffByte[i] = (byte) (((buftmp[i] & 0xff00) >> 8) & 0xff);
529
             bufBands[2].buffByte[i] = (byte) ((buftmp[i] & 0xff) & 0xff);
530
         }
531

    
532
         try {
533
             rband = dset_destino.getRasterBand(1);
534
             rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[0],
535
                               Gdal.GDT_Byte);
536
             rband = dset_destino.getRasterBand(2);
537
             rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[1],
538
                               Gdal.GDT_Byte);
539
             rband = dset_destino.getRasterBand(3);
540
             rband.writeRaster(0, posicionY, sizeWindowX, sizeY, bufBands[2],
541
                               Gdal.GDT_Byte);
542
         } catch (GdalException e) {
543
             e.printStackTrace();
544
         }
545
    }
546
    
547
    /**
548
     * Escribe tres bandas en el GDALRasterBand desde el IDataWriter con una
549
     * altura definida por sizeY.
550
     * @param buftmp        Buffer
551
     * @param sizeY        Altura en pixels del bloque leido
552
     * @param posicionY        Posici?n y a partir de la cual se escribe en el GDALRasterBand destino
553
     */
554
    private void writeBands(int sizeY, int posicionY) {
555
        //leemos el bloque origen
556
        
557
        switch(dataType){
558
        case RasterBuf.TYPE_IMAGE: 
559
                writeARGBBand(sizeY, posicionY);
560
                break;
561
        case RasterBuf.TYPE_BYTE:
562
                writeByteBand(sizeY, posicionY);
563
                break;
564
        case RasterBuf.TYPE_SHORT:
565
                writeShortBand(sizeY, posicionY);
566
                break;
567
        case RasterBuf.TYPE_INT:
568
                writeIntBand(sizeY, posicionY);
569
                break;
570
        case RasterBuf.TYPE_FLOAT:
571
                writeFloatBand(sizeY, posicionY);
572
                break;
573
        case RasterBuf.TYPE_DOUBLE:
574
                writeDoubleBand(sizeY, posicionY);
575
                break;
576
        }
577
    }
578

    
579
    /**
580
     * Funci?n que gestiona la lectura desde el origen y la escritura
581
     * de Gdal sobre el fichero destino.
582
     * @param mode        Modo de escritura
583
     * @throws IOException
584
     */
585
    private void write(int mode) throws IOException {
586
        buf = new GdalBuffer();
587
        bufBands = new GdalBuffer[nBands];
588
        for(int iBand = 0; iBand < nBands; iBand ++)
589
                bufBands[iBand] = new GdalBuffer();
590
        
591
       // int[] buftmp = null;
592

    
593
        //long t1 = System.currentTimeMillis();
594
        try {
595
            if (mode == Mode.fileWrite) {
596
                for (int iBand = 0; iBand < this.nBands; iBand++) {
597
                    rband = dset_destino.getRasterBand(iBand + 1);
598

    
599
                    for (int iBlock = 0; iBlock < nBlocks; iBlock++) {
600
                            if(write){
601
                                //leemos el bloque origen
602
                                buf.buffByte = currentRaster.getGeoFile().getWindow(0,
603
                                                                                    iBlock * this.support.getBlockSize(),
604
                                                                                    sizeWindowX,
605
                                                                                    this.support.getBlockSize(),
606
                                                                                    iBand +
607
                                                                                    1);
608
        
609
                                //Escribimos el bloque destino
610
                                rband.writeRaster(0,
611
                                                  iBlock * this.support.getBlockSize(),
612
                                                  sizeWindowX,
613
                                                  this.support.getBlockSize(), buf,
614
                                                  Gdal.GDT_Byte);
615
                            }/*else
616
                                    this.writeClose();*/
617
                    }
618
                }
619
            } else if (mode == Mode.dataWrite) {
620
                //for(int iBlock=1;iBlock<=nBlocks;iBlock++){
621
                for (int iBlock = 0; iBlock < nBlocks; iBlock++) {
622
                    int posicionY = iBlock * this.support.getBlockSize();
623
                    if(write)
624
                            writeBands( this.support.getBlockSize(), posicionY);
625
                    /*else
626
                            this.writeClose();*/
627
                }
628
            }
629

    
630
            if (anchoResto != 0) {
631
                if (mode == Mode.fileWrite) {
632
                    for (int iBand = 0; iBand < this.nBands; iBand++) {
633
                        rband = dset_destino.getRasterBand(iBand + 1);
634
                        if(write){
635
                                //leemos el bloque origen
636
                                buf.buffByte = currentRaster.getGeoFile().getWindow(0,
637
                                                                                    nBlocks * this.support.getBlockSize(),
638
                                                                                    sizeWindowX,
639
                                                                                    anchoResto,
640
                                                                                    iBand +
641
                                                                                    1);
642
        
643
                                //Escribimos el bloque destino
644
                                rband.writeRaster(0,
645
                                                  nBlocks * this.support.getBlockSize(),
646
                                                  sizeWindowX, anchoResto, buf,
647
                                                  Gdal.GDT_Byte);
648
                        }/*else
649
                                this.writeClose();*/
650
                    }
651
                } else if (mode == Mode.dataWrite) {
652
                    int posicionY = nBlocks * this.support.getBlockSize();
653
                    if(write)
654
                            writeBands(anchoResto, posicionY);
655
                    /*else
656
                            this.writeClose();*/
657
                }
658
            }
659
        } catch (GdalException e) {
660
            e.printStackTrace();
661
        }
662
    }
663

    
664
    /**
665
     * Realiza la funci?n de compresi?n a partir de un GeoRasterFile.
666
     * @throws IOException
667
     */
668
    public void fileWrite() throws IOException {
669
        if (currentRaster == null) {
670
            throw new IOException("No se ha asignado un fichero de entrada.");
671
        }
672

    
673
        this.write(Mode.fileWrite);
674
    }
675

    
676
    /**
677
     * Realiza una copia en el formato especificado.
678
     * @throws IOException
679
     */
680
    public static void createCopy(GdalDriver driverDst, String dst, String src, 
681
                    boolean bstrict, String[] params, IProjection proj) throws IOException, GdalException {
682
        if (dst == null || src == null) {
683
            throw new IOException("No se ha asignado un fichero de entrada.");
684
        }
685

    
686
        GdalFile gdalFile;
687
                try {
688
                        gdalFile = new GdalFile(proj, src);
689
                driverDst.createCopy(dst, gdalFile.file, bstrict, params);
690
                if(dst.endsWith(".jpg") || dst.endsWith(".jpeg"))
691
                        GdalWriter.createWorldFile(dst, gdalFile);
692
                gdalFile.close();
693
                } catch (NotSupportedExtensionException e) {
694
                        e.printStackTrace();
695
                }
696
    }
697
    
698
    /**
699
         * Crea un fichero de georeferenciaci?n
700
         * @param img
701
         * @param name
702
         * @return
703
         * @throws IOException
704
         */
705
        private static void createWorldFile(String name, GdalFile gdalFile) throws IOException{
706
            File tfw = null;
707
            
708
            String extWorldFile = ".wld";
709
            if(name.endsWith("tif"))
710
                    extWorldFile = ".tfw";
711
            if(name.endsWith("jpg") || name.endsWith("jpeg"))
712
                    extWorldFile = ".jpgw";
713
                                
714
            tfw = new File(name.substring(0, name.lastIndexOf(".")) + extWorldFile);
715
            
716
            //Generamos un world file para gdal
717
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(tfw)) );
718
            dos.writeBytes((gdalFile.getExtent().getMax().getX() - gdalFile.getExtent().getMin().getX())/gdalFile.getWidth()+"\n");
719
            dos.writeBytes("0.0\n");
720
            dos.writeBytes("0.0\n");
721
            dos.writeBytes((gdalFile.getExtent().getMax().getY() - gdalFile.getExtent().getMin().getY())/gdalFile.getHeight()+"\n");
722
            dos.writeBytes(""+gdalFile.getExtent().getMin().getX()+"\n");
723
            dos.writeBytes(""+gdalFile.getExtent().getMin().getY()+"\n");
724
            dos.close();    
725
        }
726

    
727
    
728
    /**
729
     * Realiza la escritura de datos con los datos que le pasa el cliente.
730
     * @throws IOException
731
     */
732
    public void dataWrite() throws IOException {
733
        if (dataWriter == null) {
734
            throw new IOException("No se ha obtenido un objeto de entrada para la escritura valido.");
735
        }
736

    
737
        this.write(Mode.dataWrite);
738
    }
739

    
740
    /**
741
     * Cancela el salvado de datos.
742
     * @throws GdalException
743
     */
744
    public void writeClose() {
745
        try {
746
                if(dset_destino != null)
747
                        dset_destino.close();
748
            oSRS = null;
749
        } catch (GdalException e) {
750
            e.printStackTrace();
751
        }
752
    }
753

    
754
    /**
755
     * Cancela el salvado de datos.
756
     */
757
    public void writeCancel() {
758
       write = false; 
759
    }
760
    
761
    /**
762
     * Devuelve la configuraci?n de la ventana de dialogo
763
     * para las propiedades del driver de escritura de Gdal.
764
     * @return XML de configuraci?n del dialogo.
765
     */
766
    public String getXMLPropertiesDialog() {
767
        StringBuffer options = null;
768
        options = new StringBuffer();
769
        options.append("<window sizex=\"" + this.windowSizeX + "\" sizey=\"" +
770
                       this.windowSizeY + "\">");
771
        options.append("<panel sizex=\"" + this.panelSizeX + "\" sizey=\"" +
772
                       this.panelSizeY + "\" layout=\"" + this.panelLayout +
773
                       "\" border=\"yes\">");
774

    
775
        options.append("<panel layout=\"FlowLayout\" position=\"North\" align=\"left\">");
776
        options.append("<label>Block Size:</label>");
777
        options.append("<combo ident=\"BLOCKSIZE\" selected=\"" +
778
                       this.support.getBlockSize() + "\">");
779

    
780
        for (int i = 0; i < this.support.getBlockSizeList().length; i++)
781
            options.append("<elem>" + this.support.getBlockSizeList()[i] +
782
                           "</elem>");
783

    
784
        options.append("</combo>");
785
        //options.append("<label>Georef Si/No:</label>");
786

    
787
        String sel = null;
788

    
789
        if (this.support.getGeoref()) {
790
            sel = new String("yes");
791
        } else {
792
            sel = new String("no");
793
        }
794

    
795
        /*options.append("<check ident=\"GEOREF\" selected=\"" + sel +
796
                       "\" text=\"\">");
797
        options.append("</check>");*/
798
        options.append("</panel>");
799

    
800
        options.append("<panel layout=\"FlowLayout\" position=\"Center\" align=\"left\">");
801
        options.append("<label>Photometric:</label>");
802
        options.append("<combo ident=\"PHOTOMETRIC\" selected=\"" +
803
                       this.support.getPhotometric() + "\">");
804

    
805
        for (int i = 0; i < this.support.getPhotometricList().length; i++)
806
            options.append("<elem>" + this.support.getPhotometricList()[i] +
807
                           "</elem>");
808

    
809
        options.append("</combo>");
810
        options.append("<label>Interleave:</label>");
811
        options.append("<combo ident=\"INTERLEAVE\" selected=\"" +
812
                       this.support.getInterleave() + "\">");
813

    
814
        for (int i = 0; i < this.support.getInterleaveList().length; i++)
815
            options.append("<elem>" + this.support.getInterleaveList()[i] +
816
                           "</elem>");
817

    
818
        options.append("</combo>");
819
        options.append("</panel>");
820

    
821
        options.append("<panel layout=\"FlowLayout\" position=\"South\" align=\"left\">");
822
        options.append("<label>Compresi?n:</label>");
823
        options.append("<combo ident=\"COMPRESS\" selected=\"" +
824
                       this.support.getCompress() + "\">");
825

    
826
        for (int i = 0; i < this.support.getCompressList().length; i++)
827
            options.append("<elem>" + this.support.getCompressList()[i] +
828
                           "</elem>");
829

    
830
        options.append("</combo>");
831
        options.append("<label>Generar Tfw:</label>");
832
        sel = null;
833

    
834
        if (this.support.getTfw()) {
835
            sel = new String("yes");
836
        } else {
837
            sel = new String("no");
838
        }
839

    
840
        options.append("<check ident=\"TFW\" selected=\"" + sel +
841
                       "\" text=\"\">");
842
        options.append("</check>");
843
        options.append("</panel>");
844

    
845
        options.append("</panel>");
846
        options.append("</window>");
847

    
848
        return options.toString();
849
    }
850

    
851
    /**
852
     * Obtiene el valor a la variable write que estar? a true cuando se est? escribiendo
853
     *  o puede escribirse la imagen de salida. El cancelar la operaci?n de escritura
854
     * pondr? esta variable a false deteniendose la escritura y cerrandose el dataset
855
     * de salida. 
856
     * @return True si puede escribirse y false si no puede
857
     */
858
    public boolean isWrite() {
859
                return write;
860
        }
861

    
862
    /**
863
     * Asigna el valor a la variable write que estar? a true cuando se est? escribiendo
864
     *  o puede escribirse la imagen de salida. El cancelar la operaci?n de escritura
865
     * pondr? esta variable a false deteniendose la escritura y cerrandose el dataset
866
     * de salida. 
867
     * @param write Variable booleana. True si puede escribirse y false si no puede
868
     */
869
        public void setWrite(boolean write) {
870
                this.write = write;
871
        }
872
        
873
        /**
874
         * Obtiene las opciones de salvado.
875
         * @return GdalSupportOptions
876
         */
877
        public GdalSupportOptions getSupport(){
878
            return this.support; 
879
    }
880
        
881
    /**
882
     *
883
     * @author Nacho Brodin (brodin_ign@gva.es)
884
     *
885
     * Opciones que soporta el driver de escritura de Gdal.
886
     */
887
    public class GdalSupportOptions extends WriterSupportOptions {
888
        private String[]         photometric = {
889
                                           "YCBR", "MINISBLACK", "MINISWHITE",
890
                                           "RGB", "CMYK", "CIELAB", "ICCLAB",
891
                                           "ITULAB", "CBCR"
892
                                       };
893
        private String[]         interleave = { "BAND", "PIXEL" };
894
        private String[]         compress = { "LZW", "PACKBITS", "DEFLATE", "NONE" };
895
        private String                 photometricDefault = "RGB";
896
        private String                 interleaveDefault = "BAND";
897
        private String                 compressDefault = "NONE";
898
       
899
        private boolean tfw = false;
900

    
901
        public GdalSupportOptions(String ext) {
902
            super(ext);
903
        }
904

    
905
        /**
906
         * @param defaultPhot        Tipo de imagen
907
         */
908
        public void setPhotometric(String defaultPhot) {
909
            this.photometricDefault = defaultPhot;
910
        }
911

    
912
        /**
913
         * @param defaultInt
914
         */
915
        public void setInterleave(String defaultInt) {
916
            this.interleaveDefault = defaultInt;
917
        }
918

    
919
        /**
920
         * @param defaultComp
921
         */
922
        public void setCompress(String defaultComp) {
923
            this.compressDefault = defaultComp;
924
        }
925

    
926
        /**
927
         * Asigna true o false si se desea generar un fichero tfw con la
928
         * georeferenciaci?n o no;
929
         * @param tfw true se genera el fichero tfw y false no se genera
930
         */
931
        public void setTfw(boolean tfw) {
932
            this.tfw = tfw;
933
        }
934

    
935
        /**
936
         * @return
937
         */
938
        public String[] getPhotometricList() {
939
            return photometric;
940
        }
941

    
942
        /**
943
         * @return
944
         */
945
        public String[] getInterleaveList() {
946
            return interleave;
947
        }
948

    
949
        /**
950
         * @return
951
         */
952
        public String[] getCompressList() {
953
            return compress;
954
        }
955

    
956
        /**
957
         * @return
958
         */
959
        public String getPhotometric() {
960
            return photometricDefault;
961
        }
962

    
963
        /**
964
         * @return
965
         */
966
        public String getInterleave() {
967
            return interleaveDefault;
968
        }
969

    
970
        /**
971
         * Obtiene el par?metro de compresi?n
972
         * @return
973
         */
974
        public String getCompress() {
975
            return compressDefault;
976
        }
977

    
978
        /**
979
         * Devuelve true o false si se genera un fichero tfw con la
980
         * georeferenciaci?n o no;
981
         * @param tfw true se genera el fichero tfw y false no se genera
982
         */
983
        public boolean getTfw() {
984
            return tfw;
985
        }
986
    }
987

    
988
    private class Mode {
989
        public final static int fileWrite = 0;
990
        public final static int dataWrite = 1;
991
    }
992
}