Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / util / RasterUtilities.java @ 12793

History | View | Annotate | Download (24.3 KB)

1
package org.gvsig.raster.util;
2

    
3
import java.awt.Dimension;
4
import java.awt.geom.AffineTransform;
5
import java.awt.geom.Dimension2D;
6
import java.awt.geom.NoninvertibleTransformException;
7
import java.awt.geom.Point2D;
8
import java.awt.geom.Rectangle2D;
9
import java.io.BufferedOutputStream;
10
import java.io.BufferedReader;
11
import java.io.DataOutputStream;
12
import java.io.File;
13
import java.io.FileInputStream;
14
import java.io.FileNotFoundException;
15
import java.io.FileOutputStream;
16
import java.io.FileReader;
17
import java.io.IOException;
18
import java.io.InputStream;
19
import java.io.OutputStream;
20

    
21
import org.gvsig.raster.buffer.RasterBuffer;
22
import org.gvsig.raster.dataset.io.rmf.RmfBlocksManager;
23
import org.gvsig.raster.dataset.serializer.GeoInfoRmfSerializer;
24
import org.gvsig.raster.datastruct.Extent;
25

    
26
import es.gva.cit.jgdal.Gdal;
27

    
28
/**
29
 * 
30
 * @author Nacho Brodin (nachobrodin@gmail.com)
31
 *
32
 */
