Skip to content

Commit

Permalink
[FEATURE] A reshape tool to apply to line/polygon geometries. The par…
Browse files Browse the repository at this point in the history
…t of a geometry between the first and last intersection of the reshape line will be replaced

git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@11500 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Aug 25, 2009
1 parent 6ef9017 commit 42be35e
Show file tree
Hide file tree
Showing 9 changed files with 719 additions and 24 deletions.
Binary file added images/themes/default/mActionReshape.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions python/core/qgsgeometry.sip
Expand Up @@ -204,6 +204,11 @@ not disjoint with existing polygons of the feature*/
@return 0 in case of success, 1 if geometry has not been split, error else*/
int splitGeometry(const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries, bool topological, QList<QgsPoint>& topologyTestPoints);

/**Replaces a part of this geometry with another line
@return 0 in case of success
@note: this function was added in version 1.3*/
int reshapeGeometry( const QList<QgsPoint>& reshapeWithLine );

/**Changes this geometry such that it does not intersect the other geometry
@param other geometry that should not be intersect
@return 0 in case of success*/
Expand Down
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -39,6 +39,7 @@ SET(QGIS_APP_SRCS
qgsmaptoolmovefeature.cpp
qgsmaptoolmovevertex.cpp
qgsmaptoolnodetool.cpp
qgsmaptoolreshape.cpp
qgsmaptoolselect.cpp
qgsmaptoolsimplify.cpp
qgsmaptoolsplitfeatures.cpp
Expand Down
25 changes: 25 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -171,6 +171,7 @@
#include "qgsmaptoolnodetool.h"
#include "qgsmaptoolpan.h"
#include "qgsmaptoolselect.h"
#include "qgsmaptoolreshape.h"
#include "qgsmaptoolsplitfeatures.h"
#include "qgsmaptoolvertexedit.h"
#include "qgsmaptoolzoom.h"
Expand Down Expand Up @@ -473,6 +474,7 @@ QgisApp::~QgisApp()
delete mMapTools.mCaptureLine;
delete mMapTools.mCapturePolygon;
delete mMapTools.mMoveFeature;
delete mMapTools.mReshapeFeatures;
delete mMapTools.mSplitFeatures;
delete mMapTools.mSelect;
delete mMapTools.mVertexAdd;
Expand Down Expand Up @@ -660,6 +662,12 @@ void QgisApp::createActions()
connect( mActionMoveFeature, SIGNAL( triggered() ), this, SLOT( moveFeature() ) );
mActionMoveFeature->setEnabled( false );

mActionReshapeFeatures = new QAction( getThemeIcon( "mActionReshape.png" ), tr( "Reshape Features" ), this );
shortcuts->registerAction( mActionReshapeFeatures );
mActionReshapeFeatures->setStatusTip( tr( "Reshape Features" ) );
connect( mActionReshapeFeatures, SIGNAL( triggered() ), this, SLOT( reshapeFeatures() ) );
mActionReshapeFeatures->setEnabled( false );

mActionSplitFeatures = new QAction( getThemeIcon( "mActionSplitFeatures.png" ), tr( "Split Features" ), this );
shortcuts->registerAction( mActionSplitFeatures );
mActionSplitFeatures->setStatusTip( tr( "Split Features" ) );
Expand Down Expand Up @@ -1062,6 +1070,8 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionCapturePolygon );
mActionMoveFeature->setCheckable( true );
mMapToolGroup->addAction( mActionMoveFeature );
mActionReshapeFeatures->setCheckable( true );
mMapToolGroup->addAction( mActionReshapeFeatures );
mActionSplitFeatures->setCheckable( true );
mMapToolGroup->addAction( mActionSplitFeatures );
mMapToolGroup->addAction( mActionDeleteSelected );
Expand Down Expand Up @@ -1175,6 +1185,7 @@ void QgisApp::createMenus()
mEditMenu->addAction( mActionAddIsland );
mEditMenu->addAction( mActionDeleteRing );
mEditMenu->addAction( mActionDeletePart );
mEditMenu->addAction( mActionReshapeFeatures );
mEditMenu->addAction( mActionSplitFeatures );
mEditMenu->addAction( mActionMergeFeatures );
mEditMenu->addAction( mActionNodeTool );
Expand Down Expand Up @@ -1383,6 +1394,7 @@ void QgisApp::createToolBars()
mAdvancedDigitizeToolBar->addAction( mActionAddIsland );
mAdvancedDigitizeToolBar->addAction( mActionDeleteRing );
mAdvancedDigitizeToolBar->addAction( mActionDeletePart );
mAdvancedDigitizeToolBar->addAction( mActionReshapeFeatures );
mAdvancedDigitizeToolBar->addAction( mActionSplitFeatures );
mAdvancedDigitizeToolBar->addAction( mActionMergeFeatures );
mAdvancedDigitizeToolBar->addAction( mActionNodeTool );
Expand Down Expand Up @@ -1605,6 +1617,7 @@ void QgisApp::setTheme( QString theThemeName )
mActionCaptureLine->setIcon( getThemeIcon( "/mActionCaptureLine.png" ) );
mActionCapturePolygon->setIcon( getThemeIcon( "/mActionCapturePolygon.png" ) );
mActionMoveFeature->setIcon( getThemeIcon( "/mActionMoveFeature.png" ) );
mActionReshapeFeatures->setIcon( getThemeIcon( "/mActionReshape.png" ) );
mActionSplitFeatures->setIcon( getThemeIcon( "/mActionSplitFeatures.png" ) );
mActionDeleteSelected->setIcon( getThemeIcon( "/mActionDeleteSelected.png" ) );
mActionAddVertex->setIcon( getThemeIcon( "/mActionAddVertex.png" ) );
Expand Down Expand Up @@ -1735,6 +1748,8 @@ void QgisApp::createCanvas()
mActionCapturePolygon->setVisible( false );
mMapTools.mMoveFeature = new QgsMapToolMoveFeature( mMapCanvas );
mMapTools.mMoveFeature->setAction( mActionMoveFeature );
mMapTools.mReshapeFeatures = new QgsMapToolReshape( mMapCanvas );
mMapTools.mReshapeFeatures->setAction( mActionReshapeFeatures );
mMapTools.mSplitFeatures = new QgsMapToolSplitFeatures( mMapCanvas );
mMapTools.mSplitFeatures->setAction( mActionSplitFeatures );
mMapTools.mSelect = new QgsMapToolSelect( mMapCanvas );
Expand Down Expand Up @@ -4337,6 +4352,11 @@ void QgisApp::splitFeatures()
mMapCanvas->setMapTool( mMapTools.mSplitFeatures );
}

