Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / grid / filter / RasterFilterListManager.java @ 11719

History | View | Annotate | Download (13.6 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.Iterator;
25
import java.util.StringTokenizer;
26
import java.util.Map.Entry;
27
import java.util.regex.Matcher;
28
import java.util.regex.Pattern;
29

    
30
import org.gvsig.raster.util.RasterUtilities;
31
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
32
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
33
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
34

    
35
/*
36
 * TODO: FUNCIONALIDAD: Anulada las estad?sticas. Hay que incluirlas de nuevo.
37
 */
38
/**
39
 * Esta clase es de la parte cliente y es la encargada de la gesti?n de la pila
40
 * de filtros. Cada tipo de filtro o conjunto de tipos de filtro deben tener un
41
 * gestor que implementa IRasterFilterManager. Esos gestores deben registrarse
42
 * en esta clase con la funci?n addClassListManager. Este registro puede hacerse
43
 * desde esta misma clase o desde una extensi?n. Un cliente que desee aplicar un
44
 * filtro deber? introducirlo en la lista usando para ello las funciones que su
45
 * manager de filtros le ofrece. Adem?s se encarga de otras funciones como la
46
 * conversi?n de un filtro a cadena de Strings y la recuperaci?n desde cadena de
47
 * Strings y el control de tipos de la salida de un raster de la lista con la
48
 * entrada del siguiente filtro.
49
 * 
50
 * @author Nacho Brodin (nachobrodin@gmail.com)
51
 */
52
public class RasterFilterListManager {
53
        protected RasterFilterList        rasterFilterList = null;
54
        private boolean                                debug = false;
55
        public int[]                                priority = null;
56
        protected ArrayList                        filterList = null;
57
        private ArrayList                        managers = new ArrayList();
58

    
59
  /**
60
         * Constructor
61
         * @param filterStack
62
         */
63
        public RasterFilterListManager(RasterFilterList filterStack) {
64
                this.rasterFilterList = filterStack;
65
                
66
                // Cargamos el manager con los gestores de drivers registrados
67
                
68
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
69
                ExtensionPoint extensionPoint = (ExtensionPoint) extensionPoints.get("RasterFilter");
70
                Iterator iterator = extensionPoint.entrySet().iterator();
71
                while (iterator.hasNext()) {
72
                        Entry entry = (Entry) iterator.next();
73
                        if (entry != null) {
74
                                Class RasterClass = (Class) entry.getValue();
75
                                Object obj = RasterFilterListManager.loadClass(RasterClass, this);
76
                                if (obj != null)
77
                                        managers.add(obj);
78
                        }
79
                }
80
        }
81

    
82
   
83
  /**
84
         * Sustituye el tipo de filtro de strPackage por el de newClass
85
         * @param strPackage cadena con el paquete y filtro a sustituir, por ej:
86
         *          org.cresques.filter.enhanced.ContrastImageFilter
87
         * @param newClass clase con el tipo a sustituir. Por ej: ContrastShortFilter
88
         * @return devuelve strPackage con la sustituci?n hecha. Por ej:
89
         *         org.cresques.filter.enhanced.ContrastShortFilter
90
         */
91
        private String getStrPackage(String strPackage, String newClass) {
92
                if (newClass.endsWith("ImageFilter"))
93
                        strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("ImageFilter"));
94
                else if (newClass.endsWith("ShortFilter"))
95
                        strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("ShortFilter"));
96
                else if (newClass.endsWith("DoubleFilter"))
97
                        strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("DoubleFilter"));
98
                else if (newClass.endsWith("FloatFilter"))
99
                        strPackage = strPackage + newClass.substring(0, newClass.lastIndexOf("FloatFilter"));
100
                strPackage = strPackage + "." + newClass;
101
                return strPackage;
102
        }
103

    
104
        /**
105
         * Controla que los tipos de los filtros de la pila sean correctos, es decir,
106
         * que el tipo de salida de un filtro de salida coincida con el tipo de la
107
         * entrada del siguiente. En caso de no ser as? crea el filtro de tipo
108
         * adecuado y lo sustituye en el no coincidente. Esto es necesario ya que en
109
         * la eliminaci?n de filtros puede quedarse en inconsistencia de tipos.
110
         */
