Statistics
| Revision:

svn-gvsig-desktop / branches / CqCMSDvp / libraries / libCq CMS for java.old / src / org / cresques / io / GeoRasterFile.java @ 2790

History | View | Annotate | Download (12.6 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
                
78
        /**
79
         * Filtro para raster.
80
         * Permite eliminar la franja inutil alrededor de un raster girado o de
81
         * un mosaico de borde irregular.
82
         * 
83
         * Funciona bien solo con raster en tonos de gris, porque se basa que
84
         * el valor del pixel no supere un determinado valor 'umbral' que se
85
         * le pasa al constructor.
86
         * 
87
         * Desarrollado para 'limpiar' los bordes de los mosaicos del SIG
88
         * Oleicola. Para ese caso los par?metros del constructo son:
89
         * PixelFilter(0x10ffff00, 0xff000000, 0xf0f0f0);
90
         */
91
        protected PixelFilter tFilter = null;
92
        
93
        /**
94
         * Asignaci?n de banda del Rojo a una banda de la imagen
95
         */
96
        protected int rBandNr = 1;
97
        
98
        /**
99
         * Asignaci?n de banda del Verde a una banda de la imagen
100
         */
101
        protected int gBandNr = 1;
102
        
103
        /**
104
         * Asignaci?n de banda del Azul a una banda de la imagen
105
         */
106
        protected int bBandNr = 1;
107
        
108
        /**
109
         * N?mero de bandas de la imagen
110
         */
111
        protected int bandCount = 1;
112
        private int dataType = DataBuffer.TYPE_BYTE;
113

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

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

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

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

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

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

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

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

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

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

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

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