Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / grid / filter / RasterFilterList.java @ 13348

History | View | Annotate | Download (13.1 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
/**
27
 * Esta clase representa la lista de filtros que debe ser manejada desde el
28
 * RasterFilterListManager.
29
 *
30
 * @author Nacho Brodin (nachobrodin@gmail.com)
31
 */
32
public class RasterFilterList {
33
        private IBuffer   rasterBuf  = null;
34
        private int       typeFilter = -1;
35
        private TreeMap   params     = new TreeMap();
36

    
37
        // Pila de objetos Filter (Contiene un RasterFilter)
38
        private ArrayList list       = new ArrayList();
39
        private Stack     status     = new Stack();
40

    
41
        /**
42
         * A?ade un par?metro a la lista de filtros. Estos par?metros luego pueden ser
43
         * utilizados por los managers que se registren
44
         * @param key Nombre del par?metro que coincide con el nombre de la clase.
45
         * @param value Objeto
46
         */
47
        public void addParam(String key, Object value) {
48
                params.put(key, value);
49
        }
50

    
51
        /**
52
         * Obtiene un par?metro de la lista de filtros.
53
         * @param key Identificador del par?metro. Coincide con el nombre de la clase del par?metro.
54
         */
55
        public Object getParam(String key) {
56
                return params.get(key);
57
        }
58

    
59
        /**
60
         * Controla que los tipos de entrada y salida de los filtros sean los
61
         * correctos
62
         */
63
        public void controlTypes() {
64
                RasterFilterListManager stackManager = new RasterFilterListManager(this);
65
                stackManager.controlTypes();
66
        }
67

    
68
        /**
69
         * A?ade un filtro al final de la lista
70
         * @param filter        filtro a?adido
71
         */
72
        public void add(RasterFilter filter) {
73
                if (isActive(filter.getName())) {
74
                        replace(filter, filter.getName());
75
                } else {
76
                        list.add(filter);
77
                        controlTypes();
78
                }
79
        }
80

    
81
        /**
82
         * Sustituye un filtro de una posici?n de la pila por otro
83
         * @param filter
84
         * @param i
85
         */
86
        public void replace(RasterFilter filter, String name) {
87
                boolean changed = false;
88

    
89
                for (int i = list.size() - 1; i >= 0; i--)
90
                        if (((RasterFilter) list.get(i)).getName().equals(name)) {
91
                                list.remove(i);
92
                                list.add(i, filter);
93
                                changed = true;
94
                        }
95

    
96
                if (changed)
97
                        controlTypes();
98
        }
99

    
100
        /**
101
         * A?ade un filtro en la lista en la posici?n indicada.
102
         * @param filter        filtro a?adido
103
         * @param pos        posici?n
104
         */
105
        public void add(RasterFilter filter, int pos) {
106
                try {
107
                        list.add(pos, filter);
108
                        controlTypes();
109
                } catch (IndexOutOfBoundsException e) {
110
                        add(filter);
111
                }
112
        }
113

    
114
        /**
115
         * Elimina un filtro a partir de su nombre
116
         * @param name Nombre del filtro a eliminar
117
         */
118
        public void remove(String name) {
119
                boolean changed = false;
120
                for (int i = list.size() - 1; i >= 0; i--)
121
                        if (((RasterFilter) list.get(i)).getName().equals(name)) {
122
                                list.remove(i);
123
                                changed = true;
124
                        }
125
                if (changed)
126
                        controlTypes();
127
        }
128

    
129
        /**
130
         * Elimina un filtro por clase.
131
         *
132
         * @param baseFilterClass
133
         */
134
        public void remove(Class baseFilterClass) {
135
                boolean changed = false;
136
                for (int i = 0; i < lenght(); i++)
137
                        if (baseFilterClass.isInstance((RasterFilter) list.get(i))) {
138
                                list.remove(i);
139
                                i--;
140
                                changed = true;
141
                        }
142
                if (changed)
143
                        controlTypes();
144
        }
145

    
146
        /**
147
         * Devuelve el tipo de dato de retorno al aplicar la pila de filtros
148
         * @return
149
         */
150
        public int getOutDataType() {
151
                if (list.size() > 0)
152
                        return ((RasterFilter) list.get(list.size() - 1)).getOutRasterDataType();
153
                else
154
                        return rasterBuf.getDataType();
155
        }
156

    
157
        /**
158
         * Devuelve el raster resultado de la aplicacion de la pila de filtros
159
         * @return
160
         */
161
        public IBuffer getResult() {
162
                return rasterBuf;
163
        }
164

    
165
        /**
166
         * Devuelve true si el filtro 'a' est? por encima del 'b' en la lista y false si no lo est?
167
         * @param a  Nombre de filtro
168
         * @param b  Nombre de filtro
169
         * @return
170
         */
171
/*
172
        private boolean isOnTop(String a, String b) {
173
                int posA = -1;
174
                int posB = -1;
175

176
                for (int i = 0; i < list.size(); i++) {
177
                        if (list.get(i).equals(a))
178
                                posA = i;
179

180
                        if (list.get(i).equals(b))
181
                                posB = i;
182

183
                        if ((posA != -1) && (posB != -1))
184
                                break;
185
                }
186

187
                if (posA < posB)
188
                        return true;
189
                else
190
                        return false;
191
        }
192
*/
193
        /**
194
         * Dado un modo de inserci?n se obtiene el tipo de dato del filtro a
195
         * introducir. Se insertionMode es ADD_END quiere decir que se a?adir? al
196
         * final de la lista por lo que devuelve el tipo de la salida del ?ltimo
197
         * filtro. Si es ADD_END_AND_DELETE lo mismo y si es MODIFY_LAST quiere decir
198
         * que buscar? si hay alguno de este tipo y si lo hay devuelve el tipo de dato
199
         * del anterior filtro en la lista.
200
         *
201
         * @param name Nombre del filtro a insertar en la lista. Este debe
202
         *          corresponder con la variable genericName definida para cada tipo
203
         *          de filtro
204
         * @param insertionMode Modo de inserci?n en la lista. Debe corresponder con
205
         *          alguna de las constantes definidas en RasterFilterList ADD_END,
206
         *          ADD_END_AND_DELETE, MODIFY_LAST o UNDEFINED
207
         */
208
/*
209
        public int getDataTypeInFilter(String name, int insertionMode) {
210

211
                // Si no hay filtros, devolvemos el inicial
212
                if (list.size() == 0)
213
                        return getInitDataType();
214

215
                if (insertionMode == MODIFY_LAST) {
216
                        for (int i = list.size() - 1; i >= 0; i--) {
217
                                if (((RasterFilter) list.get(i)).getName().equals(name)) {
218
                                        if (i > 0)
219
                                                return ((RasterFilter) list.get(i - 1)).getOutRasterDataType();
220
                                        else
221
                                                return getInitDataType();
222
                                }
223
                        }
224
                }
225

226
                // Si no se encuentra un filtro, suponemos que estamos tratando el ultimo de
227
                // la lista
228
                return ((RasterFilter) list.get(list.size() - 1)).getOutRasterDataType();
229
        }
230
*/
231

    
232
        /**
233
         * Obtiene la cantidad de filtros en la lista
234
         * @return N?mero de filtros apilados
235
         */
236
        public int lenght() {
237
                return list.size();
238
        }
239

    
240
        /**
241
         * Obtiene el filtro apilado de la posici?n i o null si el indice es incorrecto
242
         * @param i        Posici?n a acceder en la pila
243
         * @return        Filtro
244
         */
245
        public RasterFilter get(int i) {
246
                if (i >= list.size() || i < 0)
247
                        return null;
248
                return ((RasterFilter) list.get(i));
249
        }
250

    
251
        /**
252
         * Obtiene el filtro apilado de nombre name o null si no existe
253
         * @param i       Nombre del filtro buscado
254
         * @return        Filtro
255
         */
256
        public RasterFilter get(String name) {
257
                for (int i = list.size() - 1; i >= 0; i--) {
258
                        if (((RasterFilter) list.get(i)).getName().equals(name))
259
                                return ((RasterFilter) list.get(i));
260
                }
261
                return null;
262
        }
263

    
264
        /**
265
         * Obtiene el filtro apilado que corresponde con el nombre
266
         * @param name        Nombre de filtro
267
         * @return      Filtro en caso de que exista un filtro apilado de ese tipo
268
         * o null si no hay ninguno.
269
         */
270
        public RasterFilter getByName(String name) {
271
                for (int i = 0; i < lenght(); i++) {
272
                        if (((RasterFilter) list.get(i)).getName().equals(name))
273
                                return ((RasterFilter) list.get(i));
274
                }
275
                return null;
276
        }
277

    
278
        /**
279
         * Obtiene el primer filtro de la lista que es instancia de la clase pasada por
280
         * par?metro
281
         * @param baseFilterClass Filtro base
282
         * @return RasterFilter
283
         */
284
        public RasterFilter getFilterByBaseClass(Class baseFilterClass) {
285
                for (int i = 0; i < lenght(); i++) {
286
                        if (baseFilterClass.isInstance(((RasterFilter) list.get(i))))
287
                                return ((RasterFilter) list.get(i));
288
                }
289
                return null;
290
        }
291

    
292
        /**
293
         * Obtiene el tipo del filtro de la pila de la posici?n i
294
         * @param i Posici?n a acceder en la pila
295
         * @return tipo de filtro
296
         */
297
        public String getName(int i) {
298
                return ((RasterFilter) list.get(i)).getName();
299
        }
300

    
301
        /**
302
         * Elimina todos los filtros de la pila
303
         */
304
        public void clear() {
305
                list.clear();
306
        }
307

    
308
        /**
309
         * Sustituye un filtro de una posici?n de la pila por otro
310
         * @param filter
311
         * @param i
312
         */
313
        public void replace(RasterFilter filter, int i) {
314
                list.remove(i);
315
                list.add(i, filter);
316
        }
317

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

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

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

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

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

    
386
        /**
387
         * Aplica los filtros de la pila sobre el buffer correspondiente
388
         * @param dataType
389
         * @throws InterruptedException
390
         */
391
        private void executeFilterByDataType(int dataType) throws InterruptedException {
392
                for (int i = 0; i < list.size(); i++) {
393
                        RasterFilter filter = ((RasterFilter) list.get(i));
394

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

    
402
                        filter.addParam("raster", rasterBuf);
403
                        filter.execute();
404

    
405
                        if (filter.getResult("raster") != null)
406
                                this.rasterBuf = (IBuffer) filter.getResult("raster");
407
                }
408
        }
409

    
410
        /**
411
         * Aplica los filtros sobre un RasterBuf
412
         * @return IBuffer de salida
413
         * @throws InterruptedException
414
         */
415
        public IBuffer execute() throws InterruptedException {
416
                if (rasterBuf == null)
417
                        return null;
418
                executeFilterByDataType(rasterBuf.getDataType());
419
                return rasterBuf;
420
        }
421

    
422
        /**
423
         * Muestra el contenido de la pila de filtros para depuraci?n
424
         */
425
        public void show() {
426
                System.out.println("--------------------------------------------");
427

    
428
                for (int i = 0; i < list.size() ; i++) {
429
                        System.out.println("FILTRO:" + i + " NAME:" + ((RasterFilter) list.get(i)).getName() + " FIL:" + ((RasterFilter) list.get(i)).toString());
430
                }
431
        }
432

    
433
        public void resetPercent() {
434
                for (int i = 0; i < list.size(); i++)
435
                        ((RasterFilter) list.get(i)).resetPercent();
436
        }
437

    
438
        public int getPercent() {
439
                int percent = 0;
440
                if (list.size() == 0)
441
                        return 0;
442
                for (int i = 0; i < list.size(); i++)
443
                        percent += ((RasterFilter) list.get(i)).getPercent();
444

    
445
                percent = percent / list.size();
446
                return percent;
447
        }
448

    
449
        /**
450
         * Metodo para poder cancelar el proceso de calculo de histograma.
451
         */
452
        public void setCanceled(boolean value) {
453
                for (int i = 0; i < list.size(); i++)
454
                        ((RasterFilter) list.get(i)).setCanceled(value);
455
        }
456

    
457
        /**
458
         * Metodo para saber si se ha cancelado un proceso de calculo de histograma
459
         * @return boolean
460
         */
461
        public boolean isCanceled(int process) {
462
                for (int i = 0; i < list.size(); i++)
463
                        if (((RasterFilter) list.get(i)).isCanceled())
464
                                return true;
465
                return false;
466
        }
467

    
468
        /**
469
         * Guarda el estado de la lista de filtros en una pila, que se podr?
470
         * ir recuperando con popStatus()
471
         */
472
        public void pushStatus() {
473
                status.push(getStatusCloned());
474
        }
475

    
476
        /**
477
         * Obtiene el estado actual de los filtros, el ArrayList devuelto es una
478
         * clonaci?n del original, asi no compartiran datos.
479
         * @return
480
         */
481
        public ArrayList getStatusCloned() {
482
                ArrayList newArray = new ArrayList();
483
                for (int i = 0; i < list.size(); i++) {
484
                        try {
485
                                newArray.add(((RasterFilter) list.get(i)).clone());
486
                        } catch (CloneNotSupportedException e) {
487
                                System.out.println("No se ha podido clonar");
488
                        }
489
                }
490
                return newArray;
491
        }
492

    
493
        /**
494
         * Define el estado actual de los filtros
495
         * @param newArray
496
         */
497
        public void setStatus(ArrayList newArray) {
498
                list.clear();
499
                for (int i = 0; i < newArray.size(); i++) {
500
                        list.add((RasterFilter) newArray.get(i));
501
                }
502
        }
503

    
504
        /**
505
         * Recupera un estado guardado con antelaci?n mediante el m?todo pushStatus()
506
         */
507
        public void popStatus() {
508
                if (status.size() <= 0)
509
                        return;
510

    
511
                setStatus((ArrayList) status.pop());
512
        }
513
}