Statistics
| Revision:

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

History | View | Annotate | Download (17.2 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.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.io.IOException;
28
import java.io.RandomAccessFile;
29
import java.nio.channels.FileChannel;
30
import java.nio.channels.WritableByteChannel;
31
import java.util.ArrayList;
32

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

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

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

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

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

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

    
94
        public boolean         eventsEnabled     = false;
95

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

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

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

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

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

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

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

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

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

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

    
166
        /**
167
         * Tratamiento de todos los eventos visuales.
168
         */
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 (name.compareTo(RasterToolsUtil.getText(this, "datos_visualizados")) == 0) {
200
                                        ((ArrayList) comboSource.get(i)).remove(0);
201
                                        ((ArrayList) comboSource.get(i)).add(0, ((FLyrRasterSE) lyr).getRender().getLastRenderBuffer());
202
                                }
203
                                if (name.compareTo(RasterToolsUtil.getText(this, "imagen_completa")) == 0) {
204
                                        ((ArrayList) comboSource.get(i)).remove(0);
205
                                        ((ArrayList) comboSource.get(i)).add(0, ((FLyrRasterSE) lyr).getDataSource());
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
                        updateStatistic();
222
                        updateGraphic();
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(RasterToolsUtil.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
                                        RasterToolsUtil.addWindow(t);
311
                                }
312
                        } catch (IOException e1) {
313
                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
314
                        } catch (DriverLoadException e1) {
315
                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
316
                        } catch (NoSuchTableException e1) {
317
                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.getText(this,"table_not_create"));
318
                        } catch (ReadDriverException e1) {
319
                                JOptionPane.showMessageDialog(null, getHistogramPanel().getName() + " " + RasterToolsUtil.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
                if (getLastHistogram() == null)
330
                        showBands = new boolean[0];
331
                else
332
                        showBands = new boolean[getLastHistogram().getNumBands()];
333
                for (int i = 0; i < showBands.length; i++)
334
                        showBands[i] = true;
335
        }
336

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

    
345
                int dataSrc = getHistogramPanel().getComboBoxSource().getSelectedIndex();
346
                histogramable = (IHistogramable) ((ArrayList) getHistogramPanel().getComboSource().get(dataSrc)).get(0);
347

    
348
                if (getLastHistogram() == null) {
349
                        try {
350
                                if (histogramable != null)
351
                                        setNewHistogram(histogramable.getHistogram());
352
                                else
353
                                        setNewHistogram(null);
354
                        } catch (HistogramException e) {
355
                                RasterToolsUtil.messageBoxError("histogram_error", getHistogramPanel(), e);
356
                                return;
357
                        } catch (InterruptedException e) {
358

    
359
                        }
360
                        return;
361
                }
362

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

    
384
                // Si no tenemos un histograma, es que aun necesitamos calcularlo
385
                if (object == null) {
386
                        if (histogramable != null) {
387
                                HistogramProcess histogramProcess = new HistogramProcess();
388
                                histogramProcess.setActions(this);
389
                                histogramProcess.addParam("histogramable", histogramable);
390
                                histogramProcess.start();
391
                        } else {
392
                                setNewHistogram(null);
393
                        }
394
                }
395
        }
396

    
397
        /**
398
         * Actualiza la grafica con los datos que ya teniamos del histograma.
399
         */
