Statistics
| Revision:

root / trunk / extensions / extRasterTools-SE / src / org / gvsig / rastertools / histogram / HistogramPanelListener.java @ 19454

History | View | Annotate | Download (17.1 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.rastertools.histogram;
20

    
21
import java.awt.Color;
22
import java.awt.Component;
23
import java.awt.event.ActionEvent;
24
import java.awt.event.ActionListener;
25
import java.beans.PropertyChangeEvent;
26
import java.beans.PropertyChangeListener;
27
import java.io.File;
28
import java.io.IOException;
29
import java.io.RandomAccessFile;
30
import java.nio.channels.FileChannel;
31
import java.nio.channels.WritableByteChannel;
32
import java.util.ArrayList;
33

    
34
import javax.swing.JButton;
35
import javax.swing.JComboBox;
36
import javax.swing.JFileChooser;
37
import javax.swing.JOptionPane;
38
import javax.swing.table.DefaultTableModel;
39

    
40
import org.apache.log4j.Logger;
41
import org.gvsig.fmap.raster.layers.FLyrRasterSE;
42
import org.gvsig.gui.beans.graphic.GraphicEvent;
43
import org.gvsig.gui.beans.graphic.GraphicListener;
44
import org.gvsig.raster.IProcessActions;
45
import org.gvsig.raster.datastruct.Histogram;
46
import org.gvsig.raster.datastruct.HistogramClass;
47
import org.gvsig.raster.datastruct.HistogramException;
48
import org.gvsig.raster.hierarchy.IHistogramable;
49
import org.gvsig.raster.util.RasterToolsUtil;
50
import org.gvsig.rastertools.histogram.ui.HistogramPanel;
51
import org.gvsig.rastertools.statistics.StatisticsProcess;
52

    
53
import com.hardcode.driverManager.DriverLoadException;
54
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
55
import com.hardcode.gdbms.engine.data.DataSource;
56
import com.hardcode.gdbms.engine.data.DataSourceFactory;
57
import com.hardcode.gdbms.engine.data.NoSuchTableException;
58
import com.hardcode.gdbms.engine.values.Value;
59
import com.hardcode.gdbms.engine.values.ValueFactory;
60
import com.iver.andami.PluginServices;
61
import com.iver.cit.gvsig.ProjectExtension;
62
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileHeaderNIO;
63
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileWriterNIO;
64
import com.iver.cit.gvsig.fmap.edition.EditableAdapter;
65
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
66
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
67
import com.iver.cit.gvsig.project.ProjectFactory;
68
import com.iver.cit.gvsig.project.documents.table.ProjectTable;
69
import com.iver.cit.gvsig.project.documents.table.gui.Table;
70
/**
71
 * Listener para eventos del panel de histograma
72
 *
73
 * @version 20/03/2007
74
 * @author Nacho Brodin (brodin_ign@gva.es)
75
 * @author BorSanZa - Borja Sanchez Zamorano (borja.sanchez@iver.es)
76
 */
77
public class HistogramPanelListener implements GraphicListener, ActionListener, PropertyChangeListener, IProcessActions {
78
        private HistogramPanel histogramPanel    = null;
79

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

    
85
        /**
86
         * Histograma original sin convertir a RGB
87
         */
88
        private Histogram      lastHistogramReal = null;
89

    
90
        /**
91
         * Histograma convertido a rango RGB
92
         */
93
        private Histogram      lastHistogramRGB  = null;
94

    
95
        public boolean         eventsEnabled     = false;
96

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

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

    
118
        /**
119
         * Guardamos el histogramable para hacer el histogramProcess
120
         */
121
        IHistogramable histogramable = null;
122

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

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

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

    
148
        public void setControlListeners() {
149
                getHistogramPanel().getGraphicContainer().addValueChangedListener(this);
150
        }
151

    
152
        /**
153
         * Actualizar cuadro de estad?sticas
154
         */
155
        private void updateStatistic() {
156
                if (getLastHistogram() == null)
157
                        return;
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
        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(name.compareTo(PluginServices.getText(this, "datos_visualizados")) == 0) {
199
                                        ((ArrayList)comboSource.get(i)).remove(0);
200
                                        ((ArrayList)comboSource.get(i)).add(0, ((FLyrRasterSE) lyr).getRender().getLastRenderBuffer());
201
                                }
202
                                if(name.compareTo(PluginServices.getText(this, "imagen_completa")) == 0) {
203
                                        ((ArrayList)comboSource.get(i)).remove(0);
204
                                        ((ArrayList)comboSource.get(i)).add(0, ((FLyrRasterSE) lyr).getDataSource());
205
                                }
206

    
207
                        }
208
                        showHistogram();
209
                        return;
210
                }
211

    
212
                // Checkbox de eliminas extremos
213
                if (e.getSource() == getHistogramPanel().getCheckBoxDeleteEdges()) {
214
                        updateGraphic();
215
                        return;
216
                }
217

    
218
                // Checkbox de RGB
219
                if (e.getSource() == getHistogramPanel().getCheckBoxRGB()) {
220
                        selectHistogram();
221
                        updateGraphic();
222
                        updateStatistic();
223
                        return;
224
                }
225

    
226
                //--------------------------------------
227
                //Selecci?n de histograma acumulado y no acumulado
228
                JComboBox cbt = getHistogramPanel().getComboBoxType();
229
                if (e.getSource() == cbt) {
230
                        updateStatistic();
231
                        updateGraphic();
232
                        return;
233
                }
234

    
235
                //--------------------------------------
236
                // Boton Crear Tabla
237
                JButton table = getHistogramPanel().getBCreateTable();
238
                if (e.getSource() == table) {
239
                        try {
240
//                        -------Mostrar un fileChooser------------------
241
                                String fName;
242
                                JFileChooser chooser = new JFileChooser();
243
                                chooser.setDialogTitle(PluginServices.getText(this, "guardar_tabla"));
244

    
245
                                int returnVal = chooser.showOpenDialog(getHistogramPanel());
246
                                if (returnVal == JFileChooser.APPROVE_OPTION) {
247
                                        fName = chooser.getSelectedFile().toString();
248
                                        if (!fName.endsWith(".dbf"))
249
                                                fName += ".dbf";
250

    
251
                                        //-------------Crear el dbf----------------------
252

    
253
                                        DbaseFileWriterNIO dbfWrite = null;
254
                                        DbaseFileHeaderNIO myHeader;
255
                                        Value[] record;
256

    
257
                                        HistogramClass[][] histogram = getLastHistogram().getHistogram();
258
                                        int numBands = histogram.length;
259
                                        int numRecors = histogram[0].length;
260

    
261
                                        File file = new File(fName);
262

    
263
                                        String names[] = new String[numBands+1];
264
                                        int types[] = new int [numBands+1];
265
                                        int lengths[] = new int [numBands+1];
266

    
267
                                        names[0]="Value";
268
                                        types[0]=4;
269
                                        lengths[0]=15;
270
                                        for (int band = 0; band < numBands; band++){
271
                                                names[band+1]="Band"+band;
272
                                                types[band+1]=4;
273
                                                lengths[band+1]=15;
274
                                        }
275

    
276
                                        myHeader = DbaseFileHeaderNIO.createDbaseHeader(names,types,lengths);
277

    
278
                                        myHeader.setNumRecords(numRecors);
279
                                        dbfWrite = new DbaseFileWriterNIO(myHeader, (FileChannel) getWriteChannel(file.getPath()));
280
                                        record = new Value[numBands+1];
281

    
282
                                        for (int j = 0; j < numRecors; j++) {
283
                                                record[0] = ValueFactory.createValue(j);
284
                                                for (int r = 0; r < numBands; r++) {
285
                                                        record[r+1] = ValueFactory.createValue(histogram[r][j].getValue());
286
                                                }
287

    
288
                                                dbfWrite.write(record);
289
                                        }
290

    
291
                                        dbfWrite.close();
292

    
293
                                        //------------A?adir el dbf al proyecto--------------
294
                                        ProjectExtension ext = (ProjectExtension) PluginServices.getExtension(ProjectExtension.class);
295
                                        String name = file.getName();
296
                                        LayerFactory.getDataSourceFactory().addFileDataSource("gdbms dbf driver", name, fName);
297
                                        DataSource dataSource;
298
                                        dataSource = LayerFactory.getDataSourceFactory().createRandomDataSource(name, DataSourceFactory.AUTOMATIC_OPENING);
299

    
300
                                        SelectableDataSource sds = new SelectableDataSource(dataSource);
301
                                        EditableAdapter auxea=new EditableAdapter();
302
                                        auxea.setOriginalDataSource(sds);
303
                                        ProjectTable projectTable = ProjectFactory.createTable(name, auxea);
304
                                        //ext.getProject().addTable(projectTable);
305
                                        ext.getProject().addDocument(projectTable);
306

    
307
                                        Table t = new Table();
308
                                        t.setModel(projectTable);
309
                                        //projectTable.setAndamiWindow(t);
310
                                        PluginServices.getMDIManager().addWindow(t);
311
                                }
312
                        } catch (IOException e1) {
313
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
314
                        } catch (DriverLoadException e1) {
315
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
316
                        } catch (NoSuchTableException e1) {
317
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
318
                        } catch (ReadDriverException e1) {
319
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
320
                        }
321
                }
322
        }
