Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libRaster / src / org / gvsig / raster / grid / filter / RasterFilterList.java @ 30008

History | View | Annotate | Download (14 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.util.ArrayList;
22
import java.util.Stack;
23
import java.util.TreeMap;
24

    
25
import org.gvsig.raster.dataset.IBuffer;
26
import org.gvsig.raster.datastruct.Transparency;
27
/**
28
 * Esta clase representa la lista de filtros que debe ser manejada desde el
29
 * RasterFilterListManager.
30
 *
31
 * @author Nacho Brodin (nachobrodin@gmail.com)
32
 */
33
public class RasterFilterList {
34
        private IBuffer          rasterBuf            = null;
35
        private IBuffer          alphaBand            = null;
36
        private int              typeFilter           = -1;
37
        private TreeMap          environment          = new TreeMap();
38

    
39
        // Pila de objetos Filter (Contiene un RasterFilter)
40
        private ArrayList        list                 = new ArrayList();
41
        private Stack            status               = new Stack();
42
        /**
43
         * Array de listeners que ser?n informados cuando cambia la lista de filtros
44
         */
45
        private ArrayList        filterListListener   = new ArrayList();
46

    
47
        /**
48
         * Asigna un listener a la lista que ser? informado cuando cambie un
49
         * filtro o posici?n en la lista.
50
         * @param listener FilterListListener
51
         */
52
        public void addFilterListListener(FilterListChangeListener listener) {
53
                filterListListener.add(listener);
54
        }
55

    
56
        /**
57
         * M?todo llamado cuando hay un cambio en una propiedad de visualizaci?n
58
         */
59
        private void callFilterListChanged(Object obj) {
60
                for (int i = 0; i < filterListListener.size(); i++) {
61
                        FilterListChangeEvent ev = new FilterListChangeEvent(obj);
62
                        ((FilterListChangeListener)filterListListener.get(i)).filterListChanged(ev);
63
                }
64
        }
65

    
66
        /**
67
         * A?ade un par?metro a la lista de filtros. Estos par?metros luego pueden ser
68
         * utilizados por los managers que se registren
69
         * @param key Nombre del par?metro que coincide con el nombre de la clase.
70
         * @param value Objeto
71
         */
72
        public void addEnvParam(String key, Object value) {
73
                environment.put(key, value);
74
        }
75

    
76
        /**
77
         * Obtiene un par?metro de la lista de filtros.
78
         * @param key Identificador del par?metro. Coincide con el nombre de la clase del par?metro.
79
         */
80
        public Object getEnvParam(String key) {
81
                return environment.get(key);
82
        }
83

    
84
        /**
85
         * Controla que los tipos de entrada y salida de los filtros sean los
86
         * correctos
87
         * @throws FilterTypeException
88
         */
89
        public void controlTypes() throws FilterTypeException {
90
                RasterFilterListManager stackManager = new RasterFilterListManager(this);
91
                stackManager.controlTypes();
92
        }
93

    
94
        /**
95
         * A?ade un filtro al final de la lista
96
         * @param filter        filtro a?adido
97
         * @throws FilterTypeException
98
         */
99
        public void add(RasterFilter filter) throws FilterTypeException {
100
                if (isActive(filter.getName()))
101
                        replace(filter, filter.getName());
102
                else {
103
                        list.add(filter);
104
                        controlTypes();
105
                }
106
                filter.setEnv(environment);
107
                callFilterListChanged(this);
108
        }
109

    
110
        /**
111
         * Sustituye un filtro de una posici?n de la pila por otro
112
         * @param filter
113
         * @param i
114
         * @throws FilterTypeException
115
         */
116
        public void replace(RasterFilter filter, String name) throws FilterTypeException {
117
                boolean changed = false;
118
                filter.setEnv(environment);
119
                for (int i = list.size() - 1; i >= 0; i--)
120
                        if (((RasterFilter) list.get(i)).getName().equals(name)) {
121
                                list.remove(i);
122
                                list.add(i, filter);
123
                                changed = true;
124
                        }
125

    
126
                if (changed)
127
                        controlTypes();
128
                callFilterListChanged(this);
129
        }
130

    
131
        /**
132
         * A?ade un filtro en la lista en la posici?n indicada.
133
         * @param filter        filtro a?adido
134
         * @param pos        posici?n
135
         * @throws FilterTypeException
136
         */
137
        public void add(RasterFilter filter, int pos) throws FilterTypeException {
138
                try {
139
                        list.add(pos, filter);
140
                        controlTypes();
141
                } catch (IndexOutOfBoundsException e) {
142
                        add(filter);
143
                }
144
                filter.setEnv(environment);
145
                callFilterListChanged(this);
146
        }
147

    
148
        /**
149
         * Elimina un filtro a partir de su nombre
150
         * @param name Nombre del filtro a eliminar
151
         * @throws FilterTypeException
152
         */
153
        public void remove(String name) throws FilterTypeException {
154
                boolean changed = false;
155
                for (int i = list.size() - 1; i >= 0; i--)
156
                        if (((RasterFilter) list.get(i)).getName().equals(name)) {
157
                                list.remove(i);
158
                                changed = true;
159
                        }
160
                if (changed)
161
                        controlTypes();
162
                callFilterListChanged(this);
163
        }
164

    
165
        /**
166
         * Elimina un filtro por clase.
167
         *
168
         * @param baseFilterClass
169
         * @throws FilterTypeException
170
         */
171
        public void remove(Class baseFilterClass) throws FilterTypeException {
172
                boolean changed = false;
173
                for (int i = 0; i < lenght(); i++)
174
                        if (baseFilterClass.isInstance(list.get(i))) {
175
                                list.remove(i);
176
                                i--;
177
                                changed = true;
178
                        }
179
                if (changed)
180
                        controlTypes();
181
                callFilterListChanged(this);
182
        }
183

    
184
        /**
185
         * Devuelve el tipo de dato de retorno al aplicar la pila de filtros
186
         * @return
187
         */
188
        public int getOutDataType() {
189
                if (list.size() > 0)
190
                        return ((RasterFilter) list.get(list.size() - 1)).getOutRasterDataType();
191
                else
192
                        return rasterBuf.getDataType();
193
        }
194

    
195
        /**
196
         * Devuelve el raster resultado de la aplicacion de la pila de filtros
197
         * @return
198
         */
199
        public IBuffer getResult() {
200
                return rasterBuf;
201
        }
202

    
203
        /**
204
         * Devuelve la banda alpha para los filtros que generan una
205
         * @return
206
         */
207
        public IBuffer getAlphaBand() {
208
                return alphaBand;
209
        }
210

    
211
        /**
212
         * Obtiene la cantidad de filtros en la lista
213
         * @return N?mero de filtros apilados
214
         */
215
        public int lenght() {
216
                return list.size();
217
        }
218

    
219
        /**
220
         * Obtiene el filtro apilado de la posici?n i o null si el indice es incorrecto
221
         * @param i        Posici?n a acceder en la pila
222
         * @return        Filtro
223
         */
224
        public RasterFilter get(int i) {
225
                if (i >= list.size() || i < 0)
226
                        return null;
227
                return (RasterFilter) list.get(i);
228
        }
229

    
230
        /**
231
         * Obtiene el filtro apilado de nombre name o null si no existe
232
         * @param i       Nombre del filtro buscado
233
         * @return        Filtro
234
         */
235
        public RasterFilter get(String name) {
236
                for (int i = list.size() - 1; i >= 0; i--)
237
                        if (((RasterFilter) list.get(i)).getName().equals(name))
238
                                return (RasterFilter) list.get(i);
239
                return null;
240
        }
241

    
242
        /**
243
         * Obtiene el filtro apilado que corresponde con el nombre
244
         * @param name        Nombre de filtro
245
         * @return      Filtro en caso de que exista un filtro apilado de ese tipo
246
         * o null si no hay ninguno.
247
         */
248
        public RasterFilter getByName(String name) {
249
                for (int i = 0; i < lenght(); i++)
250
                        if (((RasterFilter) list.get(i)).getName().equals(name))
251
                                return (RasterFilter) list.get(i);
252
                return null;
253
        }
254

    
255
        /**
256
         * Obtiene el primer filtro de la lista que es instancia de la clase pasada por
257
         * par?metro
258
         * @param baseFilterClass Filtro base
259
         * @return RasterFilter
260
         */
261
        public RasterFilter getFilterByBaseClass(Class baseFilterClass) {
262
                for (int i = 0; i < lenght(); i++)
263
                        if (baseFilterClass.isInstance(list.get(i)))
264
                                return (RasterFilter) list.get(i);
265
                return null;
266
        }
267

    
268
        /**
269
         * Obtiene el tipo del filtro de la pila de la posici?n i
270
         * @param i Posici?n a acceder en la pila
271
         * @return tipo de filtro
272
         */
273
        public String getName(int i) {
274
                return ((RasterFilter) list.get(i)).getName();
275
        }
276

    
277
        /**
278
         * Elimina todos los filtros de la pila
279
         */
280
        public void clear() {
281
                list.clear();
282
                callFilterListChanged(this);
283
        }
284

    
285
        /**
286
         * Sustituye un filtro de una posici?n de la pila por otro
287
         * @param filter
288
         * @param i
289
         */
290
        public void replace(RasterFilter filter, int i) {
291
                filter.setEnv(environment);
292
                list.remove(i);
293
                list.add(i, filter);
294
                callFilterListChanged(this);
295
        }
296

    
297
        /**
298
         * Move un filtro determinado a la posici?n especificada.
299
         * @param filter Filtro a mover
300
         * @param position Posici?n a asignar
301
         * @return Devuelve true si el filtro existia y lo ha movido y false si no lo ha hecho.
302
         */
303
        public boolean move(Class filter, int position) {
304
                RasterFilter f = null;
305
                for (int i = 0; i < list.size(); i++)
306
                        if(filter.isInstance(list.get(i))) {
307
                                f = (RasterFilter) list.get(i);
308
                                list.remove(i);
309
                                break;
310
                        }
311
                if(f != null) {
312
                        list.add(position, f);
313
                        return true;
314
                }
315
                return false;
316
        }
317

    
318
        /**
319
         * Asigna el raster de entrada inicial
320
         * @param raster
321
         */
322
        public void setInitRasterBuf(IBuffer raster) {
323
                rasterBuf = raster;
324
                if(rasterBuf != null)
325
                        typeFilter = rasterBuf.getDataType();
326
        }
327

    
328
        /**
329
         * Devuelve el tipo de datos inicial de la lista
330
         * @return Tipo de dato del raster inicial
331
         */
332
        public int getInitDataType() {
333
                return typeFilter;
334
        }
335

    
336
        /**
337
         * Asigna el tipo de dato inicial
338
         * @param dt
339
         */
340
        public void setInitDataType(int dt) {
341
                this.typeFilter = dt;
342
        }
343

    
344
        /**
345
         * M?todo que devuelve true si el tipo de filtro pasado por par?metro est? en la
346
         * pila y false si no lo est?.
347
         * @param type        Tipo de par?metro a comprobar
348
         * @return true si est? en la pila y false si no lo est?
349
         */
350
        public boolean isActive(String name) {
351
                for (int i = list.size() - 1; i >= 0; i--)
352
                        if (((RasterFilter) list.get(i)).getName().equals(name))
353
                                return true;
354
                return false;
355
        }
356

    
357
        /**
358
         * M?todo que devuelve true si el tipo de filtro pasado por par?metro est? en
359
         * la pila y false si no lo est?.
360
         *
361
         * @param filter Tipo de filtro a comprobar
362
         * @return true si est? en la pila y false si no lo est?
363
         */
364
        public boolean isActive(RasterFilter filter) {
365
                for (int i = list.size() - 1; i >= 0; i--)
366
                        if (((RasterFilter) list.get(i)).equals(filter))
367
                                return true;
368
                return false;
369
        }
370

    
371
        /**
372
         * Devuelve la posici?n en la lista de una clase de filtro concreta
373
         *
374
         * @param c Clase a buscar en la lista
375
         * @return posici?n en la lista
376
         */
377
        public int getPosition(Class c) {
378
                for (int i = 0; i < list.size(); i++)
379
                        if (c.isInstance(list.get(i)))
380
                                return i;
381
                return -1;
382
        }
383

    
384
        /**
385
         * Aplica los filtros de la pila sobre el buffer correspondiente
386
         * @param dataType
387
         * @throws InterruptedException
388
         */
389
        private void executeFilterByDataType(int dataType) throws InterruptedException {
390
                environment.put("FirstUseTransparency", Boolean.TRUE);
391
                environment.put("HasNoDataFilter", Boolean.valueOf(isActive("nodata")));
392

    
393
                environment.put("FirstRaster", rasterBuf);
394
                alphaBand = null;
395
                for (int i = 0; i < list.size(); i++) {
396
                        RasterFilter filter = (RasterFilter) list.get(i);
397

    
398
                        // TODO: Arquitectura. Quitar el ControlTypes y en este momento
399
                        // cerciorarse de si el tipo del filtro es totalmente el correcto o hay
400
                        // que recrearlo. Ejemplo:
401
                        // Si el filtro que tenemos antes de preprocesar es de tipo Byte y la
402
                        // entrada de datos es de tipo float, reconstruir solo este filtro para
403
                        // que sea de tipo float
404

    
405
                        filter.addParam("raster", rasterBuf);
406
                        filter.execute();
407

    
408
                        if (filter.getResult("raster") != null)
409
                                this.rasterBuf = (IBuffer) filter.getResult("raster");
410

    
411
                        //Si el filtro genera una banda alpha se mezcla con la que han generado otros
412
                        if (filter.getResult("alphaBand") != null)
413
                                if(alphaBand != null)
414
                                        alphaBand = Transparency.merge(alphaBand, (IBuffer)filter.getResult("alphaBand"));
415
                                else
416
                                        alphaBand = (IBuffer)filter.getResult("alphaBand");
417
                }
418
                environment.remove("FirstRaster");
419
        }
420

    
421
        /**
422
         * Aplica los filtros sobre un RasterBuf
423
         * @return IBuffer de salida
424
         * @throws InterruptedException
425
         */
426
        public IBuffer execute() throws InterruptedException {
427
                if (rasterBuf == null)
428
                        return null;
429
                executeFilterByDataType(rasterBuf.getDataType());
430
                return rasterBuf;
431
        }
432

    
433
        /**
434
         * Muestra el contenido de la pila de filtros para depuraci?n
435
         */
436
        public void show() {
437
                System.out.println("--------------------------------------------");
438

    
439
                for (int i = 0; i < list.size() ; i++)
440
                        System.out.println("FILTRO:" + i + " NAME:" + ((RasterFilter) list.get(i)).getName() + " FIL:" + ((RasterFilter) list.get(i)).toString());
441
        }
442

    
443
        public void resetPercent() {
444
                for (int i = 0; i < list.size(); i++)
445
                        ((RasterFilter) list.get(i)).resetPercent();
446
        }
447

    
448
        public int getPercent() {
449
                int percent = 0;
450
                if (list.size() == 0)
451
                        return 0;
452
                for (int i = 0; i < list.size(); i++)
453
                        percent += ((RasterFilter) list.get(i)).getPercent();
454

    
455
                percent = percent / list.size();
456
                return percent;
457
        }
458

    
459
        /**
460
         * Guarda el estado de la lista de filtros en una pila, que se podr?
461
         * ir recuperando con popStatus()
462
         */
463
        public void pushStatus() {
464
                status.push(getStatusCloned());
465
        }
466

    
467
        /**
468
         * Obtiene el estado actual de los filtros, el ArrayList devuelto es una
469
         * clonaci?n del original, asi no compartiran datos.
470
         * @return
471
         */
472
        public ArrayList getStatusCloned() {
473
                ArrayList newArray = new ArrayList();
474
                for (int i = 0; i < list.size(); i++)
475
                        try {
476
                                newArray.add(((RasterFilter) list.get(i)).clone());
477
                        } catch (CloneNotSupportedException e) {
478
                                System.out.println("No se ha podido clonar");
479
                        }
480
                return newArray;
481
        }
482

    
483
        /**
484
         * Define el estado actual de los filtros
485
         * @param newArray
486
         */
487
        public void setStatus(ArrayList newArray) {
488
                list.clear();
489
                if(newArray == null)
490
                        return;
491
                for (int i = 0; i < newArray.size(); i++)
492
                        list.add(newArray.get(i));
493
                callFilterListChanged(this);
494
        }
495

    
496
        /**
497
         * Recupera un estado guardado con antelaci?n mediante el m?todo pushStatus()
498
         */
499
        public void popStatus() {
500
                if (status.size() <= 0)
501
                        return;
502

    
503
                setStatus((ArrayList) status.pop());
504
        }
505

    
506
        /**
507
         * Obtiene el TreeMap con los par?metros
508
         * @return TreeMap
509
         */
510
        public TreeMap getEnv() {
511
                return environment;
512
        }
513

    
514
        /**
515
         * Asigna el TreeMap con los par?metros del entorno
516
         * @param env
517
         */
518
        public void setEnv(TreeMap env) {
519
                this.environment = env;
520
        }
521

    
522
        /**
523
         * Releases buffer resources
524
         */
525
        public void free() {
526
                if (rasterBuf != null)
527
                        rasterBuf.free();
528
                if (alphaBand != null)
529
                        alphaBand.free();
530
                rasterBuf = null;
531
                alphaBand = null;
532
                for (int i = 0; i < lenght(); i++)
533
                        ((RasterFilter) list.get(i)).free();
534
        }
535
}