Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / RasterLibrary.java @ 19409

History | View | Annotate | Download (12.9 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster;
20

    
21
import java.io.File;
22
import java.io.FileFilter;
23
import java.io.IOException;
24
import java.net.MalformedURLException;
25
import java.net.URL;
26
import java.util.ArrayList;
27
import java.util.Enumeration;
28
import java.util.Hashtable;
29
import java.util.jar.JarException;
30
import java.util.zip.ZipEntry;
31
import java.util.zip.ZipException;
32
import java.util.zip.ZipFile;
33

    
34
import org.apache.log4j.Logger;
35
import org.gvsig.raster.dataset.io.ErmapperDriver;
36
import org.gvsig.raster.dataset.io.ErmapperWriter;
37
import org.gvsig.raster.dataset.io.GdalDriver;
38
import org.gvsig.raster.dataset.io.GdalWriter;
39
import org.gvsig.raster.dataset.io.JpegWriter;
40
import org.gvsig.raster.dataset.io.MemoryRasterDriver;
41
import org.gvsig.raster.dataset.io.MrSidDriver;
42
import org.gvsig.raster.dataset.io.PngWriter;
43
import org.gvsig.raster.grid.filter.bands.ColorBalanceCMYManager;
44
import org.gvsig.raster.grid.filter.bands.ColorBalanceRGBManager;
45
import org.gvsig.raster.grid.filter.bands.ColorTableListManager;
46
import org.gvsig.raster.grid.filter.bands.HSLToRGBManager;
47
import org.gvsig.raster.grid.filter.bands.RGBToHSLManager;
48
import org.gvsig.raster.grid.filter.bands.ToLumSaManager;
49
import org.gvsig.raster.grid.filter.convolution.ConvolutionListManager;
50
import org.gvsig.raster.grid.filter.correction.MedianListManager;
51
import org.gvsig.raster.grid.filter.enhancement.BrightnessContrastListManager;
52
import org.gvsig.raster.grid.filter.enhancement.EcualizationManager;
53
import org.gvsig.raster.grid.filter.enhancement.EnhancementStretchListManager;
54
import org.gvsig.raster.grid.filter.pansharp.PanSharpeningListManager;
55
import org.gvsig.raster.grid.filter.segmentation.FirstDerivativeListManager;
56
import org.gvsig.raster.grid.filter.statistics.StatisticsListManager;
57
import org.gvsig.raster.util.PropertyEvent;
58
import org.gvsig.raster.util.PropertyListener;
59
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
60
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
61
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
62
/**
63
 * Clase principal de la libreria. En ella se definen variables globales con informaci?n
64
 * de uso general, as? como acciones a realizar al arracar la librer?a. El m?todo que
65
 * contiene las acciones de arranque es wakeUp. Las tareas principales de este m?todo
66
 * son de registro de drivers de lectura y escritura y eliminaci?n del directorio de
67
 * temporales.
68
 *
69
 * @author Nacho Brodin (nachobrodin@gmail.com)
70
 */
71
public class RasterLibrary {
72
        /**
73
         * Control de librer?a ya inicializada.
74
         */
75
        public static boolean       wakeup = false;
76
        public static ArrayList     writersClassList = new ArrayList();
77

    
78
        /**
79
         * En la generaci?n autom?tica de clases esta variable representa el n?mero de
80
         * clases en las que se hace la divisi?n.
81
         */
82
        public static int          defaultNumberOfClasses = 64;
83

    
84
        /**
85
         * En la genraci?n de las paletas de color, esta variable representa el n?mero
86
         * de colores en las que se hace la divisi?n para generar la paleta nueva.
87
         * Con esto conseguimos velocidad de procesamiento. Cuanto menor sea, peor
88
         * ser? la calidad representada de la imagen.
89
         */
90
        public static int          defaultNumberOfColors = 256;
91
        /**
92
         * Tama?o de bloque en los procesos que recorren un raster completo a base de ventanas con recorrido
93
         * descendente. Esta variable indica la altura de dicho bloque. Por lo tanto cada bloque ser? de
94
         * raster.width X blockHeight. Tipicamente recorridos de este tipo se usan para el calculo de estad?sticas,
95
         * histogramas, salvado a raster, etc... Es importante para el buen funcionamiento que este bloque sea
96
         * potencia de dos.
97
         */
98
        public static int          blockHeight = 512;
99

    
100
        //*************CACHE*******************
101
        /**
102
         * Tama?o aproximado de cach? en Megas. Si este valor es alto cabr?n muchas p?ginas en memoria
103
         * a la vez y si es bajo cabr?n pocas. Hay que tener en cuenta que al instanciar se convertira en bytes
104
         * para su mejor tratamiento. Al llamar al constructor esta variable contendr? el tama?o exacto
105
         * de la cache en bytes. El tama?o aqu? especificado es aproximado. Este variar? dependiendo de los
106
         * par?metros del raster a cachear ya que las p?ginas deben tener una altura potencia de 2.
107
         */
108
        public static long          cacheSize = 25;
109
        /**
110
         * Tama?o m?ximo de la p?gina en Megas. Hay que tener en cuenta que al instanciar se convertira en bytes
111
         * para su mejor tratamiento. Al llamar al constructor esta variable contendr? el tama?o exacto
112
         * de la p?gina en bytes
113
         */
114
        public static double        pageSize = 4;
115
        /**
116
         * N?mero de p?ginas que tiene cada conjunto de cach?
117
         */
118
        public static int           pagsPerGroup = 5;
119

    
120
        //*************PATHS*******************
121

    
122
        /**
123
         * Directorio temporal para la cach?. Si gastamos el mismo que andami este se ocupar? de gestionar su
124
         * destrucci?n al cerrar gvSIG.
125
         */
126
        public static String         tempCacheDirectoryPath = System.getProperty("java.io.tmpdir") + File.separator + "tmp-andami";
127
        /**
128
         * Ruta o rutas donde busca jars con clases que incorporen elementos nuevos que extiendan
129
         * otros ya existentes. Estos pueden ser drivers o filtros.
130
         */
131
        public static String[]       pathExtensions = {"." + File.separator};
132

    
133
        private static Hashtable     clasesJar = new Hashtable();
134

    
135
        /**
136
         * Valor noData por defecto para la librer?a. En caso de no tener un valor asociado
137
         * al raster se usar? este.
138
         */
139
        public static double         defaultNoDataValue = -99999;
140
        /**
141
         * Contador global de las capas generadas para raster
142
         */
143
        private static int           layerCount = 1;
144
        private static ArrayList     propetiesListeners = new ArrayList();
145

    
146
        /**
147
         * Ejecuta las acciones necesarias para arrancar la librer?a.
148
         */
149
        public static void wakeUp() {
150
                if(wakeup)
151
                        return;
152
                
153
                //Punto de extensi?n para registro de drivers de lectura
154
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
155
                if (!extensionPoints.containsKey("RasterReader"))
156
                        extensionPoints.put( new ExtensionPoint( "RasterReader", "Raster Reader Classes"));
157

    
158
                //Punto de extensi?n para registro de drivers de escritura
159
                if (!extensionPoints.containsKey("RasterWriter"))
160
                        extensionPoints.put(new ExtensionPoint("RasterWriter", "Raster Writer Classes"));
161

    
162
                //Ejecuta el c?digo static de la clase cada driver
163
                GdalDriver.register();
164
                ErmapperDriver.register();
165
                MrSidDriver.register();
166
                MemoryRasterDriver.register();
167

    
168
                GdalWriter.register();
169
                ErmapperWriter.register();
170
                JpegWriter.register();
171
                PngWriter.register();
172

    
173
                //Punto de extensi?n para registro de filtros
174
                if (!extensionPoints.containsKey("RasterFilter")) {
175
                        extensionPoints.put(new ExtensionPoint("RasterFilter", "Raster Filter Classes"));
176
                }
177

    
178
                // Invoca las llamadas est?ticas de cada clase para registrarlas en los
179
                // puntos de extensi?n
180
                BrightnessContrastListManager.register();
181
                FirstDerivativeListManager.register();
182
                MedianListManager.register();
183
                ConvolutionListManager.register();
184
                ColorTableListManager.register();
185
                StatisticsListManager.register();
186
                PanSharpeningListManager.register();
187
                RGBToHSLManager.register();
188
                HSLToRGBManager.register();
189
                ColorBalanceCMYManager.register();
190
                ColorBalanceRGBManager.register();
191
                ToLumSaManager.register();
192
                EnhancementStretchListManager.register();
193
                EcualizationManager.register();
194
                //EnhancementListManager.register();
195
                //RGBToCMYKManager.register();
196
                // Registrar los nuevos filtros del directorio
197
                //registerClasses();
198

    
199
                //Limpiamos el directorio temporal
200
                RasterLibrary.cleanUpTempFiles();
201
                wakeup = true;
202
        }
203

    
204
        /**
205
         * Elimina los ficheros del directorio temporal. Realizamos esta acci?n al
206
         * levantar la librer?a.
207
         */
208
        public static void cleanUpTempFiles() {
209
                try {
210
                        File tempDirectory = new File(tempCacheDirectoryPath);
211

    
212
                        File[] files = tempDirectory.listFiles();
213
                        if (files != null) {
214
                                for (int i = 0; i < files.length; i++) {
215
                                        // s?lo por si en un futuro se necesitan crear directorios temporales
216
                                        if (files[i].isDirectory())
217
                                                deleteDirectory(files[i]);
218
                                        files[i].delete();
219
                                }
220
                        }
221
                        tempDirectory.delete();
222
                } catch (Exception e) {
223
                }
224
        }
225

    
226
        /**
227
         * Recursive directory delete.
228
         * @param f
229
         */
230
        private static void deleteDirectory(File f) {
231
                File[] files = f.listFiles();
232
                for (int i = 0; i < files.length; i++) {
233
                        if (files[i].isDirectory())
234
                                deleteDirectory(files[i]);
235
                        files[i].delete();
236
                }
237
        }
238
        
239
        //******* Servicio de nombres de capas ?nicos **************
240
        
241
        /**
242
         * La gesti?n de nombres ?nicos en la generaci?n de capas se lleva de forma
243
         * autom?tica. Cuando alguien crea una capa nueva, si esta no tiene nombre especifico,
244
         * obtiene su nombre mediante este m?todo. La siguiente vez que se llame dar? un nombre
245
         * distinto. El nombre de la capa ser? NewLayer_ seguido de un contador de actualizaci?n
246
         * autom?tica cada vez que se usa.
247
         * @return Nombre ?nico para la capa.
248
         */
249
        public static String usesOnlyLayerName() {
250
                String oldValue = getOnlyLayerName();
251
                String newValue = "NewLayer_" + (++RasterLibrary.layerCount);
252
                for (int i = 0; i < propetiesListeners.size(); i++) {
253
                        if(propetiesListeners.get(i) instanceof PropertyListener) 
254
                                ((PropertyListener)propetiesListeners.get(i)).actionValueChanged(new PropertyEvent(oldValue, "NewLayer", newValue, oldValue));
255
                }
256
                return newValue;
257
        }
258
        
259
        /**
260
         * Obtiene el nombre ?nico de la siguiente capa sin actualizar el contador. Es
261
         * solo para consulta. La siguiente vez que se llama a getOnlyLayerName o usesOnlyLayerName
262
         * devolver? el mismo nomnbre. 
263
         * @return Nombre ?nico para la capa.
264
         */
265
        public static String getOnlyLayerName() {
266
                return "NewLayer_" + RasterLibrary.layerCount;
267
        }
268
        
269
        /**
270
         * A?adir un listener a la lista de eventos
271
         * @param listener
272
         */
273
        public static void addOnlyLayerNameListener(PropertyListener listener) {
274
                if (!propetiesListeners.contains(listener))
275
                        propetiesListeners.add(listener);
276
        }
277
        
278
        /**
279
         * Elimina un listener de la lista de eventos
280
         * @param listener
281
         */
282
        public static void removeOnlyLayerNameListener(PropertyListener listener) {
283
                for (int i = 0; i < propetiesListeners.size(); i++)
284
                        if(propetiesListeners.get(i) == listener)
285
                                propetiesListeners.remove(i);
286
        }
287
        
288
        //******* End: Servicio de nombres de capas ?nicos **************
289

    
290
        /**
291
         * Esta funci?n buscar? todos los jars en las rutas de pathExtensions y
292
         * registrar? todos las clases registrables. En este momento hay posibilidad
293
         * de registro de drivers y filtros.
294
         */
295
        private static void registerClasses() throws Exception {
296
                RasterClassLoader loader = new RasterClassLoader();
297

    
298
                //Cargamos sobre jarList todos los File correspondientes a los jar contenidos en pathExtensions
299
                File[] jarList = null;
300
                for (int iPath = 0; iPath < pathExtensions.length; iPath++) {
301
                        File directory = new File(pathExtensions[iPath]);
302
                        if (directory.isDirectory() && directory.canRead()) {
303
                                jarList = directory.listFiles(new FileFilter() {
304
                                                                                                public boolean accept(File pathname) {
305
                                                                                                                return (pathname.getName().toUpperCase().endsWith(".JAR"));
306
                                                                                                }
307
                                                                                                });
308
                        }
309
                }
310

    
311
                //Creamos las URL
312
                URL[] urls = new URL[jarList.length];
313

    
314
                for (int j = 0; j < jarList.length; j++) {
315
                        try {
316
                                urls[j] = new URL("file:" + jarList[j]);
317
                        } catch (MalformedURLException e) {
318
                                Logger.getLogger(RasterLibrary.class.getName()).debug("Error formando la URL, jar incorrecto", e);
319
                        }
320
                }
321

    
322
                //Comprobamos que no haya clases repetidas
323
                ZipFile[] jarFiles = new ZipFile[jarList.length];
324
                for (int i = 0; i < jarList.length; i++) {
325
                        try {
326
                                jarFiles[i] = new ZipFile(jarList[i].getPath());
327

    
328
                                Enumeration entradas = jarFiles[i].entries();
329

    
330
                                while (entradas.hasMoreElements()) {
331
                                        ZipEntry file = (ZipEntry) entradas.nextElement();
332
                                        String fileName = file.getName();
333

    
334
                                        if (!fileName.toLowerCase().endsWith(".class"))
335
                                                continue;
336

    
337
                                        fileName = fileName.substring(0, fileName.length() - 6).replace('/', '.');
338

    
339
                                        if (clasesJar.get(fileName) != null) {
340
                                                throw new JarException("CLASES REPETIDAS: " + fileName + " " + " en " +
341
                                                                jarFiles[i].getName() + " y en " + ((ZipFile) clasesJar.get(fileName)).getName());
342
                                        }
343

    
344
                                        clasesJar.put(fileName, jarFiles[i]);
345
                                }
346
                        } catch (ZipException e) {
347
                                throw new IOException(" Jar: " + jarList[i].getPath() + ": " + jarFiles[i]);
348
                        } catch (IOException e) {
349
                                throw e;
350
                        }
351
                }
352

    
353
        }
354
}