Statistics
| Revision:

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

History | View | Annotate | Download (14.3 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.gvsig.gui.beans.graphic.GraphicEvent;
41
import org.gvsig.gui.beans.graphic.GraphicListener;
42
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
43
import org.gvsig.raster.datastruct.Histogram;
44
import org.gvsig.raster.datastruct.HistogramClass;
45
import org.gvsig.raster.datastruct.HistogramException;
46
import org.gvsig.raster.hierarchy.IHistogramable;
47
import org.gvsig.raster.util.RasterToolsUtil;
48
import org.gvsig.rastertools.histogram.ui.HistogramPanel;
49

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

    
79
        public boolean         eventsEnabled  = false;
80

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

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

    
101
        public HistogramPanelListener(HistogramPanel p){
102
                histogramPanel = p;
103
        }
104

    
105
        public HistogramPanel getHistogramPanel() {
106
                return histogramPanel;
107
        }
108

    
109
        public void setControlListeners(){
110
                getHistogramPanel().getGraphicContainer().addValueChangedListener(this);
111
        }
112

    
113
        /**
114
         * Actualizar cuadro de estad?sticas
115
         */
116
        private void updateStatistic() {
117
                double first = getHistogramPanel().getGraphicContainer().getX1();
118
                double end = getHistogramPanel().getGraphicContainer().getX2();
119

    
120
                getHistogramPanel().setStatistic(getLastHistogram().getBasicStats(first, end, showBands));
121
        }
122

    
123
        /**
124
         * Tratamiento de todos los eventos visuales.
125
         */
126
        public void actionPerformed(ActionEvent e) {
127
                if (!eventsEnabled) return;
128

    
129
                // Boton de desmarcar todas las bandas
130
                if (e.getSource() == getHistogramPanel().getButtonClean()) {
131
                        getHistogramPanel().refreshBands(false);
132
                        for (int i = 0; i < showBands.length; i++)
133
                                showBands[i] = false;
134
                        updateStatistic();
135
                        updateGraphic();
136
                        return;
137
                }
138

    
139
                // Boton de marcar todas las bandas
140
                if (e.getSource() == getHistogramPanel().getButtonShowAll()) {
141
                        getHistogramPanel().refreshBands(true);
142
                        for (int i = 0; i < showBands.length; i++)
143
                                showBands[i] = true;
144
                        updateStatistic();
145
                        updateGraphic();
146
                        return;
147
                }
148

    
149
                //--------------------------------------
150
                //Selecci?n de fuente de datos del histograma
151
                JComboBox cbo = getHistogramPanel().getComboBoxSource();
152
                if (e.getSource() == cbo) {
153
                        showHistogram();
154
                        return;
155
                }
156

    
157
                // Checkbox de eliminas extremos
158
                if (e.getSource() == getHistogramPanel().getCBDeleteEdges()) {
159
                        updateGraphic();
160
                        return;
161
                }
162

    
163
                //--------------------------------------
164
                //Selecci?n de histograma acumulado y no acumulado
165
                JComboBox cbt = getHistogramPanel().getComboBoxType();
166
                if (e.getSource() == cbt) {
167
                        updateStatistic();
168
                        updateGraphic();
169
                        return;
170
                }
171

    
172
                //--------------------------------------
173
                // Boton Crear Tabla
174
                JButton table = getHistogramPanel().getBCreateTable();
175
                if (e.getSource() == table) {
176
                        try {
177
//                        -------Mostrar un fileChooser------------------
178
                                String fName;
179
                                JFileChooser chooser = new JFileChooser();
180
                                chooser.setDialogTitle(PluginServices.getText(this, "guardar_tabla"));
181

    
182
                                int returnVal = chooser.showOpenDialog(getHistogramPanel());
183
                                if (returnVal == JFileChooser.APPROVE_OPTION) {
184
                                        fName = chooser.getSelectedFile().toString();
185
                                        if (!fName.endsWith(".dbf"))
186
                                                fName += ".dbf";
187

    
188
                                        //-------------Crear el dbf----------------------
189

    
190
                                        DbaseFileWriterNIO dbfWrite = null;
191
                                        DbaseFileHeaderNIO myHeader;
192
                                        Value[] record;
193

    
194
                                        HistogramClass[][] histogram = getLastHistogram().getHistogram();
195
                                        int numBands = histogram.length;
196
                                        int numRecors = histogram[0].length;
197

    
198
                                        File file = new File(fName);
199

    
200
                                        String names[] = new String[numBands+1];
201
                                        int types[] = new int [numBands+1];
202
                                        int lengths[] = new int [numBands+1];
203

    
204
                                        names[0]="Value";
205
                                        types[0]=4;
206
                                        lengths[0]=15;
207
                                        for (int band = 0; band < numBands; band++){
208
                                                names[band+1]="Band"+band;
209
                                                types[band+1]=4;
210
                                                lengths[band+1]=15;
211
                                        }
212

    
213
                                        myHeader = DbaseFileHeaderNIO.createDbaseHeader(names,types,lengths);
214

    
215
                                        myHeader.setNumRecords(numRecors);
216
                                        dbfWrite = new DbaseFileWriterNIO(myHeader, (FileChannel) getWriteChannel(file.getPath()));
217
                                        record = new Value[numBands+1];
218

    
219
                                        for (int j = 0; j < numRecors; j++) {
220
                                                record[0] = ValueFactory.createValue(j);
221
                                                for (int r = 0; r < numBands; r++) {
222
                                                        record[r+1] = ValueFactory.createValue(histogram[r][j].getValue());
223
                                                }
224

    
225
                                                dbfWrite.write(record);
226
                                        }
227

    
228
                                        dbfWrite.close();
229

    
230
                                        //------------A?adir el dbf al proyecto--------------
231
                                        ProjectExtension ext = (ProjectExtension) PluginServices.getExtension(ProjectExtension.class);
232
                                        String name = file.getName();
233
                                        LayerFactory.getDataSourceFactory().addFileDataSource("gdbms dbf driver", name, fName);
234
                                        DataSource dataSource;
235
                                        dataSource = LayerFactory.getDataSourceFactory().createRandomDataSource(name, DataSourceFactory.AUTOMATIC_OPENING);
236

    
237
                                        SelectableDataSource sds = new SelectableDataSource(dataSource);
238
                                        EditableAdapter auxea=new EditableAdapter();
239
                                        auxea.setOriginalDataSource(sds);
240
                                        ProjectTable projectTable = ProjectFactory.createTable(name, auxea);
241
                                        //ext.getProject().addTable(projectTable);
242
                                        ext.getProject().addDocument(projectTable);
243

    
244
                                        Table t = new Table();
245
                                        t.setModel(projectTable);
246
                                        //projectTable.setAndamiWindow(t);
247
                                        PluginServices.getMDIManager().addWindow(t);
248
                                }
249
                        } catch (IOException e1) {
250
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
251
                        } catch (DriverLoadException e1) {
252
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
253
                        } catch (NoSuchTableException e1) {
254
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
255
                        } catch (ReadDriverException e1) {
256
                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),getHistogramPanel().getName() + " " + PluginServices.getText(this,"table_not_create"));
257
                        }
258
                }
