/* Spatial Operations & Editing Tools for uDig * * Axios Engineering under a funding contract with: * Diputación Foral de Gipuzkoa, Ordenación Territorial * * http://b5m.gipuzkoa.net * http://www.axios.es * * (C) 2006, Diputación Foral de Gipuzkoa, Ordenación Territorial (DFG-OT). * DFG-OT agrees to licence under Lesser General Public License (LGPL). * * You can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software * Foundation; version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package es.axios.udig.ui.editingtools.merge; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.refractions.udig.project.ILayer; import net.refractions.udig.project.IMap; import net.refractions.udig.project.command.UndoableMapCommand; import net.refractions.udig.project.ui.render.displayAdapter.MapMouseEvent; import net.refractions.udig.project.ui.tool.IToolContext; import net.refractions.udig.tool.select.BBoxSelection; import org.eclipse.core.runtime.NullProgressMonitor; import org.geotools.data.DefaultQuery; import org.geotools.data.FeatureSource; import org.geotools.data.Query; import org.geotools.feature.FeatureCollection; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.Filter; import com.vividsolutions.jts.geom.Envelope; import es.axios.udig.ui.commons.mediator.AppGISMediator; import es.axios.udig.ui.commons.util.DialogUtil; import es.axios.udig.ui.editingtools.internal.commands.DefaultEdittingToolsCommandFactory; import es.axios.udig.ui.editingtools.internal.i18n.Messages; import es.axios.udig.ui.editingtools.internal.presentation.StatusBar; import es.axios.udig.ui.editingtools.merge.internal.MergeFeatureBehaviour; /** * Merge the features in bounding box * <p> * This implementation is based in {@link BBoxSelection}. The extension add behaviour object which * displays the merge dialog. * </p> * * @author Mauricio Pazos (www.axios.es) * @author Gabriel Roldan (www.axios.es) * @since 1.1.0 */ public final class MergeTool extends BBoxSelection { private static final String EXTENSION_ID = "es.axios.udig.ui.editingtools.merge.MergeTool"; //$NON-NLS-1$ /** * A new instance of MergeTool */ public MergeTool() { super(); } public String getExtensionID() { return EXTENSION_ID; } @Override public void setActive( final boolean active ) { super.setActive(active); IToolContext context = getContext(); if (active && context.getMapLayers().size() > 0) { String message = Messages.MergeTool_select_features_to_merge; StatusBar.setStatusBarMessage(context, message); } else { StatusBar.setStatusBarMessage(context, "");//$NON-NLS-1$ } } /** * Returns an in memory feature collection for the bbox filter on the current layer */ private SimpleFeature[] getFeaturesInBBox( Envelope bbox ) throws IOException { ILayer selectedLayer = getContext().getSelectedLayer(); FeatureSource<SimpleFeatureType, SimpleFeature> source = selectedLayer.getResource(FeatureSource.class, null); String typename = source.getSchema().getTypeName(); Filter filter = selectedLayer.createBBoxFilter(bbox, null); Query query = new DefaultQuery(typename, filter); FeatureCollection<SimpleFeatureType, SimpleFeature> features = source.getFeatures(query); List<SimpleFeature> featureList = new ArrayList<SimpleFeature>(); try { for( Iterator it = features.iterator(); it.hasNext(); ) { SimpleFeature f = (SimpleFeature) it.next(); featureList.add(f); } } finally { features.purge(); } SimpleFeature[] featureArray = featureList.toArray(new SimpleFeature[featureList.size()]); return featureArray; } /** * Validates the features in bounding box and creates the command to delete the source features * and insert the the new merged feature */ @Override protected void sendSelectionCommand( MapMouseEvent e, final Envelope bounds ) { super.sendSelectionCommand(e, bounds); // this may take a while, so run it with a busy indicator Runnable runnable = new Runnable(){ public void run() { final String dlgTitle = Messages.MergeTool_title_tool; SimpleFeature[] features = null; try { // gets the features in bounding box features = getFeaturesInBBox(bounds); } catch (IOException e1) { final String msg = Messages.MergeTool_failed_getting_selection; DialogUtil.openError(dlgTitle, msg); throw new IllegalStateException( e1.getMessage(), e1 ); } assert features != null; IToolContext context = getContext(); DefaultEdittingToolsCommandFactory commandFactory = new DefaultEdittingToolsCommandFactory(); final MergeFeatureBehaviour behaviour = new MergeFeatureBehaviour(context, commandFactory); behaviour.setSourceFeatures(features); if (!behaviour.isValid()) { behaviour.handleError(); return; } // execute command UndoableMapCommand cmd = null; try { cmd = behaviour.getCommand(); if (cmd == null) { return; } IMap map = context.getMap(); assert map != null; cmd.setMap(map); map.sendCommandASync(cmd); StatusBar.setStatusBarMessage(context, Messages.MergeTool_successful); } catch (Exception e1) { final String msg = Messages.MergeTool_failed_executing + ": " + e1.getMessage(); //$NON-NLS-1$ DialogUtil.openError(dlgTitle, msg); if (cmd != null) { try { cmd.rollback(new NullProgressMonitor()); } catch (Exception e2) { final String msg2 = Messages.MergeTool_failed_rollback; DialogUtil.openError(dlgTitle, msg2); throw new IllegalStateException(msg2, e2 ); } } throw new IllegalStateException( e1.getMessage(), e1 ); } finally { unselect(context); context.getViewportPane().repaint(); } } }; AppGISMediator.showWhile(getContext().getViewportPane(), runnable); } /** * Unselects the merged features * * @param context */ private void unselect( final IToolContext context ) { UndoableMapCommand clearSelectionCommand = context.getSelectionFactory() .createNoSelectCommand(); context.sendASyncCommand(clearSelectionCommand); } }