Statistics
| Revision:

svn-gvsig-desktop / tags / gvSIGv0_6_1RELEASE / libraries / libCq CMS for java.old / src / org / cresques / io / GeoRasterFile.java @ 5222

History | View | Annotate | Download (14.1 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 * 
4
 * Copyright (C) 2004-5. 
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 * 
22
 * cresques@gmail.com
23
 */
24
package org.cresques.io;
25

    
26
import java.awt.Component;
27
import java.awt.Dimension;
28
import java.awt.Image;
29
import java.awt.geom.Point2D;
30
import java.awt.image.DataBuffer;
31
import java.io.FileWriter;
32
import java.io.IOException;
33
import java.lang.reflect.Constructor;
34
import java.lang.reflect.InvocationTargetException;
35
import java.util.TreeMap;
36

    
37
import org.cresques.cts.ICoordTrans;
38
import org.cresques.cts.IProjection;
39
import org.cresques.io.raster.PixelFilter;
40
import org.cresques.io.raster.SimplePixelFilter;
41
import org.cresques.px.Extent;
42
import org.cresques.px.IObjList;
43
import org.cresques.px.PxContour;
44
import org.cresques.px.PxObjList;
45

    
46
/**
47
 * Manejador de ficheros raster georeferenciados.
48
 * 
49
 * Esta clase abstracta es el ancestro de todas las clases que proporcionan
50
 * soporte para ficheros raster georeferenciados.<br>
51
 * Actua tambien como una 'Fabrica', ocultando al cliente la manera en que
52
 * se ha implementado ese manejo. Una clase nueva que soportara un nuevo
53
 * tipo de raster tendr?a que registrar su extensi?n o extensiones usando
54
 * el m?todo @see registerExtension.<br> 
55
 * @author "Luis W. Sevilla" <sevilla_lui@gva.es>*
56
 */
57

    
58
public abstract class GeoRasterFile extends GeoFile {
59
        
60
        /**
61
         * Flag que representa a la banda del Rojo
62
         */
63
        public static final int         RED_BAND        = 0x01;
64
        
65
        /**
66
         * Flag que representa a la banda del Verde
67
         */
68
        public static final int         GREEN_BAND        = 0x02;
69
        
70
        /**
71
         * Flag que representa a la banda del Azul
72
         */
73
        public static final int         BLUE_BAND        = 0x04;
74
        private static TreeMap                 supportedExtensions = null;
75
        protected Component                 updatable = null;
76
        protected boolean                         doTransparency = false;
77
        private boolean                                verifySize = false;
78
        
79
        /**
80
         * Filtro para raster.
81
         * Permite eliminar la franja inutil alrededor de un raster girado o de
82
         * un mosaico de borde irregular.
83
         * 
84
         * Funciona bien solo con raster en tonos de gris, porque se basa que
85
         * el valor del pixel no supere un determinado valor 'umbral' que se
86
         * le pasa al constructor.
87
         * 
88
         * Desarrollado para 'limpiar' los bordes de los mosaicos del SIG
89
         * Oleicola. Para ese caso los par?metros del constructo son:
90
         * PixelFilter(0x10ffff00, 0xff000000, 0xf0f0f0);
91
         */
92
        protected PixelFilter                 tFilter = null;
93
        
94
        /**
95
         * Asignaci?n de banda del Rojo a una banda de la imagen
96
         */
97
        protected int                                 rBandNr = 1;
98
        
99
        /**
100
         * Asignaci?n de banda del Verde a una banda de la imagen
101
         */
102
        protected int                                 gBandNr = 1;
103
        
104
        /**
105
         * Asignaci?n de banda del Azul a una banda de la imagen
106
         */
107
        protected int                                 bBandNr = 1;
108
        
109
        /**
110
         * N?mero de bandas de la imagen
111
         */
112
        protected int                                 bandCount = 1;
113
        private int                                 dataType = DataBuffer.TYPE_BYTE;
114

    
115
        static {
116
                supportedExtensions = new TreeMap();
117
                supportedExtensions.put("ecw",  EcwFile.class);
118
                supportedExtensions.put("jp2",  EcwFile.class);
119
                
120
                supportedExtensions.put("tif",  GdalFile.class);
121
                supportedExtensions.put("tiff", GdalFile.class);
122
                //supportedExtensions.put("jpg",  TifGeoRefFile.class);
123
                supportedExtensions.put("jpg",  GdalFile.class);
124
                //supportedExtensions.put("png",  TifGeoRefFile.class);
125
                supportedExtensions.put("png",  GdalFile.class);
126
                supportedExtensions.put("sid",  MrSidFile.class);
127
        }
128
        
129
        /**
130
         * Factoria para abrir distintos tipos de raster.
131
         * 
132
         * @param proj Proyecci?n en la que est? el raster.
133
         * @param fName Nombre del fichero.
134
         * @return GeoRasterFile, o null si hay problemas.
135
         */
136
        public static GeoRasterFile openFile(IProjection proj, String fName) {
137
                String ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
138
                GeoRasterFile grf = null;
139
                // TODO NotSupportedExtensionException
140
                if (!supportedExtensions.containsKey(ext)) return grf;
141
                /**/
142
                Class clase = (Class) supportedExtensions.get(ext);
143
                Class [] args = {IProjection.class, String.class};
144
                try {
145
                        Constructor hazNuevo = clase.getConstructor(args);
146
                        Object [] args2 = {proj, fName};
147
                        grf = (GeoRasterFile) hazNuevo.newInstance(args2);
148
                } catch (SecurityException e) {
149
                        // TODO Auto-generated catch block
150
                        e.printStackTrace();
151
                } catch (NoSuchMethodException e) {
152
                        // TODO Auto-generated catch block
153
                        e.printStackTrace();
154
                } catch (IllegalArgumentException e) {
155
                        // TODO Auto-generated catch block
156
                        e.printStackTrace();
157
                } catch (InstantiationException e) {
158
                        // TODO Auto-generated catch block
159
                        e.printStackTrace();
160
                } catch (IllegalAccessException e) {
161
                        // TODO Auto-generated catch block
162
                        e.printStackTrace();
163
                } catch (InvocationTargetException e) {
164
                        // TODO Auto-generated catch block
165
                        e.printStackTrace();
166
                }
167
                 
168
                /* * /
169
                if (ext.compareTo("ecw") == 0) {
170
                        grf = new EcwFile(proj, fName);
171
                } else if (ext.compareTo("tif") == 0 || ext.compareTo("tiff") == 0 || ext.compareTo("jpg") == 0  || ext.compareTo("png") == 0 ) {
172
                        grf = new TifGeoRefFile(proj, fName);
173
                }/ * */
174

    
175
                return grf;
176
        }
177
        
178
        /**
179
         * Registra una clase que soporta una extensi?n raster.
180
         * @param ext extensi?n soportada.
181
         * @param clase clase que la soporta.
182
         */
183
        public static void registerExtension(String ext, Class clase) {
184
                ext = ext.toLowerCase();
185
                System.out.println("RASTER: extension '"+ext+"' supported.");
186
                supportedExtensions.put(ext, clase);
187
        }
188
        
189
        /**
190
         * Tipo de fichero soportado.
191
         * Devuelve true si el tipo de fichero (extension) est? soportado, si no
192
         * devuelve false.
193
         * 
194
         * @param fName Fichero raster
195
         * @return  true si est? soportado, si no false.
196
          */
197
        public static boolean fileIsSupported(String fName) {
198
                String ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
199
                return supportedExtensions.containsKey(ext);
200
        }
201
        
202
        /**
203
         * Constructor
204
         * @param proj        Proyecci?n
205
         * @param name        Nombre del fichero de imagen.
206
         */
207
        public GeoRasterFile(IProjection proj, String name) {
208
                super(proj, name);
209
        }
210
        
211
        /**
212
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar 
213
         * un objeto de este tipo.
214
         */
215
        abstract public GeoFile load();
216
        
217
        /**
218
         * Cierra el fichero y libera los recursos.
219
         */
220
        abstract public void close();
221
        
222
        public static PxContour getContour(String fName, String name, IProjection proj) {
223
                PxContour contour = null;
224
                return contour;
225
        }
226
        
227
        /**
228
         * Obtiene el ancho de la imagen
229
         * @return Ancho de la imagen
230
         */
231
        abstract public int getWidth();
232
        
233
        /**
234
         * Obtiene el ancho de la imagen
235
         * @return Ancho de la imagen
236
         */
237
        abstract public int getHeight();
238

    
239
        /**
240
         * Reproyecci?n.
241
         * @param rp        Coordenadas de la transformaci?n
242
         */
243
        abstract public void reProject(ICoordTrans rp);
244

    
245
        /**
246
         * Asigna un nuevo Extent 
247
         * @param e        Extent
248
         */
249
        abstract public void setView(Extent e);
250
        
251
        /**
252
         * Obtiene el extent asignado
253
         * @return        Extent
254
         */
255
        abstract public Extent getView();
256
        
257
        public void setTransparency(boolean t) {
258
                doTransparency = t;
259
                tFilter = new PixelFilter(255);
260
        }
261
        
262
        /**
263
         * Asigna un valor de transparencia
264
         * @param t        Valor de transparencia
265
         */
266
        public void setTransparency(int t ) {
267
                doTransparency = true;
268
                tFilter = new SimplePixelFilter(255 - t);
269
        }
270
        
271
        public boolean getTransparency() { return doTransparency; }
272
        
273
        public void setAlpha(int alpha) {
274
                if (!doTransparency) setTransparency(255 - alpha);
275
                else tFilter.setAlpha(alpha);
276
        }
277
        public int getAlpha() {
278
                if (tFilter == null)
279
                        return 255;
280
                return tFilter.getAlpha();
281
        }
282
        
283
        public void setUpdatable(Component c) { updatable = c; }
284
        
285
        /**
286
         * Actualiza la imagen
287
         * @param width        ancho
288
         * @param height        alto
289
         * @param rp        Reproyecci?n
290
         * @return        img
291
         */
292
        abstract public Image updateImage(int width, int height, ICoordTrans rp);
293

    
294
        /**
295
         * Obtiene el valor del raster en la coordenada que se le pasa.
296
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
297
         * raster.
298
         * @param x        coordenada X
299
         * @param y coordenada Y
300
         * @return
301
         */
302
        abstract public Object getData(int x, int y, int band);
303

    
304
        /**
305
         * Actualiza la/s banda/s especificadas en la imagen.
306
         * @param width                ancho
307
         * @param height        alto
308
         * @param rp                reproyecci?n
309
         * @param img                imagen
310
         * @param flags                que bandas [ RED_BAND | GREEN_BAND | BLUE_BAND ]
311
         * @return                img
312
         * @throws SupersamplingNotSupportedException
313
         */
314
        abstract public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBand)throws SupersamplingNotSupportedException;
315

    
316
        public int getBandCount() { return bandCount; }
317
        
318
        /**
319
         * Asocia un colorBand al rojo, verde o azul.
320
         * @param flag cual (o cuales) de las bandas.
321
         * @param nBand        que colorBand
322
         */
323
        
324
        public void setBand(int flag, int bandNr) {
325
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) rBandNr = bandNr;
326
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) gBandNr = bandNr;
327
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) bBandNr = bandNr;
328
        }
