/* * Copyright (C) 2014 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.pixex.visat; import com.bc.ceres.binding.PropertyContainer; import com.bc.ceres.core.ProgressMonitor; import com.bc.ceres.swing.progress.ProgressMonitorSwingWorker; import org.esa.snap.core.dataio.ProductIO; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.gpf.GPF; import org.esa.snap.core.gpf.OperatorSpi; import org.esa.snap.core.gpf.annotations.ParameterDescriptorFactory; import org.esa.snap.core.gpf.ui.OperatorMenu; import org.esa.snap.core.gpf.ui.OperatorParameterSupport; import org.esa.snap.core.gpf.ui.ParameterUpdater; import org.esa.snap.core.util.SystemUtils; import org.esa.snap.core.util.io.WildcardMatcher; import org.esa.snap.pixex.Coordinate; import org.esa.snap.pixex.PixExOp; import org.esa.snap.ui.AppContext; import org.esa.snap.ui.ModelessDialog; import javax.swing.AbstractButton; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.border.EmptyBorder; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import java.awt.Component; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.TreeSet; import java.util.concurrent.ExecutionException; import java.util.logging.Logger; class PixelExtractionDialog extends ModelessDialog implements ParameterUpdater { private static final String OPERATOR_NAME = "PixEx"; private final Map<String, Object> parameterMap; private final AppContext appContext; private final PixelExtractionIOForm ioForm; private final PixelExtractionParametersForm parametersForm; PixelExtractionDialog(AppContext appContext, String title, String helpID) { super(appContext.getApplicationWindow(), title, ID_OK | ID_CLOSE | ID_HELP, helpID); this.appContext = appContext; AbstractButton button = getButton(ID_OK); button.setText("Extract"); button.setMnemonic('E'); parameterMap = new HashMap<>(); final OperatorSpi operatorSpi = GPF.getDefaultInstance().getOperatorSpiRegistry().getOperatorSpi(OPERATOR_NAME); final PropertyContainer propertyContainer = createParameterMap(parameterMap); final OperatorParameterSupport parameterSupport = new OperatorParameterSupport(operatorSpi.getOperatorDescriptor(), propertyContainer, parameterMap, this); final OperatorMenu operatorMenu = new OperatorMenu(this.getJDialog(), operatorSpi.getOperatorDescriptor(), parameterSupport, appContext, getHelpID()); getJDialog().setJMenuBar(operatorMenu.createDefaultMenu()); ListDataListener changeListener = new ListDataListener() { @Override public void intervalAdded(ListDataEvent e) { contentsChanged(e); } @Override public void intervalRemoved(ListDataEvent e) { contentsChanged(e); } @Override public void contentsChanged(ListDataEvent e) { final Product[] sourceProducts = ioForm.getSourceProducts(); if (sourceProducts.length > 0) { parametersForm.setActiveProduct(sourceProducts[0]); return; } else { if (parameterMap.containsKey("sourceProductPaths")) { final String[] inputPaths = (String[]) parameterMap.get("sourceProductPaths"); if (inputPaths.length > 0) { Product firstProduct = openFirstProduct(inputPaths); if (firstProduct != null) { parametersForm.setActiveProduct(firstProduct); return; } } } } parametersForm.setActiveProduct(null); } }; ioForm = new PixelExtractionIOForm(appContext, propertyContainer, changeListener); parametersForm = new PixelExtractionParametersForm(appContext, propertyContainer); final JPanel ioPanel = ioForm.getPanel(); ioPanel.setBorder(new EmptyBorder(4, 4, 4, 4)); final JPanel parametersPanel = parametersForm.getPanel(); parametersPanel.setBorder(new EmptyBorder(4, 4, 4, 4)); JTabbedPane tabbedPanel = new JTabbedPane(); tabbedPanel.addTab("Input/Output", ioPanel); tabbedPanel.addTab("Parameters", parametersPanel); setContent(tabbedPanel); } private Product openFirstProduct(String[] inputPaths) { if (inputPaths != null) { final Logger logger = SystemUtils.LOG; for (String inputPath : inputPaths) { if (inputPath == null || inputPath.trim().length() == 0) { continue; } try { final TreeSet<File> fileSet = new TreeSet<>(); WildcardMatcher.glob(inputPath, fileSet); for (File file : fileSet) { final Product product = ProductIO.readProduct(file); if (product != null) { return product; } } } catch (IOException e) { logger.severe("I/O problem occurred while scanning source product files: " + e.getMessage()); } } } return null; } @Override protected void onOK() { handleParameterSaveRequest(parameterMap); ProgressMonitorSwingWorker worker = new MyProgressMonitorSwingWorker(getParent(), "Creating output file(s)..."); worker.executeWithBlocking(); } @Override public void close() { super.close(); ioForm.clear(); } @Override public int show() { ioForm.addProduct(appContext.getSelectedProduct()); return super.show(); } private static PropertyContainer createParameterMap(Map<String, Object> map) { ParameterDescriptorFactory parameterDescriptorFactory = new ParameterDescriptorFactory(); final PropertyContainer container = PropertyContainer.createMapBacked(map, PixExOp.class, parameterDescriptorFactory); container.setDefaultValues(); return container; } @Override public void handleParameterSaveRequest(Map<String, Object> parameterMap) { parameterMap.put("expression", parametersForm.getExpression()); parameterMap.put("exportExpressionResult", parametersForm.isExportExpressionResultSelected()); parameterMap.put("timeDifference", parametersForm.getAllowedTimeDifference()); parameterMap.put("coordinates", parametersForm.getCoordinates()); } @Override public void handleParameterLoadRequest(Map<String, Object> parameterMap) { Object expressionObject = parameterMap.get("expression"); String expression = ""; if (expressionObject instanceof String) { expression = (String) expressionObject; } parametersForm.setExpression(expression); Object exportExpressionResultObject = parameterMap.get("exportExpressionResult"); if (exportExpressionResultObject instanceof Boolean) { parametersForm.setExportExpressionResultSelected((Boolean) exportExpressionResultObject); } Object timeDifferenceObject = parameterMap.get("timeDifference"); String timeDifference = null; if (timeDifferenceObject instanceof String) { timeDifference = (String) timeDifferenceObject; } parametersForm.setAllowedTimeDifference(timeDifference); Object coordinatesObject = parameterMap.get("coordinates"); Coordinate[] coordinates = new Coordinate[0]; if (coordinatesObject instanceof Coordinate[]) { coordinates = (Coordinate[]) coordinatesObject; } parametersForm.setCoordinates(coordinates); parametersForm.updateUi(); } private class MyProgressMonitorSwingWorker extends ProgressMonitorSwingWorker<Void, Void> { protected MyProgressMonitorSwingWorker(Component parentComponent, String title) { super(parentComponent, title); } @Override protected Void doInBackground(ProgressMonitor pm) throws Exception { pm.beginTask("Computing pixel values...", -1); AbstractButton runButton = getButton(ID_OK); runButton.setEnabled(false); try { GPF.createProduct("PixEx", parameterMap, ioForm.getSourceProducts()); pm.worked(1); } finally { pm.done(); } return null; } @Override protected void done() { try { get(); Object outputDir = parameterMap.get("outputDir"); String message; if (outputDir != null) { message = String.format( "The pixel extraction tool has run successfully and written the result file(s) to %s.", outputDir.toString()); } else { message = "The pixel extraction tool has run successfully and written the result file to to std.out."; } showInformationDialog(message); } catch (InterruptedException ignore) { } catch (ExecutionException e) { appContext.handleError(e.getMessage(), e); } finally { AbstractButton runButton = getButton(ID_OK); runButton.setEnabled(true); } } } }