259
        }
260

    
261
        /**
262
         * Actualizar la variable de las bandas visibles y su componente visual.
263
         */
264
        private void refreshBands() {
265
                getHistogramPanel().refreshBands(true);
266
                showBands = new boolean[getLastHistogram().getNumBands()];
267
                for (int i = 0; i < showBands.length; i++)
268
                        showBands[i] = true;
269
        }
270

    
271
        /**
272
         * Lanza los dos threads para procesar el histograma y visualizar la
273
         * ventana de incremento
274
         */
275
        public void showHistogram() {
276
                if (getHistogramPanel().getComboBoxSource().getSelectedIndex() < 0)
277
                        return;
278

    
279
                int dataSrc = getHistogramPanel().getComboBoxSource().getSelectedIndex();
280
                IHistogramable iaux = (IHistogramable) ((ArrayList) getHistogramPanel().getComboSource().get(dataSrc)).get(0);
281

    
282
                if (lastHistogram == null) {
283
                        try {
284
                                setNewHistogram(iaux.getHistogram());
285
                        } catch (HistogramException e) {
286
                                RasterToolsUtil.messageBoxError("histogram_error", histogramPanel, e);
287
                                return;
288
                        } catch (InterruptedException e) {
289
                                
290
                        }
291
                        return;
292
                }
293

    
294
                HistogramProcess histogramProcess = new HistogramProcess(iaux, this);
295
                IncrementableTask incrementableTask = new IncrementableTask(histogramProcess);
296
                histogramProcess.setIncrementableTask(incrementableTask);
297
                incrementableTask.showWindow();
298
                iaux.resetPercent();
299
                histogramProcess.start();
300
                incrementableTask.start();
301
        }
302

    
303
        /**
304
         * A?ade o elimina una banda de la visualizaci?n. Si la banda se est? visualizando
305
         * se elimina y si no entonces se muestra
306
         * @param band banda a visualizar o borrar del gr?fico
307
         */
308
        public void addOrRemoveGraphicBand(int band){
309
                if (band > showBands.length) return;
310
                showBands[band] = !showBands[band];
311
        }
312

    
313
        /**
314
         * Actualiza la grafica con los datos que ya teniamos del histograma.
315
         */