33
public class RasterUtilities {        
34
        public static final        int MAX_BYTE_BIT_VALUE        = 255;
35
        public static final        int MAX_SHORT_BIT_VALUE        = 65535;
36
            
37
    //---------------------------------------------------------------
38
    //TIPOS DE DATOS
39
    
40
    /**
41
     * Conversi?n de los tipos de datos de gdal a los tipos de datos de 
42
     * RasterBuf
43
     * @param gdalType Tipo de dato de gdal
44
     * @return Tipo de dato de RasterBuf
45
     */
46
    public static int getRasterBufTypeFromGdalType(int gdalType){
47
            switch(gdalType){
48
                case 1:return  RasterBuffer.TYPE_BYTE;//GDT_BYTE 
49
                case 2://GDT_UInt16
50
                case 8://GDT_CInt16
51
                case 3:return RasterBuffer.TYPE_SHORT;//GDT_Int16        
52
                case 4://GDT_UInt32
53
                case 9://GDT_CInt32
54
                case 5:return RasterBuffer.TYPE_INT;//GDT_Int32
55
                case 10://GDT_CFloat32
56
                case 6:return RasterBuffer.TYPE_FLOAT;//GDT_Float32
57
                case 11://GDT_CFloat64
58
                case 7:return RasterBuffer.TYPE_DOUBLE;//GDT_Float64
59
                }
60
            return RasterBuffer.TYPE_UNDEFINED;
61
    }
62
    
63
    /**
64
     * Conversi?n de los tipos de datos de RasterBuf en los de gdal.
65
     * @param rasterBufType Tipo de dato de RasterBuf
66
     * @return Tipo de dato de Gdal
67
     */
68
    public static int getGdalTypeFromRasterBufType(int rasterBufType){
69
            switch(rasterBufType){
70
                case RasterBuffer.TYPE_BYTE:return Gdal.GDT_Byte;
71
                case RasterBuffer.TYPE_USHORT: return Gdal.GDT_UInt16;
72
                case RasterBuffer.TYPE_SHORT: return Gdal.GDT_Int16;
73
                case RasterBuffer.TYPE_INT: return Gdal.GDT_Int32;
74
                case RasterBuffer.TYPE_FLOAT: return Gdal.GDT_Float32;
75
                case RasterBuffer.TYPE_DOUBLE: return Gdal.GDT_Float64;
76
                case RasterBuffer.TYPE_UNDEFINED: return Gdal.GDT_Unknown;
77
                case RasterBuffer.TYPE_IMAGE: return Gdal.GDT_Byte;
78
                }
79
            return Gdal.GDT_Unknown;
80
    }
81
    
82
    /**
83
     * Conversi?n de los tipos de datos de MrSID a los tipos de datos de 
84
     * RasterBuf
85
     * @param mrsidType Tipo de dato de MrSID
86
     * @return Tipo de dato de RasterBuf
87
     */
88
    public static int getRasterBufTypeFromMrSIDType(int mrsidType){
89
            switch(mrsidType){
90
            case 0:return RasterBuffer.TYPE_UNDEFINED;//INVALID
91
                case 1://UINT8 
92
                case 2:return  RasterBuffer.TYPE_BYTE;//SINT8
93
                case 3://UINT16
94
                case 4:return RasterBuffer.TYPE_SHORT;//SINT16        
95
                case 5://UINT32
96
                case 6:return RasterBuffer.TYPE_INT;//SINT32        
97
                case 7:return RasterBuffer.TYPE_FLOAT;//FLOAT32
98
                case 8:return RasterBuffer.TYPE_DOUBLE;//FLOAT64
99
                }
100
            return RasterBuffer.TYPE_UNDEFINED;
101
    }
102
    
103
    /**
104
     * Obtiene el n?mero de bytes que ocupa un tipo de dato concreto. 
105
     * Los tipos de datos son los utilizados en RasterBuffer
106
     * @param rasterBufType Tipo de dato del que se solicita el n?mero de bytes ocupados
107
     * @return
108
     */
109
    public static int getBytesFromRasterBufType(int rasterBufType){
110
            switch(rasterBufType){
111
                case RasterBuffer.TYPE_BYTE:return 1;
112
                case RasterBuffer.TYPE_USHORT:
113
                case RasterBuffer.TYPE_SHORT: return 2;
114
                case RasterBuffer.TYPE_INT:
115
                case RasterBuffer.TYPE_FLOAT:
116
                case RasterBuffer.TYPE_IMAGE: return 4;
117
                case RasterBuffer.TYPE_DOUBLE: return 8;
118
                }
119
            return 0; //TYPE_UNDEFINED
120
    }
121
    
122
    /**
123
     * Convierte un tipo de dato a cadena
124
     * @param type Tipo de dato
125
     * @return cadena  que representa el tipo de dato
126
     */
127
    public static String typesToString(int type) {
128
        switch (type) {
129
        case RasterBuffer.TYPE_IMAGE:
130
            return new String("Image");
131

    
132
        case RasterBuffer.TYPE_BYTE:
133
            return new String("Byte");
134

    
135
        case RasterBuffer.TYPE_DOUBLE:
136
            return new String("Double");
137

    
138
        case RasterBuffer.TYPE_FLOAT:
139
            return new String("Float");
140

    
141
        case RasterBuffer.TYPE_INT:
142
                return new String("Integer");
143
                
144
        case RasterBuffer.TYPE_USHORT:
145
        case RasterBuffer.TYPE_SHORT:
146
            return new String("Short");
147
        }
148

    
149
        return null;
150
    }
151
    
152
    /**
153
     * Parseo de las proyecciones que genera gdal para meter espaciados y saltos de l?nea HTML
154
     * @param proj Proyecci?n
155
     * @return Cadena con la proyecci?n parseada
156
     */
157
    public static String parserGdalProj(String proj){
158
            if(proj == null)
159
                    return "";
160
            String[] list = proj.split(",");
161
            int level = 0;
162
            for(int i = 0; i < list.length; i++){
163
                    if(list[i].indexOf("[") >= 0){
164
                            level ++;
165
                            String spaces = "";
166
                            for(int j = 0; j < level; j++)
167
                                    spaces += "&nbsp;&nbsp;"; 
168
                            list[i] = spaces + list[i];
169
                    }
170
                    if(list[i].indexOf("]]") >= 0)
171
                            level = level - 2;
172
                    else if(list[i].indexOf("]") >= 0)
173
                            level --;
174
            }
175
            StringBuffer str = new StringBuffer();            
176
            for(int i = 0; i < list.length; i++){
177
                    if(i < list.length){
178
                            if(i + 1 < list.length && list[i + 1].indexOf("[") >= 0)
179
                                    str.append(list[i] + ",<BR>");
180
                            else
181
                                    str.append(list[i] + ",");
182
                    }
183
            }
184
            return str.toString();
185
    }
186
        
187
    //---------------------------------------------------------------
188
    //ESPACIO DE COLOR
189
    
190
    /**
191
     * Descompone un entero que representa un ARGB en sus 4 valores byte
192
     * Obtiene un array de 4 elementos donde el elemento 0 es el Rojo, el 1 es el
193
     * verde, el 2 el azul y el 3 el alpha.
194
     * @param rgb Entero con el valor ARGB a descomponer;
195
     * @return Array de cuatro elementos
196
     */
197
    public static byte[] getARGBFromIntToByteArray(int rgb){
198
            byte[] b = new byte[4];
199
            b[0] = (byte)((rgb & 0x00ff0000) >> 16);
200
            b[1] = (byte)((rgb & 0x0000ff00) >> 8);
201
            b[2] = (byte)(rgb & 0x000000ff);
202
            b[3] = (byte)((rgb & 0xff000000) >> 24);
203
            return b;
204
    }
205
    
206
    /**
207
     * Descompone un entero que representa un ARGB en sus 4 valores byte
208
     * Obtiene un array de 4 elementos donde el elemento 0 es el Rojo, el 1 es el
209
     * verde, el 2 el azul y el 3 el alpha.
210
     * @param rgb Entero con el valor ARGB a descomponer;
211
     * @return
212
     */
213
    public static int[] getARGBFromIntToIntArray(int rgb){
214
            int[] i = new int[4];
215
            i[0] = (((rgb & 0x00ff0000) >> 16) & 0xff);
216
            i[1] = (((rgb & 0x0000ff00) >> 8) & 0xff);
217
            i[2] = ((rgb & 0x000000ff) & 0xff);
218
            i[3] = (((rgb & 0xff000000) >> 24) & 0xff);
219
            return i;
220
    }
221
    
222
    /**
223
     * Obtiene un entero con los valores ARGB pasados por par?metro
224
     * @param a Valor de alpha
225
     * @param r Valor del rojo
226
     * @param g Valor del verde
227
     * @param b Valor del azul
228
     * @return entero con la mezcla de valores
229
     */
230
    public static int getIntFromARGB(int a, int r, int g, int b){
231
              return (((a & 0xff) << 24) + ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff));
232
    }
