/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * Copyright (C) 2003 Vivid Solutions * * 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 2 * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For more information, contact: * * Vivid Solutions * Suite #1A * 2328 Government Street * Victoria BC V8T 5G5 * Canada * * (250)385-6040 * www.vividsolutions.com */ package com.vividsolutions.jump.workbench.ui.plugin.analysis; import java.util.*; import java.awt.event.*; import javax.swing.*; import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.feature.*; import com.vividsolutions.jump.task.*; import com.vividsolutions.jump.workbench.WorkbenchContext; import com.vividsolutions.jump.workbench.model.*; import com.vividsolutions.jump.workbench.plugin.*; import com.vividsolutions.jump.workbench.plugin.util.*; import com.vividsolutions.jump.workbench.ui.*; import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller; /** * Queries a layer by a spatial predicate. */ public class SpatialJoinPlugIn extends AbstractPlugIn implements ThreadedPlugIn { private Layer srcLayerA; private Layer srcLayerB; private JTextField paramField; private Collection functionNames; private MultiInputDialog dialog; private String funcNameToRun; private GeometryPredicate functionToRun = null; private boolean exceptionThrown = false; private double[] params = new double[2]; public SpatialJoinPlugIn() { functionNames = GeometryPredicate.getNames(); } private String categoryName = StandardCategoryNames.RESULT; public String getName(){ //exchanged plugin with SIGLE plugin return I18N.get("ui.plugin.analysis.SpatialJoinPlugIn.Spatial-Join"); //return I18N.get("org.openjump.sigle.plugin.SpatialJoinPlugIn.Transfer-Attributes"); } public void setCategoryName(String value) { categoryName = value; } public void initialize(PlugInContext context) throws Exception { FeatureInstaller featureInstaller = new FeatureInstaller(context.getWorkbenchContext()); featureInstaller.addMainMenuItem( this, new String[] {MenuNames.TOOLS, MenuNames.TOOLS_ANALYSIS}, this.getName() + "...", false, //checkbox null, //icon createEnableCheck(context.getWorkbenchContext())); } public static MultiEnableCheck createEnableCheck(WorkbenchContext workbenchContext) { EnableCheckFactory checkFactory = new EnableCheckFactory(workbenchContext); return new MultiEnableCheck() .add(checkFactory.createWindowWithLayerNamePanelMustBeActiveCheck()) .add(checkFactory.createAtLeastNLayersMustExistCheck(2)); } public boolean execute(PlugInContext context) throws Exception { dialog = new MultiInputDialog(context.getWorkbenchFrame(), getName(), true); setDialogValues(dialog, context); GUIUtil.centreOnWindow(dialog); dialog.setVisible(true); if (! dialog.wasOKPressed()) { return false; } getDialogValues(dialog); return true; } public void run(TaskMonitor monitor, PlugInContext context) throws Exception { monitor.allowCancellationRequests(); // input-proofing if (functionToRun == null) return; if (srcLayerA == null) return; if (srcLayerB == null) return; monitor.report( I18N.get("ui.plugin.analysis.SpatialJoinPlugIn.Executing-join") + " " + functionToRun.getName() + "..."); FeatureCollection srcAFC = srcLayerA.getFeatureCollectionWrapper(); FeatureCollection srcBFC = srcLayerB.getFeatureCollectionWrapper(); //[sstein 28.Mar.2008] reversed order of input //(to be able to read from top to down the spatial relations) SpatialJoinExecuter executer = new SpatialJoinExecuter(srcBFC, srcAFC); FeatureCollection resultFC = executer.getResultFC(); executer.execute(monitor, functionToRun, params, resultFC); if (monitor.isCancelRequested()) return; String outputLayerName = I18N.get("ui.plugin.analysis.SpatialJoinPlugIn.Join")+ "-" + funcNameToRun; context.getLayerManager().addCategory(categoryName); context.addLayer(categoryName, outputLayerName, resultFC); if (exceptionThrown) { context.getWorkbenchFrame() .warnUser("Errors found while executing query"); } } private final static String LAYER_A = GenericNames.LAYER_A + " (" + GenericNames.TARGET_LAYER + ")"; private final static String LAYER_B = GenericNames.LAYER_B + " (" + GenericNames.SOURCE_LAYER + ")"; private final static String PREDICATE = GenericNames.RELATION; private final static String PARAM = GenericNames.PARAMETER; private void setDialogValues(MultiInputDialog dialog, PlugInContext context) { //dialog.setSideBarImage(new ImageIcon(getClass().getResource("DiffSegments.png"))); //[sstein 31March2008] replaced sidebar description by better description use in SIGLE plugin /* dialog.setSideBarDescription( I18N.get("ui.plugin.analysis.SpatialJoinPlugIn.Joins-two-layers-on-a-given-spatial-relationship") + " (" + I18N.get("ui.plugin.analysis.SpatialJoinPlugIn.example") +")"); */ dialog.setSideBarDescription( I18N.get("org.openjump.sigle.plugin.SpatialJoinPlugIn.Transfers-the-attributes-of-Layer-B-to-Layer-A-using-a-spatial-criterion") ); //Set initial layer values to the first and second layers in the layer list. //In #initialize we've already checked that the number of layers >= 1. [Jon Aquino] Layer initLayer1 = (srcLayerA == null)? context.getCandidateLayer(0) : srcLayerA; Layer initLayer2 = (srcLayerB == null)? context.getCandidateLayer(1) : srcLayerB; dialog.addLayerComboBox(LAYER_A, initLayer1, context.getLayerManager()); JComboBox functionComboBox = dialog.addComboBox(PREDICATE, funcNameToRun, functionNames, null); functionComboBox.addItemListener(new MethodItemListener()); paramField = dialog.addDoubleField(PARAM, params[0], 10); dialog.addLayerComboBox(LAYER_B, initLayer2, context.getLayerManager()); updateUIForFunction(funcNameToRun); } private void getDialogValues(MultiInputDialog dialog) { srcLayerA = dialog.getLayer(LAYER_A); srcLayerB = dialog.getLayer(LAYER_B); funcNameToRun = dialog.getText(PREDICATE); functionToRun = GeometryPredicate.getPredicate(funcNameToRun); params[0] = dialog.getDouble(PARAM); } private void updateUIForFunction(String funcName) { boolean paramUsed = false; GeometryPredicate func = GeometryPredicate.getPredicate(funcName); if (func != null) { paramUsed = func.getParameterCount() > 0; } paramField.setEnabled(paramUsed); // this has the effect of making the background gray (disabled) paramField.setOpaque(paramUsed); } private class MethodItemListener implements ItemListener { public void itemStateChanged(ItemEvent e) { updateUIForFunction((String) e.getItem()); } } }