323

    
324
        /**
325
         * Actualizar la variable de las bandas visibles y su componente visual.
326
         */
327
        private void refreshBands() {
328
                getHistogramPanel().refreshBands(true);
329
                showBands = new boolean[getLastHistogram().getNumBands()];
330
                for (int i = 0; i < showBands.length; i++)
331
                        showBands[i] = true;
332
        }
333

    
334
        /**
335
         * Lanza los dos threads para procesar el histograma y visualizar la
336
         * ventana de incremento
337
         */
338
        public void showHistogram() {
339
                if (getHistogramPanel().getComboBoxSource().getSelectedIndex() < 0)
340
                        return;
341

    
342
                int dataSrc = getHistogramPanel().getComboBoxSource().getSelectedIndex();
343
                histogramable = (IHistogramable) ((ArrayList) getHistogramPanel().getComboSource().get(dataSrc)).get(0);
344

    
345
                if (getLastHistogram() == null) {
346
                        try {
347
                                setNewHistogram(histogramable.getHistogram());
348
                        } catch (HistogramException e) {
349
                                RasterToolsUtil.messageBoxError("histogram_error", getHistogramPanel(), e);
350
                                return;
351
                        } catch (InterruptedException e) {
352

    
353
                        }
354
                        return;
355
                }
356

    
357
                // Calculo las estadisticas para luego hacer el proceso del histograma.
358
                // El parametro object es el que se le pasara al siguiente proceso
359
                // Mirar el metodo end()
360
                StatisticsProcess statisticsProcess = new StatisticsProcess();
361
                statisticsProcess.setActions(this);
362
                statisticsProcess.addParam("layer", lyr);
363
                statisticsProcess.addParam("force", Boolean.FALSE);
364
                statisticsProcess.start();
365
        }
