Example Plugin For Buffering Features in a Layer
Jump to navigation
Jump to search
this example plugin shows:
- how to retrieve data from a layer
- how to provide input paramter for a spatial analysis
- how to create a new layer that contains your results
package ch.unizh.geo.degen.jumpplugins;
import java.util.Collection;
import java.util.Iterator;
import javax.swing.JComboBox;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jump.feature.Feature;
import com.vividsolutions.jump.feature.FeatureCollection;
import com.vividsolutions.jump.feature.FeatureDataset;
import com.vividsolutions.jump.feature.FeatureSchema;
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.AbstractPlugIn;
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.ThreadedPlugIn;
import com.vividsolutions.jump.workbench.ui.GUIUtil;
import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
/**
* @description:
* Example plugin which creates buffers from the input
* features. The Plugin ask for the layer with the features
* and the radius for the buffer. The output will be
* the buffered features containing the attributes from the
* source features.
*
* @author sstein
*
**/
public class BufferFeaturesFromLayerPlugIn extends AbstractPlugIn implements ThreadedPlugIn{
private String T1 ="buffers all features in a layer";
private String T2 ="buffer radius";
private String CLAYER = "select layer";
private Layer itemlayer = null;
private double radius = 0;
/**
* this method is called on the startup by JUMP/OpenJUMP.
* We set here the menu entry for calling the function.
*/
public void initialize(PlugInContext context) throws Exception {
FeatureInstaller featureInstaller = new FeatureInstaller(context.getWorkbenchContext());
featureInstaller.addMainMenuItem(
this, //exe
new String[] {"SSTools"}, //menu path
this.getName(), //name methode .getName recieved by AbstractPlugIn
false, //checkbox
null, //icon
createEnableCheck(context.getWorkbenchContext())); //enable check
}
/**
* This method is used to define when the menu entry is activated or
* disabled. In this example we allow the menu entry to be usable only
* if one layer exists.
* @param workbenchContext
* @return
*/
public static MultiEnableCheck createEnableCheck(WorkbenchContext workbenchContext) {
EnableCheckFactory checkFactory = new EnableCheckFactory(workbenchContext);
return new MultiEnableCheck()
.add(checkFactory.createAtLeastNLayersMustExistCheck(1))
.add(checkFactory.createTaskWindowMustBeActiveCheck());
}
/**
* this function is called by JUMP/OpenJUMP if one clicks on the menu entry.
* It is called before the "run" method and useful to do all the GUI /user-input things
* In this example we call two additional methods {@link #setDialogValues(MultiInputDialog, PlugInContext)}
* and {@link #getDialogValues(MultiInputDialog)} to obtain the Layer and the buffer radius by the user.
*/
public boolean execute(PlugInContext context) throws Exception{
this.reportNothingToUndoYet(context);
MultiInputDialog dialog = new MultiInputDialog(
context.getWorkbenchFrame(), getName(), true);
this.setDialogValues(dialog, context);
GUIUtil.centreOnWindow(dialog);
dialog.setVisible(true);
if (! dialog.wasOKPressed()) { return false; }
this.getDialogValues(dialog);
return true;
}
private void setDialogValues(MultiInputDialog dialog, PlugInContext context){
dialog.setSideBarDescription(T1);
JComboBox addLayerComboBoxBuild = dialog.addLayerComboBox(this.CLAYER, context.getCandidateLayer(0), null, context.getLayerManager());
dialog.addDoubleField(T2, this.radius, 6);
}
private void getDialogValues(MultiInputDialog dialog){
this.itemlayer = dialog.getLayer(this.CLAYER);
this.radius = dialog.getDouble(T2);
}
/**
* This method is called by JUMP/OpenJUMP after {@link #execute(PlugInContext)},
* It is usefull to do some longterm calculations.
*/
public void run(TaskMonitor monitor, PlugInContext context) throws Exception{
//-- allow cancel
monitor.allowCancellationRequests();
this.bufferItems(context, monitor, this.radius);
System.gc();
}
/**
* This is a method which calculates buffers from the items in a layer.
* @param context
* @param monitor
* @param radius used for the buffer
* @return
* @throws Exception
*/
private boolean bufferItems(PlugInContext context, TaskMonitor monitor, double radius) throws Exception{
System.gc(); //flush garbage collector
// --------------------------
//-- get items
final Collection features = this.itemlayer.getFeatureCollectionWrapper().getFeatures();
//-- create the FeatureCollection which will contain the buffers
FeatureCollection myCollA = null;
// get the first feature to determine the FeatureSchema of the collection
Feature firstF = (Feature)features.iterator().next();
// get FeatureSchema
FeatureSchema fs = firstF.getSchema();
// create the new FeatureCollection (containing the output of the buffer operation)
myCollA = new FeatureDataset(fs);
// get every feature(clone it!) - get the geometry - calculate the buffer
// and set as new Geometry the buffer geometry
// so the buffers have the same attributes as the original features
int numFeatures = features.size();
int count=0;
for (Iterator iter = features.iterator(); iter.hasNext();) {
Feature f = (Feature) iter.next();
//-- clone the feature - so we can add it to a new FC
Feature newF = f.clone(false);
Geometry geom = f.getGeometry();
//-- calculate the buffer
Geometry buffer = geom.buffer(radius);
//-- set as new geometry the buffer geometry
newF.setGeometry(buffer);
//-- add the new (cloned) feature to the collection
myCollA.add(newF);
count++;
//-- give the user some info : how far the calculation is
monitor.report("processed: "+count+" of " + numFeatures + " items");
//-- stop here if the user whishes
// we will not display the buffers calculated so far
if (monitor.isCancelRequested()){
return false;
}
}
//-- display the resulting buffer features
context.addLayer(StandardCategoryNames.WORKING, "buffers", myCollA);
return true;
}
}