/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * JUMP is Copyright (C) 2003 Vivid Solutions * * This program implements extensions to JUMP and is * Copyright (C) Stefan Steiniger. * * 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: * Stefan Steiniger * perriger@gmx.de */ /***************************************************** * created: 22.06.2006 * last modified: * * @author sstein * * Merges attributes according to some spatial and statistical criteria * from one dataset to another *****************************************************/ package org.openjump.core.ui.plugin.tools; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.List; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import org.openjump.core.attributeoperations.*; import com.vividsolutions.jump.I18N; import com.vividsolutions.jump.feature.FeatureDataset; import com.vividsolutions.jump.task.TaskMonitor; import com.vividsolutions.jump.workbench.WorkbenchContext; import com.vividsolutions.jump.workbench.model.Layer; import com.vividsolutions.jump.workbench.model.StandardCategoryNames; import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory; import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck; import com.vividsolutions.jump.workbench.plugin.PlugInContext; import com.vividsolutions.jump.workbench.plugin.ThreadedBasePlugIn; import com.vividsolutions.jump.workbench.ui.GUIUtil; import com.vividsolutions.jump.workbench.ui.MenuNames; import com.vividsolutions.jump.workbench.ui.MultiInputDialog; import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller; /** * Merges attributes according to some spatial and statistical criteria * from one dataset to another * * @author sstein * **/ public class JoinAttributesSpatiallyPlugIn extends ThreadedBasePlugIn{ private String sidebartext = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.Joins-attributes-of-source-layer-according-to-a-spatial-and-a-statistic-criterion"); private String SRC_LAYER = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-layer"); private String TGT_LAYER = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.target-layer"); private String SRC_ATTRIB = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute"); private String ATTRIB_OP = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute-operation"); private String SPATIAL_OP = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-spatial-operation"); private String joinresult = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.join-result"); private String notimplemented= I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.not-implemented"); private String BUFFER_RADIUS = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.buffer-radius"); //-- vars private Layer srcLayer = null; private Layer targetLayer = null; private String attrName = ""; int attributeOperation = 0; int spatialOperation = 0; private double bradius = 0.0; private MultiInputDialog dialog; private PlugInContext pc = null; ArrayList attrOpList = new ArrayList(); ArrayList spatialOpList = new ArrayList(); 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 String getName(){ return I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.Join-Attributes-Spatially") + "..."; } public static MultiEnableCheck createEnableCheck(WorkbenchContext workbenchContext) { EnableCheckFactory checkFactory = new EnableCheckFactory(workbenchContext); return new MultiEnableCheck() .add(checkFactory.createWindowWithLayerNamePanelMustBeActiveCheck()) .add(checkFactory.createAtLeastNLayersMustExistCheck(2)) /*.add(checkFactory.createAtLeastNItemsMustBeSelectedCheck(2)*)*/; } /* * do some dialog things first - processing is done in #run() */ public boolean execute(PlugInContext context) throws Exception { sidebartext = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.Joins-attributes-of-source-layer-according-to-a-spatial-and-a-statistic-criterion"); SRC_LAYER = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-layer"); TGT_LAYER = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.target-layer"); SRC_ATTRIB = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute"); ATTRIB_OP = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-attribute-operation"); SPATIAL_OP = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.select-spatial-operation"); joinresult = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.join-result"); notimplemented= I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.not-implemented"); BUFFER_RADIUS = I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.buffer-radius"); this.generateOpLists(); this.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(); this.pc = context; List srcFeatures = this.srcLayer.getFeatureCollectionWrapper().getFeatures(); List targetFeatures = this.targetLayer.getFeatureCollectionWrapper().getFeatures(); FeatureDataset results = JoinAttributes.joinAttributes(srcFeatures, targetFeatures, this.attrName, this.attributeOperation, this.spatialOperation, this.bradius, monitor); if(results.size() > 0){ context.addLayer(StandardCategoryNames.RESULT, joinresult, results); } else{ context.getWorkbenchFrame().warnUser(notimplemented); } //context.getWorkbenchContext().getLayerViewPanel().getSelectionManager().clear(); } //============================================================ // dialog things //============================================================ private JComboBox layerboxA; private JComboBox layerboxB; private JComboBox attribbox; private JComboBox attribOpbox; private JComboBox spatialOpbox; private Object attrValue = null; private Object attrOpValue = ""; private Object spatialOpValue = ""; private ArrayList attColl = new ArrayList(); private ArrayList attOpColl = new ArrayList(); private ArrayList SpatialOpColl = new ArrayList(); /** * @param selectTypeDialog2 * @param context */ private void setDialogValues(MultiInputDialog selectTypeDialog2, PlugInContext context) { this.dialog.setSideBarDescription(sidebartext); //-- target layer if (targetLayer == null) targetLayer = context.getCandidateLayer(0); layerboxA = this.dialog.addLayerComboBox(TGT_LAYER, targetLayer,"", context.getLayerManager()); //-- source layer if (srcLayer == null) srcLayer = context.getCandidateLayer(0); layerboxB = this.dialog.addLayerComboBox(SRC_LAYER, srcLayer,"", context.getLayerManager()); layerboxB.addItemListener(new MethodItemListener()); //-- attribute attribbox = this.dialog.addComboBox(SRC_ATTRIB,attrValue,attColl,""); updateUIForAttributes(); //-- attributeOp attribOpbox = this.dialog.addComboBox(ATTRIB_OP,attrOpValue,attOpColl,""); DefaultComboBoxModel modelA = new DefaultComboBoxModel(); for(int i=0; i < this.attrOpList.size(); i++){ modelA.addElement(this.attrOpList.get(i)); } attribOpbox.setModel(modelA); //-- spatial Relation spatialOpbox = this.dialog.addComboBox(SPATIAL_OP,attrValue,attOpColl,""); DefaultComboBoxModel modelS = new DefaultComboBoxModel(); for(int i=0; i < this.spatialOpList.size(); i++){ modelS.addElement(this.spatialOpList.get(i)); } spatialOpbox.setModel(modelS); //-- add buffer dialog.addDoubleField(BUFFER_RADIUS, this.bradius, 7); } private void updateUIForAttributes(){ this.srcLayer = dialog.getLayer(SRC_LAYER); DefaultComboBoxModel model = new DefaultComboBoxModel(); for (int i = 0; i < srcLayer.getFeatureCollectionWrapper().getFeatureSchema().getAttributeCount(); i++){ if (i == srcLayer.getFeatureCollectionWrapper().getFeatureSchema().getGeometryIndex()) { continue; } model.addElement(srcLayer.getFeatureCollectionWrapper() .getFeatureSchema().getAttributeName(i)); } attribbox.setModel(model); if (model.getSize() == 0) { //Can get here if the only attribute is the geometry. [Jon Aquino] } this.dialog.validate(); } private void getdialogValues(MultiInputDialog dialog) { this.srcLayer = dialog.getLayer(SRC_LAYER); this.targetLayer = dialog.getLayer(TGT_LAYER); this.attrName = (String) attribbox.getSelectedItem(); this.attributeOperation = attribOpbox.getSelectedIndex(); this.spatialOperation = spatialOpbox.getSelectedIndex(); this.bradius = dialog.getDouble(BUFFER_RADIUS); } private void generateOpLists(){ //-- note the order and position is important // since it will be used to obtain directly the values // the available operations are defined in AttributeOp.java /** copy from AttributeOp public final static int MAJORITY = 0; public final static int MINORITY = 1; public final static int MEAN = 2; public final static int MEDIAN = 3; public final static int MIN = 4; public final static int MAX = 5; public final static int STD = 6; public final static int SUM = 7; public final static int COUNT = 8; **/ this.attrOpList.clear(); //because function may be called several times this.attrOpList.add(AttributeOp.MAJORITY,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.majority")); this.attrOpList.add(AttributeOp.MINORITY,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.minority")); this.attrOpList.add(AttributeOp.MEAN,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.mean")); this.attrOpList.add(AttributeOp.MEDIAN,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.median")); this.attrOpList.add(AttributeOp.MIN,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.minimum")); this.attrOpList.add(AttributeOp.MAX,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.maximum")); this.attrOpList.add(AttributeOp.STD,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.standard-dev")); this.attrOpList.add(AttributeOp.SUM,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.sum")); this.attrOpList.add(AttributeOp.COUNT,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.count")); // the available operations are defined in SpatialRelationOp.java /** copy from SpatialRelationOp public final static int CONTAINS = 0; public final static int INTERSECTS = 1; **/ this.spatialOpList.clear(); this.spatialOpList.add(SpatialRelationOp.CONTAINS,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-features-contained-in-a-target-feature")); this.spatialOpList.add(SpatialRelationOp.INTERSECTS,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.source-features-intersecting-a-target-feature")); this.spatialOpList.add(SpatialRelationOp.COVEREDBY,I18N.get("org.openjump.core.ui.plugin.tools.JoinAttributesSpatiallyPlugIn.target-feature-covered-by-source-features")); } //============================================================ // dialog listeners //============================================================ private class MethodItemListener implements ItemListener{ public void itemStateChanged(ItemEvent e) { updateUIForAttributes(); } } }