/* * Copyright (C) 2011 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.core.gpf.ui.mosaic; import com.bc.ceres.binding.PropertySet; import com.bc.ceres.swing.TableLayout; import com.bc.ceres.swing.binding.BindingContext; import org.esa.snap.core.datamodel.GeoPos; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.dataop.dem.ElevationModelDescriptor; import org.esa.snap.core.dataop.dem.ElevationModelRegistry; import org.esa.snap.ui.AppContext; import org.esa.snap.ui.BoundsInputPanel; import org.esa.snap.ui.RegionSelectableWorldMapPane; import org.esa.snap.ui.WorldMapPaneDataModel; import org.esa.snap.ui.crs.CrsForm; import org.esa.snap.ui.crs.CrsSelectionPanel; import org.esa.snap.ui.crs.CustomCrsForm; import org.esa.snap.ui.crs.PredefinedCrsForm; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import javax.swing.BorderFactory; import javax.swing.DefaultComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.List; /** * @author Marco Peters * @since BEAM 4.7 */ class MosaicMapProjectionPanel extends JPanel { private final AppContext appContext; private final MosaicFormModel mosaicModel; private CrsSelectionPanel crsSelectionPanel; private BoundsInputPanel boundsInputPanel; private final BindingContext bindingCtx; private String[] demValueSet; MosaicMapProjectionPanel(AppContext appContext, MosaicFormModel mosaicModel) { this.appContext = appContext; this.mosaicModel = mosaicModel; bindingCtx = new BindingContext(mosaicModel.getPropertySet()); init(); createUI(); updateForCrsChanged(); bindingCtx.adjustComponents(); } public BindingContext getBindingContext(){ return bindingCtx;} private void init() { final ElevationModelDescriptor[] descriptors = ElevationModelRegistry.getInstance().getAllDescriptors(); demValueSet = new String[descriptors.length]; for (int i = 0; i < descriptors.length; i++) { demValueSet[i] = descriptors[i].getName(); } if (demValueSet.length > 0) { mosaicModel.getPropertySet().setValue(MosaicFormModel.PROPERTY_ELEVATION_MODEL_NAME, demValueSet[0]); } bindingCtx.addPropertyChangeListener(MosaicFormModel.PROPERTY_UPDATE_MODE, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { final Boolean updateMode = (Boolean) evt.getNewValue(); Boolean enabled1 = !updateMode; crsSelectionPanel.setEnabled(enabled1); } }); } private void createUI() { final TableLayout layout = new TableLayout(1); layout.setTableAnchor(TableLayout.Anchor.WEST); layout.setTableFill(TableLayout.Fill.BOTH); layout.setTableWeightX(1.0); layout.setTableWeightY(0.0); layout.setRowWeightY(2, 1.0); layout.setTablePadding(3, 3); setLayout(layout); CrsForm customCrsUI = new CustomCrsForm(appContext); CrsForm predefinedCrsUI = new PredefinedCrsForm(appContext); crsSelectionPanel = new CrsSelectionPanel(customCrsUI, predefinedCrsUI); crsSelectionPanel.addPropertyChangeListener(MosaicFormModel.PROPERTY_CRS, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { updateForCrsChanged(); } }); add(crsSelectionPanel); add(createOrthorectifyPanel()); add(createMosaicBoundsPanel()); } private void updateForCrsChanged() { final float lon = (float) mosaicModel.getTargetEnvelope().getMedian(0); final float lat = (float) mosaicModel.getTargetEnvelope().getMedian(1); try { final CoordinateReferenceSystem crs = crsSelectionPanel.getCrs(new GeoPos(lat, lon)); if (crs != null) { updatePixelUnit(crs); mosaicModel.setTargetCRS(crs.toWKT()); } else { mosaicModel.setTargetCRS(null); } } catch (FactoryException ignored) { mosaicModel.setTargetCRS(null); } } private void updatePixelUnit(CoordinateReferenceSystem crs) { boundsInputPanel.updatePixelUnit(crs); } private JPanel createMosaicBoundsPanel() { final TableLayout layout = new TableLayout(1); layout.setTableAnchor(TableLayout.Anchor.WEST); layout.setTableFill(TableLayout.Fill.BOTH); layout.setTableWeightX(1.0); layout.setTableWeightY(0.0); layout.setRowWeightY(1, 1.0); layout.setRowAnchor(2, TableLayout.Anchor.EAST); layout.setRowFill(2, TableLayout.Fill.NONE); layout.setTablePadding(3, 3); final JPanel panel = new JPanel(layout); panel.setBorder(BorderFactory.createTitledBorder("Mosaic Bounds")); final WorldMapPaneDataModel worldMapModel = mosaicModel.getWorldMapModel(); setMapBoundary(worldMapModel); final JPanel worldMapPanel = new RegionSelectableWorldMapPane(worldMapModel, bindingCtx).createUI(); bindingCtx.addPropertyChangeListener(new MapBoundsChangeListener()); worldMapPanel.setMinimumSize(new Dimension(250, 125)); worldMapPanel.setBorder(BorderFactory.createEtchedBorder()); final JCheckBox showSourceProductsCheckBox = new JCheckBox("Display source products"); bindingCtx.bind(MosaicFormModel.PROPERTY_SHOW_SOURCE_PRODUCTS, showSourceProductsCheckBox); boundsInputPanel = new BoundsInputPanel(bindingCtx, MosaicFormModel.PROPERTY_UPDATE_MODE); panel.add(boundsInputPanel.createBoundsInputPanel(true)); panel.add(worldMapPanel); panel.add(showSourceProductsCheckBox); return panel; } private JPanel createOrthorectifyPanel() { final TableLayout layout = new TableLayout(2); layout.setTableAnchor(TableLayout.Anchor.WEST); layout.setTableFill(TableLayout.Fill.HORIZONTAL); layout.setTableWeightX(1.0); layout.setTableWeightY(1.0); layout.setTablePadding(3, 3); final JPanel panel = new JPanel(layout); panel.setBorder(BorderFactory.createTitledBorder("Orthorectification")); final JCheckBox orthoCheckBox = new JCheckBox("Orthorectify input products"); bindingCtx.bind(MosaicFormModel.PROPERTY_ORTHORECTIFY, orthoCheckBox); bindingCtx.bindEnabledState(MosaicFormModel.PROPERTY_ORTHORECTIFY, false, MosaicFormModel.PROPERTY_UPDATE_MODE, true); final JComboBox<String> demComboBox = new JComboBox<>(new DefaultComboBoxModel<>(demValueSet)); bindingCtx.bind(MosaicFormModel.PROPERTY_ELEVATION_MODEL_NAME, demComboBox); bindingCtx.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (MosaicFormModel.PROPERTY_ORTHORECTIFY.equals(evt.getPropertyName()) || MosaicFormModel.PROPERTY_UPDATE_MODE.equals(evt.getPropertyName())) { final PropertySet propertySet = bindingCtx.getPropertySet(); boolean updateMode = Boolean.TRUE.equals(propertySet.getValue(MosaicFormModel.PROPERTY_UPDATE_MODE)); boolean orthorectify = Boolean.TRUE.equals(propertySet.getValue(MosaicFormModel.PROPERTY_ORTHORECTIFY)); demComboBox.setEnabled(orthorectify && !updateMode); } } }); layout.setCellColspan(0, 0, 2); panel.add(orthoCheckBox); layout.setCellWeightX(1, 0, 0.0); panel.add(new JLabel("Elevation model:")); layout.setCellWeightX(1, 1, 1.0); panel.add(demComboBox); return panel; } private void setMapBoundary(WorldMapPaneDataModel worldMapModel) { Product boundaryProduct; try { boundaryProduct = mosaicModel.getBoundaryProduct(); } catch (Throwable ignored) { boundaryProduct = null; } worldMapModel.setSelectedProduct(boundaryProduct); } public void prepareShow() { crsSelectionPanel.prepareShow(); } public void prepareHide() { crsSelectionPanel.prepareHide(); } private class MapBoundsChangeListener implements PropertyChangeListener { private final List<String> knownProperties; private MapBoundsChangeListener() { knownProperties = Arrays.asList( MosaicFormModel.PROPERTY_WEST_BOUND, MosaicFormModel.PROPERTY_NORTH_BOUND, MosaicFormModel.PROPERTY_EAST_BOUND, MosaicFormModel.PROPERTY_SOUTH_BOUND, MosaicFormModel.PROPERTY_CRS); } @Override public void propertyChange(PropertyChangeEvent evt) { if (knownProperties.contains(evt.getPropertyName())) { setMapBoundary(mosaicModel.getWorldMapModel()); } } } }