316
        private void updateGraphic() {
317
                if (getLastHistogram() == null) return;
318
                HistogramClass[][] histogramClass = getLastHistogram().getHistogramByType(Histogram.getType(getHistogramPanel().getComboBoxType().getSelectedIndex()));
319
                if (histogramClass == null) return;
320

    
321
                double[][][] datos = new double[histogramClass.length][histogramClass[0].length][2];
322
                for (int iBand=0; iBand < histogramClass.length; iBand++) {
323
                        for (int i=0; i<histogramClass[iBand].length; i++) {
324
                                datos[iBand][i][0] = histogramClass[iBand][i].getMin();
325
                                datos[iBand][i][1] = histogramClass[iBand][i].getValue();
326
                        }
327
                }
328

    
329
                // Definimos el principio y final de la grafica, sirve para descartar valores.
330
                int first = (int) getHistogramPanel().getBoxesValues(false)[1];
331
                int end = (int) getHistogramPanel().getBoxesValues(false)[0];
332

    
333
                // Si hay que eliminar los limites, quitamos el ultimo y primer valor de la grafica
334
                if (getHistogramPanel().getCBDeleteEdges().isSelected()) {
335
                        if ((first + 1) <= end)
336
                                first++;
337
                        if ((end - 1) >= first)
338
                                end--;
339
                }
340

    
341
                int bandCount = 0;
342
                for (int i = 0; i < showBands.length; i++) {
343
                        if (showBands[i]) bandCount++;
344
                }
345

    
346
                double[][][] newHistogram = new double[bandCount][end - first][2];
347
                String[] bandNames = new String[bandCount];
348

    
349
                bandCount = datos.length;
350

    
351
                int numBand = 0;
352
                for (int iBand = 0; iBand < datos.length; iBand++) {
353
                        if (!showBands[iBand]) continue;
354

    
355
                        for (int j=first; j<end; j++) {
356
                                newHistogram[numBand][j-first][0] = datos[iBand][j][0];
357
                                newHistogram[numBand][j-first][1] = datos[iBand][j][1];
358
                        }
359
                        bandNames[numBand] = (String) ((DefaultTableModel) getHistogramPanel().getJTableBands().getModel()).getValueAt(iBand, 1);
360

    
361
                        getHistogramPanel().getGraphicContainer().setBandColor(numBand, bandsColor[iBand % bandsColor.length]);
362

    
363
                        numBand++;
364
                }
365

    
366
                getHistogramPanel().getGraphicContainer().getPGraphic().setNewChart(newHistogram, bandNames);
367
        }
368

    
369
        /**
370
         * Definir el nuevo histograma, metodo pu?blico para ser invocado desde
371
         * histogramProcess
372
         * @param histograma nuevo
373
         */
374
        public void setNewHistogram(Histogram value) {
375
                getHistogramPanel().panelInizialited = false;
376
                eventsEnabled = false;
377
                lastHistogram = value;
378
                refreshBands();
379
                updateGraphic();
380
                updateStatistic();
381

    
382
                // Activo la ejecucion de los eventos porque seguro que ya tenemos un histograma
383
                eventsEnabled = true;
384
                getHistogramPanel().panelInizialited = true;
385
        }
386

    
387
        /**
388
         * Obtener ?ltimo histograma
389
         * @return Histogram
390
         */
391
        public Histogram getLastHistogram() {
392
                return lastHistogram;
393
        }
394

    
395
        /**
396
         * Eventos de los BoxValues
397
         */
398
        public void actionValueChanged(GraphicEvent e) {
399
                updateStatistic();
400
        }
401

    
402
        /**
403
         * Proceso para guardar una estadistica en un fichero.
404
         * @param path
405
         * @return
406
         * @throws IOException
407
         */
408
        private WritableByteChannel getWriteChannel(String path) throws IOException {
409
                WritableByteChannel channel;
410

    
411
                File f = new File(path);
412

    
413
                if (!f.exists()) {
414
                        System.out.println("Creando fichero " + f.getAbsolutePath());
415

    
416
                        if (!f.createNewFile()) {
417
                                throw new IOException("Cannot create file " + f);
418
                        }
419
                }
420

    
421
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
422
                channel = raf.getChannel();
423

    
424
                return channel;
425
        }
426

    
427
        /**
428
         *  Cuando se selecciona/deselecciona una banda
429
         */
430
        public void propertyChange(PropertyChangeEvent evt) {
431
                if (!eventsEnabled) return;
432
                int countRow = ((DefaultTableModel) histogramPanel.getJTableBands().getModel()).getRowCount();
433
                for (int i=0; i<countRow; i++) {
434
                        showBands[i] = ((Boolean) ((DefaultTableModel) histogramPanel.getJTableBands().getModel()).getValueAt(i, 0)).booleanValue();
435
                }
436
                updateGraphic();
437
                updateStatistic();
438
        }
439
}