Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / grid / filter / RasterFilterListManager.java @ 10740

History | View | Annotate | Download (15.4 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.grid.filter;
20

    
21
import java.lang.reflect.Constructor;
22
import java.lang.reflect.InvocationTargetException;
23
import java.util.ArrayList;
24
import java.util.StringTokenizer;
25
import java.util.regex.Matcher;
26
import java.util.regex.Pattern;
27

    
28
import org.gvsig.raster.grid.filter.enhancement.BrightnessContrastListManager;
29
import org.gvsig.raster.grid.filter.enhancement.EnhancementListManager;
30
import org.gvsig.raster.shared.RasterUtilities;
31

    
32
/*
33
 * TODO: FUNCIONALIDAD: Anulada las estad?sticas. Hay que incluirlas de nuevo.
34
 */
35
/**
36
 * Esta clase es de la parte cliente y es la encargada de la gesti?n
37
 * de la pila de filtros. Cada tipo de filtro o conjunto de tipos de filtro deben tener un gestor
38
 * que implementa IRasterFilterManager. Esos gestores deben registrarse en esta clase con
39
 * la funci?n addClassListManager. Este registro puede hacerse desde esta misma clase o desde 
40
 * una extensi?n. Un cliente que desee aplicar un filtro deber? introducirlo en la lista usando 
41
 * para ello las funciones que su manager de filtros le ofrece. Adem?s se encarga de otras 
42
 * funciones como la conversi?n de un filtro a cadena de Strings y la recuperaci?n desde cadena
43
 * de Strings y el control de tipos de la salida de un raster de la lista con la entrada del 
44
 * siguiente filtro.
45
 * 
46
 * @author Nacho Brodin (nachobrodin@gmail.com)
47
 *
48
 */
49
public class RasterFilterListManager implements IRasterFilterListManager {
50
    protected RasterFilterList                 rasterFilterList = null;
51
    private boolean                                 debug = false;
52
    public int[]                                         priority = null;
53
    protected ArrayList                         filterList = null;
54
    private static ArrayList                stackManagerClass = new ArrayList();
55
    private ArrayList                                 managers = new ArrayList();
56
        
57
    static{
58
            RasterFilterListManager.addClassListManager(BrightnessContrastListManager.class);
59
            RasterFilterListManager.addClassListManager(EnhancementListManager.class);
60
    }
61
    
62
        /**
63
         * Registra las clases que tendr?n gesti?n de alg?n filtro. Esta funci?n suele llamarse en 
64
         * la carga de una extensi?n.
65
         * @param clase Clase a registrar
66
         */
67
        public static void addClassListManager(Class clase) {
68
                boolean esta = false;
69
                for(int i=0;i<stackManagerClass.size();i++)
70
                        if(((Class)stackManagerClass.get(i)).equals(clase))
71
                                esta = true;
72
                if(!esta)
73
                        RasterFilterListManager.stackManagerClass.add(clase);
74
        }
75
        
76
    /**
77
     * Constructor
78
     * @param filterStack
79
     */
80
    public RasterFilterListManager(RasterFilterList filterStack) {
81
        this.rasterFilterList = filterStack;
82
        init();
83
                    
84
        //Cargamos el manager con los gestores de drivers registrados
85
        for(int i = 0;i<RasterFilterListManager.stackManagerClass.size();i++){
86
                Object obj = RasterFilterListManager.loadClass((Class)stackManagerClass.get(i), this);
87
                if(obj != null)
88
                        managers.add(obj);
89
        }
90
        
91
    }
92

    
93
    /**
94
     * Inicializaci?n. Asigna el orden de los filtros
95
     */
96
    protected void init() {
97

    
98
    }
99
     
100
    /**
101
     * Sustituye el tipo de filtro de strPackage por el de newClass
102
     * @param strPackage cadena con el paquete y filtro a sustituir, 
103
     * por ej: org.cresques.filter.enhanced.ContrastImageFilter
104
     * @param newClass clase con el tipo a sustituir. Por ej: ContrastShortFilter
105
     * @return devuelve strPackage con la sustituci?n hecha.
106
     * Por ej: org.cresques.filter.enhanced.ContrastShortFilter
107
     */
108
    private String getStrPackage(String strPackage, String newClass){
109
            if(newClass.endsWith("ImageFilter"))
110
                strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("ImageFilter"));
111
        else if(newClass.endsWith("ShortFilter"))
112
                strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("ShortFilter"));
113
        else if(newClass.endsWith("DoubleFilter"))
114
                strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("DoubleFilter"));