233
    
234
    //---------------------------------------------------------------
235
    //CONVERSI?N DE COORDENADAS
236
    
237
    /**
238
     * Convierte una ventana en coordenadas del mundo real a sus coordenadas relativas en pixels teniendo
239
     * en cuenta que la coordenada superior izquierda es 0,0 y la inferior derecha es maxX y maY
240
     * @param extent Extent de la imagen original
241
     * @param widthPx Ancho en pixeles de la imagen original
242
     * @param heightPx Alto en pixeles de la imagen original
243
     * @param window Ventana en coordenadas reales a transportar a coordenadas pixel
244
     * @return Ventana en coordenadas pixel
245
     */
246
    public static Rectangle2D getPxRectFromMapRect(Rectangle2D extent, double widthPx, double heightPx, Rectangle2D window){
247
            double widthWC = extent.getWidth();
248
                double heightWC = extent.getHeight();
249
                
250
                double wWindowWC = Math.abs(window.getMaxX() - window.getMinX());
251
                   double hWindowWC = Math.abs(window.getMaxY() - window.getMinY());
252
                   
253
                   double wWindowPx = ((wWindowWC * widthPx) /  widthWC);
254
                   double hWindowPx = ((hWindowWC * heightPx) /  heightWC);
255
                   
256
                   double initDistanceX = Math.abs(window.getMinX() - extent.getMinX());
257
                   double initDistanceY = Math.abs(window.getMaxY() - extent.getMaxY());
258
                   
259
                   double initPxX = ((initDistanceX * widthPx) /  widthWC);
260
                   double initPxY = ((initDistanceY * heightPx) /  heightWC);
261
                   
262
                   Rectangle2D pxRec = new Rectangle2D.Double(        initPxX, 
263
                                                                                                           initPxY,
264
                                                                                                           wWindowPx,
265
                                                                                                           hWindowPx); 
266
                   return pxRec;
267
    }
