Statistics
| Revision:

root / trunk / libraries / libCq CMS for java.old / src / org / cresques / io / GeoRasterFile.java @ 2849

History | View | Annotate | Download (14.4 KB)

1 2 luisw
/*
2 2809 nacho
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 *
4
 * Copyright (C) 2004-5.
5 2 luisw
 *
6 2809 nacho
 * 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 2 luisw
 */
24
package org.cresques.io;
25
26 130 luisw
import java.awt.Component;
27 2809 nacho
import java.awt.Dimension;
28 2 luisw
import java.awt.Image;
29 2809 nacho
import java.awt.geom.Point2D;
30
import java.awt.image.DataBuffer;
31
import java.io.FileWriter;
32
import java.io.IOException;
33 157 luisw
import java.lang.reflect.Constructor;
34
import java.lang.reflect.InvocationTargetException;
35
import java.util.TreeMap;
36 2 luisw
37 94 luisw
import org.cresques.cts.ICoordTrans;
38
import org.cresques.cts.IProjection;
39 2809 nacho
import org.cresques.io.raster.PixelFilter;
40
import org.cresques.io.raster.SimplePixelFilter;
41 2 luisw
import org.cresques.px.Extent;
42 96 luisw
import org.cresques.px.IObjList;
43 2 luisw
import org.cresques.px.PxContour;
44 96 luisw
import org.cresques.px.PxObjList;
45
46 2 luisw
/**
47 157 luisw
 * Manejador de ficheros raster georeferenciados.
48 2 luisw
 *
49 157 luisw
 * 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 50 luisw
 * @author "Luis W. Sevilla" <sevilla_lui@gva.es>*
56 2 luisw
 */