115
        else if(newClass.endsWith("FloatFilter"))
116
                strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("FloatFilter"));
117
        strPackage = strPackage + "." + newClass;
118
            return strPackage;
119
    }
120
    
121
    /**
122
     * Controla que los tipos de los filtros de la pila sean correctos, es decir, que
123
     * el tipo de salida de un filtro de salida coincida con el tipo de la entrada del
124
     * siguiente. En caso de no ser as? crea el filtro de tipo adecuado y lo sustituye
125
     * en el no coincidente. Esto es necesario ya que en la eliminaci?n de filtros puede
126
     * quedarse en inconsistencia de tipos.
127
     */
128
    public void controlTypes() {
129
        for (int i = rasterFilterList.lenght(); i >= 0; i--) {
130
                String classFilter = null, packageFilter = null, oldClass = null;
131
                try{
132
                        classFilter = rasterFilterList.get(i - 1).getClass().toString();
133
                        packageFilter = classFilter.substring(classFilter.indexOf(" ") + 1, classFilter.lastIndexOf("."));
134
                        oldClass = classFilter.substring(classFilter.lastIndexOf(".") +1, classFilter.length());
135
                }catch(ArrayIndexOutOfBoundsException ex){
136
                        return;
137
                }catch(NullPointerException ex){
138
                        return;
139
                }
140
                
141
            if ((i - 1) >= 0) {
142
                //Para el primer filtro comprobamos con el tipo de dato de entrada a la pila
143
                if (i == rasterFilterList.lenght()) {
144
                    if (rasterFilterList.getInitDataType() != rasterFilterList.get(i - 1).getInRasterDataType()) {
145
                        Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i - 1).getInRasterDataType()));
146
                        Matcher m = p.matcher(oldClass);
147
                        String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.getInitDataType()));
148
                        String strPackage = packageFilter + "." + newClass;
149
                    
150
                        try {
151
                            Class filterClass = Class.forName(strPackage);
152
                            Constructor con = filterClass.getConstructor(null);
153
                            RasterFilter newFilter = (RasterFilter) con.newInstance(null);
154
                            newFilter.params = rasterFilterList.get(i - 1).params;
155
                            rasterFilterList.replace(newFilter, i - 1);
156
                        } catch (Exception e) {
157
                            e.printStackTrace();
158
                        }
159
                    }
160

    
161
                    //Desde el filtro 2 en adelante se compara la salida de uno con la entrada del siguiente
162
                } else if (rasterFilterList.get(i).getOutRasterDataType() != rasterFilterList.get(i - 1).getInRasterDataType()) {
163
                    Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i - 1).getInRasterDataType()));
164
                    Matcher m = p.matcher(oldClass);
165
                    String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.get(i).getOutRasterDataType()));
166
                    String strPackage = packageFilter + "." + newClass;
167
                    
168
                    try {
169
                        Class filterClass = Class.forName(strPackage.trim());
170
                        Constructor con = filterClass.getConstructor(null);
171
                        RasterFilter newFilter = (RasterFilter) con.newInstance(null);
172
                        //newFilter.setFilterName(filterStack.get(i - 1).getFilterName());
173
                        newFilter.params = rasterFilterList.get(i - 1).params;
174
                        rasterFilterList.replace(newFilter, i - 1);
175
                    } catch (Exception e) {
176
                        e.printStackTrace();
177
                    }
178
                }
179
            }
180
        }
181

    
182
        if (debug) 
183
                rasterFilterList.show();
184
    }
185

    
186
    /**
187
     * M?todo que devuelve true si el tipo de filtro pasado por par?metro est? en la
188
     * pila y false si no lo est?.
189
     * @param filter        Tipo de filtro a comprobar
190
     * @return true si est? en la pila y false si no lo est?
191
     */