268
    
269
    /**
270
     * Convierte una ventana en coordenadas del mundo real a sus coordenadas relativas en pixels teniendo
271
     * en cuenta que la coordenada superior izquierda es 0,0 y la inferior derecha es maxX y maY
272
     * @param extent Extent de la imagen original
273
     * @param widthPx Ancho en pixeles de la imagen original
274
     * @param heightPx Alto en pixeles de la imagen original
275
     * @param window Ventana en coordenadas reales a transportar a coordenadas pixel
276
     * @return Ventana en coordenadas pixel
277
     */
278
    public static Rectangle2D getMapRectFromPxRect(Rectangle2D extent, double widthPx, double heightPx, Rectangle2D pxWindow){
279
                   double wWindowWC = ((pxWindow.getWidth() * extent.getWidth()) /  widthPx);
280
                   double hWindowWC = ((pxWindow.getHeight() * extent.getHeight()) /  heightPx);
281
                   
282
                   double initWCX = extent.getMinX() + ((pxWindow.getMinX() * extent.getWidth()) /  widthPx);
283
                   double initWCY = extent.getMaxY() - ((pxWindow.getMinY() * extent.getHeight()) /  heightPx);
284
                   
285
                   Rectangle2D mapRec = new Rectangle2D.Double(initWCX, 
286
                                                                                                           initWCY - hWindowWC,
287
                                                                                                           wWindowWC,
288
                                                                                                           hWindowWC); 
289
                   return mapRec;
290
    }
291
    
292
    /**
293
     * Convierte un punto en coordenadas del mundo a coordenadas pixel
294
     * @param p Punto a convertir
295
     * @param ext Extent completo de la imagen
296
     * @return Punto en coordenadas pixel
297
     */
298
    public static Point2D worldPointToRaster(Point2D p, Extent ext, int pxWidth, int pxHeight) { 
299
            double x = p.getX() - ext.getMin().getX();
300
            double y = p.getY() - ext.getMin().getY();
301
            int pxX = (int)((x * pxWidth) / ext.width());
302
            int pxY = (int)((y * pxHeight) / ext.height());
303
            return new Point2D.Double(pxX, pxY);
304
    }
305
    
306
    /**
307
     * Ajusta la extensi?n pasada por par?metro a los valores m?ximos y m?nimos de la 
308
     * imagen. Esto sirve para que la petici?n al driver nunca sobrepase los l?mites 
309
     * de la imagen tratada aunque la vista donde se dibuje sea de mayor tama?o.
310
     * 
311
     * @param imgExt Extent completo de la vista donde se va a dibujar.
312
     * @param extToAdj Extent a ajustar.
313
     * @return adjustedExtent Extent ajustado a m?ximos y m?nimos
314
     */
315
    public static Extent calculateAdjustedView(Extent extToAdj, Extent imgExt) { 
316
        double vx = extToAdj.minX();
317
        double vy = extToAdj.minY();
318
        double vx2 = extToAdj.maxX();
319
        double vy2 = extToAdj.maxY();
320

    
321
        if (extToAdj.minX() < imgExt.minX())
322
            vx = imgExt.minX();
323
        
324
        if (extToAdj.minY() < imgExt.minY()) 
325
            vy = imgExt.minY();
326
        
327
        if (extToAdj.maxX() > imgExt.maxX()) 
328
            vx2 = imgExt.maxX();
329
        
330
        if (extToAdj.maxY() > imgExt.maxY())
331
            vy2 = imgExt.maxY();
332
        
333
        return new Extent(vx, vy, vx2, vy2);
334
    }
335
    