57 50 luisw
58 2 luisw
public abstract class GeoRasterFile extends GeoFile {
59 2809 nacho
60 184 luisw
        /**
61 2809 nacho
         * 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 2849 nacho
        /**
78
         * Variable que puede tener un valor si se le asigna el extent
79
         * de la vista. Esto es util para cargar imagenes sin georreferenciar
80
         * ya que podemos asignar el extent que queramos para ajustarnos a una
81
         * vista concreta
82
         */
83
        private Extent tempExtent = null;
84 2809 nacho
85
        /**
86 184 luisw
         * Filtro para raster.
87
         * Permite eliminar la franja inutil alrededor de un raster girado o de
88
         * un mosaico de borde irregular.
89
         *
90
         * Funciona bien solo con raster en tonos de gris, porque se basa que
91
         * el valor del pixel no supere un determinado valor 'umbral' que se
92
         * le pasa al constructor.
93
         *
94
         * Desarrollado para 'limpiar' los bordes de los mosaicos del SIG
95
         * Oleicola. Para ese caso los par?metros del constructo son:
96
         * PixelFilter(0x10ffff00, 0xff000000, 0xf0f0f0);
97
         */
98
        protected PixelFilter tFilter = null;
99 2809 nacho
100
        /**
101
         * Asignaci?n de banda del Rojo a una banda de la imagen
102
         */
103
        protected int rBandNr = 1;
104
105
        /**
106
         * Asignaci?n de banda del Verde a una banda de la imagen
107
         */
108
        protected int gBandNr = 1;
109
110
        /**
111
         * Asignaci?n de banda del Azul a una banda de la imagen
112
         */
113
        protected int bBandNr = 1;
114
115
        /**
116
         * N?mero de bandas de la imagen
117
         */
118
        protected int bandCount = 1;
119
        private int dataType = DataBuffer.TYPE_BYTE;
120 184 luisw
121 157 luisw
        static {
122
                supportedExtensions = new TreeMap();
123 2809 nacho
                //if (System.getProperty("os.name").toUpperCase().startsWith("WIN")) {
124
                        supportedExtensions.put("ecw",  EcwFile.class);
125
                //}
126 157 luisw
                supportedExtensions.put("tif",  TifGeoRefFile.class);
127
                supportedExtensions.put("tiff", TifGeoRefFile.class);
128 2809 nacho
                //supportedExtensions.put("jpg",  TifGeoRefFile.class);
129
                supportedExtensions.put("jpg",  GdalFile.class);
130
                //supportedExtensions.put("png",  TifGeoRefFile.class);
131
                supportedExtensions.put("png",  GdalFile.class);
132
                supportedExtensions.put("sid",  MrSidFile.class);
133 157 luisw
        }
134
135 50 luisw
        /**
136 157 luisw
         * Factoria para abrir distintos tipos de raster.
137
         *
138
         * @param proj Proyecci?n en la que est? el raster.
139
         * @param fName Nombre del fichero.
140
         * @return GeoRasterFile, o null si hay problemas.
141 50 luisw
         */
142 94 luisw
        public static GeoRasterFile openFile(IProjection proj, String fName) {
143 58 luisw
                String ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
144 157 luisw
                GeoRasterFile grf = null;
145
                // TODO NotSupportedExtensionException
146
                if (!supportedExtensions.containsKey(ext)) return grf;
147
                /**/
148
                Class clase = (Class) supportedExtensions.get(ext);
149
                Class [] args = {IProjection.class, String.class};
150
                try {
151
                        Constructor hazNuevo = clase.getConstructor(args);
152
                        Object [] args2 = {proj, fName};
153
                        grf = (GeoRasterFile) hazNuevo.newInstance(args2);
154
                } catch (SecurityException e) {
155
                        // TODO Auto-generated catch block
156
                        e.printStackTrace();
157
                } catch (NoSuchMethodException e) {
158
                        // TODO Auto-generated catch block
159
                        e.printStackTrace();
160
                } catch (IllegalArgumentException e) {
161
                        // TODO Auto-generated catch block
162
                        e.printStackTrace();
163
                } catch (InstantiationException e) {
164
                        // TODO Auto-generated catch block
165
                        e.printStackTrace();
166
                } catch (IllegalAccessException e) {
167
                        // TODO Auto-generated catch block
168
                        e.printStackTrace();
169
                } catch (InvocationTargetException e) {
170
                        // TODO Auto-generated catch block
171
                        e.printStackTrace();
172 2809 nacho
                }
173 157 luisw
174
                /* * /
175 110 luisw
                if (ext.compareTo("ecw") == 0) {
176 157 luisw
                        grf = new EcwFile(proj, fName);
177 110 luisw
                } else if (ext.compareTo("tif") == 0 || ext.compareTo("tiff") == 0 || ext.compareTo("jpg") == 0  || ext.compareTo("png") == 0 ) {
178 157 luisw
                        grf = new TifGeoRefFile(proj, fName);
179
                }/ * */
180 50 luisw
181 157 luisw
                return grf;
182 50 luisw
        }
183 157 luisw
184
        /**
185
         * Registra una clase que soporta una extensi?n raster.
186
         * @param ext extensi?n soportada.
187
         * @param clase clase que la soporta.
188
         */
189
        public static void registerExtension(String ext, Class clase) {
190
                ext = ext.toLowerCase();
191 2809 nacho
                System.out.println("RASTER: extension '"+ext+"' supported.");
192 157 luisw
                supportedExtensions.put(ext, clase);
193
        }
194
195 2809 nacho
        /**
196
         * Tipo de fichero soportado.
197
         * Devuelve true si el tipo de fichero (extension) est? soportado, si no
198
         * devuelve false.
199
         *
200
         * @param fName Fichero raster
201
         * @return  true si est? soportado, si no false.
202
          */
203
        public static boolean fileIsSupported(String fName) {
204
                String ext = fName.toLowerCase().substring(fName.lastIndexOf('.')+1);
205
                return supportedExtensions.containsKey(ext);
206
        }
207 184 luisw
208 2809 nacho
        /**
209
         * Constructor
210
         * @param proj        Proyecci?n
211
         * @param name        Nombre del fichero de imagen.
212
         */
213 94 luisw
        public GeoRasterFile(IProjection proj, String name) {
214 13 luisw
                super(proj, name);
215 2 luisw
        }
216 157 luisw
217 2809 nacho
        /**
218
         * Carga un fichero raster. Puede usarse para calcular el extent e instanciar
219
         * un objeto de este tipo.
220
         */
221 157 luisw
        abstract public GeoFile load();
222
223 2809 nacho
        /**
224
         * Cierra el fichero y libera los recursos.
225
         */
226
        abstract public void close();
227
228 125 luisw
        public static PxContour getContour(String fName, String name, IProjection proj) {
229 2 luisw
                PxContour contour = null;
230
                return contour;
231
        }
232 130 luisw
233 2809 nacho
        /**
234
         * Obtiene el ancho de la imagen
235
         * @return Ancho de la imagen
236
         */
237 130 luisw
        abstract public int getWidth();
238 2809 nacho
239
        /**
240
         * Obtiene el ancho de la imagen
241
         * @return Ancho de la imagen
242
         */
243 130 luisw
        abstract public int getHeight();
244 2 luisw
245 2809 nacho
        /**
246
         * Reproyecci?n.
247
         * @param rp        Coordenadas de la transformaci?n
248
         */
249 94 luisw
        abstract public void reProject(ICoordTrans rp);
250 2 luisw
251 2809 nacho
        /**
252
         * Asigna un nuevo Extent
253
         * @param e        Extent
254
         */
255 2 luisw
        abstract public void setView(Extent e);
256 2809 nacho
257
        /**
258
         * Obtiene el extent asignado
259
         * @return        Extent
260
         */
261 2 luisw
        abstract public Extent getView();
262
263 2809 nacho
        public void setTransparency(boolean t) {
264
                doTransparency = t;
265
                tFilter = new PixelFilter(255);
266
        }
267 2 luisw
268 2809 nacho
        /**
269
         * Asigna un valor de transparencia
270
         * @param t        Valor de transparencia
271
         */
272
        public void setTransparency(int t ) {
273
                doTransparency = true;
274
                tFilter = new SimplePixelFilter(255 - t);
275
        }
276
277
        public boolean getTransparency() { return doTransparency; }
278
279
        public void setAlpha(int alpha) {
280
                if (!doTransparency) setTransparency(255 - alpha);
281
                else tFilter.setAlpha(alpha);
282
        }
283
        public int getAlpha() {
284
                if (tFilter == null)
285
                        return 255;
286
                return tFilter.getAlpha();
287
        }
288
289 130 luisw
        public void setUpdatable(Component c) { updatable = c; }
290
291 2809 nacho
        /**
292
         * Actualiza la imagen
293
         * @param width        ancho
294
         * @param height        alto
295
         * @param rp        Reproyecci?n
296
         * @return        img
297
         */
298 94 luisw
        abstract public Image updateImage(int width, int height, ICoordTrans rp);
299 2809 nacho
300
        /**
301
         * Obtiene el valor del raster en la coordenada que se le pasa.
302
         * El valor ser? Double, Int, Byte, etc. dependiendo del tipo de
303
         * raster.
304
         * @param x        coordenada X
305
         * @param y coordenada Y
306
         * @return
307
         */
308
        abstract public Object getData(int x, int y, int band);
309
310
        /**
311
         * Actualiza la/s banda/s especificadas en la imagen.
312
         * @param width                ancho
313
         * @param height        alto
314
         * @param rp                reproyecci?n
315
         * @param img                imagen
316
         * @param flags                que bandas [ RED_BAND | GREEN_BAND | BLUE_BAND ]
317
         * @return                img
318
         */
319
        abstract public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBand);