400
        private void updateGraphic() {
401
                if (getLastHistogram() == null) {
402
                        getHistogramPanel().getGraphicContainer().getPGraphic().cleanChart();
403
                        return;
404
                }
405

    
406
                HistogramClass[][] histogramClass = getLastHistogram().getHistogramByType(Histogram.getType(getHistogramPanel().getComboBoxType().getSelectedIndex()));
407
                if (histogramClass == null)
408
                        return;
409

    
410
                double[][][] datos = new double[histogramClass.length][histogramClass[0].length][2];
411
                for (int iBand = 0; iBand < histogramClass.length; iBand++) {
412
                        for (int i = 0; i < histogramClass[iBand].length; i++) {
413
                                datos[iBand][i][0] = histogramClass[iBand][i].getMin();
414
                                datos[iBand][i][1] = histogramClass[iBand][i].getValue();
415
                        }
416
                }
417

    
418
                // Definimos el principio y final de la grafica, sirve para descartar valores.
419
                int first = (int) getHistogramPanel().getBoxValueX1();
420
                int end = (int) getHistogramPanel().getBoxValueX2();
421
                //first = 0;
422
                //end = 100;
423

    
424
                int min = 0;
425
                int max = histogramClass[0].length - 1;
426

    
427
                first = min + ((first * (max - min))/ 100);
428
                end = min + ((end * (max - min))/ 100);
429

    
430
                // Si hay que eliminar los limites, quitamos el ultimo y primer valor de la grafica
431
                if (getHistogramPanel().getCheckBoxDeleteEdges().isSelected()) {
432
                        if ((first + 1) <= end)
433
                                first++;
434
                        if ((end - 1) >= first)
435
                                end--;
436
                }
437

    
438
                int bandCount = 0;
439
                for (int i = 0; i < showBands.length; i++)
440
                        if (showBands[i])
441
                                bandCount++;
442

    
443
                double[][][] newHistogram = new double[bandCount][end - first + 1][2];
444
                String[] bandNames = new String[bandCount];
445

    
446
                int numBand = 0;
447
                for (int iBand = 0; iBand < showBands.length; iBand++) {
448
                        if (!showBands[iBand])
449
                                continue;
450
                        for (int j = first; j <= end; j++) {
451
                                try {
452
                                        newHistogram[numBand][j - first][0] = datos[iBand][j][0];
453
                                        newHistogram[numBand][j - first][1] = datos[iBand][j][1];
454
                                } catch (ArrayIndexOutOfBoundsException e) {
455
                                        Logger.getLogger(getHistogramPanel().getClass().getName()).debug("Error al crear el array del histograma. DataType: " + getHistogramPanel().getDataType() + " Posici?n: " + j, e);
456
                                }
457
                        }
458
                        bandNames[numBand] = (String) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(iBand, 1);
459

    
460
                        getHistogramPanel().getGraphicContainer().setBandColor(numBand, bandsColor[iBand % bandsColor.length]);
461

    
462
                        numBand++;
463
                }
464

    
465
                getHistogramPanel().getGraphicContainer().getPGraphic().setNewChart(newHistogram, bandNames);
466
        }
467

    
468

    
469
        public void selectHistogram() {
470
                if (getHistogramPanel().getCheckBoxRGB().isSelected())
471
                        lastHistogram = lastHistogramRGB;
472
                else
473
                        lastHistogram = lastHistogramReal;
474
        }
475
        /**
476
         * Definir el nuevo histograma, metodo pu?blico para ser invocado desde
477
         * histogramProcess
478
         * @param histograma nuevo
479
         */
480
        public void setNewHistogram(Histogram histogram) {
481
                getHistogramPanel().panelInizialited = false;
482
                eventsEnabled = false;
483

    
484
                this.lastHistogramReal = histogram;;
485
                this.lastHistogramRGB = Histogram.convertHistogramToRGB(histogram);
486
                selectHistogram();
487

    
488
                refreshBands();
489
                updateStatistic();
490
                updateGraphic();
491

    
492
                // Activo la ejecucion de los eventos porque seguro que ya tenemos un histograma
493
                eventsEnabled = true;
494
                getHistogramPanel().panelInizialited = true;
495
        }
496

    
497
        /**
498
         * Obtener ?ltimo histograma
499
         * @return Histogram
500
         */
501
        public Histogram getLastHistogram() {
502
                return lastHistogram;
503
        }
504

    
505
        /**
506
         * Eventos de los BoxValues
507
         */
508
        public void actionValueChanged(GraphicEvent e) {
509
                updateStatistic();
510
                updateGraphic();
511
        }
512

    
513
        /**
514
         * Proceso para guardar una estadistica en un fichero.
515
         * @param path
516
         * @return
517
         * @throws IOException
518
         */
519
        private WritableByteChannel getWriteChannel(String path) throws IOException {
520
                WritableByteChannel channel;
521

    
522
                File f = new File(path);
523

    
524
                if (!f.exists()) {
525
                        if (!f.createNewFile()) {
526
                                throw new IOException("Cannot create file " + f);
527
                        }
528
                }
529

    
530
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
531
                channel = raf.getChannel();
532

    
533
                return channel;
534
        }
535

    
536
        /**
537
         *  Cuando se selecciona/deselecciona una banda
538
         */
539
        public void propertyChange(PropertyChangeEvent evt) {
540
                if (!eventsEnabled)
541
                        return;
542
                int countRow = ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getRowCount();
543
                for (int i = 0; i < countRow; i++)
544
                        showBands[i] = ((Boolean) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(i, 0)).booleanValue();
545

    
546
                updateStatistic();
547
                updateGraphic();
548
        }
549

    
550
        public void interrupted() {}
551
}