Statistics
| Revision:

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

History | View | Annotate | Download (15.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.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.gui.beans.incrementabletask.IncrementableTask;
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

    
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 {
77
        private HistogramPanel histogramPanel = null;
78
        private Histogram      lastHistogram  = null;
79

    
80
        public boolean         eventsEnabled  = false;
81

    
82
        /**
83
   * Bandas que se est?n mostrando en el gr?fico. Se inicializa con las 3 bandas
84
   * RGB de la visualizaci?n. Este array puede tener m?s elementos ya que si las
85
   * bandas no son de visualizaci?n (bandas de la imagen en disco) tendr? un
86
   * elemento por cada una.
87
   */
88
        private boolean[]      showBands      = null;
89
        private FLyrRasterSE   lyr = null;        
90

    
91
        private Color[]                                                bandsColor = {
92
                        Color.red,
93
                        Color.green,
94
                        Color.blue,
95
                        Color.cyan,
96
                        Color.black,
97
                        Color.darkGray,
98
                        Color.gray,
99
                        Color.magenta,
100
                        Color.yellow,
101
                        Color.orange};
102

    
103
        /**
104
         * Constructor. Asigna el panel del histograma
105
         * @param p Panel
106
         */
107
        public HistogramPanelListener(HistogramPanel p) {
108
                histogramPanel = p;
109
        }
110

    
111
        /**
112
         * Obtiene el panel del histograma
113
         * @return HistogramPanel
114
         */
115
        public HistogramPanel getHistogramPanel() {
116
                return histogramPanel;
117
        }
118

    
119
        /**
120
         * Asigna la capa para obtener las fuentes de datos tanto del 
121
         * datasource como de la visualizaci?n.
122
         * @param lyr Capa
123
         */
124
        public void setLayer(FLyrRasterSE lyr) {
125
                this.lyr = lyr;
126
        }
127
        
128
        public void setControlListeners() {
129
                getHistogramPanel().getGraphicContainer().addValueChangedListener(this);
130
        }
131

    
132
        /**
133
         * Actualizar cuadro de estad?sticas
134
         */
135
        private void updateStatistic() {
136
                double first = getHistogramPanel().getGraphicContainer().getX1();
137
                double end = getHistogramPanel().getGraphicContainer().getX2();
138

    
139
                getHistogramPanel().setStatistic(getLastHistogram().getBasicStats(first, end, showBands));
140
        }
141

    
142
        /**
143
         * Tratamiento de todos los eventos visuales.
144
         */
145
        public void actionPerformed(ActionEvent e) {
146
                if (!eventsEnabled) return;
147

    
148
                // Boton de desmarcar todas las bandas
149
                if (e.getSource() == getHistogramPanel().getButtonClean()) {
150
                        getHistogramPanel().refreshBands(false);
151
                        for (int i = 0; i < showBands.length; i++)
152
                                showBands[i] = false;
153
                        updateStatistic();
154
                        updateGraphic();
155
                        return;
156
                }
157

    
158
                // Boton de marcar todas las bandas
159
                if (e.getSource() == getHistogramPanel().getButtonShowAll()) {
160
                        getHistogramPanel().refreshBands(true);
161
                        for (int i = 0; i < showBands.length; i++)
162
                                showBands[i] = true;
163
                        updateStatistic();
164
                        updateGraphic();
165
                        return;
166
                }
167

    
168
                //--------------------------------------
169
                //Selecci?n de fuente de datos del histograma
170
                JComboBox cbo = getHistogramPanel().getComboBoxSource();
171
                if (e.getSource() == cbo) {
172
                        ArrayList comboSource = histogramPanel.getComboSource();
173
                        for (int i = 0; i < comboSource.size(); i++) {
174
                                String name = (String)((ArrayList)comboSource.get(i)).get(1);
175
                                if(name.compareTo(PluginServices.getText(this, "datos_visualizados")) == 0) {
176
                                        ((ArrayList)comboSource.get(i)).remove(0);
177
                                        ((ArrayList)comboSource.get(i)).add(0, ((FLyrRasterSE) lyr).getRender().getLastRenderBuffer());
178
                                }
179
                                if(name.compareTo(PluginServices.getText(this, "imagen_completa")) == 0) {
180
                                        ((ArrayList)comboSource.get(i)).remove(0);
181
                                        ((ArrayList)comboSource.get(i)).add(0, ((FLyrRasterSE) lyr).getDataSource());
182
                                }
183
                                        
184
                        }
185
                        showHistogram();
186
                        return;
187
                }
188

    
189
                // Checkbox de eliminas extremos
190
                if (e.getSource() == getHistogramPanel().getCBDeleteEdges()) {
191
                        updateGraphic();
192
                        return;
193
                }
194

    
195
                //--------------------------------------
196
                //Selecci?n de histograma acumulado y no acumulado
197
                JComboBox cbt = getHistogramPanel().getComboBoxType();
198
                if (e.getSource() == cbt) {
199
                        updateStatistic();
200
                        updateGraphic();
201
                        return;
202
                }
203

    
204
                //--------------------------------------
205
                // Boton Crear Tabla
206
                JButton table = getHistogramPanel().getBCreateTable();
207
                if (e.getSource() == table) {
208
                        try {
209
//                        -------Mostrar un fileChooser------------------
210
                                String fName;
211
                                JFileChooser chooser = new JFileChooser();
212
                                chooser.setDialogTitle(PluginServices.getText(this, "guardar_tabla"));
213

    
214
                                int returnVal = chooser.showOpenDialog(getHistogramPanel());
215
                                if (returnVal == JFileChooser.APPROVE_OPTION) {
216
                                        fName = chooser.getSelectedFile().toString();
217
                                        if (!fName.endsWith(".dbf"))
218
                                                fName += ".dbf";
219

    
220
                                        //-------------Crear el dbf----------------------
221

    
222
                                        DbaseFileWriterNIO dbfWrite = null;
223
                                        DbaseFileHeaderNIO myHeader;
224
                                        Value[] record;
225

    
226
                                        HistogramClass[][] histogram = getLastHistogram().getHistogram();
227
                                        int numBands = histogram.length;
228
                                        int numRecors = histogram[0].length;
229

    
230
                                        File file = new File(fName);
231

    
232
                                        String names[] = new String[numBands+1];
233
                                        int types[] = new int [numBands+1];
234
                                        int lengths[] = new int [numBands+1];
235

    
236
                                        names[0]="Value";
237
                                        types[0]=4;
238
                                        lengths[0]=15;
239
                                        for (int band = 0; band < numBands; band++){
240
                                                names[band+1]="Band"+band;
241
                                                types[band+1]=4;
242
                                                lengths[band+1]=15;
243
                                        }
244

    
245
                                        myHeader = DbaseFileHeaderNIO.createDbaseHeader(names,types,lengths);
246

    
247
                                        myHeader.setNumRecords(numRecors);
248
                                        dbfWrite = new DbaseFileWriterNIO(myHeader, (FileChannel) getWriteChannel(file.getPath()));
249
                                        record = new Value[numBands+1];
250

    
251
                                        for (int j = 0; j < numRecors; j++) {
252
                                                record[0] = ValueFactory.createValue(j);
253
                                                for (int r = 0; r < numBands; r++) {
254
                                                        record[r+1] = ValueFactory.createValue(histogram[r][j].getValue());
255
                                                }
256

    
257
                                                dbfWrite.write(record);
258
                                        }
259

    
260
                                        dbfWrite.close();
261

    
262
                                        //------------A?adir el dbf al proyecto--------------
263
                                        ProjectExtension ext = (ProjectExtension) PluginServices.getExtension(ProjectExtension.class);
264
                                        String name = file.getName();
265
                                        LayerFactory.getDataSourceFactory().addFileDataSource("gdbms dbf driver", name, fName);
266
                                        DataSource dataSource;
267
                                        dataSource = LayerFactory.getDataSourceFactory().createRandomDataSource(name, DataSourceFactory.AUTOMATIC_OPENING);
268

    
269
                                        SelectableDataSource sds = new SelectableDataSource(dataSource);
270
                                        EditableAdapter auxea=new EditableAdapter();
271
                                        auxea.setOriginalDataSource(sds);
272
                                        ProjectTable projectTable = ProjectFactory.createTable(name, auxea);
273
                                        //ext.getProject().addTable(projectTable);
274
                                        ext.getProject().addDocument(projectTable);
275

    
276
                                        Table t = new Table();
277
                                        t.setModel(projectTable);
278
                                        //projectTable.setAndamiWindow(t);
279
                                        PluginServices.getMDIManager().addWindow(t);
280
                                }
281
                        } catch (IOException e1) {
282
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
283
                        } catch (DriverLoadException e1) {
284
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
285
                        } catch (NoSuchTableException e1) {
286
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
287
                        } catch (ReadDriverException e1) {
288
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
289
                        }
290
                }
291
        }
292

    
293
        /**
294
         * Actualizar la variable de las bandas visibles y su componente visual.
295
         */
296
        private void refreshBands() {
297
                getHistogramPanel().refreshBands(true);
298
                showBands = new boolean[getLastHistogram().getNumBands()];
299
                for (int i = 0; i < showBands.length; i++)
300
                        showBands[i] = true;
301
        }
302

    
303
        /**
304
         * Lanza los dos threads para procesar el histograma y visualizar la
305
         * ventana de incremento
306
         */
307
        public void showHistogram() {
308
                if (getHistogramPanel().getComboBoxSource().getSelectedIndex() < 0)
309
                        return;
310

    
311
                int dataSrc = getHistogramPanel().getComboBoxSource().getSelectedIndex();
312
                IHistogramable iaux = (IHistogramable) ((ArrayList) getHistogramPanel().getComboSource().get(dataSrc)).get(0);
313

    
314
                if (lastHistogram == null) {
315
                        try {
316
                                setNewHistogram(iaux.getHistogram());
317
                        } catch (HistogramException e) {
318
                                RasterToolsUtil.messageBoxError("histogram_error", histogramPanel, e);
319
                                return;
320
                        } catch (InterruptedException e) {
321
                                
322
                        }
323
                        return;
324
                }
325

    
326
                HistogramProcess histogramProcess = new HistogramProcess(iaux, this);
327
                IncrementableTask incrementableTask = new IncrementableTask(histogramProcess);
328
                histogramProcess.setIncrementableTask(incrementableTask);
329
                incrementableTask.showWindow();
330
                iaux.resetPercent();
331
                histogramProcess.start();
332
                incrementableTask.start();
333
        }
334

    
335
        /**
336
         * A?ade o elimina una banda de la visualizaci?n. Si la banda se est? visualizando
337
         * se elimina y si no entonces se muestra
338
         * @param band banda a visualizar o borrar del gr?fico
339
         */
340
        public void addOrRemoveGraphicBand(int band) {
341
                if (band > showBands.length) return;
342
                showBands[band] = !showBands[band];
343
        }
344

    
345
        /**
346
         * Actualiza la grafica con los datos que ya teniamos del histograma.
347
         */
348
        private void updateGraphic() {
349
                if (getLastHistogram() == null) return;
350
                HistogramClass[][] histogramClass = getLastHistogram().getHistogramByType(Histogram.getType(getHistogramPanel().getComboBoxType().getSelectedIndex()));
351
                if (histogramClass == null) return;
352

    
353
                double[][][] datos = new double[histogramClass.length][histogramClass[0].length][2];
354
                for (int iBand=0; iBand < histogramClass.length; iBand++) {
355
                        for (int i=0; i<histogramClass[iBand].length; i++) {
356
                                datos[iBand][i][0] = histogramClass[iBand][i].getMin();
357
                                datos[iBand][i][1] = histogramClass[iBand][i].getValue();
358
                        }
359
                }
360

    
361
                // Definimos el principio y final de la grafica, sirve para descartar valores.
362
                int first = (int) getHistogramPanel().getBoxesValues(false)[1];
363
                int end = (int) getHistogramPanel().getBoxesValues(false)[0];
364

    
365
                // Si hay que eliminar los limites, quitamos el ultimo y primer valor de la grafica
366
                if (getHistogramPanel().getCBDeleteEdges().isSelected()) {
367
                        if ((first + 1) <= end)
368
                                first++;
369
                        if ((end - 1) >= first)
370
                                end--;
371
                }
372

    
373
                int bandCount = 0;
374
                for (int i = 0; i < showBands.length; i++)
375
                        if (showBands[i]) bandCount++;
376

    
377
                double[][][] newHistogram = new double[bandCount][end - first + 1][2];
378
                String[] bandNames = new String[bandCount];
379

    
380
                bandCount = datos.length;
381

    
382
                int numBand = 0;
383
                for (int iBand = 0; iBand < datos.length; iBand++) {
384
                        if (!showBands[iBand])
385
                                continue;
386
                        for (int j = first; j <= end; j++) {
387
                                try {
388
                                        newHistogram[numBand][j-first][0] = datos[iBand][j][0];
389
                                        newHistogram[numBand][j-first][1] = datos[iBand][j][1];
390
                                } catch (ArrayIndexOutOfBoundsException e) {
391
                                        Logger.getLogger(histogramPanel.getClass().getName()).debug("Error al crear el array del histograma. DataType: " + histogramPanel.getDataType() + " Posici?n: " + j, e);
392
                                }
393
                        }
394
                        bandNames[numBand] = (String) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(iBand, 1);
395

    
396
                        getHistogramPanel().getGraphicContainer().setBandColor(numBand, bandsColor[iBand % bandsColor.length]);
397

    
398
                        numBand++;
399
                }
400

    
401
                getHistogramPanel().getGraphicContainer().getPGraphic().setNewChart(newHistogram, bandNames);
402
        }
403

    
404
        /**
405
         * Definir el nuevo histograma, metodo pu?blico para ser invocado desde
406
         * histogramProcess
407
         * @param histograma nuevo
408
         */
409
        public void setNewHistogram(Histogram value) {
410
                getHistogramPanel().panelInizialited = false;
411
                eventsEnabled = false;
412
                lastHistogram = value;
413
                refreshBands();
414
                updateGraphic();
415
                updateStatistic();
416

    
417
                // Activo la ejecucion de los eventos porque seguro que ya tenemos un histograma
418
                eventsEnabled = true;
419
                getHistogramPanel().panelInizialited = true;
420
        }
421

    
422
        /**
423
         * Obtener ?ltimo histograma
424
         * @return Histogram
425
         */
426
        public Histogram getLastHistogram() {
427
                return lastHistogram;
428
        }
429

    
430
        /**
431
         * Eventos de los BoxValues
432
         */
433
        public void actionValueChanged(GraphicEvent e) {
434
                updateStatistic();
435
        }
436

    
437
        /**
438
         * Proceso para guardar una estadistica en un fichero.
439
         * @param path
440
         * @return
441
         * @throws IOException
442
         */
443
        private WritableByteChannel getWriteChannel(String path) throws IOException {
444
                WritableByteChannel channel;
445

    
446
                File f = new File(path);
447

    
448
                if (!f.exists()) {
449
                        System.out.println("Creando fichero " + f.getAbsolutePath());
450

    
451
                        if (!f.createNewFile()) {
452
                                throw new IOException("Cannot create file " + f);
453
                        }
454
                }
455

    
456
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
457
                channel = raf.getChannel();
458

    
459
                return channel;
460
        }
461

    
462
        /**
463
         *  Cuando se selecciona/deselecciona una banda
464
         */
465
        public void propertyChange(PropertyChangeEvent evt) {
466
                if (!eventsEnabled) return;
467
                int countRow = ((DefaultTableModel) histogramPanel.getJTableBands().getModel()).getRowCount();
468
                for (int i=0; i<countRow; i++) {
469
                        showBands[i] = ((Boolean) ((DefaultTableModel) histogramPanel.getJTableBands().getModel()).getValueAt(i, 0)).booleanValue();
470
                }
471
                updateGraphic();
472
                updateStatistic();
473
        }
474
}