336
    /**
337
     * Ajusta la extensi?n pasada por par?metro a los valores m?ximos y m?nimos de la 
338
     * imagen. Esto sirve para que la petici?n al driver nunca sobrepase los l?mites 
339
     * de la imagen tratada aunque la vista donde se dibuje sea de mayor tama?o. Este m?todo 
340
     * tiene en cuenta la rotaci?n aplicada al raster por lo que no ajustamos a un extent sino
341
     * a una matriz de transformaci?n. Esta tiene los par?metros de traslaci?n, rotaci?n y
342
     * escalado del raster destino. Esta matriz transforma coordenadas pixel a real y viceversa.
343
     * 
344
     * @param imgExt Extent completo de la vista donde se va a dibujar.
345
     * @param AffineTransform Matriz de transformaci?n del raster destino
346
     * @return adjustedExtent Extent ajustado a m?ximos y m?nimos
347
     */
348
    public static Extent calculateAdjustedView(Extent extToAdj, AffineTransform at, Dimension2D dim) { 
349
            //Obtenemos los cuatro puntos de la petici?n de origen
350
                Point2D ul = new Point2D.Double(extToAdj.getULX(), extToAdj.getULY());
351
                Point2D lr = new Point2D.Double(extToAdj.getLRX(), extToAdj.getLRY());
352
                
353
                //Los convertimos a coordenadas pixel con la matriz de transformaci?n
354
                try {
355
                        at.inverseTransform(ul, ul);
356
                        at.inverseTransform(lr, lr);
357
                } catch (NoninvertibleTransformException e) {
358
                        return extToAdj;
359
                }
360
                
361
                //Ajustamos a la dimensi?n del raster en pixeles
362
        if (ul.getX() < 0)
363
            ul.setLocation(0, ul.getY());
364
        if (ul.getX() >= dim.getWidth())
365
            ul.setLocation(dim.getWidth(), ul.getY());
366
        if (ul.getY() < 0)
367
            ul.setLocation(ul.getX(), 0);
368
        if (ul.getY() >= dim.getHeight())
369
            ul.setLocation(ul.getX(), dim.getHeight());
370
        
371
        if (lr.getX() < 0)
372
                lr.setLocation(0, lr.getY());
373
        if (lr.getX() >= dim.getWidth())
374
                lr.setLocation(dim.getWidth(), lr.getY());
375
        if (lr.getY() < 0)
376
                lr.setLocation(lr.getX(), 0);
377
        if (lr.getY() >= dim.getHeight())
378
                lr.setLocation(lr.getX(), dim.getHeight());
379
        
380
        //Lo convertimos a coordenadas reales nuevamente
381
        at.transform(ul, ul);
382
        at.transform(lr, lr);
383
        return new Extent(ul, lr);
384
    }
385
    
386
    /**
387
     * Compara dos extents y devuelve true si son iguales
388
     * @param e1 Extent a comparar
389
     * @param e2 Extent a comparar
390
     * @return true si los extents pasados por par?metro son iguales y false si no lo son
391
     */
392
    public static boolean compareExtents(Extent e1, Extent e2){
393
            return ((e1.getMin().getX() == e2.getMin().getX()) && (e1.getMin().getY() == e2.getMin().getY()) &&
394
                            (e1.getMax().getX() == e2.getMax().getX())) && (e1.getMax().getY() == e2.getMax().getY());
395
    }
396
    
397
    /**
398
     * Comprueba si un extent est? contenido dentro de otro y devuelve true en este caso.
399
     * @param e1 Extent a comprobar si est? contenido en e2
400
     * @param e2 Extent sobre el que se comprueba si e1 est? dentro
401
     * @return true si e1 est? dentro de e1
402
     */
403
    public static boolean isInside(Extent e1, Extent e2){
404
            return ((e1.getMin().getX() >= e2.getMin().getX()) && (e1.getMin().getY() >= e2.getMin().getY()) &&
405
                            (e1.getMax().getX() <= e2.getMax().getX())) && (e1.getMax().getY() <= e2.getMax().getY());
406
    }
407
    