329

    
330
        /**
331
         * Devuelve el colorBand activo en la banda especificada.
332
         * @param flag banda.
333
         */
334
        
335
        public int getBand(int flag) {
336
                if (flag == GeoRasterFile.RED_BAND) return rBandNr;
337
                if (flag == GeoRasterFile.GREEN_BAND) return gBandNr;
338
                if (flag == GeoRasterFile.BLUE_BAND) return bBandNr;
339
                return -1;
340
        }
341
        
342
        /**
343
         * @return Returns the dataType.
344
         */
345
        public int getDataType() {
346
                return dataType;
347
        }
348
        
349
        /**
350
         * @param dataType The dataType to set.
351
         */
352
        public void setDataType(int dataType) {
353
                this.dataType = dataType;
354
        }
355

    
356
        public IObjList getObjects() {
357
                // TODO hay que a?adir el raster a la lista de objetos
358
                IObjList oList = new PxObjList(proj);
359
                return oList;
360
        }
361
        
362
        /**
363
         * Calcula los par?metros de un worl file a partir de las esquinas del raster.
364
         *    1. X pixel size A
365
         *    2. X rotation term D
366
         *    3. Y rotation term B
367
         *    4. Y pixel size E
368
         *    5. X coordinate of upper left corner C
369
         *    6. Y coordinate of upper left corner F
370
         * where the real-world coordinates x',y' can be calculated from
371
         * the image coordinates x,y with the equations
372
         *  x' = Ax + By + C and y' = Dx + Ey + F.
373
         *  The signs of the first 4 parameters depend on the orientation
374
         *  of the image. In the usual case where north is more or less
375
         *  at the top of the image, the X pixel size will be positive
376
         *  and the Y pixel size will be negative. For a south-up image,
377
         *  these signs would be reversed.
378
         * 
379
         * You can calculate the World file parameters yourself based
380
         * on the corner coordinates. The X and Y pixel sizes can be
381
         *  determined simply by dividing the distance between two
382
         *  adjacent corners by the number of columns or rows in the image.
383
         *  The rotation terms are calculated with these equations:
384
         * 
385
         *  # B = (A * number_of_columns + C - lower_right_x') / number_of_rows * -1
386
         *  # D = (E * number_of_rows + F - lower_right_y') / number_of_columns * -1
387
         * 
388
         * @param corner (tl, tr, br, bl)
389
         * @return
390
         */
