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 / histogram / HistogramPanelListener.java @ 2480

History | View | Annotate | Download (17.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
*
3
* Copyright (C) 2005 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.tools.app.basic.tool.histogram;
20

    
21
import java.awt.Color;
22
import java.awt.event.ActionEvent;
23
import java.awt.event.ActionListener;
24
import java.beans.PropertyChangeEvent;
25
import java.beans.PropertyChangeListener;
26
import java.io.File;
27
import java.util.ArrayList;
28

    
29
import javax.swing.JButton;
30
import javax.swing.JComboBox;
31
import javax.swing.JFileChooser;
32
import javax.swing.JOptionPane;
33
import javax.swing.table.DefaultTableModel;
34

    
35
import org.gvsig.app.ApplicationLocator;
36
import org.gvsig.app.ApplicationManager;
37
import org.gvsig.app.project.documents.table.TableDocument;
38
import org.gvsig.app.project.documents.table.TableManager;
39
import org.gvsig.fmap.dal.DALLocator;
40
import org.gvsig.fmap.dal.DataManager;
41
import org.gvsig.fmap.dal.DataServerExplorer;
42
import org.gvsig.fmap.dal.DataServerExplorerParameters;
43
import org.gvsig.fmap.dal.coverage.RasterLocator;
44
import org.gvsig.fmap.dal.coverage.datastruct.BufferHistogram;
45
import org.gvsig.fmap.dal.coverage.datastruct.HistogramClass;
46
import org.gvsig.fmap.dal.coverage.exception.HistogramException;
47
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
48
import org.gvsig.fmap.dal.coverage.exception.QueryException;
49
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
50
import org.gvsig.fmap.dal.coverage.store.props.HistogramComputer;
51
import org.gvsig.fmap.dal.exception.DataException;
52
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
53
import org.gvsig.fmap.dal.feature.EditableFeature;
54
import org.gvsig.fmap.dal.feature.EditableFeatureType;
55
import org.gvsig.fmap.dal.feature.FeatureStore;
56
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
57
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
58
import org.gvsig.gui.beans.graphic.GraphicEvent;
59
import org.gvsig.gui.beans.graphic.GraphicListener;
60
import org.gvsig.raster.fmap.layers.FLyrRaster;
61
import org.gvsig.raster.swing.RasterSwingLibrary;
62
import org.gvsig.raster.tools.app.basic.RasterToolsUtil;
63
import org.gvsig.raster.tools.app.basic.raster.process.HistogramProcess;
64
import org.gvsig.raster.tools.app.basic.raster.process.IProcessActions;
65
import org.gvsig.raster.tools.app.basic.raster.process.StatisticsProcess;
66
import org.gvsig.raster.tools.app.basic.tool.histogram.ui.HistogramPanel;
67
import org.gvsig.tools.dataTypes.DataTypes;
68
/**
69
 * Listener para eventos del panel de histograma
70
 *
71
 * @version 20/03/2007
72
 * @author Nacho Brodin (brodin_ign@gva.es)
73
 * @author BorSanZa - Borja Sanchez Zamorano (borja.sanchez@iver.es)
74
 */
75
public class HistogramPanelListener implements GraphicListener, ActionListener, PropertyChangeListener, IProcessActions {
76
        private HistogramPanel histogramPanel    = null;
77

    
78
        /**
79
         * Variable que apunta a uno de los dos histogramas posibles: Real o RGB
80
         */
81
        private BufferHistogram      lastHistogram     = null;
82

    
83
        /**
84
         * Histograma original sin convertir a RGB
85
         */
86
        private BufferHistogram      lastHistogramReal = null;
87

    
88
        /**
89
         * Histograma convertido a rango RGB
90
         */
91
        private BufferHistogram      lastHistogramRGB  = null;
92

    
93
        public boolean         eventsEnabled     = false;
94

    
95
        /**
96
         * Bandas que se est?n mostrando en el gr?fico. Se inicializa con las 3 bandas
97
         * RGB de la visualizaci?n. Este array puede tener m?s elementos ya que si las
98
         * bandas no son de visualizaci?n (bandas de la imagen en disco) tendr? un
99
         * elemento por cada una.
100
         */
101
        private boolean[]      showBands         = null;
102
        private FLyrRaster     lyr               = null;
103

    
104
        private Color[]                                                bandsColor     = {
105
                        Color.red,
106
                        Color.green,
107
                        Color.blue,
108
                        Color.cyan,
109
                        Color.black,
110
                        Color.darkGray,
111
                        Color.gray,
112
                        Color.magenta,
113
                        Color.yellow,
114
                        Color.orange};
115

    
116
        /**
117
         * Guardamos el histogramable para hacer el histogramProcess
118
         */
119
        HistogramComputer histogramable = null;
120

    
121
        /**
122
         * Constructor. Asigna el panel del histograma
123
         * @param p Panel
124
         */
125
        public HistogramPanelListener(HistogramPanel histogramPanel) {
126
                this.histogramPanel = histogramPanel;
127
        }
128

    
129
        /**
130
         * Obtiene el panel del histograma
131
         * @return HistogramPanel
132
         */
133
        private HistogramPanel getHistogramPanel() {
134
                return histogramPanel;
135
        }
136

    
137
        /**
138
         * Asigna la capa para obtener las fuentes de datos tanto del
139
         * datasource como de la visualizaci?n.
140
         * @param lyr Capa
141
         */
142
        public void setLayer(FLyrRaster lyr) {
143
                this.lyr = lyr;
144
        }
145

    
146
        public void setControlListeners() {
147
                getHistogramPanel().getGraphicContainer().addValueChangedListener(this);
148
        }
149

    
150
        /**
151
         * Actualizar cuadro de estad?sticas
152
         */
153
        private void updateStatistic() {
154
                if (getLastHistogram() == null) {
155
                        getHistogramPanel().setStatistic(null);
156
                        return;
157
                }
158

    
159
                double first = getHistogramPanel().getGraphicContainer().getX1();
160
                double end = getHistogramPanel().getGraphicContainer().getX2();
161

    
162
                getHistogramPanel().setStatistic(getLastHistogram().getBasicStats(first, end, showBands));
163
        }
164

    
165
        /**
166
         * Tratamiento de todos los eventos visuales.
167
         */
168
        @SuppressWarnings("unchecked")
169
        public void actionPerformed(ActionEvent e) {
170
                if (!eventsEnabled) return;
171

    
172
                // Boton de desmarcar todas las bandas
173
                if (e.getSource() == getHistogramPanel().getButtonClean()) {
174
                        getHistogramPanel().refreshBands(false);
175
                        for (int i = 0; i < showBands.length; i++)
176
                                showBands[i] = false;
177
                        updateStatistic();
178
                        updateGraphic();
179
                        return;
180
                }
181

    
182
                // Boton de marcar todas las bandas
183
                if (e.getSource() == getHistogramPanel().getButtonShowAll()) {
184
                        getHistogramPanel().refreshBands(true);
185
                        for (int i = 0; i < showBands.length; i++)
186
                                showBands[i] = true;
187
                        updateStatistic();
188
                        updateGraphic();
189
                        return;
190
                }
191

    
192
                //--------------------------------------
193
                //Selecci?n de fuente de datos del histograma
194
                JComboBox cbo = getHistogramPanel().getComboBoxSource();
195
                if (e.getSource() == cbo) {
196
                        ArrayList comboSource = getHistogramPanel().getComboSource();
197
                        for (int i = 0; i < comboSource.size(); i++) {
198
                                String name = (String) ((ArrayList) comboSource.get(i)).get(1);
199
                                if (cbo.getSelectedItem().equals(name) && 
200
                                        name.compareTo(RasterToolsUtil.getText(this, "datos_visualizados")) == 0) {
201
                                        ((ArrayList) comboSource.get(i)).remove(0);
202
                                        try {
203
                                                ((ArrayList) comboSource.get(i)).add(0, ((FLyrRaster) lyr).getRender().getLastRenderBuffer().getHistogramComputer());
204
                                        } catch (QueryException e1) {
205
                                                RasterSwingLibrary.messageBoxError("histogram_error", getHistogramPanel(), e1);
206
                                        } catch (ProcessInterruptedException e1) {
207
                                        }
208

    
209
                                }
210
                                if (cbo.getSelectedItem().equals(name) && 
211
                                        name.compareTo(RasterToolsUtil.getText(this, "imagen_completa")) == 0) {
212
                                        ((ArrayList) comboSource.get(i)).remove(0);
213
                                        ((ArrayList) comboSource.get(i)).add(0, ((FLyrRaster) lyr).getDataStore().getHistogramComputer());
214
                                }
215
                        }
216
                        showHistogram();
217
                        return;
218
                }
219

    
220
                // Checkbox de eliminas extremos
221
                if (e.getSource() == getHistogramPanel().getCheckBoxDeleteEdges()) {
222
                        updateGraphic();
223
                        return;
224
                }
225

    
226
                // Checkbox de RGB
227
                if (e.getSource() == getHistogramPanel().getCheckBoxRGB()) {
228
                        selectHistogram();
229
                        updateStatistic();
230
                        updateGraphic();
231
                        return;
232
                }
233

    
234
                //--------------------------------------
235
                //Selecci?n de histograma acumulado y no acumulado
236
                JComboBox cbt = getHistogramPanel().getComboBoxType();
237
                if (e.getSource() == cbt) {
238
                        getHistogramPanel().getGraphicContainer().getPGraphic().setViewType(getHistogramPanel().getComboBoxType().getSelectedIndex());
239
                        return;
240
                }
241

    
242
                //--------------------------------------
243
                // Boton Crear Tabla
244
                JButton table = getHistogramPanel().getBCreateTable();
245
                if (e.getSource() == table) {
246
                        
247
                                //-------Mostrar un fileChooser------------------
248
                                String fName;
249
                                JFileChooser chooser = new JFileChooser();
250
                                chooser.setDialogTitle(RasterToolsUtil.getText(this, "guardar_tabla"));
251

    
252
                                int returnVal = chooser.showOpenDialog(getHistogramPanel());
253
                                if (returnVal == JFileChooser.APPROVE_OPTION) {
254
                                        fName = chooser.getSelectedFile().toString();
255
                                        if (!fName.endsWith(".dbf"))
256
                                                fName += ".dbf";
257

    
258
                                        //-------------Crear el dbf----------------------
259

    
260
                                        HistogramClass[][] histogram = getLastHistogram().getHistogram();
261
                                        int numBands = histogram.length;
262
                                        int numRecors = histogram[0].length;
263

    
264
                                        File file = new File(fName);
265

    
266
                                        String names[] = new String[numBands + 2];
267
                                        int types[] = new int [numBands + 2];
268
                                        int lengths[] = new int [numBands + 2];
269

    
270
                                        names[0] = "Min";
271
                                        types[0] = DataTypes.DOUBLE;
272
                                        lengths[0] = 15;
273
                                        
274
                                        names[1] = "Max";
275
                                        types[1] = DataTypes.DOUBLE;
276
                                        lengths[1] = 15;
277
                                        
278
                                        for (int band = 0; band < numBands; band++) {
279
                                                names[band + 2] = "Band" + band;
280
                                                types[band + 2] = DataTypes.DOUBLE;
281
                                                lengths[band + 2] = 15;
282
                                        }
283
                                        FeatureStore store = null;
284
                                        
285
                                        try {
286
                                                DataManager manager = DALLocator.getDataManager();
287
                                                DataServerExplorerParameters eparams = manager.createServerExplorerParameters("FilesystemExplorer");
288
                                                eparams.setDynValue("initialpath", "/data");
289
                                                DataServerExplorer serverExplorer = manager.openServerExplorer("FilesystemExplorer", eparams);
290

    
291
                                                NewFeatureStoreParameters sparams = (NewFeatureStoreParameters)serverExplorer.getAddParameters("DBF");
292
                                                ((FilesystemStoreParameters) sparams).setFile(file);
293
                                                
294
                                                EditableFeatureType featureType = sparams.getDefaultFeatureType();
295
                                                
296
                                                //Creating table structure
297
                                                for (int i = 0; i < names.length; i++) {
298
                                                        featureType.add(names[i], types[i], lengths[i]);
299
                                                }
300
                                                
301
                                                manager.newStore("FilesystemExplorer", "DBF", sparams, true);
302
                                                store = (FeatureStore)manager.openStore(sparams.getDataStoreName(), sparams);
303

    
304
                                                //Loading data
305
                                                store.edit();
306
                                                
307
                                                for (int j = 0; j < numRecors; j++) {
308
                                                        EditableFeature feature = store.createNewFeature();
309
                                                        feature.set(names[0], histogram[0][j].getMin());
310
                                                        feature.set(names[1], histogram[0][j].getMax());
311

    
312
                                                        for (int r = 0; r < numBands; r++) {
313
                                                                feature.set(names[r + 2], histogram[r][j].getValue());
314
                                                        }
315
                                                        store.insert(feature);
316
                                                }
317

    
318
                                                store.finishEditing();
319
                                        } catch (DataException e1) {
320
                                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
321
                                        } catch (ValidateDataParametersException e2) {
322
                                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
323
                                        }
324
                                        
325
                                        //------------A?adir el dbf al proyecto--------------
326
                                        
327
                                        ApplicationManager application = ApplicationLocator.getManager(); 
328
                                        TableDocument tableDocument = (TableDocument)application.getProjectManager().createDocument(TableManager.TYPENAME, 
329
                                                        "Histogram_"+lyr.getName());
330
                                        tableDocument.setStore(store);
331
                                        application.getCurrentProject().add(tableDocument);
332
                                        tableDocument.getFactory().getMainWindow(tableDocument);
333
                                }
334
                }
335
        }
336

    
337
        /**
338
         * Actualizar la variable de las bandas visibles y su componente visual.
339
         */
340
        private void refreshBands() {
341
                getHistogramPanel().refreshBands(true);
342
                if (getLastHistogram() == null)
343
                        showBands = new boolean[0];
344
                else
345
                        showBands = new boolean[getLastHistogram().getNumBands()];
346
                for (int i = 0; i < showBands.length; i++)
347
                        showBands[i] = true;
348
        }
349

    
350
        /**
351
         * Lanza los dos threads para procesar el histograma y visualizar la
352
         * ventana de incremento
353
         */
354
        @SuppressWarnings("unchecked")
355
        public void showHistogram() {
356
                if (getHistogramPanel().getComboBoxSource().getSelectedIndex() < 0)
357
                        return;
358

    
359
                int dataSrc = getHistogramPanel().getComboBoxSource().getSelectedIndex();
360
                histogramable = (HistogramComputer) ((ArrayList) getHistogramPanel().getComboSource().get(dataSrc)).get(0);
361

    
362
                if (getLastHistogram() == null) {
363
                        try {
364
                                if (histogramable != null)
365
                                        setNewHistogram(histogramable.getBufferHistogram());
366
                                else
367
                                        setNewHistogram(null);
368
                        } catch (HistogramException e) {
369
                                RasterSwingLibrary.messageBoxError("histogram_error", getHistogramPanel(), e);
370
                                return;
371
                        } catch (ProcessInterruptedException e) {
372
                                
373
                        } 
374
                        return;
375
                }
376

    
377
                // Calculo las estadisticas para luego hacer el proceso del histograma.
378
                // El parametro object es el que se le pasara al siguiente proceso
379
                // Mirar el metodo end()
380
                StatisticsProcess statisticsProcess = new StatisticsProcess();
381
                statisticsProcess.setActions(this);
382
                statisticsProcess.addParam("layer", lyr);
383
                statisticsProcess.addParam("force", Boolean.FALSE);
384
                statisticsProcess.start();
385
        }
386
        
387
        /*
388
         * (non-Javadoc)
389
         * @see org.gvsig.rastertools.IProcessActions#end(java.lang.Object)
390
         */
391
        public void end(Object object) {
392
                // Si tenemos un histograma en el parametro, es que ya ha finalizado el proceso
393
                if (object instanceof BufferHistogram) {
394
                        setNewHistogram((BufferHistogram) object);
395
                        return;
396
                }
397

    
398
                // Si no tenemos un histograma, osease, tenemos un layer, 
399
                // es que aun necesitamos calcularlo
400
                if (object instanceof FLyrRaster) {
401
                        if (histogramable != null) {
402
                                HistogramProcess histogramProcess = new HistogramProcess();
403
                                histogramProcess.setActions(this);
404
                                histogramProcess.addParam("histogramable", histogramable);
405
                                histogramProcess.start();
406
                        } else {
407
                                setNewHistogram(null);
408
                        }
409
                }
410
        }
411

    
412
        /**
413
         * Actualiza la grafica con los datos que ya teniamos del histograma.
414
         */
415
        private void updateGraphic() {
416
                if (getLastHistogram() == null) {
417
                        getHistogramPanel().getGraphicContainer().getPGraphic().cleanChart();
418
                        return;
419
                }
420

    
421
                HistogramClass[][] histogramClass = getLastHistogram().getHistogram();
422
                if (histogramClass == null)
423
                        return;
424

    
425
                double[][][] datos = new double[histogramClass.length][histogramClass[0].length][2];
426
                for (int iBand = 0; iBand < histogramClass.length; iBand++) {
427
                        for (int i = 0; i < histogramClass[iBand].length; i++) {
428
                                datos[iBand][i][0] = histogramClass[iBand][i].getMin();
429
                                datos[iBand][i][1] = histogramClass[iBand][i].getValue();
430
                        }
431
                }
432

    
433
                // Definimos el principio y final de la grafica, sirve para descartar valores.
434
                int first = (int) getHistogramPanel().getBoxValueX1();
435
                int end = (int) getHistogramPanel().getBoxValueX2();
436
                //first = 0;
437
                //end = 100;
438

    
439
                int min = 0;
440
                int max = histogramClass[0].length - 1;
441

    
442
                first = min + ((first * (max - min))/ 100);
443
                end = min + ((end * (max - min))/ 100);
444

    
445
                // Si hay que eliminar los limites, quitamos el ultimo y primer valor de la grafica
446
                if (getHistogramPanel().getCheckBoxDeleteEdges().isSelected()) {
447
                        if ((first + 1) <= end)
448
                                first++;
449
                        if ((end - 1) >= first)
450
                                end--;
451
                }
452

    
453
                int bandCount = 0;
454
                for (int i = 0; i < showBands.length; i++)
455
                        if (showBands[i])
456
                                bandCount++;
457

    
458
                double[][][] newHistogram = new double[bandCount][end - first + 1][2];
459
                String[] bandNames = new String[bandCount];
460

    
461
                int numBand = 0;
462
                for (int iBand = 0; iBand < showBands.length; iBand++) {
463
                        if (!showBands[iBand])
464
                                continue;
465
                        for (int j = first; j <= end; j++) {
466
                                try {
467
                                        newHistogram[numBand][j - first][0] = datos[iBand][j][0];
468
                                        newHistogram[numBand][j - first][1] = datos[iBand][j][1];
469
                                } catch (ArrayIndexOutOfBoundsException e) {
470
                                        RasterSwingLibrary.messageBoxError("Error al crear el array del histograma. DataType: " + getHistogramPanel().getDataType() + " Posici?n: " + j, this, e);
471
                                }
472
                        }
473
                        bandNames[numBand] = (String) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(iBand, 1);
474

    
475
                        getHistogramPanel().getGraphicContainer().setBandColor(numBand, bandsColor[iBand % bandsColor.length]);
476

    
477
                        numBand++;
478
                }
479

    
480
                getHistogramPanel().getGraphicContainer().getPGraphic().setNewChart(newHistogram, bandNames);
481
        }
482

    
483

    
484
        public void selectHistogram() {
485
                if (getHistogramPanel().getCheckBoxRGB().isSelected())
486
                        lastHistogram = lastHistogramRGB;
487
                else
488
                        lastHistogram = lastHistogramReal;
489
        }
490
        /**
491
         * Definir el nuevo histograma, metodo pu?blico para ser invocado desde
492
         * histogramProcess
493
         * @param histograma nuevo
494
         */
495
        public void setNewHistogram(BufferHistogram histogram) {
496
                getHistogramPanel().panelInizialited = false;
497
                eventsEnabled = false;
498

    
499
                this.lastHistogramReal = histogram;
500
                this.lastHistogramRGB = RasterLocator.getManager().getRasterUtils().convertHistogramToRGB(lastHistogramReal);
501
                selectHistogram();
502

    
503
                refreshBands();
504
                updateStatistic();
505
                updateGraphic();
506

    
507
                // Activo la ejecucion de los eventos porque seguro que ya tenemos un histograma
508
                eventsEnabled = true;
509
                getHistogramPanel().panelInizialited = true;
510
        }
511

    
512
        /**
513
         * Obtener ?ltimo histograma
514
         * @return Histogram
515
         */
516
        public BufferHistogram getLastHistogram() {
517
                return lastHistogram;
518
        }
519

    
520
        /**
521
         * Eventos de los BoxValues
522
         */
523
        public void actionValueChanged(GraphicEvent e) {
524
                updateStatistic();
525
                updateGraphic();
526
        }
527

    
528
        /**
529
         *  Cuando se selecciona/deselecciona una banda
530
         */
531
        public void propertyChange(PropertyChangeEvent evt) {
532
                if (!eventsEnabled)
533
                        return;
534
                int countRow = ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getRowCount();
535
                for (int i = 0; i < countRow; i++)
536
                        showBands[i] = ((Boolean) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(i, 0)).booleanValue();
537

    
538
                updateStatistic();
539
                updateGraphic();
540
        }
541

    
542
        public void interrupted() {}
543
}