366
        
367
        /*
368
         * (non-Javadoc)
369
         * @see org.gvsig.rastertools.IProcessActions#end(java.lang.Object)
370
         */
371
        public void end(Object object) {
372
                // Si tenemos un histograma en el parametro, es que ya ha finalizado el proceso
373
                if (object instanceof Histogram) {
374
                        setNewHistogram((Histogram) object);
375
                        return;
376
                }
377

    
378
                // Si no tenemos un histograma, es que aun necesitamos calcularlo
379
                if (object == null) {
380
                        HistogramProcess histogramProcess = new HistogramProcess();
381
                        histogramProcess.setActions(this);
382
                        histogramProcess.addParam("histogramable", histogramable);
383
                        histogramProcess.start();
384
                }
385
        }
386

    
387
        /**
388
         * Actualiza la grafica con los datos que ya teniamos del histograma.
389
         */
390
        private void updateGraphic() {
391
                if (getLastHistogram() == null)
392
                        return;
393

    
394
                HistogramClass[][] histogramClass = getLastHistogram().getHistogramByType(Histogram.getType(getHistogramPanel().getComboBoxType().getSelectedIndex()));
395
                if (histogramClass == null)
396
                        return;
397

    
398
                double[][][] datos = new double[histogramClass.length][histogramClass[0].length][2];
399
                for (int iBand = 0; iBand < histogramClass.length; iBand++) {
400
                        for (int i = 0; i < histogramClass[iBand].length; i++) {
401
                                datos[iBand][i][0] = histogramClass[iBand][i].getMin();
402
                                datos[iBand][i][1] = histogramClass[iBand][i].getValue();
403
                        }
404
                }
405

    
406
                // Definimos el principio y final de la grafica, sirve para descartar valores.
407
                int first = (int) getHistogramPanel().getBoxValueX1();
408
                int end = (int) getHistogramPanel().getBoxValueX2();
409
                //first = 0;
410
                //end = 100;
411

    
412
                int min = 0;
413
                int max = histogramClass[0].length - 1;
414

    
415
                first = min + ((first * (max - min))/ 100);
416
                end = min + ((end * (max - min))/ 100);
417

    
418
                // Si hay que eliminar los limites, quitamos el ultimo y primer valor de la grafica
419
                if (getHistogramPanel().getCheckBoxDeleteEdges().isSelected()) {
420
                        if ((first + 1) <= end)
421
                                first++;
422
                        if ((end - 1) >= first)
423
                                end--;
424
                }
425

    
426
                int bandCount = 0;
427
                for (int i = 0; i < showBands.length; i++)
428
                        if (showBands[i])
429
                                bandCount++;
430

    
431
                double[][][] newHistogram = new double[bandCount][end - first + 1][2];
432
                String[] bandNames = new String[bandCount];
433

    
434
                int numBand = 0;
435
                for (int iBand = 0; iBand < showBands.length; iBand++) {
436
                        if (!showBands[iBand])
437
                                continue;
438
                        for (int j = first; j <= end; j++) {
439
                                try {
440
                                        newHistogram[numBand][j - first][0] = datos[iBand][j][0];
441
                                        newHistogram[numBand][j - first][1] = datos[iBand][j][1];
442
                                } catch (ArrayIndexOutOfBoundsException e) {
443
                                        Logger.getLogger(getHistogramPanel().getClass().getName()).debug("Error al crear el array del histograma. DataType: " + getHistogramPanel().getDataType() + " Posici?n: " + j, e);
444
                                }
445
                        }
446
                        bandNames[numBand] = (String) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(iBand, 1);
447

    
448
                        getHistogramPanel().getGraphicContainer().setBandColor(numBand, bandsColor[iBand % bandsColor.length]);
449

    
450
                        numBand++;
451
                }
452

    
453
                getHistogramPanel().getGraphicContainer().getPGraphic().setNewChart(newHistogram, bandNames);
454
        }