391
        public static double [] cornersToWorldFile(Point2D [] esq, Dimension size) {
392
                double a=0,b=0,c=0,d=0,e=0,f=0;
393
                double x1 = esq[0].getX(), y1 = esq[0].getY();
394
                double x2 = esq[1].getX(), y2 = esq[1].getY();
395
                double x3 = esq[2].getX(), y3 = esq[2].getY();
396
                double x4 = esq[3].getX(), y4 = esq[3].getY();
397
                // A: X-scale
398
                a = Math.abs( Math.sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
399
                      / size.getWidth());
400

    
401
                // E: negative Y-scale
402
                e =  - Math.abs(Math.sqrt((x1-x4)*(x1-x4)+
403
                      (y1-y4)*(y1-y4))/size.getHeight());
404

    
405
                // C, F: upper-left coordinates
406
                c = x1;
407
                f = y1;
408
                
409
                // B & D: rotation parameters
410
                b = (a * size.getWidth() + c - x3 ) / size.getHeight() * -1;
411
                d = (e * size.getHeight() + f - y3 ) / size.getWidth() * -1;
412

    
413
                double [] wf = {a,d,b,e,c,f}; 
414
                return wf;  
415
        }
416
    public static String printWF(String fName, Point2D [] esq, Dimension sz) {
417
            double [] wf = GeoRasterFile.cornersToWorldFile(esq, sz);
418
            System.out.println("wf para "+fName);
419
            System.out.println(esq+"\n"+sz);
420
            String wfData = "";
421
            for (int i=0; i<6; i++)
422
                    wfData += wf[i]+"\n";
423
                System.out.println(wfData);
424
                return wfData;
425
    }
