Statistics
| Revision:

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

History | View | Annotate | Download (15.5 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.util.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
                        RasterFilter rf = rasterFilterList.get(i - 1);
133
                        if(rf == null)
134
                                return;
135
                        classFilter = rf.getClass().toString();
136
                        packageFilter = classFilter.substring(classFilter.indexOf(" ") + 1, classFilter.lastIndexOf("."));
137
                        oldClass = classFilter.substring(classFilter.lastIndexOf(".") +1, classFilter.length());
138
                }catch(ArrayIndexOutOfBoundsException ex){
139
                        return;
140
                }catch(NullPointerException ex){
141
                        return;
142
                }
143
                
144
            if ((i - 1) >= 0) {
145
                //Para el primer filtro comprobamos con el tipo de dato de entrada a la pila
146
                if (i == rasterFilterList.lenght()) {
147
                    if (rasterFilterList.getInitDataType() != rasterFilterList.get(i - 1).getInRasterDataType()) {
148
                        Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i - 1).getInRasterDataType()));
149
                        Matcher m = p.matcher(oldClass);
150
                        String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.getInitDataType()));
151
                        String strPackage = packageFilter + "." + newClass;
152
                    
153
                        try {
154
                            Class filterClass = Class.forName(strPackage);
155
                            Constructor con = filterClass.getConstructor(null);
156
                            RasterFilter newFilter = (RasterFilter) con.newInstance(null);
157
                            newFilter.params = rasterFilterList.get(i - 1).params;
158
                            rasterFilterList.replace(newFilter, i - 1);
159
                        } catch (Exception e) {
160
                            e.printStackTrace();
161
                        }
162
                    }
163

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

    
185
        if (debug) 
186
                rasterFilterList.show();
187
    }
188

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

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

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

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

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

    
239
        return filterList;
240
    }
241

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

    
273
        int filteri = pos.intValue();
274

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

    
283
            filteri++;
284
        }
285
    }
286

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

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

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

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

    
328
            String r = rangoStr.toString();
329

    
330
            if (r.endsWith(":")) {
331
                r = r.substring(0, r.length() - 1);
332
            }
333

    
334
            return r;
335
        } else {
336
            return null;
337
        }
338
    }
339

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

    
351
            while (tokenizer.hasMoreTokens())
352
                lista.add(tokenizer.nextToken());
353

    
354
            int[][] intervalos = new int[(int) (lista.size() / 2)][2];
355

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

    
361
            return intervalos;
362
        } else {
363
            return null;
364
        }
365
    }
366

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

    
418
}
419