408
    /**
409
     * Comprueba si alguna parte de un extent est? fuera del extent que tenemos como referencia.
410
     * @param e1 Extent a comprobar si est? fuera
411
     * @param ref Extent de referencia
412
     * @return Devuelve true si alguna parte de e1 cae fuera de ref y false si no tiene ninguna fuera.
413
     */
414
    public static boolean isOutside(Extent e1, Extent ref){
415
            return ((e1.getMin().getX() > ref.getMax().getX()) || (e1.getMin().getY() > ref.getMax().getY()) ||
416
                            (e1.getMax().getX() < ref.getMin().getX()) || (e1.getMax().getY() < ref.getMin().getY()));
417
    }
418
    
419
        /**
420
         * Calcula los par?metros de un worl file a partir de las esquinas del raster.
421
         *    1. X pixel size A
422
         *    2. X rotation term D
423
         *    3. Y rotation term B
424
         *    4. Y pixel size E
425
         *    5. X coordinate of upper left corner C
426
         *    6. Y coordinate of upper left corner F
427
         * where the real-world coordinates x',y' can be calculated from
428
         * the image coordinates x,y with the equations
429
         *  x' = Ax + By + C and y' = Dx + Ey + F.
430
         *  The signs of the first 4 parameters depend on the orientation
431
         *  of the image. In the usual case where north is more or less
432
         *  at the top of the image, the X pixel size will be positive
433
         *  and the Y pixel size will be negative. For a south-up image,
434
         *  these signs would be reversed.
435
         * 
436
         * You can calculate the World file parameters yourself based
437
         * on the corner coordinates. The X and Y pixel sizes can be
438
         *  determined simply by dividing the distance between two
439
         *  adjacent corners by the number of columns or rows in the image.
440
         *  The rotation terms are calculated with these equations:
441
         * 
442
         *  # B = (A * number_of_columns + C - lower_right_x') / number_of_rows * -1
443
         *  # D = (E * number_of_rows + F - lower_right_y') / number_of_columns * -1
444
         * 
445
         * @param corner (tl, tr, br, bl)
446
         * @return
447
         */
448
        public static double [] cornersToWorldFile(Point2D [] esq, Dimension size) {
449
                double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
450
                double x1 = esq[0].getX(), y1 = esq[0].getY();
451
                double x2 = esq[1].getX(), y2 = esq[1].getY();
452
                double x3 = esq[2].getX(), y3 = esq[2].getY();
453
                double x4 = esq[3].getX(), y4 = esq[3].getY();
454
                // A: X-scale
455
                a = Math.abs( Math.sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
456
                      / size.getWidth());
457

    
458
                // E: negative Y-scale
459
                e =  - Math.abs(Math.sqrt((x1 - x4) * (x1 - x4) +
460
                      (y1 - y4) * (y1 - y4)) / size.getHeight());
461

    
462
                // C, F: upper-left coordinates
463
                c = x1;
464
                f = y1;
465
                
466
                // B & D: rotation parameters
467
                b = (a * size.getWidth() + c - x3 ) / size.getHeight() * -1;
468
                d = (e * size.getHeight() + f - y3 ) / size.getWidth() * -1;
469

    
470
                double [] wf = {a, d, b, e, c, f}; 
471
                return wf;  
472
        }
473
        
474
    //---------------------------------------------------------------
475
    //TRATAMIENTO DE FICHEROS
476
    
477
    /**
478
     * Copia de ficheros
479
     * @param pathOrig Ruta de origen
480
     * @param pathDst Ruta de destino.
481
     */
482
    public static void copyFile(String pathOrig, String pathDst) 
483
            throws FileNotFoundException, IOException{
484
             InputStream in;
485
             OutputStream out;
486
             
487
             if(pathOrig == null || pathDst == null){
488
                     System.err.println("Error en path");
489
                     return;
490
             }
491
             
492
             File orig = new File(pathOrig);
493
             if(!orig.exists() || !orig.isFile() || !orig.canRead()){
494
                     System.err.println("Error en fichero de origen");
495
                     return;
496
             }
497
             
498
             File dest = new File(pathDst);
499
             String file = pathOrig.substring(pathOrig.lastIndexOf(File.separator), pathOrig.length());
500
             if(dest.isDirectory())
501
                     pathDst += file;
502
            
503
             in = new FileInputStream(pathOrig);
504
             out = new FileOutputStream(pathDst);
505
            
506
             byte[] buf = new byte[1024];
507
             int len;
508
             
509
             while ((len = in.read(buf)) > 0)
510
                        out.write(buf, 0, len);
511
                
512
             in.close();
513
             out.close();
514
    }