320
321
        public int getBandCount() { return bandCount; }
322 96 luisw
323 2809 nacho
        /**
324
         * Asocia un colorBand al rojo, verde o azul.
325
         * @param flag cual (o cuales) de las bandas.
326
         * @param nBand        que colorBand
327
         */
328
329
        public void setBand(int flag, int bandNr) {
330
                if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) rBandNr = bandNr;
331
                if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) gBandNr = bandNr;
332
                if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) bBandNr = bandNr;
333
        }
334
335
        /**
336
         * Devuelve el colorBand activo en la banda especificada.
337
         * @param flag banda.
338
         */
339
340
        public int getBand(int flag) {
341
                if (flag == GeoRasterFile.RED_BAND) return rBandNr;
342
                if (flag == GeoRasterFile.GREEN_BAND) return gBandNr;
343
                if (flag == GeoRasterFile.BLUE_BAND) return bBandNr;
344
                return -1;
345
        }
346
347
        /**
348
         * @return Returns the dataType.
349
         */
350
        public int getDataType() {
351
                return dataType;
352
        }
353
354
        /**
355
         * @param dataType The dataType to set.
356
         */
357
        public void setDataType(int dataType) {
358
                this.dataType = dataType;
359
        }
360
361 96 luisw
        public IObjList getObjects() {
362
                // TODO hay que a?adir el raster a la lista de objetos
363
                IObjList oList = new PxObjList(proj);
364
                return oList;
365
        }
366 2809 nacho
367
        /**
368
         * Calcula los par?metros de un worl file a partir de las esquinas del raster.
369
         *    1. X pixel size A
370
         *    2. X rotation term D
371
         *    3. Y rotation term B
372
         *    4. Y pixel size E
373
         *    5. X coordinate of upper left corner C
374
         *    6. Y coordinate of upper left corner F
375
         * where the real-world coordinates x',y' can be calculated from
376
         * the image coordinates x,y with the equations
377
         *  x' = Ax + By + C and y' = Dx + Ey + F.
378
         *  The signs of the first 4 parameters depend on the orientation
379
         *  of the image. In the usual case where north is more or less
380
         *  at the top of the image, the X pixel size will be positive
381
         *  and the Y pixel size will be negative. For a south-up image,
382
         *  these signs would be reversed.
383
         *
384
         * You can calculate the World file parameters yourself based
385
         * on the corner coordinates. The X and Y pixel sizes can be
386
         *  determined simply by dividing the distance between two
387
         *  adjacent corners by the number of columns or rows in the image.
388
         *  The rotation terms are calculated with these equations:
389
         *
390
         *  # B = (A * number_of_columns + C - lower_right_x') / number_of_rows * -1
391
         *  # D = (E * number_of_rows + F - lower_right_y') / number_of_columns * -1
392
         *
393
         * @param corner (tl, tr, br, bl)
394
         * @return
395
         */