111
        public void controlTypes() {
112
                for (int i = rasterFilterList.lenght(); i >= 0; i--) {
113
                        String classFilter = null, packageFilter = null, oldClass = null;
114
                        try {
115
                                RasterFilter rf = rasterFilterList.get(i - 1);
116
                                if (rf == null)
117
                                        return;
118
                                classFilter = rf.getClass().toString();
119
                                packageFilter = classFilter.substring(classFilter.indexOf(" ") + 1, classFilter.lastIndexOf("."));
120
                                oldClass = classFilter.substring(classFilter.lastIndexOf(".") + 1, classFilter.length());
121
                        } catch (ArrayIndexOutOfBoundsException ex) {
122
                                return;
123
                        } catch (NullPointerException ex) {
124
                                return;
125
                        }
126

    
127
                        if ((i - 1) >= 0) {
128
                                // Para el primer filtro comprobamos con el tipo de dato de entrada a la
129
                                // pila
130
                                if (i == rasterFilterList.lenght()) {
131
                                        if (rasterFilterList.getInitDataType() != rasterFilterList.get(i - 1).getInRasterDataType()) {
132
                                                Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i - 1).getInRasterDataType()));
133
                                                Matcher m = p.matcher(oldClass);
134
                                                String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.getInitDataType()));
135
                                                String strPackage = packageFilter + "." + newClass;
136

    
137
                                                try {
138
                                                        Class filterClass = Class.forName(strPackage);
139
                                                        Constructor con = filterClass.getConstructor(null);
140
                                                        RasterFilter newFilter = (RasterFilter) con.newInstance(null);
141
                                                        newFilter.params = rasterFilterList.get(i - 1).params;
142
                                                        rasterFilterList.replace(newFilter, i - 1);
143
                                                } catch (Exception e) {
144
                                                        e.printStackTrace();
145
                                                }
146
                                        }
147

    
148
                                        // Desde el filtro 2 en adelante se compara la salida de uno con la
149
                                        // entrada del siguiente
150
                                } else if (rasterFilterList.get(i).getOutRasterDataType() != rasterFilterList.get(i - 1).getInRasterDataType()) {
151
                                        Pattern p = Pattern.compile(RasterUtilities.typesToString(rasterFilterList.get(i - 1).getInRasterDataType()));
152
                                        Matcher m = p.matcher(oldClass);
153
                                        String newClass = m.replaceAll(RasterUtilities.typesToString(rasterFilterList.get(i).getOutRasterDataType()));
154
                                        String strPackage = packageFilter + "." + newClass;
155

    
156
                                        try {
157
                                                Class filterClass = Class.forName(strPackage.trim());
158
                                                Constructor con = filterClass.getConstructor(null);
159
                                                RasterFilter newFilter = (RasterFilter) con.newInstance(null);
160
//                                                newFilter.setFilterName(filterStack.get(i - 1).getFilterName());
161
                                                newFilter.params = rasterFilterList.get(i - 1).params;
162
                                                rasterFilterList.replace(newFilter, i - 1);
163
                                        } catch (Exception e) {
164
                                                e.printStackTrace();
165
                                        }
166
                                }
167
                        }
168
                }
169

    
170
                if (debug)
171
                        rasterFilterList.show();
172
        }
173

    
174
        /**
175
         * M?todo que devuelve true si el tipo de filtro pasado por par?metro est? en
176
         * la pila y false si no lo est?.
177
         * 
178
         * @param filter Tipo de filtro a comprobar
179
         * @return true si est? en la pila y false si no lo est?
180
         */
181
        public boolean isActive(String name) {
182
                return rasterFilterList.isActive(name);
183
        }
184

    
185
        /**
186
         * Elimina los filtros de la pila de un determinado tipo
187
         * 
188
         * @param type Tipo de filtro a eliminar
189
         */