426
    
427
    public static void saveWF(String fName, String data) throws IOException {
428
            FileWriter fw = new FileWriter(fName);
429
            fw.write(data);
430
            fw.flush();
431
            fw.close();
432
    }
433

    
434
        /**
435
         * Cosulta si hay que verificar la relaci?n de aspecto de la imagen, es decir comprueba que el ancho/alto
436
         * pasados a updateImage coinciden con el ancho/alto solicitado en setView a la imagen
437
         * @return true si est? verificando la relaci?n de aspecto. 
438
         */
439
        public boolean mustVerifySize() {
440
                return verifySize;
441
        }
442

    
443
        /**
444
         * Asigna el flag que dice si hay que verificar la relaci?n de aspecto de la imagen, es decir 
445
         * comprueba que el ancho/alto pasados a updateImage coinciden con el ancho/alto solicitado 
446
         * en setView a la imagen.
447
         * @return true si est? verificando la relaci?n de aspecto. 
448
         */
449
        public void setMustVerifySize(boolean verifySize) {
450
                this.verifySize = verifySize;
451
        }
452

    
453
        abstract public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band);
454
        abstract public int getBlockSize();
455
        
456
        /*
457
         * Obtiene el extent temporal.
458
         * @return Returns the tempExtent.
459
         *
460
        public Extent getExtent() {
461
                return extent;
462
        }*/
463
        
464
        /**
465
         * Asigna un extent temporal que puede coincidir con el de la vista. Esto es 
466
         * util para cargar imagenes sin georreferenciar ya que podemos asignar el extent
467
         * que queramos para ajustarnos a una vista concreta
468
         * @param tempExtent The tempExtent to set.
469
         */
470
        public void setExtent(Extent ext) {
471
                this.extent = ext;
472
        }
473
        
474
        /*
475
         * Asigna  al flag que le dice al driver si tiene que coger el extent
476
         * pasado desde el cliente.
477
         * @param aExt Valor de un flag ASIGNED_EXTENT, IMAGE_EXTENT, ORDER  
478
         *
479
        public void setExtentFlag(int aExt){
480
                this.assignedExtent = aExt;
481
        }*/
482
        
483
}