Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tools / trunk / org.gvsig.raster.tools / org.gvsig.raster.tools.app.basic / src / main / java / org / gvsig / raster / tools / app / basic / tool / properties / control / EnhancedControl.java @ 4177

History | View | Annotate | Download (16.4 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
package org.gvsig.raster.tools.app.basic.tool.properties.control;
23

    
24
import java.awt.event.ActionEvent;
25
import java.awt.event.ActionListener;
26
import java.util.ArrayList;
27
import java.util.List;
28

    
29
import javax.swing.JCheckBox;
30

    
31
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
32
import org.gvsig.fmap.dal.coverage.datastruct.Params;
33
import org.gvsig.fmap.dal.coverage.exception.FilterAddException;
34
import org.gvsig.fmap.dal.coverage.exception.FilterManagerException;
35
import org.gvsig.fmap.dal.coverage.exception.FilterTypeException;
36
import org.gvsig.fmap.dal.coverage.grid.RasterFilter;
37
import org.gvsig.fmap.dal.coverage.grid.RasterFilterList;
38
import org.gvsig.fmap.dal.coverage.grid.RasterFilterListManager;
39
import org.gvsig.fmap.dal.coverage.grid.filter.LinearStretchParams;
40
import org.gvsig.fmap.dal.coverage.store.props.Statistics;
41
import org.gvsig.gui.beans.panelGroup.AbstractPanelGroup;
42
import org.gvsig.gui.beans.slidertext.listeners.SliderEvent;
43
import org.gvsig.gui.beans.slidertext.listeners.SliderListener;
44
import org.gvsig.i18n.Messages;
45
import org.gvsig.raster.fmap.layers.FLyrRaster;
46
import org.gvsig.raster.mainplugin.properties.RasterPropertiesTocMenuEntry;
47
import org.gvsig.raster.swing.RasterSwingLibrary;
48
import org.gvsig.raster.tools.app.basic.RasterExtension;
49
import org.gvsig.raster.tools.app.basic.raster.process.IProcessActions;
50
import org.gvsig.raster.tools.app.basic.raster.process.StatisticsProcess;
51
import org.gvsig.raster.tools.app.basic.tool.properties.panel.EnhancedBrightnessContrastPanel;
52
import org.gvsig.raster.tools.app.basic.tool.properties.panel.EnhancedPanel;
53
import org.gvsig.raster.tools.app.basic.tool.properties.panel.EnhancedWithTrimPanel;
54

    
55

    
56
/**
57
 * Clase que hace de interfaz entre los objetos que contienen la informaci?n de
58
 * realce y el panel.
59
 *
60
 * @author Nacho Brodin (nachobrodin@gmail.com)
61
 */
62
public class EnhancedControl implements IProcessActions {
63
        private EnhancedPanel                   tPanel      = null;
64
        private RasterFilterList                filterList  = null;
65
        private EnhancedWithTrimPanel           ePanel      = null;
66
        private EnhancedBrightnessContrastPanel bcPanel     = null;
67
        private FLyrRaster                      lyr         = null;
68
        private AbstractPanelGroup              panelGroup  = null;
69
        private Statistics                      stats       = null;
70
        private int[]                           renderBands = new int[] { 0, 1, 2 };
71

    
72

    
73
        /**
74
         * Manejador de eventos de los slider de brillo y contraste.
75
         * @author Nacho Brodin (nachobrodin@gmail.com)
76
         */
77
        class BrightnessContrastListener implements ActionListener, SliderListener {
78
                JCheckBox active = null;
79
                /**
80
                 * Constructor. Registra los listener
81
                 * @param panel
82
                 */
83
                public BrightnessContrastListener(EnhancedBrightnessContrastPanel panel) {
84
                        panel.addBrightnessValueChangedListener(this);
85
                        panel.addContrastValueChangedListener(this);
86
                        active = panel.getActive();
87
                        active.addActionListener(this);
88
                }
89

    
90
                public void actionPerformed(ActionEvent e) {
91
                        if (!RasterExtension.autoRefreshView)
92
                                return;
93

    
94
                        if (e.getSource() == active)
95
                                onlyApply();
96
                }
97

    
98
                public void actionValueChanged(SliderEvent e) {
99
                        if (!RasterExtension.autoRefreshView)
100
                                return;
101

    
102
                        onlyApply();
103
                }
104

    
105
                public void actionValueDragged(SliderEvent e) {
106
                }
107
        }
108

    
109
        /**
110
         * Manejador de eventos del panel EnhancedWithTrim.
111
         *
112
         * @author BorSanZa - Borja Sanchez Zamorano 
113
         */
114
        class EnhancedWithTrimListener implements ActionListener, SliderListener {
115
                JCheckBox active = null;
116
                /**
117
                 * Constructor. Registra los listener
118
                 * @param panel
119
                 */
120
                public EnhancedWithTrimListener(EnhancedWithTrimPanel panel) {
121
                        active = panel.getActive();
122
                        active.addActionListener(this);
123
                        panel.getRemoveCheck().addActionListener(this);
124
                        panel.getTrimCheck().addActionListener(this);
125
                        panel.getTrimSlider().addValueChangedListener(this);
126
                }
127

    
128
                public void actionPerformed(ActionEvent e) {
129
                        if (!RasterExtension.autoRefreshView)
130
                                return;
131

    
132
                        onlyApply();
133
                }
134

    
135
                public void actionValueChanged(SliderEvent e) {
136
                        if (!RasterExtension.autoRefreshView)
137
                                return;
138

    
139
                        onlyApply();
140
                }
141

    
142
                public void actionValueDragged(SliderEvent e) {
143
                }
144
        }
145

    
146
        /**
147
         * Constructor
148
         * @param tp
149
         */
150
        public EnhancedControl(AbstractPanelGroup panelGroup, EnhancedPanel tp, FLyrRaster lyr, RasterFilterList rfl) {
151
                this.panelGroup = panelGroup;
152
                this.tPanel = tp;
153
                this.filterList = rfl;
154
                this.lyr = lyr;
155
                this.bcPanel = tPanel.getBrightnessContrastPanel();
156
                this.ePanel = tPanel.getEnhancedWithTrimPanel();
157
                new BrightnessContrastListener(bcPanel);
158
                new EnhancedWithTrimListener(ePanel);
159

    
160
                try {
161
                        saveStatus();
162
                } catch (FilterManagerException e) {
163
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_saving_filters"), this, e);
164
                } catch (FilterTypeException e) {
165
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_saving_filters"), this, e);
166
                }
167

    
168
                setValuesFromFilterToPanel();
169
        }
170

    
171
        /**
172
         * Carga los valores del panel desde el filtro
173
         */
174
        private void setValuesFromFilterToPanel() {
175
                // BRILLO
176
                RasterFilter bFilter = filterList.getByName("brightness");
177
                if (bFilter != null){
178
                        int incr = ((Integer)bFilter.getParam("incrBrillo")).intValue();
179
                        bcPanel.setBrightnessValue((double) incr);
180
                }else
181
                        bcPanel.setBrightnessValue(0);
182

    
183
                // CONTRASTE
184
                RasterFilter cFilter = filterList.getByName("contrast");
185
                if (cFilter != null){
186
                        int incr = ((Integer)cFilter.getParam("incrContraste")).intValue();
187
                        bcPanel.setContrastValue((double) incr);
188
                }
189
                else
190
                        bcPanel.setContrastValue(0);
191

    
192
                if (bFilter != null || cFilter != null)
193
                        bcPanel.setControlEnabled(true);
194
                else
195
                        bcPanel.setControlEnabled(false);
196

    
197
                // REALCE LINEAL
198
                RasterFilter eFilter = filterList.getByName("enhanced_stretch");
199
                if (eFilter != null) {
200
                        ePanel.setControlEnabled(true);
201

    
202
                        // Comprueba si esta activo eliminar extremos
203
                        boolean removeEnds = false;
204
                        if (eFilter.getParam("remove") != null)
205
                                removeEnds = ((Boolean) eFilter.getParam("remove")).booleanValue();
206
                        ePanel.setRemoveEndsActive(removeEnds);
207
                        
208
                        // Comprueba si hay recorte de colas
209
                        LinearStretchParams stretchs = (LinearStretchParams) eFilter.getParam("stretchs");
210
                        double[] tailTrimList;
211
                        if (stretchs != null)
212
                                tailTrimList = stretchs.getTailTrimList();
213
                        else
214
                                tailTrimList = new double[0];
215
                        double median = 0;
216
                        double nValues = tailTrimList.length;
217
                        for (int i = 0; i < tailTrimList.length; i++) 
218
                                median += tailTrimList[i];
219
                        double tailTrim = new Double(nValues > 0 ? median / nValues : median).doubleValue();
220
                        
221
                        if (tailTrim != 0) {
222
                                ePanel.setTailTrimCheckActive(true);
223
                                ePanel.setTailTrimValue(tailTrim * 100);
224
                        } else {
225
                                ePanel.setTailTrimCheckActive(false);
226
                                ePanel.setTailTrimValue(0);
227
                        }
228
                } else {
229
                        ePanel.setControlEnabled(false);
230
                        ePanel.setRemoveEndsActive(false);
231
                        ePanel.setTailTrimCheckActive(false);
232
                        ePanel.setTailTrimValue(0);
233
                }
234
        }
235

    
236
        /**
237
         * Carga los valores del filtro desde el panel
238
         * @throws FilterTypeException
239
         * @throws FilterAddException 
240
         */
241
        private void setValuesFromPanelToFilter() throws FilterTypeException, FilterAddException {
242

    
243
                // REALCE
244
                if (ePanel.getActive().isSelected()) {
245
                        if(lyr != null) {
246
                                stats = lyr.getDataStore().getStatistics();
247
                                renderBands = lyr.getRender().getRenderColorInterpretation().buildRenderBands();
248
                                // En este caso siempre es necesario el m?ximo y m?nimo
249
                                try {
250
                                        if(!stats.isCalculated() && lyr instanceof FLyrRaster) 
251
                                                StatisticsProcess.launcher(lyr, this);
252
                                        else {
253
                                                RasterFilterListManager enhancementManager = filterList.getManagerByID("EnhancementStretch");
254
                                                Params params = filterList.createEmptyFilterParams();
255
                                                params.setParam("stats", stats);
256
                                                params.setParam("remove", ePanel.isRemoveEndsSelected());
257
                                                params.setParam("renderBands", renderBands);
258
                                                params.setParam("rgb", lyr.isRGB());
259
                                                
260
                                                if (ePanel.isTailTrimCheckSelected()) {
261
                                                        params.setParam("tailtrim", (double) (ePanel.getTrimValue() / 100D));
262
                                                } else {
263
                                                        params.setParam("tailtrim", 0.0);
264
                                                }
265
                                                
266
                                                enhancementManager.addFilter(params);
267
                                        }
268
                                } catch (FilterManagerException e) {
269
                                        throw new FilterAddException("No se han podido calcular estadisticas. Error al a?adir realce;" + e.getMessage());
270
                                } 
271
                        }
272
                } else {
273
                        if(lyr != null) {
274
                                renderBands = lyr.getRender().getRenderColorInterpretation().buildRenderBands();
275
                                if(lyr.getDataStore().getDataType()[0] != Buffer.TYPE_BYTE || renderBands.length < 3){
276
                                        RasterFilter colortable = filterList.getByName("colortable");
277
                                        filterList.removeAll();
278
                                        if(colortable != null){
279
                                                filterList.add(colortable);
280
                                        }
281
                                } else {
282
                                        filterList.remove("enhanced_stretch");
283
                                        filterList.remove("tailTrim");
284
                                }
285
                        } else {
286
                                filterList.remove("enhanced_stretch");
287
                                filterList.remove("tailTrim");
288
                        }
289
                }
290

    
291
                // BRILLO Y CONTRASTE
292
                try {
293
                        RasterFilterListManager bcManager = filterList.getManagerByID("BrightnessContrast");
294

    
295
                        if (bcPanel.getActive().isSelected() && ((int) bcPanel.getBrightnessValue() != 0)) {
296
                                Params params = filterList.createEmptyFilterParams();
297
                                params.setParam("Brightness", new Integer((int) bcPanel.getBrightnessValue()));
298
                                filterList.add(bcManager.createFilter(params));
299
                        } else
300
                                filterList.remove("brightness");
301

    
302
                        if (bcPanel.getActive().isSelected() && ((int) bcPanel.getContrastValue() != 0)) {
303
                                Params params = filterList.createEmptyFilterParams();
304
                                params.setParam("Contrast", new Integer((int) bcPanel.getContrastValue()));
305
                                filterList.add(bcManager.createFilter(params));
306
                        } else
307
                                filterList.remove("contrast");
308
                } catch (FilterManagerException e) {
309
                        throw new FilterAddException("No se han podido calcular estadisticas. Error al a?adir realce;" + e.getMessage());
310
                }
311

    
312
                endActionsForFilterSettings();
313
        }
314
        
315
        /**
316
         * Acciones realizadas al final la aplicaci?n de filtros
317
         * @throws FilterTypeException
318
         */
319
        private void endActionsForFilterSettings() throws FilterTypeException {
320
                ArrayList listOrder = (ArrayList) panelGroup.getProperties().get("filterOrder");
321
                List<RasterFilter> listCopy = filterList.getStatusCloned();
322
                int cont = 0;
323
                for (int i = 0; i < listOrder.size(); i++) {
324
                        int pos = hasFilter(listCopy, ((RasterFilter) listOrder.get(i)).getName());
325
                        if (pos != -1) {
326
                                // Esta pero en posicion equivocada
327
                                if (pos != cont) {
328
                                        RasterFilter copy = listCopy.remove(pos);
329
                                        listCopy.add(cont, copy);
330
                                }
331
                                cont++;
332
                        }
333
                }
334
                filterList.setStatus(listCopy);
335
                filterList.controlTypes();
336

    
337
                // Redibujamos
338
                if (lyr != null)
339
                        lyr.getMapContext().invalidate();
340
        }
341

    
342
        /**
343
         * Acciones a ejecutar cuando se acepta
344
         */
345
        public void accept() {
346
                try {
347
                        setValuesFromPanelToFilter();
348
                } catch (FilterTypeException e) {
349
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_adding_filters"), this, e);
350
                } catch (FilterAddException e) {
351
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_adding_filters"), this, e);
352
                }
353
        }
354

    
355
        /**
356
         * Acciones a ejecutar cuando se aplica
357
         */
358
        public void apply() {
359
                onlyApply();
360
                try {
361
                        saveStatus();
362
                } catch (FilterManagerException e) {
363
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_saving_filters"), this, e);
364
                } catch (FilterTypeException e) {
365
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_saving_filters"), this, e);
366
                }
367
        }
368

    
369
        /**
370
         * Acciones a ejecutar cuando se aplica
371
         */
372
        public void onlyApply() {
373
                if (RasterPropertiesTocMenuEntry.enableEvents)
374
                        try {
375
                                setValuesFromPanelToFilter();
376
                        } catch (FilterTypeException e) {
377
                                RasterSwingLibrary.messageBoxError(Messages.getText("error_adding_filters"), this, e);
378
                        } catch (FilterAddException e) {
379
                                RasterSwingLibrary.messageBoxError(Messages.getText("error_adding_filters"), this, e);
380
                        }
381
        }
382

    
383
        /**
384
         * Acciones a ejecutar cuando se cancela
385
         */
386
        public void cancel() {
387
                restoreStatus();
388
        }
389

    
390
        /**
391
         * Consulta si el filtro especificado en el par?metro name est? dentro
392
         * de la lista filter.
393
         * @param filter Lista donde se consulta
394
         * @param name Nombre a comprobar si est? en la lista
395
         * @return true si est? en la lista y false si no est?.
396
         */
397
        private int hasFilter(List<RasterFilter> filter, String name) {
398
                for (int i = 0; i < filter.size(); i++) {
399
                        if (((RasterFilter) filter.get(i)).getName().equals(name))
400
                                return i;
401
                }
402
                return -1;
403
        }
404

    
405
        @SuppressWarnings("unchecked")
406
        public void saveStatus() throws FilterManagerException, FilterTypeException {
407
                panelGroup.getProperties().put("filterStatus", filterList.getStatusCloned());
408

    
409
                List<RasterFilter> filterOrder = filterList.getStatusCloned();
410
                int posEnhanced = hasFilter(filterOrder, "enhanced_stretch");
411
                int posTailTrim = hasFilter(filterOrder, "tailTrim");
412
                
413
                RasterFilterListManager statFilterManager = filterList.getManagerByID("Statistics");
414
                Params params = filterList.createEmptyFilterParams();
415
                params.setParam("stats", null);
416
                params.setParam("tail", new Double(0.0));
417
                params.setParam("samples", new Double(0.0));
418
                params.setParam("remove", new Boolean(false));
419
                RasterFilter filter = statFilterManager.createFilter(params);
420
                
421
                // Si tiene realce comprobamos el tailtrim
422
                if (posEnhanced != -1) {
423
                        // Si no tiene el tailTrim, insertamos uno antes del realce
424
                        if (posTailTrim == -1) {
425
                                filterOrder.add(posEnhanced, filter);
426
                        }
427
                } else {
428
                        // Si existe un tailTrim lo borramos pq no tiene realce
429
                        if (posTailTrim != -1)
430
                                filterOrder.remove(posTailTrim);
431
                        // Insertamos primero el tailtrim y luego el realce para conservar un orden logico
432
                        filterOrder.add(0, filter);
433
                        RasterFilterListManager eManager = filterList.getManagerByID("EnhancementStretch");
434
                        params = filterList.createEmptyFilterParams();
435
                        params.setParam("remove", new Boolean(false));
436
                        eManager.createFilter(params);
437
                }
438

    
439
                RasterFilterListManager bcManager = filterList.getManagerByID("BrightnessContrast");
440
                
441
                // Si no tiene brillo, lo insertamos
442
                if (hasFilter(filterOrder, "brightness") == -1) {
443
                        params = filterList.createEmptyFilterParams();
444
                        params.setParam("Brightness", new Integer(0));
445
                        filterOrder.add(bcManager.createFilter(params));
446
                }
447

    
448
                // Si no tiene el contraste, lo insertamos
449
                if (hasFilter(filterOrder, "contrast") == -1) {
450
                        params = filterList.createEmptyFilterParams();
451
                        params.setParam("Contrast", new Integer(0));
452
                        filterOrder.add(bcManager.createFilter(params));
453
                }
454

    
455
                panelGroup.getProperties().put("filterOrder", filterOrder);
456
        }
457

    
458
        @SuppressWarnings("unchecked")
459
        public void restoreStatus() {
460
                filterList.setStatus((ArrayList) panelGroup.getProperties().get("filterStatus"));
461

    
462
                if (lyr != null)
463
                        lyr.getMapContext().invalidate();
464
        }
465
        
466
        public void end(Object param) {
467
                Statistics st = null;
468
                if(param instanceof FLyrRaster && ((FLyrRaster)param).getDataStore() != null) 
469
                        st = ((FLyrRaster)param).getDataStore().getStatistics();
470
                Statistics statistics = (st == null) ? stats : st;
471
                
472
                try {                
473
                        RasterFilterListManager enhancementManager = filterList.getManagerByID("EnhancementStretch");
474
                        Params params = filterList.createEmptyFilterParams();
475
                        params.setParam("stats", statistics);
476
                        params.setParam("remove", ePanel.isRemoveEndsSelected());
477
                        params.setParam("renderBands", renderBands);
478
                        params.setParam("rgb", lyr.isRGB());
479
                        
480
                        if (ePanel.isTailTrimCheckSelected()) {
481
                                params.setParam("tailtrim", (double) (ePanel.getTrimValue() / 100D));
482
                        } else {
483
                                filterList.remove("tailTrim");
484
                                params.setParam("tailtrim", 0.0);
485
                        }
486
                        
487
                        enhancementManager.addFilter(params);
488
                        endActionsForFilterSettings();
489
                } catch (FilterManagerException e) {
490
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_adding_stats"), this, e);
491
                } catch (FilterTypeException e) {
492
                        RasterSwingLibrary.messageBoxError(Messages.getText("error_adding_stats"), this, e);
493
                }
494
        }
495

    
496
        public void interrupted() {
497
        }
498
}