190
        public void removeFilter(String name) {
191
                rasterFilterList.remove(name);
192
                this.controlTypes();
193
        }
194

    
195
  /**
196
   * Elimina los filtros de la pila de una determinada prioridad
197
   * 
198
   * @param priority Prioridad de los filtros a elimina
199
   */
200
        public void removeFilter(int priority) {
201
                rasterFilterList.remove(priority);
202
                this.controlTypes();
203
        }
204

    
205
        public ArrayList getStringsFromFilterList() {
206
                filterList = new ArrayList();
207
                for (int i = 0; i < rasterFilterList.lenght(); i++) {
208
                        RasterFilter rf = rasterFilterList.get(i);
209

    
210
                        // Se recorren todos los managers registrados comprobando si corresponde a
211
                        // la clase del filtro
212
                        for (int j = 0; j < managers.size(); j++)
213
                                filterList = ((IRasterFilterListManager) managers.get(j)).getStringsFromFilterList(filterList, rf);
214
                }
215

    
216
                return filterList;
217
        }
218

    
219
  /*
220
   * (non-Javadoc)
221
   * @see org.gvsig.raster.grid.filter.IRasterFilterListManager#createStackFromStrings(java.util.ArrayList, java.lang.String, int)
222
   */
223
  public int createStackFromStrings(ArrayList filters, String fil, int filteri) {
224
                return filteri;
225
  }
226

    
227
  /**
228
   * Crea una pila de filtros a partir de un Array de Strings. Cada elemento del array debe
229
   * tener la forma elemento=valor.
230
   * @param filters
231
   */
232
  public void createFilterListFromStrings(ArrayList f) {
233
          createFilterListFromStrings(f, new Integer(0));
234
  }
235
 
236
  /**
237
   * Crea una pila de filtros a partir de un Array de Strings. Cada elemento del array debe
238
   * tener la forma elemento=valor.
239
   * @param pos Posici?n desde la cual se empieza a analizar.
240
   * @param filters
241
   */
242
  private void createFilterListFromStrings(ArrayList f, Integer pos) {
243
                ArrayList filters = (ArrayList) f.clone();
244
                rasterFilterList.clear();
245

    
246
                int filteri = pos.intValue();
247

    
248
                // Busca un filtro activo y despu?s todas las propiedades que necesita ese
249
                // filtro para ser creado. Una vez las tiene a?ade en la pila el tipo de
250
                // filtro.
251
                while ((filters.size() > 0) && (filteri < filters.size())) {
252
                        String fil = (String) filters.get(filteri);
253

    
254
                        for (int j = 0; j < managers.size(); j++)
255
                                filteri = ((IRasterFilterListManager) managers.get(j)).createFilterListFromStrings(filters, fil, filteri);
256

    
257
                        filteri++;
258
                }
259
        }
260

    
261
  /**
262
         * Obtiene el elemento de una cadena de la forma elemento=valor
263
         * @param cadena
264
         * @return
265
         */
266
  public static String getElem(String cadena) {
267
                if (cadena != null) {
268
                        return cadena.substring(0, cadena.indexOf("="));
269
                } else {
270
                        return null;
271
                }
272
        }
273

    
274
  /**
275
         * Obtiene el valor de una cadena de la forma elemento=valor
276
         * @param cadena
277
         * @return
278
         */
279
  public static String getValue(String cadena) {
280
                if (cadena != null) {
281
                        return cadena.substring(cadena.indexOf("=") + 1, cadena.length());
282
                } else {
283
                        return null;
284
                }
285
        }
286

    
287
  /**
288
         * Convierte un rango contenido en una array doble en una cadena de strings
289
         * para poder salvar a xml
290
         * @param rang
291
         * @return
292
         */
