001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032:
033: package com.vividsolutions.jump.workbench.ui.plugin.analysis;
034:
035: import java.util.*;
036:
037: import java.awt.event.*;
038: import javax.swing.*;
039:
040: import com.vividsolutions.jts.geom.*;
041: import com.vividsolutions.jump.feature.*;
042: import com.vividsolutions.jump.task.*;
043: import com.vividsolutions.jump.workbench.model.*;
044: import com.vividsolutions.jump.workbench.plugin.*;
045: import com.vividsolutions.jump.workbench.plugin.util.*;
046: import com.vividsolutions.jump.workbench.ui.*;
047: import com.vividsolutions.jump.I18N;
048:
049: /**
050: * Queries a layer by a spatial predicate.
051: */
052: public class SpatialQueryPlugIn extends AbstractPlugIn implements
053: ThreadedPlugIn {
054:
055: private static String UPDATE_SRC = I18N
056: .get("ui.plugin.analysis.SpatialQueryPlugIn.Select-features-in-the-source-layer");
057: private static String CREATE_LYR = I18N
058: .get("ui.plugin.analysis.SpatialQueryPlugIn.Create-a-new-layer-for-the-results");
059: private static String MASK_LAYER = GenericNames.MASK_LAYER;
060: private static String SRC_LAYER = GenericNames.SOURCE_LAYER;
061: private static String PREDICATE = I18N
062: .get("ui.plugin.analysis.SpatialQueryPlugIn.Relation");
063: private static String PARAM = GenericNames.PARAMETER;
064: private static String DIALOG_COMPLEMENT = I18N
065: .get("ui.plugin.analysis.SpatialQueryPlugIn.Complement-Result");
066: private static String ALLOW_DUPS = I18N
067: .get("ui.plugin.analysis.SpatialQueryPlugIn.Allow-Duplicates-in-Result");
068:
069: private JTextField paramField;
070: private Collection functionNames;
071: private MultiInputDialog dialog;
072: private Layer maskLyr;
073: private Layer srcLayer;
074: private String funcNameToRun;
075: private GeometryPredicate functionToRun = null;
076: private boolean complementResult = false;
077: private boolean allowDups = false;
078: private boolean exceptionThrown = false;
079: private JRadioButton updateSourceRB;
080: private JRadioButton createNewLayerRB;
081: private boolean createLayer = true;
082:
083: private double[] params = new double[2];
084:
085: public SpatialQueryPlugIn() {
086: functionNames = GeometryPredicate.getNames();
087: }
088:
089: private String categoryName = StandardCategoryNames.RESULT;
090:
091: public void setCategoryName(String value) {
092: categoryName = value;
093: }
094:
095: public String getName() {
096: return I18N
097: .get("ui.plugin.analysis.SpatialQueryPlugIn.Spatial-Query");
098: }
099:
100: public boolean execute(PlugInContext context) throws Exception {
101: //[sstein] added again for correct language setting
102: UPDATE_SRC = I18N
103: .get("ui.plugin.analysis.SpatialQueryPlugIn.Select-features-in-the-source-layer");
104: CREATE_LYR = I18N
105: .get("ui.plugin.analysis.SpatialQueryPlugIn.Create-a-new-layer-for-the-results");
106: MASK_LAYER = GenericNames.MASK_LAYER;
107: SRC_LAYER = GenericNames.SOURCE_LAYER;
108: PREDICATE = I18N
109: .get("ui.plugin.analysis.SpatialQueryPlugIn.Relation");
110: PARAM = GenericNames.PARAMETER;
111: DIALOG_COMPLEMENT = I18N
112: .get("ui.plugin.analysis.SpatialQueryPlugIn.Complement-Result");
113: ALLOW_DUPS = I18N
114: .get("ui.plugin.analysis.SpatialQueryPlugIn.Allow-Duplicates-in-Result");
115:
116: dialog = new MultiInputDialog(context.getWorkbenchFrame(),
117: getName(), true);
118: setDialogValues(dialog, context);
119: GUIUtil.centreOnWindow(dialog);
120: dialog.setVisible(true);
121: if (!dialog.wasOKPressed()) {
122: return false;
123: }
124: getDialogValues(dialog);
125: return true;
126: }
127:
128: public void run(TaskMonitor monitor, PlugInContext context)
129: throws Exception {
130: monitor.allowCancellationRequests();
131:
132: // input-proofing
133: if (functionToRun == null)
134: return;
135: if (maskLyr == null)
136: return;
137: if (srcLayer == null)
138: return;
139:
140: monitor
141: .report(I18N
142: .get("ui.plugin.analysis.SpatialQueryPlugIn.Executing-query")
143: + " " + functionToRun.getName() + "...");
144:
145: FeatureCollection maskFC = maskLyr
146: .getFeatureCollectionWrapper();
147: FeatureCollection sourceFC = srcLayer
148: .getFeatureCollectionWrapper();
149:
150: int nArgs = functionToRun.getGeometryArgumentCount();
151:
152: SpatialQueryExecuter executer = new SpatialQueryExecuter(
153: maskFC, sourceFC);
154: executer.setAllowDuplicates(allowDups);
155: executer.setComplementResult(complementResult);
156: FeatureCollection resultFC = executer.getResultFC();
157: executer.execute(monitor, functionToRun, params, resultFC);
158:
159: if (monitor.isCancelRequested())
160: return;
161:
162: if (createLayer) {
163: String outputLayerName = LayerNameGenerator
164: .generateOperationOnLayerName(funcNameToRun,
165: srcLayer.getName());
166: context.getLayerManager().addCategory(categoryName);
167: context.addLayer(categoryName, outputLayerName, resultFC);
168: } else {
169: SelectionManager selectionManager = context
170: .getLayerViewPanel().getSelectionManager();
171: selectionManager.clear();
172: selectionManager.getFeatureSelection().selectItems(
173: srcLayer, resultFC.getFeatures());
174: }
175:
176: if (exceptionThrown) {
177: context
178: .getWorkbenchFrame()
179: .warnUser(
180: I18N
181: .get("ui.plugin.analysis.SpatialQueryPlugIn.Errors-found-while-executing-query"));
182: }
183: }
184:
185: private void setDialogValues(MultiInputDialog dialog,
186: PlugInContext context) {
187: //dialog.setSideBarImage(new ImageIcon(getClass().getResource("DiffSegments.png")));
188: dialog
189: .setSideBarDescription(I18N
190: .get("ui.plugin.analysis.SpatialQueryPlugIn.Finds-the-Source-features-which-have-a-given-spatial-relationship-to-some-feature-in-the-Mask-layer")
191: + " ("
192: + I18N
193: .get("ui.plugin.analysis.SpatialQueryPlugIn.ie-where-Source.Relationship(Mask)-is-true")
194: + ")");
195:
196: //Set initial layer values to the first and second layers in the layer list.
197: //In #initialize we've already checked that the number of layers >= 1. [Jon Aquino]
198: Layer initLayer = (srcLayer == null) ? context
199: .getCandidateLayer(0) : srcLayer;
200:
201: dialog.addLayerComboBox(SRC_LAYER, initLayer, context
202: .getLayerManager());
203: JComboBox functionComboBox = dialog.addComboBox(PREDICATE,
204: funcNameToRun, functionNames, null);
205: functionComboBox.addItemListener(new MethodItemListener());
206: dialog.addLayerComboBox(MASK_LAYER, maskLyr, context
207: .getLayerManager());
208:
209: paramField = dialog.addDoubleField(PARAM, params[0], 10);
210: dialog.addCheckBox(ALLOW_DUPS, allowDups);
211: dialog.addCheckBox(DIALOG_COMPLEMENT, complementResult);
212:
213: final String OUTPUT_GROUP = "OUTPUT_GROUP";
214: createNewLayerRB = dialog.addRadioButton(CREATE_LYR,
215: OUTPUT_GROUP, createLayer, CREATE_LYR);
216: updateSourceRB = dialog.addRadioButton(UPDATE_SRC,
217: OUTPUT_GROUP, !createLayer, UPDATE_SRC);
218:
219: updateUIForFunction(funcNameToRun);
220: }
221:
222: private void getDialogValues(MultiInputDialog dialog) {
223: maskLyr = dialog.getLayer(MASK_LAYER);
224: srcLayer = dialog.getLayer(SRC_LAYER);
225: funcNameToRun = dialog.getText(PREDICATE);
226: functionToRun = GeometryPredicate.getPredicate(funcNameToRun);
227: params[0] = dialog.getDouble(PARAM);
228: allowDups = dialog.getBoolean(ALLOW_DUPS);
229: complementResult = dialog.getBoolean(DIALOG_COMPLEMENT);
230: createLayer = dialog.getBoolean(CREATE_LYR);
231: }
232:
233: private void updateUIForFunction(String funcName) {
234: boolean paramUsed = false;
235: GeometryPredicate func = GeometryPredicate
236: .getPredicate(funcName);
237: if (func != null) {
238: paramUsed = func.getParameterCount() > 0;
239: }
240: paramField.setEnabled(paramUsed);
241: // this has the effect of making the background gray (disabled)
242: paramField.setOpaque(paramUsed);
243: }
244:
245: private class MethodItemListener implements ItemListener {
246: public void itemStateChanged(ItemEvent e) {
247: updateUIForFunction((String) e.getItem());
248: }
249: }
250:
251: }
|