Statistics
| Revision:

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

History | View | Annotate | Download (11.7 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
        public static final int RED_BAND        = 0x01;
60
        public static final int GREEN_BAND        = 0x02;
61
        public static final int BLUE_BAND        = 0x04;
62

    
63
        /**
64
         * Filtro para raster.
65
         * Permite eliminar la franja inutil alrededor de un raster girado o de
66
         * un mosaico de borde irregular.
67
         * 
68
         * Funciona bien solo con raster en tonos de gris, porque se basa que
69
         * el valor del pixel no supere un determinado valor 'umbral' que se
70
         * le pasa al constructor.
71
         * 
72
         * Desarrollado para 'limpiar' los bordes de los mosaicos del SIG
73
         * Oleicola. Para ese caso los par?metros del constructo son:
74
         * PixelFilter(0x10ffff00, 0xff000000, 0xf0f0f0);
75
         * 
76
         * @author "Luis W. Sevilla" <sevilla_lui@gva.es>
77
         */
78

    
79
        
80
        private static TreeMap supportedExtensions = null;
81
        protected Component updatable = null;
82
        protected boolean doTransparency = false;
83
        //protected int alpha = 0;
84
        protected PixelFilter tFilter = null;
85

    
86
        protected int rBandNr = 1, gBandNr = 1, bBandNr = 1;
87
        protected int bandCount = 1;
88
        private int dataType = DataBuffer.TYPE_BYTE;
89

    
90
        static {
91
                supportedExtensions = new TreeMap();
92
                //if (System.getProperty("os.name").toUpperCase().startsWith("WIN")) {
93
                        supportedExtensions.put("ecw",  EcwFile.class);
94
                //}
95
                supportedExtensions.put("tif",  TifGeoRefFile.class);
96
                supportedExtensions.put("tiff", TifGeoRefFile.class);
97
                //supportedExtensions.put("jpg",  TifGeoRefFile.class);
98
                supportedExtensions.put("jpg",  GdalFile.class);
99
                //supportedExtensions.put("png",  TifGeoRefFile.class);
100
                supportedExtensions.put("png",  GdalFile.class);
101
                supportedExtensions.put("sid",  MrSidFile.class);
102
        }
103
        
104
        /**
105
         * Factoria para abrir distintos tipos de raster.
106
         * 
107
         * @param proj Proyecci?n en la que est? el raster.
108
         * @param fName Nombre del fichero.
109
         * @return GeoRasterFile, o null si hay problemas.
110
         */
111
        public static GeoRasterFile openFile(IProjection proj, String fName) {
112
                String ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
113
                GeoRasterFile grf = null;
114
                // TODO NotSupportedExtensionException
115
                if (!supportedExtensions.containsKey(ext)) return grf;
116
                /**/
117
                Class clase = (Class) supportedExtensions.get(ext);
118
                Class [] args = {IProjection.class, String.class};
119
                try {
120
                        Constructor hazNuevo = clase.getConstructor(args);
121
                        Object [] args2 = {proj, fName};
122
                        grf = (GeoRasterFile) hazNuevo.newInstance(args2);
123
                } catch (SecurityException e) {
124
                        // TODO Auto-generated catch block
125
                        e.printStackTrace();
126
                } catch (NoSuchMethodException e) {
127
                        // TODO Auto-generated catch block
128
                        e.printStackTrace();
129
                } catch (IllegalArgumentException e) {
130
                        // TODO Auto-generated catch block
131
                        e.printStackTrace();
132
                } catch (InstantiationException e) {
133
                        // TODO Auto-generated catch block
134
                        e.printStackTrace();
135
                } catch (IllegalAccessException e) {
136
                        // TODO Auto-generated catch block
137
                        e.printStackTrace();
138
                } catch (InvocationTargetException e) {
139
                        // TODO Auto-generated catch block
140
                        e.printStackTrace();
141
                }/**/
142
                 
143
                /* * /
144
                if (ext.compareTo("ecw") == 0) {
145
                        grf = new EcwFile(proj, fName);
146
                } else if (ext.compareTo("tif") == 0 || ext.compareTo("tiff") == 0 || ext.compareTo("jpg") == 0  || ext.compareTo("png") == 0 ) {
147
                        grf = new TifGeoRefFile(proj, fName);
148
                }/ * */
149

    
150
                return grf;
151
        }
152
        
153
        /**
154
         * Registra una clase que soporta una extensi?n raster.
155
         * @param ext extensi?n soportada.
156
         * @param clase clase que la soporta.
157
         */
158
        public static void registerExtension(String ext, Class clase) {
159
                ext = ext.toLowerCase();
160
                System.out.println("RASTER: extension '"+ext+"' supported.");
161
                supportedExtensions.put(ext, clase);
162
        }
163
        
164
        /**
165
         * Tipo de fichero soportado.
166
         * Devuelve true si el tipo de fichero (extension) est? soportado, si no
167
         * devuelve false.
168
         * 
169
         * @param fName Fichero raster
170
         * @return  true si est? soportado, si no false.
171
          */
172
        public static boolean fileIsSupported(String fName) {
173
                String ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
174
                return supportedExtensions.containsKey(ext);
175
        }
176
        
177
        public GeoRasterFile(IProjection proj, String name) {
178
                super(proj, name);
179
        }
180
        
181
        abstract public GeoFile load();
182
        
183
        abstract public void close();
184
        
185
        public static PxContour getContour(String fName, String name, IProjection proj) {
186
                PxContour contour = null;
187
                return contour;
188
        }
189
        
190
        abstract public int getWidth();
191
        abstract public int getHeight();
192

    
193
        abstract public void reProject(ICoordTrans rp);
194

    
195
        abstract public void setView(Extent e);
196
        abstract public Extent getView();
197
        
198
        // TRANSPARENCIA. Versi?n de pruebas. Hay que verificar que se puede
199
        // tener filtros y valores alpha, que no es lento, y que no hay una manera
200
        // mejor de hacerlo.
201
        //abstract public void setTransparency(boolean t);
202
        //abstract public void setTransparency(int t);
203
        public void setTransparency(boolean t) {
204
                doTransparency = t;
205
                tFilter = new PixelFilter(255);
206
        }
207
        public void setTransparency(int t ) {
208
                doTransparency = true;
209
                tFilter = new SimplePixelFilter(255 - t);
210
        }
211
        public boolean getTransparency() { return doTransparency; }
212
        public void setAlpha(int alpha) {
213
                if (!doTransparency) setTransparency(255 - alpha);
214
                else tFilter.setAlpha(alpha);
215
        }
216
        public int getAlpha() {
217
                if (tFilter == null)
218
                        return 255;
219
                return tFilter.getAlpha();
220
        }
221
        
222
        public void setUpdatable(Component c) { updatable = c; }
223
        
224
        abstract public Image updateImage(int width, int height, ICoordTrans rp);
225

    
226
        /**
227
         * Obtiene el valor del raster en la coordenada que se le pasa.
228
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
229
         * raster.
230
         * @param x        coordenada X
231
         * @param y coordenada Y
232
         * @return
233
         */
234
        abstract public Object getData(int x, int y, int band);
235

    
236
        /**
237
         * Actualiza la/s banda/s especificadas en la imagen.
238
         * @param width                ancho
239
         * @param height        alto
240
         * @param rp                reproyecci?n
241
         * @param img                imagen
242
         * @param flags                que bandas [ RED_BAND | GREEN_BAND | BLUE_BAND ]
243
         * @return                img
244
         */
245
        abstract public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBand);