192
    public boolean isActive(String name) {
193
        return rasterFilterList.isActive(name);
194
    }
195

    
196
    /**
197
     * Elimina los filtros de la pila de un determinado tipo
198
     * @param type        Tipo de filtro a eliminar
199
     */
200
    public void removeFilter(String name) {
201
            rasterFilterList.remove(name);
202
        this.controlTypes();
203
    }
204
    
205
    /**
206
     * Elimina los filtros de la pila de una determinada prioridad
207
     * @param priority Prioridad de los filtros a elimina
208
     */
209
    public void removeFilter(int priority) {
210
            rasterFilterList.remove(priority);
211
        this.controlTypes();
212
    }
213

    
214
    /**
215
     * Obtiene el objeto de estadisticas asignado a la pila.
216
     * @return
217
     */
218
    /*public Statistic getStackStats() {
219
        return filterStack.getStats();
220
    }*/
221

    
222
    /* (non-Javadoc)
223
     * @see org.cresques.io.raster.StackManager#getStringsFromStack()
224
     */
225
    public ArrayList getStringsFromStack() {
226
        filterList = new ArrayList();
227
        for (int i = 0; i < rasterFilterList.lenght(); i++) {
228
            RasterFilter rf = rasterFilterList.get(i);
229

    
230
            //Se recorren todos los managers registrados comprobando si corresponde a la clase del filtro
231
            for (int j = 0; j < managers.size(); j++){
232
                    filterList = ((IRasterFilterListManager) managers.get(j)).getStringsFromStack(filterList, rf);
233
            }
234
        }
235

    
236
        return filterList;
237
    }
238

    
239
    /* (non-Javadoc)
240
     * @see org.cresques.io.raster.StackManager#getStringsFromStack()
241
     */
242
    public ArrayList getStringsFromStack(ArrayList filterList, RasterFilter rf){
243
            return null;
244
    }
245
    
246
    /*
247
     *  (non-Javadoc)
248
     * @see org.gvsig.fmap.grid.filter.IStackManager#createStackFromStrings(java.util.ArrayList, java.lang.String, int)
249
     */
250
    public int createStackFromStrings(ArrayList filters, String fil, int filteri) {
251
                return filteri;
252
        }
253
    
254
    /*
255
     *  (non-Javadoc)
256
     * @see org.gvsig.fmap.grid.filter.IStackManager#createStackFromStrings(java.util.ArrayList)
257
     */
258
    public void createStackFromStrings(ArrayList f) {
259
        createStackFromStrings(f, new Integer(0));
260
    }
261
   
262
    /*
263
     *  (non-Javadoc)
264
     * @see org.gvsig.fmap.grid.filter.IStackManager#createStackFromStrings(java.util.ArrayList, java.lang.Integer)
265
     */
266
    public void createStackFromStrings(ArrayList f, Integer pos) {
267
        ArrayList filters = (ArrayList) f.clone();
268
        rasterFilterList.clear();
269

    
270
        int filteri = pos.intValue();
271

    
272
        //Busca un filtro activo y despu?s todas las propiedades que necesita ese filtro para
273
        //ser creado. Una vez las tiene a?ade en la pila el tipo de filtro.
274
        while ((filters.size() > 0) && (filteri < filters.size())) {
275
            String fil = (String) filters.get(filteri);
276
            
277
            for (int j = 0; j < managers.size(); j++)
278
                    filteri = ((IRasterFilterListManager) managers.get(j)).createStackFromStrings(filters, fil, filteri);
279

    
280
            filteri++;
281
        }
282
    }
283

    
284
    /**
285
     * Obtiene el elemento de una cadena de la forma elemento=valor
286
     * @param cadena
287
     * @return
288
     */
289
    public static String getElem(String cadena) {
290
        if (cadena != null) {
291
            return cadena.substring(0, cadena.indexOf("="));
292
        } else {
293
            return null;
294
        }
295
    }
296

    
297
    /**
298
     * Obtiene el valor de una cadena de la forma elemento=valor
299
     * @param cadena
300
     * @return
301
     */