455

    
456

    
457
        public void selectHistogram() {
458
                if (getHistogramPanel().getCheckBoxRGB().isSelected())
459
                        lastHistogram = lastHistogramRGB;
460
                else
461
                        lastHistogram = lastHistogramReal;
462
        }
463
        /**
464
         * Definir el nuevo histograma, metodo pu?blico para ser invocado desde
465
         * histogramProcess
466
         * @param histograma nuevo
467
         */
468
        public void setNewHistogram(Histogram histogram) {
469
                getHistogramPanel().panelInizialited = false;
470
                eventsEnabled = false;
471

    
472
                this.lastHistogramReal = histogram;;
473
                this.lastHistogramRGB = Histogram.convertHistogramToRGB(histogram);
474
                selectHistogram();
475

    
476
                refreshBands();
477
                updateGraphic();
478
                updateStatistic();
479

    
480
                // Activo la ejecucion de los eventos porque seguro que ya tenemos un histograma
481
                eventsEnabled = true;
482
                getHistogramPanel().panelInizialited = true;
483
        }
484

    
485
        /**
486
         * Obtener ?ltimo histograma
487
         * @return Histogram
488
         */
489
        public Histogram getLastHistogram() {
490
                return lastHistogram;
491
        }
492

    
493
        /**
494
         * Eventos de los BoxValues
495
         */
496
        public void actionValueChanged(GraphicEvent e) {
497
                updateGraphic();
498
                updateStatistic();
499
        }
500

    
501
        /**
502
         * Proceso para guardar una estadistica en un fichero.
503
         * @param path
504
         * @return
505
         * @throws IOException
506
         */
507
        private WritableByteChannel getWriteChannel(String path) throws IOException {
508
                WritableByteChannel channel;
509

    
510
                File f = new File(path);
511

    
512
                if (!f.exists()) {
513
                        if (!f.createNewFile()) {
514
                                throw new IOException("Cannot create file " + f);
515
                        }
516
                }
517

    
518
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
519
                channel = raf.getChannel();
520

    
521
                return channel;
522
        }
523

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

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

    
538
        public void interrupted() {}
539
}