Statistics
| Revision:

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

History | View | Annotate | Download (37 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")) && GeoRasterWriter.writeTfw)
752
                        GdalWriter.createWorldFile(dst, gdalFile);
753
                gdalFile.close();
754
                GeoRasterWriter.writeTfw = true;
755
                } catch (NotSupportedExtensionException e) {
756
                        e.printStackTrace();
757
                }
758
    }
759

    
760
    /**
761
         * Crea un fichero de georeferenciaci?n
762
         * @param img
763
         * @param name
764
         * @return
765
         * @throws IOException
766
         */
767
        private static void createWorldFile(String name, GdalFile gdalFile) throws IOException{
768
            File tfw = null;
769

    
770
            String extWorldFile = ".wld";
771
            if(name.endsWith("tif"))
772
                    extWorldFile = ".tfw";
773
            if(name.endsWith("jpg") || name.endsWith("jpeg"))
774
                    extWorldFile = ".jpgw";
775

    
776
            tfw = new File(name.substring(0, name.lastIndexOf(".")) + extWorldFile);
777

    
778
            //Generamos un world file para gdal
779
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(tfw)) );
780
            dos.writeBytes((gdalFile.getExtent().getMax().getX() - gdalFile.getExtent().getMin().getX())/gdalFile.getWidth()+"\n");
781
            dos.writeBytes("0.0\n");
782
            dos.writeBytes("0.0\n");
783
            dos.writeBytes("-"+Math.abs((gdalFile.getExtent().getMax().getY() - gdalFile.getExtent().getMin().getY())/gdalFile.getHeight())+"\n");
784
            dos.writeBytes(""+gdalFile.getExtent().getMin().getX()+"\n");
785
            dos.writeBytes(""+gdalFile.getExtent().getMax().getY()+"\n");
786
            dos.close();
787
        }
788

    
789

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

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

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

    
816
    /**
817
     * Cancela el salvado de datos.
818
     */
819
    public void writeCancel() {
820
       write = false;
821
    }
822

    
823
    /**
824
     * Devuelve la configuraci?n de la ventana de dialogo
825
     * para las propiedades del driver de escritura de Gdal.
826
     * @return XML de configuraci?n del dialogo.
827
     */
828
    public String getXMLPropertiesDialog() {
829
        StringBuffer options = null;
830
        options = new StringBuffer();
831
        options.append("<window sizex=\"" + this.windowSizeX + "\" sizey=\"" +
832
                       this.windowSizeY + "\">");
833
        options.append("<panel sizex=\"" + this.panelSizeX + "\" sizey=\"" +
834
                       this.panelSizeY + "\" layout=\"" + this.panelLayout +
835
                       "\" border=\"yes\">");
836

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

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

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

    
849
        String sel = null;
850

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

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

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

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

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

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

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

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

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

    
892
        options.append("</combo>");
893
        options.append("<label>make_tfw</label>");
894
        sel = null;
895

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

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

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

    
910
        return options.toString();
911
    }
912

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

    
924
    /**
925
     * Asigna el valor a la variable write que estar? a true cuando se est? escribiendo
926
     *  o puede escribirse la imagen de salida. El cancelar la operaci?n de escritura
927
     * pondr? esta variable a false deteniendose la escritura y cerrandose el dataset
928
     * de salida.
929
     * @param write Variable booleana. True si puede escribirse y false si no puede
930
     */
931
        public void setWrite(boolean write) {
932
                this.write = write;
933
        }
934

    
935
        /**
936
         * Obtiene las opciones de salvado.
937
         * @return GdalSupportOptions
938
         */
939
        public GdalSupportOptions getSupport(){
940
            return this.support;
941
    }
942

    
943
    /**
944
     *
945
     * @author Nacho Brodin (brodin_ign@gva.es)
946
     *
947
     * Opciones que soporta el driver de escritura de Gdal.
948
     */
949
    public class GdalSupportOptions extends WriterSupportOptions {
950
        private String[]         photometric = {
951
                                           "YCBR", "MINISBLACK", "MINISWHITE",
952
                                           "RGB", "CMYK", "CIELAB", "ICCLAB",
953
                                           "ITULAB", "CBCR"
954
                                       };
955
        private String[]         interleave = { "BAND", "PIXEL" };
956
        private String[]         compress = { "LZW", "PACKBITS", "DEFLATE", "NONE" };
957
        private String                 photometricDefault = "RGB";
958
        private String                 interleaveDefault = "BAND";
959
        private String                 compressDefault = "NONE";
960

    
961
        private boolean tfw = false;
962

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

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

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

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

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

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

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

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

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

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

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

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

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