515
    
516
    /**
517
         * Crea un fichero de georeferenciaci?n (world file) para un dataset determinado
518
         * @param GdalDriver
519
         * @param fileName Nombre completo del fichero de raster
520
         * @param Extent 
521
         * @param pxWidth Ancho en p?xeles
522
         * @param pxHeight Alto en p?xeles
523
         * @return
524
         * @throws IOException
525
         */
526
        public static void createWorldFile(String fileName, Extent ext, int pxWidth, int pxHeight) throws IOException {
527
            File tfw = null;
528
            
529
            String extWorldFile = ".wld";
530
            if(fileName.endsWith("tif"))
531
                    extWorldFile = ".tfw";
532
            if(fileName.endsWith("jpg") || fileName.endsWith("jpeg"))
533
                    extWorldFile = ".jpgw";
534
                                
535
            tfw = new File(fileName.substring(0, fileName.lastIndexOf(".")) + extWorldFile);
536
            
537
            //Generamos un world file para gdal
538
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(tfw)) );
539
            dos.writeBytes((ext.getMax().getX() - ext.getMin().getX()) / pxWidth + "\n");
540
            dos.writeBytes("0.0\n");
541
            dos.writeBytes("0.0\n");
542
            dos.writeBytes((ext.getMin().getY() - ext.getMax().getY()) / pxHeight + "\n");
543
            dos.writeBytes("" + ext.getMin().getX() + "\n");
544
            dos.writeBytes("" + ext.getMax().getY() + "\n");
545
            dos.close();    
546
        }
547
        
548
    /**
549
         * Crea un fichero de georeferenciaci?n (world file) para un dataset determinado
550
         * @param GdalDriver
551
         * @param fileName Nombre completo del fichero de raster
552
         * @param AffineTransform 
553
         * @param pxWidth Ancho en p?xeles
554
         * @param pxHeight Alto en p?xeles
555
         * @return
556
         * @throws IOException
557
         */
558
        public static void createWorldFile(String fileName, AffineTransform at, int pxWidth, int pxHeight) throws IOException {
559
            File tfw = null;
560
            
561
            String extWorldFile = ".wld";
562
            if(fileName.endsWith("tif"))
563
                    extWorldFile = ".tfw";
564
            if(fileName.endsWith("jpg") || fileName.endsWith("jpeg"))
565
                    extWorldFile = ".jpgw";
566
                                
567
            tfw = new File(fileName.substring(0, fileName.lastIndexOf(".")) + extWorldFile);
568
            
569
            //Generamos un world file para gdal
570
            DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(tfw)) );
571
            dos.writeBytes(at.getScaleX() + "\n");
572
            dos.writeBytes(at.getShearX() + "\n");
573
            dos.writeBytes(at.getShearY() + "\n");
574
            dos.writeBytes(at.getScaleY() + "\n");
575
            dos.writeBytes("" + at.getTranslateX() + "\n");
576
            dos.writeBytes("" + at.getTranslateY() + "\n");
577
            dos.close();    
578
        }
579
        
580
    /**
581
     * Formatea en forma de cadena un tama?o dado en bytes. El resultado
582
     * ser? una cadena con GB, MB, KB y B
583
     * @param size tama?o a formatear
584
     * @return cadena con la cantidad formateada
585
     */