246

    
247
        public int getBandCount() { return bandCount; }
248
        
249
        /**
250
         * Asocia un colorBand al rojo, verde o azul.
251
         * @param flag cual (o cuales) de las bandas.
252
         * @param nBand        que colorBand
253
         */
254
        
255
        public void setBand(int flag, int bandNr) {
256
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) rBandNr = bandNr;
257
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) gBandNr = bandNr;
258
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) bBandNr = bandNr;
259
        }
260

    
261
        /**
262
         * Devuelve el colorBand activo en la banda especificada.
263
         * @param flag banda.
264
         */
265
        
266
        public int getBand(int flag) {
267
                if (flag == GeoRasterFile.RED_BAND) return rBandNr;
268
                if (flag == GeoRasterFile.GREEN_BAND) return gBandNr;
269
                if (flag == GeoRasterFile.BLUE_BAND) return bBandNr;
270
                return -1;
271
        }
272
        
273
        /**
274
         * @return Returns the dataType.
275
         */
276
        public int getDataType() {
277
                return dataType;
278
        }
279
        /**
280
         * @param dataType The dataType to set.
281
         */
282
        public void setDataType(int dataType) {
283
                this.dataType = dataType;
284
        }
285

    
286
        public IObjList getObjects() {
287
                // TODO hay que a?adir el raster a la lista de objetos
288
                IObjList oList = new PxObjList(proj);
289
                return oList;
290
        }
