Statistics
| Revision:

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

History | View | Annotate | Download (37.3 KB)

1 8026 nacho
/*
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 10645 nacho
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 8026 nacho
273 10645 nacho
        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 8026 nacho
    /**
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 12080 nacho
                if((dst.endsWith(".jpg") || dst.endsWith(".jpeg")) && GeoRasterWriter.writeTfw)
752 8026 nacho
                        GdalWriter.createWorldFile(dst, gdalFile);
753
                gdalFile.close();
754 12080 nacho
                GeoRasterWriter.writeTfw = true;
755 8026 nacho
                } 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 12087 nacho
            dos.writeBytes("-"+Math.abs((gdalFile.getExtent().getMax().getY() - gdalFile.getExtent().getMin().getY())/gdalFile.getHeight())+"\n");
784 8026 nacho
            dos.writeBytes(""+gdalFile.getExtent().getMin().getX()+"\n");
785 12341 nacho
            dos.writeBytes(""+gdalFile.getExtent().getMax().getY()+"\n");
786 8026 nacho
            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>Compresi?n:</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>Generar 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
}