586
    public static String formatFileSize(long size){
587
            double bytes = (double)size, kBytes = 0, mBytes = 0, gBytes = 0;
588
                if(size >= 1024){
589
                        kBytes = (double)(size / 1024D);
590
                        bytes = (int)(size - (((int)kBytes) * 1024));
591
                        if(kBytes >= 1024){
592
                                mBytes = (double)(((int)kBytes) / 1024D);
593
                                kBytes = (double)(((int)kBytes) - (((int)mBytes) * 1024));
594
                                if(mBytes >= 1024){
595
                                        gBytes = (int)(((int)mBytes) / 1024);
596
                                        mBytes = (int)(((int)mBytes) - (gBytes * 1024));
597
                                }
598
                        }
599
                }
600

    
601
                if(gBytes > 0)
602
                        return MathUtils.format(gBytes, 1) + "G";
603
                if(mBytes > 0)
604
                        return MathUtils.format(mBytes, 1) + "M";
605
                if(kBytes > 0)
606
                        return MathUtils.format(kBytes, 1) + "K";
607
                if(bytes != 0)
608
                        return ((int)bytes) + "";
609
                
610
                return "";
611
    }
612
    
613
    /**
614
     * Obtiene la extensi?n del fichero a partir de su nombre.
615
     * @param file Nombre o ruta del fichero
616
     * @return Cadena con la extensi?n que representa el tipo de fichero.
617
     */
618
    public static String getExtensionFromFileName(String file) {
619
            return file.toLowerCase().substring(file.lastIndexOf(".") + 1);
620
    }
621
    
622
        /**
623
         * Obtiene la codificaci?n de un fichero XML
624
         * @param file Nombre del fichero XML
625
         * @return Codificaci?n
626
         */
627
        public static String readFileEncoding(String file){
628
                FileReader fr;
629
                String encoding = null;
630
                try {
631
                        fr = new FileReader(file);
632
                    BufferedReader br = new BufferedReader(fr);
633
                    char[] buffer = new char[100];
634
                    br.read(buffer);
635
                    StringBuffer st = new StringBuffer(new String(buffer));
636
                    String searchText = "encoding=\"";
637
                    int index = st.indexOf(searchText);
638
                    if (index >- 1) {
639
                            st.delete(0, index+searchText.length());
640
                            encoding = st.substring(0, st.indexOf("\""));
641
                    }
642
                    fr.close();
643
            } catch(FileNotFoundException ex)        {
644
                    ex.printStackTrace();
645
            } catch (IOException e) {
646
                        e.printStackTrace();
647
                }
648
            return encoding;
649
        }
650
        
651
        /**
652
         * Guarda la informaci?n de georreferenciaci?n de un raster en su fichero rmf adjunto.
653
         * @param path
654
         * @param at
655
         * @param dim
656
         * @throws IOException 
657
         */
658
        public static void saveGeoInfo(String outRmf, AffineTransform at, Point2D dim) throws IOException {
659
                RmfBlocksManager manager = new RmfBlocksManager(outRmf + ".rmf");
660
                GeoInfoRmfSerializer ser3 = new GeoInfoRmfSerializer(at, dim);
661
                manager.addClient(ser3);
662
                manager.write();
663
        }
664
        
665
    //---------------------------------------------------------------
666
    //VARIOS
667
    
668
        /**
669
         * Formatea el tiempo en milisegundos devolviendo un String en formato .
670
         * dias, horas, minutos y segundos.
671
         * @param time Tiempo en milisegundos
672
         */
673
        public static String formatTime(long time) {
674
                int days = 0, hours = 0, minuts = 0, seconds = (int)(time / 1000D);
675
                if(seconds >= 60){
676
                        minuts = (int)(seconds / 60);
677
                        seconds = (int)(seconds - (minuts * 60));
678
                        if(minuts >= 60){
679
                                hours = (int)(minuts / 1024);
680
                                minuts = (int)(minuts - (hours * 60));
681
                        }
682
                }
683
                StringBuffer s = new StringBuffer();
684
                if(hours != 0)
685
                        s.append(hours+" H ");
686
                if(minuts != 0)
687
                        s.append(minuts+" Min ");
688
                if(seconds != 0)
689
                        s.append(seconds+" Sec ");
690
                return s.toString();
691
        }        
692
}