Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / util / RasterUtilities.java @ 12767

History | View | Annotate | Download (22.6 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.datastruct.Extent;
23

    
24
import es.gva.cit.jgdal.Gdal;
25

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

    
130
        case RasterBuffer.TYPE_BYTE:
131
            return new String("Byte");
132

    
133
        case RasterBuffer.TYPE_DOUBLE:
134
            return new String("Double");
135

    
136
        case RasterBuffer.TYPE_FLOAT:
137
            return new String("Float");
138

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

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

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

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

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

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

    
567
                if(gBytes > 0)
568
                        return MathUtils.format(gBytes, 1) + "G";
569
                if(mBytes > 0)
570
                        return MathUtils.format(mBytes, 1) + "M";
571
                if(kBytes > 0)
572
                        return MathUtils.format(kBytes, 1) + "K";
573
                if(bytes != 0)
574
                        return ((int)bytes) + "";
575
                
576
                return "";
577
    }
578
    
579
    /**
580
     * Obtiene la extensi?n del fichero a partir de su nombre.
581
     * @param file Nombre o ruta del fichero
582
     * @return Cadena con la extensi?n que representa el tipo de fichero.
583
     */
584
    public static String getExtensionFromFileName(String file) {
585
            return file.toLowerCase().substring(file.lastIndexOf(".") + 1);
586
    }
587
    
588
        /**
589
         * Obtiene la codificaci?n de un fichero XML
590
         * @param file Nombre del fichero XML
591
         * @return Codificaci?n
592
         */
593
        public static String readFileEncoding(String file){
594
                FileReader fr;
595
                String encoding = null;
596
                try {
597
                        fr = new FileReader(file);
598
                    BufferedReader br = new BufferedReader(fr);
599
                    char[] buffer = new char[100];
600
                    br.read(buffer);
601
                    StringBuffer st = new StringBuffer(new String(buffer));
602
                    String searchText = "encoding=\"";
603
                    int index = st.indexOf(searchText);
604
                    if (index >- 1) {
605
                            st.delete(0, index+searchText.length());
606
                            encoding = st.substring(0, st.indexOf("\""));
607
                    }
608
                    fr.close();
609
            } catch(FileNotFoundException ex)        {
610
                    ex.printStackTrace();
611
            } catch (IOException e) {
612
                        e.printStackTrace();
613
                }
614
            return encoding;
615
        }
616
        
617
    //---------------------------------------------------------------
618
    //VARIOS
619
    
620
        /**
621
         * Formatea el tiempo en milisegundos devolviendo un String en formato .
622
         * dias, horas, minutos y segundos.
623
         * @param time Tiempo en milisegundos
624
         */
625
        public static String formatTime(long time) {
626
                int days = 0, hours = 0, minuts = 0, seconds = (int)(time / 1000D);
627
                if(seconds >= 60){
628
                        minuts = (int)(seconds / 60);
629
                        seconds = (int)(seconds - (minuts * 60));
630
                        if(minuts >= 60){
631
                                hours = (int)(minuts / 1024);
632
                                minuts = (int)(minuts - (hours * 60));
633
                        }
634
                }
635
                StringBuffer s = new StringBuffer();
636
                if(hours != 0)
637
                        s.append(hours+" H ");
638
                if(minuts != 0)
639
                        s.append(minuts+" Min ");
640
                if(seconds != 0)
641
                        s.append(seconds+" Sec ");
642
                return s.toString();
643
        }        
644
}