293
  private String rangeToString(int[][] rang) {
294
                StringBuffer rangoStr = new StringBuffer();
295

    
296
                if (rang != null) {
297
                        for (int i = 0; i < rang.length; i++) {
298
                                rangoStr.append(String.valueOf(rang[i][0]) + ":");
299
                                rangoStr.append(String.valueOf(rang[i][1]) + ":");
300
                        }
301

    
302
                        String r = rangoStr.toString();
303

    
304
                        if (r.endsWith(":")) {
305
                                r = r.substring(0, r.length() - 1);
306
                        }
307

    
308
                        return r;
309
                } else {
310
                        return null;
311
                }
312
        }
313

    
314
  /**
315
         * Convierte una cadena en una lista de rangos numericos para poder asignar
316
         * transparencias a la imagen
317
         * @param rang
318
         * @return
319
         */
320
  private int[][] stringToRange(String rang) {
321
                if ((rang != null) && !rang.equals("null")) {
322
                        ArrayList lista = new ArrayList();
323
                        StringTokenizer tokenizer = new StringTokenizer(rang, ":");
324

    
325
                        while (tokenizer.hasMoreTokens())
326
                                lista.add(tokenizer.nextToken());
327

    
328
                        int[][] intervalos = new int[(int) (lista.size() / 2)][2];
329

    
330
                        for (int i = 0; i < lista.size(); i = i + 2) {
331
                                intervalos[i / 2][0] = Integer.valueOf((String) lista.get(i)).intValue();
332
                                intervalos[i / 2][1] = Integer.valueOf((String) lista.get(i + 1)).intValue();
333
                        }
334

    
335
                        return intervalos;
336
                } else {
337
                        return null;
338
                }
339
        }
340

    
341
  /**
342
         * Obtiene la lista de filtros
343
         * @return RasterFilterList
344
         */
345
        public RasterFilterList getFilterList() {
346
                return rasterFilterList;
347
        }
348
        
349
        /**
350
         * Carga una clase pasada por par?metro. Como argumento del constructor de la
351
         * clase se pasar? un RasterFilterStackManager. Esto es usado para instanciar
352
         * los gestores de filtros registrados
353
         * @param clase Clase a instanciar
354
         * @param stackManager Par?metro del constructor de la clase a instanciar
355
         * @return Objeto que corresponde a la instancia de la clase pasada.
356
         */
357
        public static Object loadClass(Class clase, RasterFilterListManager stackManager) {
358
                Object obj = null;
359
                Class[] args = { RasterFilterListManager.class };
360
                try {
361
                        Constructor hazNuevo = clase.getConstructor(args);
362
                        Object[] args2 = { stackManager };
363
                        obj = hazNuevo.newInstance(args2);
364
                } catch (SecurityException e) {
365
                        e.printStackTrace();
366
                } catch (NoSuchMethodException e) {
367
                        e.printStackTrace();
368
                } catch (IllegalArgumentException e) {
369
                        e.printStackTrace();
370
                } catch (InstantiationException e) {
371
                        e.printStackTrace();
372
                } catch (IllegalAccessException e) {
373
                        e.printStackTrace();
374
                } catch (InvocationTargetException e) {
375
                        e.printStackTrace();
376
                }
377
                return obj;
378
        }
379
        
380
        /**
381
         * Obtiene el manager registrado a partir de la clase
382
         * @return
383
         */
384
        public IRasterFilterListManager getManagerByClass(Class c) {
385
                for (int j = 0; j < managers.size(); j++) {
386
                        if (managers.get(j).getClass().equals(c))
387
                                return (IRasterFilterListManager) managers.get(j);
388
                }
389
                return null;
390
        }
391

    
392
        /*
393
         * (non-Javadoc)
394
         * @see org.gvsig.raster.grid.filter.IRasterFilterListManager#getRasterFilterList()
395
         */
396
        public ArrayList getRasterFilterList() {
397
                ArrayList filters = new ArrayList();
398
                for (int i = 0; i < managers.size(); i++) {
399
                        ArrayList auxFilters = ((IRasterFilterListManager) managers.get(i)).getRasterFilterList();
400
                        for (int j = 0; j < auxFilters.size(); j++) {
401
                                filters.add(auxFilters.get(j));
402
                        }
403
                }
404
                return filters;
405
        }
406
}