void QgisApp::reshapeFeatures()
{
mMapCanvas->setMapTool( mMapTools.mReshapeFeatures );
}

void QgisApp::capturePoint()
{
if ( mMapCanvas && mMapCanvas->isDrawing() )
Expand Down Expand Up @@ -5634,6 +5654,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionMoveVertex->setEnabled( false );
mActionAddRing->setEnabled( false );
mActionAddIsland->setEnabled( false );
mActionReshapeFeatures->setEnabled( false );
mActionSplitFeatures->setEnabled( false );
mActionSimplifyFeature->setEnabled( false );
mActionDeleteRing->setEnabled( false );
Expand All @@ -5650,6 +5671,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
{
mActionCaptureLine->setEnabled( true );
mActionCaptureLine->setVisible( true );
mActionReshapeFeatures->setEnabled( true );
mActionSplitFeatures->setEnabled( true );
mActionSimplifyFeature->setEnabled( true );
mActionDeletePart->setEnabled( true );
Expand All @@ -5659,6 +5681,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
{
mActionCaptureLine->setEnabled( false );
mActionCaptureLine->setVisible( false );
mActionReshapeFeatures->setEnabled( false );
mActionSplitFeatures->setEnabled( false );
mActionSimplifyFeature->setEnabled( false );
mActionDeletePart->setEnabled( false );
Expand All @@ -5679,6 +5702,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionCapturePolygon->setVisible( true );
mActionAddRing->setEnabled( true );
mActionAddIsland->setEnabled( true );
mActionReshapeFeatures->setEnabled( true );
mActionSplitFeatures->setEnabled( true );
mActionSimplifyFeature->setEnabled( true );
mActionDeleteRing->setEnabled( true );
Expand All @@ -5690,6 +5714,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionCapturePolygon->setVisible( false );
mActionAddRing->setEnabled( false );
mActionAddIsland->setEnabled( false );
mActionReshapeFeatures->setEnabled( false );
mActionSplitFeatures->setEnabled( false );
mActionSimplifyFeature->setEnabled( false );
mActionDeleteRing->setEnabled( false );
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -497,6 +497,8 @@ class QgisApp : public QMainWindow
void deleteSelected();
//! activates the move feature tool
void moveFeature();
//! activates the reshape features tool
void reshapeFeatures();
//! activates the split features tool
void splitFeatures();
//! activates the add vertex tool
Expand Down Expand Up @@ -725,6 +727,7 @@ class QgisApp : public QMainWindow
QAction *mActionCapturePolygon;
QAction *mActionDeleteSelected;
QAction *mActionMoveFeature;
QAction *mActionReshapeFeatures;
QAction *mActionSplitFeatures;
QAction *mActionAddVertex;
QAction *mActionDeleteVertex;
Expand Down Expand Up @@ -847,6 +850,7 @@ class QgisApp : public QMainWindow
QgsMapTool* mCaptureLine;
QgsMapTool* mCapturePolygon;
QgsMapTool* mMoveFeature;
QgsMapTool* mReshapeFeatures;
QgsMapTool* mSplitFeatures;
QgsMapTool* mSelect;
QgsMapTool* mVertexAdd;
Expand Down
128 changes: 128 additions & 0 deletions src/app/qgsmaptoolreshape.cpp
@@ -0,0 +1,128 @@
/***************************************************************************
qgsmaptoolreshape.cpp
---------------------------
begin : Juli 2009
copyright : (C) 2009 by Marco Hugentobler
email : marco dot hugentobler at karto dot baug dot ethz dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id$ */

#include "qgsmaptoolreshape.h"
#include "qgsgeometry.h"
#include "qgsmapcanvas.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include <QMessageBox>
#include <QMouseEvent>

QgsMapToolReshape::QgsMapToolReshape( QgsMapCanvas* canvas ): QgsMapToolCapture( canvas, QgsMapToolCapture::CaptureLine )
{

}

QgsMapToolReshape::~QgsMapToolReshape()
{

}

void QgsMapToolReshape::canvasReleaseEvent( QMouseEvent * e )
{
//check if we operate on a vector layer //todo: move this to a function in parent class to avoid duplication
QgsVectorLayer *vlayer = dynamic_cast <QgsVectorLayer*>( mCanvas->currentLayer() );

if ( !vlayer )
{
QMessageBox::information( 0, tr( "Not a vector layer" ),
tr( "The current layer is not a vector layer" ) );
return;
}

if ( !vlayer->isEditable() )
{
QMessageBox::information( 0, tr( "Layer not editable" ),
tr( "Cannot edit the vector layer. To make it editable, go to the file item "
"of the layer, right click and check 'Allow Editing'." ) );
return;
}

//add point to list and to rubber band
int error = addVertex( e->pos() );
if ( error == 1 )
{
//current layer is not a vector layer
return;
}
else if ( error == 2 )
{
//problem with coordinate transformation
QMessageBox::information( 0, tr( "Coordinate transform error" ),
tr( "Cannot transform the point to the layers coordinate system" ) );
return;
}

if ( e->button() == Qt::LeftButton )
{
mCapturing = TRUE;
}
else if ( e->button() == Qt::RightButton )
{
mCapturing = FALSE;
delete mRubberBand;
mRubberBand = 0;

//find out bounding box of mCaptureList
if(mCaptureList.size() < 1)
{
return;
}
QgsPoint firstPoint = mCaptureList.at(0);
QgsRectangle bbox(firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y());
for(int i = 1; i < mCaptureList.size(); ++i)
{
bbox.combineExtentWith(mCaptureList.at(i).x(), mCaptureList.at(i).y());
}

//query all the features that intersect bounding box of capture line
vlayer->select(QgsAttributeList(), bbox, true, false);
QgsFeature f;
int reshapeReturn;
bool reshapeDone = false;

vlayer->beginEditCommand( tr( "Reshape" ) );
while(vlayer->nextFeature(f))
{
//query geometry
//call geometry->reshape(mCaptureList)
//register changed geometry in vector layer
QgsGeometry* geom = f.geometry();
if(geom)
{
reshapeReturn = geom->reshapeGeometry(mCaptureList);
if(reshapeReturn == 0)
{
vlayer->changeGeometry(f.id(), geom);
reshapeDone = true;
}
}
}

if(reshapeDone)
{
vlayer->endEditCommand();
}
else
{
vlayer->destroyEditCommand();
}

mCaptureList.clear();
mCanvas->refresh();
}
}
31 changes: 31 additions & 0 deletions src/app/qgsmaptoolreshape.h
@@ -0,0 +1,31 @@
/***************************************************************************
qgsmaptoolreshape.h
---------------------
begin : Juli 2009
copyright : (C) 2009 by Marco Hugentobler
email : marco.hugentobler at karto dot baug dot ethz dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
/* $Id$ */

#ifndef QGSMAPTOOLRESHAPE_H
#define QGSMAPTOOLRESHAPE_H

#include "qgsmaptoolcapture.h"

/**A map tool that draws a line and splits the features cut by the line*/
class QgsMapToolReshape: public QgsMapToolCapture
{
public:
QgsMapToolReshape( QgsMapCanvas* canvas );
virtual ~QgsMapToolReshape();
void canvasReleaseEvent( QMouseEvent * e );
};

#endif

0 comments on commit 42be35e

Please sign in to comment.