302
    public static String getValue(String cadena) {
303
        if (cadena != null) {
304
            return cadena.substring(cadena.indexOf("=") + 1, cadena.length());
305
        } else {
306
            return null;
307
        }
308
    }
309

    
310
    /**
311
     * Convierte un rango contenido en una array doble en una cadena
312
     * de strings para poder salvar a xml
313
     * @param rang
314
     * @return
315
     */
316
    private String rangeToString(int[][] rang) {
317
        StringBuffer rangoStr = new StringBuffer();
318

    
319
        if (rang != null) {
320
            for (int i = 0; i < rang.length; i++) {
321
                rangoStr.append(String.valueOf(rang[i][0]) + ":");
322
                rangoStr.append(String.valueOf(rang[i][1]) + ":");
323
            }
324

    
325
            String r = rangoStr.toString();
326

    
327
            if (r.endsWith(":")) {
328
                r = r.substring(0, r.length() - 1);
329
            }
330

    
331
            return r;
332
        } else {
333
            return null;
334
        }
335
    }
336

    
337
    /**
338
     * Convierte una cadena en una lista de rangos numericos para poder
339
     * asignar transparencias a la imagen
340
     * @param rang
341
     * @return
342
     */
343
    private int[][] stringToRange(String rang) {
344
        if ((rang != null) && !rang.equals("null")) {
345
            ArrayList lista = new ArrayList();
346
            StringTokenizer tokenizer = new StringTokenizer(rang, ":");
347

    
348
            while (tokenizer.hasMoreTokens())
349
                lista.add(tokenizer.nextToken());
350

    
351
            int[][] intervalos = new int[(int) (lista.size() / 2)][2];
352

    
353
            for (int i = 0; i < lista.size(); i = i + 2) {
354
                intervalos[i / 2][0] = Integer.valueOf((String) lista.get(i)).intValue();
355
                intervalos[i / 2][1] = Integer.valueOf((String) lista.get(i + 1)).intValue();
356
            }
357

    
358
            return intervalos;
359
        } else {
360
            return null;
361
        }
362
    }
363

    
364
    /**
365
     * Obtiene la lista de filtros
366
     * @return RasterFilterList
367
     */
368
        public RasterFilterList getFilterList() {
369
                return rasterFilterList;
370
        }
371
        
372
        /**
373
         * Carga una clase pasada por par?metro. Como argumento del constructor de la clase se 
374
         * pasar? un RasterFilterStackManager. Esto es usado para instanciar los gestores de filtros
375
         * registrados
376
         * @param clase Clase a instanciar
377
         * @param stackManager Par?metro del constructor de la clase a instanciar
378
         * @return Objeto que corresponde a la instancia de la clase pasada.
379
         */
380
        public static Object loadClass(Class clase, RasterFilterListManager stackManager) {
381
                Object obj = null;
382
                Class [] args = {RasterFilterListManager.class};
383
                try {
384
                        Constructor hazNuevo = clase.getConstructor(args);
385
                        Object [] args2 = {stackManager};
386
                        obj =  hazNuevo.newInstance(args2);
387
                } catch (SecurityException e) {
388
                        e.printStackTrace();
389
                } catch (NoSuchMethodException e) {
390
                        e.printStackTrace();
391
                } catch (IllegalArgumentException e) {
392
                        e.printStackTrace();
393
                } catch (InstantiationException e) {
394
                        e.printStackTrace();
395
                } catch (IllegalAccessException e) {
396
                        e.printStackTrace();
397
                } catch (InvocationTargetException e) {
398
                        e.printStackTrace();
399
                }
400
                return obj;
401
        }
402
        
403
        /**
404
         * Obtiene el manager registrado a partir de la clase
405
         * @return
406
         */
407
        public IRasterFilterListManager getManagerByClass(Class c){
408
                for (int j = 0; j < managers.size(); j++){
409
                if(managers.get(j).getClass().equals(c))
410
                        return (IRasterFilterListManager)managers.get(j);
411
        }
412
                return null;
413
        }
414

    
415
}
416