Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tools / trunk / org.gvsig.raster.tools / org.gvsig.raster.tools.app / org.gvsig.raster.tools.app.basic / src / main / java / org / gvsig / raster / tools / app / basic / tool / histogram / HistogramPanelListener.java @ 1676

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.InvalidSetViewException;
48
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
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.tools.app.basic.RasterToolsUtil;
62
import org.gvsig.raster.tools.app.basic.raster.process.HistogramProcess;
63
import org.gvsig.raster.tools.app.basic.raster.process.IProcessActions;
64
import org.gvsig.raster.tools.app.basic.raster.process.StatisticsProcess;
65
import org.gvsig.raster.tools.app.basic.tool.histogram.ui.HistogramPanel;
66
import org.gvsig.tools.dataTypes.DataTypes;
67
/**
68
 * Listener para eventos del panel de histograma
69
 *
70
 * @version 20/03/2007
71
 * @author Nacho Brodin (brodin_ign@gva.es)
72
 * @author BorSanZa - Borja Sanchez Zamorano (borja.sanchez@iver.es)
73
 */
74
public class HistogramPanelListener implements GraphicListener, ActionListener, PropertyChangeListener, IProcessActions {
75
        private HistogramPanel histogramPanel    = null;
76

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

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

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

    
92
        public boolean         eventsEnabled     = false;
93

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
259
                                        //-------------Crear el dbf----------------------
260

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

    
265
                                        File file = new File(fName);
266

    
267
                                        String names[] = new String[numBands + 1];
268
                                        int types[] = new int [numBands + 1];
269
                                        int lengths[] = new int [numBands + 1];
270

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

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

    
300
                                                //Loading data
301
                                                store.edit();
302
                                                
303
                                                for (int j = 0; j < numRecors; j++) {
304
                                                        EditableFeature feature = store.createNewFeature();
305
                                                        feature.set(names[0], j);
306
                                                        
307
                                                        for (int r = 0; r < numBands; r++) {
308
                                                                feature.set(names[r + 1], histogram[r][j].getValue());
309
                                                        }
310
                                                        store.insert(feature);
311
                                                }
312
                                                
313
                                                store.finishEditing();
314
                                        } catch (DataException e1) {
315
                                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
316
                                        } catch (ValidateDataParametersException e2) {
317
                                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
318
                                        }
319
                                        
320
                                        //------------A?adir el dbf al proyecto--------------
321
                                        
322
                                        ApplicationManager application = ApplicationLocator.getManager(); 
323
                                        TableDocument tableDocument = (TableDocument)application.getProjectManager().createDocument(TableManager.TYPENAME, 
324
                                                        "Histogram_"+lyr.getName());
325
                                        tableDocument.setStore(store);
326
                                        application.getCurrentProject().add(tableDocument);
327
                                        tableDocument.getFactory().getMainWindow(tableDocument);
328
                                }
329
                }
330
        }
331

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

    
345
        /**
346
         * Lanza los dos threads para procesar el histograma y visualizar la
347
         * ventana de incremento
348
         */
349
        @SuppressWarnings("unchecked")
350
        public void showHistogram() {
351
                if (getHistogramPanel().getComboBoxSource().getSelectedIndex() < 0)
352
                        return;
353

    
354
                int dataSrc = getHistogramPanel().getComboBoxSource().getSelectedIndex();
355
                histogramable = (HistogramComputer) ((ArrayList) getHistogramPanel().getComboSource().get(dataSrc)).get(0);
356

    
357
                if (getLastHistogram() == null) {
358
                        try {
359
                                if (histogramable != null)
360
                                        setNewHistogram(histogramable.getBufferHistogram());
361
                                else
362
                                        setNewHistogram(null);
363
                        } catch (HistogramException e) {
364
                                RasterToolsUtil.messageBoxError("histogram_error", getHistogramPanel(), e);
365
                                return;
366
                        } catch (ProcessInterruptedException e) {
367
                                
368
                        } 
369
                        return;
370
                }
371

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

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

    
407
        /**
408
         * Actualiza la grafica con los datos que ya teniamos del histograma.
409
         */
410
        private void updateGraphic() {
411
                if (getLastHistogram() == null) {
412
                        getHistogramPanel().getGraphicContainer().getPGraphic().cleanChart();
413
                        return;
414
                }
415

    
416
                HistogramClass[][] histogramClass = getLastHistogram().getHistogram();
417
                if (histogramClass == null)
418
                        return;
419

    
420
                double[][][] datos = new double[histogramClass.length][histogramClass[0].length][2];
421
                for (int iBand = 0; iBand < histogramClass.length; iBand++) {
422
                        for (int i = 0; i < histogramClass[iBand].length; i++) {
423
                                datos[iBand][i][0] = histogramClass[iBand][i].getMin();
424
                                datos[iBand][i][1] = histogramClass[iBand][i].getValue();
425
                        }
426
                }
427

    
428
                // Definimos el principio y final de la grafica, sirve para descartar valores.
429
                int first = (int) getHistogramPanel().getBoxValueX1();
430
                int end = (int) getHistogramPanel().getBoxValueX2();
431
                //first = 0;
432
                //end = 100;
433

    
434
                int min = 0;
435
                int max = histogramClass[0].length - 1;
436

    
437
                first = min + ((first * (max - min))/ 100);
438
                end = min + ((end * (max - min))/ 100);
439

    
440
                // Si hay que eliminar los limites, quitamos el ultimo y primer valor de la grafica
441
                if (getHistogramPanel().getCheckBoxDeleteEdges().isSelected()) {
442
                        if ((first + 1) <= end)
443
                                first++;
444
                        if ((end - 1) >= first)
445
                                end--;
446
                }
447

    
448
                int bandCount = 0;
449
                for (int i = 0; i < showBands.length; i++)
450
                        if (showBands[i])
451
                                bandCount++;
452

    
453
                double[][][] newHistogram = new double[bandCount][end - first + 1][2];
454
                String[] bandNames = new String[bandCount];
455

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

    
470
                        getHistogramPanel().getGraphicContainer().setBandColor(numBand, bandsColor[iBand % bandsColor.length]);
471

    
472
                        numBand++;
473
                }
474

    
475
                getHistogramPanel().getGraphicContainer().getPGraphic().setNewChart(newHistogram, bandNames);
476
        }
477

    
478

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

    
494
                this.lastHistogramReal = histogram;
495
                this.lastHistogramRGB = RasterLocator.getManager().getRasterUtils().convertHistogramToRGB(lastHistogramReal);
496
                selectHistogram();
497

    
498
                refreshBands();
499
                updateStatistic();
500
                updateGraphic();
501

    
502
                // Activo la ejecucion de los eventos porque seguro que ya tenemos un histograma
503
                eventsEnabled = true;
504
                getHistogramPanel().panelInizialited = true;
505
        }
506

    
507
        /**
508
         * Obtener ?ltimo histograma
509
         * @return Histogram
510
         */
511
        public BufferHistogram getLastHistogram() {
512
                return lastHistogram;
513
        }
514

    
515
        /**
516
         * Eventos de los BoxValues
517
         */
518
        public void actionValueChanged(GraphicEvent e) {
519
                updateStatistic();
520
                updateGraphic();
521
        }
522

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

    
533
                updateStatistic();
534
                updateGraphic();
535
        }
536

    
537
        public void interrupted() {}
538
}