/* * 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.jts.geom.*; 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; import com.vividsolutions.jump.I18N; /** * Queries a layer by a spatial predicate. */ public class SpatialQueryPlugIn extends AbstractPlugIn implements ThreadedPlugIn { private static String UPDATE_SRC = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Select-features-in-the-source-layer"); private static String CREATE_LYR = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Create-a-new-layer-for-the-results"); private static String MASK_LAYER = GenericNames.MASK_LAYER; private static String SRC_LAYER = GenericNames.SOURCE_LAYER; private static String PREDICATE = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Relation"); private static String PARAM = GenericNames.PARAMETER; private static String DIALOG_COMPLEMENT = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Complement-Result"); private static String ALLOW_DUPS = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Allow-Duplicates-in-Result"); private JTextField paramField; private Collection functionNames; private MultiInputDialog dialog; private Layer maskLyr; private Layer srcLayer; private String funcNameToRun; private GeometryPredicate functionToRun = null; private boolean complementResult = false; private boolean allowDups = false; private boolean exceptionThrown = false; private JRadioButton updateSourceRB; private JRadioButton createNewLayerRB; private boolean createLayer = true; private double[] params = new double[2]; public SpatialQueryPlugIn() { functionNames = GeometryPredicate.getNames(); } private String categoryName = StandardCategoryNames.RESULT; public void setCategoryName(String value) { categoryName = value; } public String getName(){ return I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Spatial-Query"); } public void initialize(PlugInContext context) throws Exception { FeatureInstaller featureInstaller = new FeatureInstaller(context.getWorkbenchContext()); featureInstaller.addMainMenuItem( this, //exe new String[] {MenuNames.TOOLS, MenuNames.TOOLS_QUERIES}, //menu path this.getName() + "..." , //name methode .getName received by AbstractPlugIn false, //checkbox null, //icon createEnableCheck(context.getWorkbenchContext())); //enable check } 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 { //[sstein] added again for correct language setting UPDATE_SRC = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Select-features-in-the-source-layer"); CREATE_LYR = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Create-a-new-layer-for-the-results"); MASK_LAYER = GenericNames.MASK_LAYER; SRC_LAYER = GenericNames.SOURCE_LAYER; PREDICATE = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Relation"); PARAM = GenericNames.PARAMETER; DIALOG_COMPLEMENT = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Complement-Result"); ALLOW_DUPS = I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Allow-Duplicates-in-Result"); 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 (maskLyr == null) return; if (srcLayer == null) return; monitor.report(I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Executing-query")+" " + functionToRun.getName() + "..."); FeatureCollection maskFC = maskLyr.getFeatureCollectionWrapper(); FeatureCollection sourceFC = srcLayer.getFeatureCollectionWrapper(); int nArgs = functionToRun.getGeometryArgumentCount(); SpatialQueryExecuter executer = new SpatialQueryExecuter(maskFC, sourceFC); executer.setAllowDuplicates(allowDups); executer.setComplementResult(complementResult); // Code added by the Sunburned Surveyor to allow // the creation of "normal" selections if a new // layer isn't being created for the features // selected as part of the spatial analysis. executer.setCreateNewLayer(createLayer); FeatureCollection resultFC = executer.getResultFC(); executer.execute(monitor, functionToRun, params, resultFC); if (monitor.isCancelRequested()) return; if (createLayer) { String outputLayerName = LayerNameGenerator.generateOperationOnLayerName( funcNameToRun, srcLayer.getName()); context.getLayerManager().addCategory(categoryName); context.addLayer(categoryName, outputLayerName, resultFC); } else { SelectionManager selectionManager = context.getLayerViewPanel().getSelectionManager(); selectionManager.clear(); selectionManager.getFeatureSelection().selectItems( srcLayer, resultFC.getFeatures() ); } if (exceptionThrown) { context.getWorkbenchFrame().warnUser(I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Errors-found-while-executing-query")); } } private void setDialogValues(MultiInputDialog dialog, PlugInContext context) { //dialog.setSideBarImage(new ImageIcon(getClass().getResource("DiffSegments.png"))); dialog.setSideBarDescription( I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.Finds-the-Source-features-which-have-a-given-spatial-relationship-to-some-feature-in-the-Mask-layer") + " (" + I18N.get("ui.plugin.analysis.SpatialQueryPlugIn.ie-where-Source.Relationship(Mask)-is-true") + ")" ); //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 initLayer = (srcLayer == null)? context.getCandidateLayer(0) : srcLayer; dialog.addLayerComboBox(SRC_LAYER, initLayer, context.getLayerManager()); JComboBox functionComboBox = dialog.addComboBox(PREDICATE, funcNameToRun, functionNames, null); functionComboBox.addItemListener(new MethodItemListener()); dialog.addLayerComboBox(MASK_LAYER, maskLyr, context.getLayerManager()); paramField = dialog.addDoubleField(PARAM, params[0], 10); dialog.addCheckBox(ALLOW_DUPS, allowDups); dialog.addCheckBox(DIALOG_COMPLEMENT, complementResult); final String OUTPUT_GROUP = "OUTPUT_GROUP"; createNewLayerRB = dialog.addRadioButton(CREATE_LYR, OUTPUT_GROUP, createLayer,CREATE_LYR); updateSourceRB = dialog.addRadioButton(UPDATE_SRC, OUTPUT_GROUP, !createLayer, UPDATE_SRC); updateUIForFunction(funcNameToRun); } private void getDialogValues(MultiInputDialog dialog) { maskLyr = dialog.getLayer(MASK_LAYER); srcLayer = dialog.getLayer(SRC_LAYER); funcNameToRun = dialog.getText(PREDICATE); functionToRun = GeometryPredicate.getPredicate(funcNameToRun); params[0] = dialog.getDouble(PARAM); allowDups = dialog.getBoolean(ALLOW_DUPS); complementResult = dialog.getBoolean(DIALOG_COMPLEMENT); createLayer = dialog.getBoolean(CREATE_LYR); } 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()); } } }