291
        
292
        /**
293
         * Calcula los par?metros de un worl file a partir de las esquinas del raster.
294
         *    1. X pixel size A
295
         *    2. X rotation term D
296
         *    3. Y rotation term B
297
         *    4. Y pixel size E
298
         *    5. X coordinate of upper left corner C
299
         *    6. Y coordinate of upper left corner F
300
         * where the real-world coordinates x',y' can be calculated from
301
         * the image coordinates x,y with the equations
302
         *  x' = Ax + By + C and y' = Dx + Ey + F.
303
         *  The signs of the first 4 parameters depend on the orientation
304
         *  of the image. In the usual case where north is more or less
305
         *  at the top of the image, the X pixel size will be positive
306
         *  and the Y pixel size will be negative. For a south-up image,
307
         *  these signs would be reversed.
308
         * 
309
         * You can calculate the World file parameters yourself based
310
         * on the corner coordinates. The X and Y pixel sizes can be
311
         *  determined simply by dividing the distance between two
312
         *  adjacent corners by the number of columns or rows in the image.
313
         *  The rotation terms are calculated with these equations:
314
         * 
315
         *  # B = (A * number_of_columns + C - lower_right_x') / number_of_rows * -1
316
         *  # D = (E * number_of_rows + F - lower_right_y') / number_of_columns * -1
317
         * 
318
         * @param corner (tl, tr, br, bl)
319
         * @return
320
         */
321
        
322
        public static double [] cornersToWorldFile(Point2D [] esq, Dimension size) {
323
                double a=0,b=0,c=0,d=0,e=0,f=0;
324
                double x1 = esq[0].getX(), y1 = esq[0].getY();
325
                double x2 = esq[1].getX(), y2 = esq[1].getY();
326
                double x3 = esq[2].getX(), y3 = esq[2].getY();
327
                double x4 = esq[3].getX(), y4 = esq[3].getY();
328
                // A: X-scale
329
                a = Math.abs( Math.sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
330
                      / size.getWidth());
331

    
332
                // E: negative Y-scale
333
                e =  - Math.abs(Math.sqrt((x1-x4)*(x1-x4)+
334
                      (y1-y4)*(y1-y4))/size.getHeight());
335

    
336
                // C, F: upper-left coordinates
337
                c = x1;
338
                f = y1;
339
                
340
                // B & D: rotation parameters
341
                b = (a * size.getWidth() + c - x3 ) / size.getHeight() * -1;
342
                d = (e * size.getHeight() + f - y3 ) / size.getWidth() * -1;
343

    
344
                double [] wf = {a,d,b,e,c,f}; 
345
                return wf;  
346
        }
347
    public static String printWF(String fName, Point2D [] esq, Dimension sz) {
348
            double [] wf = GeoRasterFile.cornersToWorldFile(esq, sz);
349
            System.out.println("wf para "+fName);
350
            System.out.println(esq+"\n"+sz);
351
            String wfData = "";
352
            for (int i=0; i<6; i++)
353
                    wfData += wf[i]+"\n";
354
                System.out.println(wfData);
355
                return wfData;
356
    }
357
    
358
    public static void saveWF(String fName, String data) throws IOException {
359
            FileWriter fw = new FileWriter(fName);
360
            fw.write(data);
361
            fw.flush();
362
            fw.close();
363
    }
364
    
365
        abstract public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band);
366
        abstract public int getBlockSize();
367
}