Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / org.gvsig.desktop.library / org.gvsig.fmap.mapcontext.swing / org.gvsig.fmap.mapcontext.swing.impl / src / main / java / org / gvsig / fmap / mapcontext / raster / swing / impl / bands / BandsPanelController.java @ 43876

History | View | Annotate | Download (20.7 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2017 gvSIG Association
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., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.mapcontext.raster.swing.impl.bands;
24

    
25
import java.awt.color.ColorSpace;
26
import java.awt.event.ActionEvent;
27
import java.awt.event.ActionListener;
28
import java.awt.event.ItemEvent;
29
import java.awt.event.ItemListener;
30
import java.io.File;
31
import java.util.ArrayList;
32
import java.util.Iterator;
33
import java.util.List;
34
import java.util.Locale;
35

    
36
import javax.swing.JComponent;
37
import javax.swing.JFileChooser;
38
import javax.swing.JOptionPane;
39
import javax.swing.ListSelectionModel;
40
import javax.swing.event.ListSelectionEvent;
41
import javax.swing.event.ListSelectionListener;
42
import javax.swing.filechooser.FileFilter;
43
import javax.swing.table.DefaultTableColumnModel;
44
import javax.swing.table.TableColumn;
45
import javax.swing.table.TableColumnModel;
46
import javax.swing.table.TableModel;
47

    
48
import org.slf4j.Logger;
49
import org.slf4j.LoggerFactory;
50

    
51
import org.gvsig.fmap.dal.DALLocator;
52
import org.gvsig.fmap.dal.DataManager;
53
import org.gvsig.fmap.dal.DataServerExplorerParameters;
54
import org.gvsig.fmap.dal.exception.DataException;
55
import org.gvsig.fmap.dal.exception.InitializeException;
56
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
57
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
58
import org.gvsig.fmap.dal.raster.BandDescriptor;
59
import org.gvsig.fmap.dal.raster.RasterStore;
60
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemFileFilter;
61
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
62
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
63
import org.gvsig.fmap.mapcontext.layers.FLayer;
64
import org.gvsig.fmap.mapcontext.raster.api.RasterLayer;
65
import org.gvsig.fmap.mapcontext.raster.swing.bands.BandsPanel;
66
import org.gvsig.raster.lib.buffer.api.BufferLocator;
67
import org.gvsig.raster.lib.buffer.api.BufferManager;
68
import org.gvsig.raster.lib.buffer.api.NoData;
69
import org.gvsig.raster.lib.legend.api.RasterLegend;
70
import org.gvsig.raster.lib.legend.api.RasterLegendLocator;
71
import org.gvsig.raster.lib.legend.api.RasterLegendManager;
72
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
73
import org.gvsig.tools.ToolsLocator;
74
import org.gvsig.tools.dispose.DisposeUtils;
75
import org.gvsig.tools.dynobject.DynObject;
76
import org.gvsig.tools.i18n.I18nManager;
77
import org.gvsig.tools.swing.api.ToolsSwingLocator;
78
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
79

    
80
/**
81
 * @author fdiaz
82
 *
83
 */
84
public class BandsPanelController extends BandsPanelView implements BandsPanel, ActionListener, ListSelectionListener {
85

    
86
    /**
87
     *
88
     */
89
    private static final long serialVersionUID = 8255630092178065352L;
90
    @SuppressWarnings("unused")
91
    private static final Logger LOG = LoggerFactory.getLogger(BandsPanelController.class);
92
    private RasterLayer layer;
93

    
94
    private static final String RASTER_FILTER = "All_raster_supported";
95

    
96
    // FLayer layer;
97

    
98
    /**
99
     * @param layer
100
     */
101
    @SuppressWarnings("unchecked")
102
    public BandsPanelController() {
103
        DisposeUtils.bind(this);
104
        translate();
105
        initializeComponents();
106
    }
107

    
108
    private void initializeComponents() {
109
        this.btnAdd.addActionListener(this);
110
        this.btnRemove.addActionListener(this);
111
        tblBands.setRowSelectionAllowed(true);
112
        tblBands.setColumnSelectionAllowed(false);
113
        tblBands.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
114
        tblBands.getSelectionModel().addListSelectionListener(this);
115
        BandsTableModel model = new BandsTableModel();
116
        tblBands.setModel(model);
117

    
118
        tblBands.setColumnModel(new DefaultTableColumnModel());
119
        TableColumnModel columnModel = tblBands.getColumnModel();
120
        columnModel.setColumnSelectionAllowed(false);
121
        for (int i = 0; i < model.getColumnCount(); i++) {
122
            TableColumn tableColumn = new TableColumn(i);
123
            tableColumn.setIdentifier(model.getColumnName(i));
124
            tableColumn.setHeaderValue(model.getColumnName(i));
125
            columnModel.addColumn(tableColumn);
126
        }
127

    
128
        cboColorSpaces.addItem(ColorInterpretation.RGB);
129
        cboColorSpaces.addItem(ColorInterpretation.CMYK);
130
        cboColorSpaces.addItem(ColorInterpretation.HSL);
131
        //FIXME: Uncomment when a operation to convert RGB to/from HSL is implemented.
132
//        cboColorSpaces.addItem(ColorInterpretation.YCBCR);
133
        cboColorSpaces.addItemListener(new ItemListener() {
134

    
135
            @Override
136
            public void itemStateChanged(ItemEvent e) {
137
                doChangeColorColumnCellEditor();
138
            }
139
        });
140

    
141
        // FIXME: esto ser?a lo que habr?a que cambiar si se desea implementar
142
        // otros espacios de color
143
//        columnModel.getColumn(0).setCellEditor(new ColorInterpretationCellEditor(BandsTableModel.RGBColorSpace));
144
        columnModel.getColumn(0).setCellRenderer(new ColorInterpretationCellRenderer());
145

    
146
        columnModel.getColumn(1).setCellRenderer(new NoDataCellRenderer());
147
        // columnModel.getColumn(1).setCellEditor(new NoDataCellEditor());
148

    
149
        columnModel.getColumn(2).setCellRenderer(new DataTypeCellRenderer());
150

    
151
    }
152

    
153
    private void translate() {
154
        I18nManager i18nManager = ToolsLocator.getI18nManager();
155
        lblBands.setText(i18nManager.getTranslation(lblBands.getText()));
156
        lblColorSpace.setText(i18nManager.getTranslation(lblColorSpace.getText()));
157
        cboColorSpaces.setToolTipText(i18nManager.getTranslation(cboColorSpaces.getToolTipText()));
158
        btnAdd.setText(i18nManager.getTranslation(btnAdd.getText()));
159
        btnAdd.setToolTipText(i18nManager.getTranslation(btnAdd.getToolTipText()));
160
        btnRemove.setText(i18nManager.getTranslation(btnRemove.getText()));
161
        btnRemove.setToolTipText(i18nManager.getTranslation(btnRemove.getToolTipText()));
162
    }
163

    
164
    /**
165
     * @param locale
166
     *
167
     */
168
    public void setLocate(Locale locale) {
169
        Locale l = super.getLocale();
170
        if (!l.equals(locale)) {
171
            translate();
172
        }
173
        super.setLocale(locale);
174
    }
175

    
176
    /**
177
     * @param layer
178
     */
179
    @SuppressWarnings("unchecked")
180
    public void set(FLayer layer) {
181
        if(this.layer!=null){
182
            DisposeUtils.dispose(this.layer);
183
        }
184
        this.layer = (RasterLayer) layer;
185
        DisposeUtils.bind(layer);
186
        RasterLegend legend = this.layer.getLegend();
187
        ColorInterpretation colorInterpretation = null;
188
        if (legend != null) {
189
            colorInterpretation = legend.getColorInterpretation();
190
        }
191
        RasterStore store = this.layer.getRasterStore();
192
        addBands(store, colorInterpretation);
193
    }
194

    
195
    /**
196
     * @param colorInterpretation
197
     * @param store
198
     * @param model
199
     */
200
    private void addBands(RasterStore store, ColorInterpretation colorInterpretation) {
201
        String colorSpace = "";
202
        if (colorInterpretation.hasAnyCMYKBand()) {
203
            colorSpace = ColorInterpretation.CMYK;
204
        } else if (colorInterpretation.hasAnyHSLBand()) {
205
            colorSpace = ColorInterpretation.HSL;
206
        } else if (colorInterpretation.hasAnyHSLBand()) {
207
            colorSpace = ColorInterpretation.YCBCR;
208
        } else {
209
            colorSpace = ColorInterpretation.RGB;
210
        }
211
        cboColorSpaces.setSelectedItem(colorSpace);
212
        doChangeColorColumnCellEditor();
213

    
214
        BandsTableModel model = ((BandsTableModel) tblBands.getModel());
215
        for (int i = 0; i < store.getBands(); i++) {
216
            BandDescriptor bandDescriptor = store.getBandDescriptor(i);
217

    
218
            RasterStoreBand rasterStoreBand = new RasterStoreBand(bandDescriptor.getStore(), bandDescriptor.getBand());
219
            NoData noData = bandDescriptor.getNoData();
220
            if (noData != null) {
221
                rasterStoreBand.setNoDataNumber(noData.getValue());
222
            }
223
            rasterStoreBand.setBandName(bandDescriptor.getName());
224
            rasterStoreBand.setDataType(bandDescriptor.getDataType());
225

    
226
            if (colorInterpretation != null) {
227
                rasterStoreBand.setBandColorInterpretation(colorInterpretation.get(i));
228
            } else {
229
                rasterStoreBand.setBandColorInterpretation(ColorInterpretation.UNDEFINED_BAND);
230
            }
231
            model.add(rasterStoreBand);
232
            DisposeUtils.disposeQuietly(rasterStoreBand);
233
            model.fireTableDataChanged();
234
        }
235
    }
236

    
237
    /**
238
     * @param layer
239
     */
240
    public boolean fetch(FLayer layer) {
241
        RasterLayer rasterLayer = (RasterLayer) layer;
242
        RasterStore store = rasterLayer.getRasterStore();
243
        RasterLegendManager rasterLegendManager = RasterLegendLocator.getRasterLegendManager();
244
        if (willBeChangedBands(store)) {
245
            store.clearAdditionalBands();
246
            BandsTableModel model = (BandsTableModel) tblBands.getModel();
247
            BufferManager bufferManager = BufferLocator.getBufferManager();
248

    
249
            for (int index = 0; index < model.getRowCount(); index++) {
250
                RasterStoreBand rasterStoreBand = model.getElementAt(index);
251
                RasterStore subStore = rasterStoreBand.getStore();
252
                int band = rasterStoreBand.getBand();
253
                if (subStore != store) {
254
                    try {
255
                        store.addBand(subStore, band);
256
                    } catch (DataException e) {
257
                        ThreadSafeDialogsManager dlgManager = ToolsSwingLocator.getThreadSafeDialogsManager();
258
                        String message = "_cant_add_band_XbandX_from_store_XsourceX_to_store_XtargetX";
259
                        String title = "_error_adding_bands";
260
                        dlgManager.messageDialog(message, new String[] { String.valueOf(band), subStore.getName(),
261
                            store.getName() }, title, JOptionPane.WARNING_MESSAGE);
262
                        LOG.warn(message, e);
263
                        return false;
264
                    }
265
                }
266
                BandDescriptor bandDescriptor = store.getBandDescriptor(index);
267
                NoData noData = bandDescriptor.getNoData();
268
                Number value = null;
269
                value = rasterStoreBand.getNoDataNumber();
270

    
271
                if (noData == null) {
272
                    noData = bufferManager.createNoData(value, null);
273
                } else {
274
                    noData.setValue((Number) value);
275
                }
276
                bandDescriptor.setNoData(noData);
277
            }
278
            rasterLayer.recalculateStatistics();
279

    
280
            List<String> colorInterpretations = getColorInterpretations();
281

    
282
            boolean createNewLegend = true;
283
            RasterLegend oldLegend = rasterLayer.getLegend();
284
            if(oldLegend!=null){
285
                ColorInterpretation oldColorInterpretation = oldLegend.getColorInterpretation();
286
                if(oldColorInterpretation.length()==colorInterpretations.size()){
287
                    for (int band=0; band<oldColorInterpretation.length(); band++) {
288
                        oldColorInterpretation.setColorInterpValue(band, colorInterpretations.get(band));
289
                    }
290
                    createNewLegend = false;
291
                }
292
            }
293

    
294
            if(createNewLegend) {
295
                ColorInterpretation colorInterpretation =
296
                    rasterLegendManager.createColorInterpretation(colorInterpretations.toArray(new String[0]));
297

    
298
                RasterLegend legend = rasterLegendManager.createLegend(colorInterpretation);
299
                rasterLayer.setLegend(legend);
300
            }
301

    
302

    
303
            rasterLayer.getMapContext().invalidate();
304
        }
305

    
306
        return true;
307
    }
308

    
309
    private List<String> getColorInterpretations(){
310
        List<String> colorInterpretations = new ArrayList();
311
        BandsTableModel model = (BandsTableModel) tblBands.getModel();
312

    
313
        for (int index = 0; index < model.getRowCount(); index++) {
314
            RasterStoreBand rasterStoreBand = model.getElementAt(index);
315
            RasterStore subStore = rasterStoreBand.getStore();
316
            int band = rasterStoreBand.getBand();
317
            colorInterpretations.add(rasterStoreBand.getBandColorInterpretation());
318
        }
319
        return colorInterpretations;
320
    }
321

    
322
    private boolean willBeChangedBands(RasterStore store){
323

    
324
        BandsTableModel model = (BandsTableModel) tblBands.getModel();
325

    
326
        if(store.getBands()!=model.getRowCount()){
327
            return true;
328
        }
329
        ColorInterpretation colorInterpretation = this.layer.getLegend().getColorInterpretation();
330
        for (int index = 0; index < model.getRowCount(); index++) {
331
            RasterStoreBand rasterStoreBand = model.getElementAt(index);
332
            RasterStore subStore = rasterStoreBand.getStore();
333
            int band = rasterStoreBand.getBand();
334
            BandDescriptor bandDescriptor = store.getBandDescriptor(index);
335
            if (bandDescriptor.getStore() != subStore || bandDescriptor.getBand() != band
336
                || isChangedNoData(bandDescriptor.getNoData(), rasterStoreBand.getNoDataNumber())
337
                || !(rasterStoreBand.getBandColorInterpretation().equals(colorInterpretation.get(index)))
338
               ){
339
                return true;
340
            }
341
        }
342
        return false;
343
    }
344

    
345
    private boolean isChangedNoData(NoData noData, Number number){
346
        if(noData!=null){
347
            return noData.getValue()!=number;
348
        } else {
349
            return number!=null;
350
        }
351
    }
352

    
353
    @Override
354
    public JComponent asJComponent() {
355
        return this;
356
    }
357

    
358
    @SuppressWarnings("unchecked")
359
    @Override
360
    public void actionPerformed(ActionEvent e) {
361
        if (e.getSource() == btnRemove) {
362
            BandsTableModel model = (BandsTableModel) tblBands.getModel();
363
            model.removeElementAt(tblBands.getSelectedRow());
364
            model.fireTableDataChanged();
365

    
366
        } else if (e.getSource() == btnAdd) {
367
            DataManager manager = DALLocator.getDataManager();
368

    
369
            JFileChooser fileChooser = createJFileChooser();
370
            int result = fileChooser.showOpenDialog(this);
371

    
372
            if (result == JFileChooser.APPROVE_OPTION) {
373
                File[] files = fileChooser.getSelectedFiles();
374
                for (File file : files) {
375

    
376
                    DataServerExplorerParameters fileExplorerParams;
377
                    try {
378
                        fileExplorerParams = manager.createServerExplorerParameters(FilesystemServerExplorer.NAME);
379
                        FilesystemServerExplorer explorer =
380
                            (FilesystemServerExplorer) manager.openServerExplorer(FilesystemServerExplorer.NAME,
381
                                fileExplorerParams);
382
                        String type = explorer.getProviderName(file);
383
                        DynObject params = manager.createStoreParameters(type);
384
                        if (params.getDynClass().getDynField("file") != null) {
385
                            params.setDynValue("file", file);
386
                        }
387
                        // FIXME: ?se le pone la proyecci?n del raster principal
388
                        // o se busca la que tenga el archivo si la tiene?
389
                        if (params.getDynClass().getDynField("crs") != null) {
390
                            params.setDynValue("crs", this.layer.getProjection());
391
                        }
392
                        RasterStore store = (RasterStore) manager.openStore(type, params);
393
                        DisposeUtils.disposeQuietly(explorer);
394

    
395
                        addBands(store, null);
396
                        DisposeUtils.disposeQuietly(store);
397

    
398
                    } catch (InitializeException | ProviderNotRegisteredException | ValidateDataParametersException e1) {
399
                        LOG.warn("Can't add bands from the file '" + file.getName() + "'", e1);
400
                        // e1.printStackTrace();
401
                    }
402
                }
403
            }
404
        }
405
    }
406

    
407
    @Override
408
    public void valueChanged(ListSelectionEvent e) {
409
        if (e.getSource() == tblBands.getSelectionModel()) {
410
            if (tblBands.getSelectedRow() >= 0) {
411
                if (this.layer.getRasterStore() != ((BandsTableModel) tblBands.getModel()).getElementAt(
412
                    tblBands.getSelectedRow()).getStore()) {
413
                    btnRemove.setEnabled(true);
414
                } else {
415
                    btnRemove.setEnabled(false);
416
                }
417
            } else {
418
                btnRemove.setEnabled(false);
419
            }
420
        }
421
    }
422

    
423
    private JFileChooser createJFileChooser() {
424
        I18nManager i18nManager = ToolsLocator.getI18nManager();
425
        JFileChooser fileChooser = new JFileChooser();
426

    
427
        int mode = FilesystemServerExplorer.MODE_RASTER;
428
        FilesystemServerExplorer explorer;
429

    
430
        DataManager dm = DALLocator.getDataManager();
431
        FilesystemServerExplorerParameters param;
432
        try {
433
            param =
434
                (FilesystemServerExplorerParameters) dm.createServerExplorerParameters(FilesystemServerExplorer.NAME);
435
            explorer = (FilesystemServerExplorer) dm.openServerExplorer(FilesystemServerExplorer.NAME, param);
436
        } catch (Exception e) {
437
            throw new RuntimeException(e);
438
        }
439

    
440
        FilesystemFileFilter filter = explorer.getFilter(mode, i18nManager.getTranslation(RASTER_FILTER));
441

    
442
        fileChooser.setMultiSelectionEnabled(true);
443
        fileChooser.setAcceptAllFileFilterUsed(false);
444
        fileChooser.setFileFilter(new MyFileFilter(filter));
445
        DisposeUtils.dispose(explorer);
446

    
447
        return fileChooser;
448
    }
449

    
450
    /**
451
     * @author fdiaz
452
     *
453
     */
454
    public class MyFileFilter extends FileFilter {
455

    
456
        public FilesystemFileFilter filter = null;
457

    
458
        /**
459
         * @param params
460
         */
461
        public MyFileFilter(FilesystemFileFilter params) {
462
            this.filter = params;
463
        }
464

    
465
        /**
466
         * @see javax.swing.filechooser.FileFilter#accept(java.io.File)
467
         */
468
        public boolean accept(File f) {
469
            if (f.isDirectory()) {
470
                return true;
471
            }
472
            return filter.accept(f);
473

    
474
        }
475

    
476
        /**
477
         * @see javax.swing.filechooser.FileFilter#getDescription()
478
         */
479
        public String getDescription() {
480
            return filter.getDescription();
481
        }
482

    
483
        /**
484
         * @return
485
         */
486
        public String getName() {
487
            return filter.getDataStoreProviderName();
488
        }
489
    }
490

    
491
    @Override
492
    public void dispose() {
493
        if(!ToolsLocator.getDisposableManager().release(this)){
494
            return;
495
        }
496
        DisposeUtils.dispose(this.layer);
497
        this.layer = null;
498

    
499
        BandsTableModel model = (BandsTableModel) tblBands.getModel();
500

    
501
        for (int index = 0; index < model.getRowCount(); index++) {
502
            RasterStoreBand rasterStoreBand = model.getElementAt(index);
503
            DisposeUtils.disposeQuietly(rasterStoreBand);
504
        }
505
    }
506

    
507
    private void doChangeColorColumnCellEditor() {
508
        TableColumnModel columnModel = tblBands.getColumnModel();
509

    
510
        String selectedItem = (String)cboColorSpaces.getSelectedItem();
511
        if(selectedItem.equalsIgnoreCase(ColorInterpretation.RGB)){
512

    
513
            columnModel.getColumn(0).setCellEditor(new ColorInterpretationCellEditor(BandsTableModel.RGBColorSpace));
514
        }
515
        if(selectedItem.equalsIgnoreCase(ColorInterpretation.CMYK)){
516
            columnModel.getColumn(0).setCellEditor(new ColorInterpretationCellEditor(BandsTableModel.CMYKColorSpace));
517
        }
518
        if(selectedItem.equalsIgnoreCase(ColorInterpretation.HSL)){
519
            columnModel.getColumn(0).setCellEditor(new ColorInterpretationCellEditor(BandsTableModel.HSLColorSpace));
520
        }
521
        if(selectedItem.equalsIgnoreCase(ColorInterpretation.YCBCR)){
522
            columnModel.getColumn(0).setCellEditor(new ColorInterpretationCellEditor(BandsTableModel.YCBCRColorSpace));
523
        }
524

    
525
        TableModel bandModel = tblBands.getModel();
526
        for (int i = 0; i < tblBands.getRowCount(); i++) {
527
            bandModel.setValueAt(ColorInterpretation.UNDEFINED_BAND, i, 0);
528
        }
529
    }
530
}