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: * JUMP is Copyright (C) 2003 Vivid Solutions
006: *
007: * This program implements extensions to JUMP and is
008: * Copyright (C) Stefan Steiniger.
009: *
010: * This program is free software; you can redistribute it and/or
011: * modify it under the terms of the GNU General Public License
012: * as published by the Free Software Foundation; either version 2
013: * of the License, or (at your option) any later version.
014: *
015: * This program is distributed in the hope that it will be useful,
016: * but WITHOUT ANY WARRANTY; without even the implied warranty of
017: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: * GNU General Public License for more details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with this program; if not, write to the Free Software
022: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
023: *
024: * For more information, contact:
025: * Stefan Steiniger
026: * perriger@gmx.de
027: */
028: /*****************************************************
029: * created: 22.06.2006
030: * last modified:
031: *
032: *
033: * author: sstein
034: *
035: * description:
036: * merges attributes according to some spatial and statistical criteria
037: * from one dataset to another
038: *****************************************************/package org.openjump.core.ui.plugin.tools;
039:
040: import java.awt.event.ItemEvent;
041: import java.awt.event.ItemListener;
042: import java.util.ArrayList;
043: import java.util.List;
044:
045: import javax.swing.DefaultComboBoxModel;
046: import javax.swing.JComboBox;
047:
048: import org.openjump.core.spatialAttributeOps.*;
049:
050: import com.vividsolutions.jump.I18N;
051: import com.vividsolutions.jump.feature.FeatureDataset;
052: import com.vividsolutions.jump.task.TaskMonitor;
053: import com.vividsolutions.jump.workbench.WorkbenchContext;
054: import com.vividsolutions.jump.workbench.model.Layer;
055: import com.vividsolutions.jump.workbench.model.StandardCategoryNames;
056: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
057: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
058: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
059: import com.vividsolutions.jump.workbench.plugin.ThreadedBasePlugIn;
060: import com.vividsolutions.jump.workbench.ui.GUIUtil;
061: import com.vividsolutions.jump.workbench.ui.MenuNames;
062: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
063: import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
064:
065: /**
066: * @description:
067: * merges attributes according to some spatial and statistical criteria
068: * from one dataset to another
069: *
070: * @author sstein
071: *
072: **/
073: public class JoinAttributesSpatiallyPlugIn extends ThreadedBasePlugIn {
074:
075: private String sidebartext = I18N
076: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.Joins-attributes-of-source-layer-according-to-a-spatial-and-a-statistic-criterion");
077: private String SRC_LAYER = I18N
078: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-layer");
079: private String TGT_LAYER = I18N
080: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.target-layer");
081: private String SRC_ATTRIB = I18N
082: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute");
083: private String ATTRIB_OP = I18N
084: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute-operation");
085: private String SPATIAL_OP = I18N
086: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-spatial-operation");
087: private String joinresult = I18N
088: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.join-result");
089: private String notimplemented = I18N
090: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.not-implemented");
091: private String BUFFER_RADIUS = I18N
092: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.buffer-radius");
093: //-- vars
094: private Layer srcLayer = null;
095: private Layer targetLayer = null;
096: private String attrName = "";
097: int attributeOperation = 0;
098: int spatialOperation = 0;
099: private double bradius = 0.0;
100:
101: private MultiInputDialog dialog;
102: private PlugInContext pc = null;
103:
104: ArrayList attrOpList = new ArrayList();
105: ArrayList spatialOpList = new ArrayList();
106:
107: public void initialize(PlugInContext context) throws Exception {
108:
109: FeatureInstaller featureInstaller = new FeatureInstaller(
110: context.getWorkbenchContext());
111: featureInstaller.addMainMenuItem(this , //exe
112: new String[] { MenuNames.TOOLS,
113: MenuNames.TOOLS_ANALYSIS }, //menu path
114: this .getName() + "{pos:5}", //name methode .getName recieved by AbstractPlugIn
115: false, //checkbox
116: null, //icon
117: createEnableCheck(context.getWorkbenchContext())); //enable check
118: }
119:
120: public String getName() {
121: return I18N
122: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.Join-Attributes-Spatially");
123: }
124:
125: public static MultiEnableCheck createEnableCheck(
126: WorkbenchContext workbenchContext) {
127: EnableCheckFactory checkFactory = new EnableCheckFactory(
128: workbenchContext);
129:
130: return new MultiEnableCheck()
131: .add(
132: checkFactory
133: .createWindowWithLayerNamePanelMustBeActiveCheck())
134: .add(checkFactory.createAtLeastNLayersMustExistCheck(2))
135: /*.add(checkFactory.createAtLeastNItemsMustBeSelectedCheck(2)*)*/;
136: }
137:
138: /*
139: * do some dialog things first - processing is done in #run()
140: */
141: public boolean execute(PlugInContext context) throws Exception {
142:
143: sidebartext = I18N
144: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.Joins-attributes-of-source-layer-according-to-a-spatial-and-a-statistic-criterion");
145: SRC_LAYER = I18N
146: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-layer");
147: TGT_LAYER = I18N
148: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.target-layer");
149: SRC_ATTRIB = I18N
150: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute");
151: ATTRIB_OP = I18N
152: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute-operation");
153: SPATIAL_OP = I18N
154: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-spatial-operation");
155: joinresult = I18N
156: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.join-result");
157: notimplemented = I18N
158: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.not-implemented");
159: BUFFER_RADIUS = I18N
160: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.buffer-radius");
161:
162: this .generateOpLists();
163:
164: this .dialog = new MultiInputDialog(context.getWorkbenchFrame(),
165: getName(), true);
166: setDialogValues(dialog, context);
167: GUIUtil.centreOnWindow(dialog);
168: dialog.setVisible(true);
169: if (!dialog.wasOKPressed()) {
170: return false;
171: }
172: getdialogValues(dialog);
173: return true;
174: }
175:
176: public void run(TaskMonitor monitor, PlugInContext context)
177: throws Exception {
178:
179: monitor.allowCancellationRequests();
180: this .pc = context;
181:
182: List srcFeatures = this .srcLayer.getFeatureCollectionWrapper()
183: .getFeatures();
184: List targetFeatures = this .targetLayer
185: .getFeatureCollectionWrapper().getFeatures();
186:
187: FeatureDataset results = JoinAttributes.joinAttributes(
188: srcFeatures, targetFeatures, this .attrName,
189: this .attributeOperation, this .spatialOperation,
190: this .bradius, monitor);
191: if (results.size() > 0) {
192: context.addLayer(StandardCategoryNames.WORKING, joinresult,
193: results);
194: } else {
195: context.getWorkbenchFrame().warnUser(notimplemented);
196: }
197: //context.getWorkbenchContext().getLayerViewPanel().getSelectionManager().clear();
198: }
199:
200: //============================================================
201: // dialog things
202: //============================================================
203:
204: private JComboBox layerboxA;
205: private JComboBox layerboxB;
206: private JComboBox attribbox;
207: private JComboBox attribOpbox;
208: private JComboBox spatialOpbox;
209:
210: private Object attrValue = null;
211: private Object attrOpValue = "";
212: private Object spatialOpValue = "";
213: private ArrayList attColl = new ArrayList();
214: private ArrayList attOpColl = new ArrayList();
215: private ArrayList SpatialOpColl = new ArrayList();
216:
217: /**
218: * @param selectTypeDialog2
219: * @param context
220: */
221: private void setDialogValues(MultiInputDialog selectTypeDialog2,
222: PlugInContext context) {
223: this .dialog.setSideBarDescription(sidebartext);
224: //-- target layer
225: if (targetLayer == null)
226: targetLayer = context.getCandidateLayer(0);
227: layerboxA = this .dialog.addLayerComboBox(TGT_LAYER,
228: targetLayer, "", context.getLayerManager());
229: //-- source layer
230: if (srcLayer == null)
231: srcLayer = context.getCandidateLayer(0);
232: layerboxB = this .dialog.addLayerComboBox(SRC_LAYER, srcLayer,
233: "", context.getLayerManager());
234: layerboxB.addItemListener(new MethodItemListener());
235:
236: //-- attribute
237: attribbox = this .dialog.addComboBox(SRC_ATTRIB, attrValue,
238: attColl, "");
239: updateUIForAttributes();
240:
241: //-- attributeOp
242: attribOpbox = this .dialog.addComboBox(ATTRIB_OP, attrOpValue,
243: attOpColl, "");
244: DefaultComboBoxModel modelA = new DefaultComboBoxModel();
245: for (int i = 0; i < this .attrOpList.size(); i++) {
246: modelA.addElement(this .attrOpList.get(i));
247: }
248: attribOpbox.setModel(modelA);
249:
250: //-- spatial Relation
251: spatialOpbox = this .dialog.addComboBox(SPATIAL_OP, attrValue,
252: attOpColl, "");
253: DefaultComboBoxModel modelS = new DefaultComboBoxModel();
254: for (int i = 0; i < this .spatialOpList.size(); i++) {
255: modelS.addElement(this .spatialOpList.get(i));
256: }
257: spatialOpbox.setModel(modelS);
258:
259: //-- add buffer
260: dialog.addDoubleField(BUFFER_RADIUS, this .bradius, 7);
261: }
262:
263: private void updateUIForAttributes() {
264: this .srcLayer = dialog.getLayer(SRC_LAYER);
265: DefaultComboBoxModel model = new DefaultComboBoxModel();
266: for (int i = 0; i < srcLayer.getFeatureCollectionWrapper()
267: .getFeatureSchema().getAttributeCount(); i++) {
268: if (i == srcLayer.getFeatureCollectionWrapper()
269: .getFeatureSchema().getGeometryIndex()) {
270: continue;
271: }
272: model.addElement(srcLayer.getFeatureCollectionWrapper()
273: .getFeatureSchema().getAttributeName(i));
274: }
275: attribbox.setModel(model);
276:
277: if (model.getSize() == 0) {
278: //Can get here if the only attribute is the geometry. [Jon Aquino]
279: }
280: this .dialog.validate();
281:
282: }
283:
284: private void getdialogValues(MultiInputDialog dialog) {
285: this .srcLayer = dialog.getLayer(SRC_LAYER);
286: this .targetLayer = dialog.getLayer(TGT_LAYER);
287: this .attrName = (String) attribbox.getSelectedItem();
288: this .attributeOperation = attribOpbox.getSelectedIndex();
289: this .spatialOperation = spatialOpbox.getSelectedIndex();
290: this .bradius = dialog.getDouble(BUFFER_RADIUS);
291: }
292:
293: private void generateOpLists() {
294: //-- note the order and position is important
295: // since it will be used to obtain directly the values
296:
297: // the available operations are defined in AttributeOp.java
298: /** copy from AttributeOp
299: public final static int MAJORITY = 0;
300: public final static int MINORITY = 1;
301: public final static int MEAN = 2;
302: public final static int MEDIAN = 3;
303: public final static int MIN = 4;
304: public final static int MAX = 5;
305: public final static int STD = 6;
306: public final static int SUM = 7;
307: public final static int COUNT = 8;
308: **/
309: this .attrOpList.clear(); //because function may be called several times
310: this .attrOpList
311: .add(
312: AttributeOp.MAJORITY,
313: I18N
314: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.majority"));
315: this .attrOpList
316: .add(
317: AttributeOp.MINORITY,
318: I18N
319: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.minority"));
320: this .attrOpList
321: .add(
322: AttributeOp.MEAN,
323: I18N
324: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.mean"));
325: this .attrOpList
326: .add(
327: AttributeOp.MEDIAN,
328: I18N
329: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.median"));
330: this .attrOpList
331: .add(
332: AttributeOp.MIN,
333: I18N
334: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.minimum"));
335: this .attrOpList
336: .add(
337: AttributeOp.MAX,
338: I18N
339: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.maximum"));
340: this .attrOpList
341: .add(
342: AttributeOp.STD,
343: I18N
344: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.standard-dev"));
345: this .attrOpList
346: .add(
347: AttributeOp.SUM,
348: I18N
349: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.sum"));
350: this .attrOpList
351: .add(
352: AttributeOp.COUNT,
353: I18N
354: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.count"));
355:
356: // the available operations are defined in SpatialRelationOp.java
357: /** copy from SpatialRelationOp
358: public final static int CONTAINS = 0;
359: public final static int INTERSECTS = 1;
360: **/
361: this .spatialOpList.clear();
362: this .spatialOpList
363: .add(
364: SpatialRelationOp.CONTAINS,
365: I18N
366: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-features-contained-in-a-target-feature"));
367: this .spatialOpList
368: .add(
369: SpatialRelationOp.INTERSECTS,
370: I18N
371: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-features-intersecting-a-target-feature"));
372: this .spatialOpList
373: .add(
374: SpatialRelationOp.COVEREDBY,
375: I18N
376: .get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.target-feature-covered-by-source-features"));
377: }
378:
379: //============================================================
380: // dialog listeners
381: //============================================================
382:
383: private class MethodItemListener implements ItemListener {
384:
385: public void itemStateChanged(ItemEvent e) {
386: updateUIForAttributes();
387: }
388: }
389:
390: }
|