396
        public static double [] cornersToWorldFile(Point2D [] esq, Dimension size) {
397
                double a=0,b=0,c=0,d=0,e=0,f=0;
398
                double x1 = esq[0].getX(), y1 = esq[0].getY();
399
                double x2 = esq[1].getX(), y2 = esq[1].getY();
400
                double x3 = esq[2].getX(), y3 = esq[2].getY();
401
                double x4 = esq[3].getX(), y4 = esq[3].getY();
402
                // A: X-scale
403
                a = Math.abs( Math.sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
404
                      / size.getWidth());
405
406
                // E: negative Y-scale
407
                e =  - Math.abs(Math.sqrt((x1-x4)*(x1-x4)+
408
                      (y1-y4)*(y1-y4))/size.getHeight());
409
410
                // C, F: upper-left coordinates
411
                c = x1;
412
                f = y1;
413
414
                // B & D: rotation parameters
415
                b = (a * size.getWidth() + c - x3 ) / size.getHeight() * -1;
416
                d = (e * size.getHeight() + f - y3 ) / size.getWidth() * -1;
417
418
                double [] wf = {a,d,b,e,c,f};
419
                return wf;
420
        }
421
    public static String printWF(String fName, Point2D [] esq, Dimension sz) {
422
            double [] wf = GeoRasterFile.cornersToWorldFile(esq, sz);
423
            System.out.println("wf para "+fName);
424
            System.out.println(esq+"\n"+sz);
425
            String wfData = "";
426
            for (int i=0; i<6; i++)
427
                    wfData += wf[i]+"\n";
428
                System.out.println(wfData);
429
                return wfData;
430
    }
431
432
    public static void saveWF(String fName, String data) throws IOException {
433
            FileWriter fw = new FileWriter(fName);
434
            fw.write(data);
435
            fw.flush();
436
            fw.close();
437
    }
438
439
        abstract public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band);
440
        abstract public int getBlockSize();
441 2849 nacho
442
        /**
443
         * Obtiene el extent temporal.
444
         * @return Returns the tempExtent.
445
         */
446
        public Extent getTempExtent() {
447
                return tempExtent;
448
        }
449
450
        /**
451
         * Asigna un extent temporal que puede coincidir con el de la vista. Esto es
452
         * util para cargar imagenes sin georreferenciar ya que podemos asignar el extent
453
         * que queramos para ajustarnos a una vista concreta
454
         * @param tempExtent The tempExtent to set.
455
         */
456
        public void setTempExtent(Extent tempExtent) {
457
                this.tempExtent = tempExtent;
458
        }
459
460
        /**
461
         * Calcula un extent posible para la imagen a partir del extent de la vista
462
         * @param w        Ancho de la imagen
463
         * @param h Alto de la imagen
464
         * @return        Extent para la imagen
465
         */
466
        protected Extent calcTempExtent(double w, double h){
467
                double ulX = 0D, ulY = 0D, lrX = 0D, lrY = 0D;
468
                if(w > h){
469
                        double widthView = tempExtent.maxX() - tempExtent.minX();
470
                        ulX = tempExtent.minX() + (widthView / 4);
471
                        lrX = ulX + (widthView / 2);
472
                        double newAlto = ((h * (widthView / 2)) / w);
473
                        double centroY = tempExtent.minY()+((tempExtent.maxY() - tempExtent.minY())/2);
474
                        ulY = centroY - (newAlto / 2);
475
                        lrY = centroY + (newAlto / 2);
476
                }else{
477
                        double heightView = tempExtent.maxY() - tempExtent.minY();
478
                        ulY = tempExtent.minY() + (heightView / 4);
479
                        lrY = ulY + (heightView / 2);
480
                        double newAncho = ((w * (heightView / 2)) / h);
481
                        double centroX = tempExtent.minX()+((tempExtent.maxX() - tempExtent.minX())/2);
482
                        ulX = centroX - (newAncho / 2);
483
                        lrX = centroX + (newAncho / 2);
484
                }
485
                return new Extent(ulX, ulY, lrX, lrY);
486
        }
487 2 luisw
}