Skip to content

Commit

Permalink
[FEATURE] Allow map simplify tool to smooth features
Browse files Browse the repository at this point in the history
And rename to "Simplify/smooth features". This change allows interactive
smoothing of features.
  • Loading branch information
nyalldawson authored and 3nids committed Feb 26, 2018
1 parent dce2188 commit 295e1b5
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 98 deletions.
81 changes: 69 additions & 12 deletions src/app/qgsmaptoolsimplify.cpp
Expand Up @@ -35,22 +35,40 @@ QgsSimplifyDialog::QgsSimplifyDialog( QgsMapToolSimplify *tool, QWidget *parent
{
setupUi( this );

mMethodComboBox->addItem( tr( "Simplify by distance" ), ( int )QgsVectorSimplifyMethod::Distance );
mMethodComboBox->addItem( tr( "Simplify by snapping to grid" ), ( int )QgsVectorSimplifyMethod::SnapToGrid );
mMethodComboBox->addItem( tr( "Simplify by area (Visvalingam)" ), ( int )QgsVectorSimplifyMethod::Visvalingam );
mMethodComboBox->addItem( tr( "Simplify by distance" ), QgsMapToolSimplify::SimplifyDistance );
mMethodComboBox->addItem( tr( "Simplify by snapping to grid" ), QgsMapToolSimplify::SimplifySnapToGrid );
mMethodComboBox->addItem( tr( "Simplify by area (Visvalingam)" ), QgsMapToolSimplify::SimplifyVisvalingam );
mMethodComboBox->addItem( tr( "Smooth" ), QgsMapToolSimplify::Smooth );

spinTolerance->setValue( mTool->tolerance() );
spinTolerance->setShowClearButton( false );
cboToleranceUnits->setCurrentIndex( ( int ) mTool->toleranceUnits() );

mOffsetSpin->setClearValue( 25 );
mOffsetSpin->setValue( mTool->smoothOffset() * 100 );
mIterationsSpin->setClearValue( 1 );
mIterationsSpin->setValue( mTool->smoothIterations() );

mMethodComboBox->setCurrentIndex( mMethodComboBox->findData( mTool->method() ) );
if ( mMethodComboBox->currentData().toInt() != QgsMapToolSimplify::Smooth )
mOptionsStackedWidget->setCurrentIndex( 0 );
else
mOptionsStackedWidget->setCurrentIndex( 1 );

// communication with map tool
connect( spinTolerance, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), mTool, &QgsMapToolSimplify::setTolerance );
connect( cboToleranceUnits, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), mTool, &QgsMapToolSimplify::setToleranceUnits );
connect( mMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), mTool, [ = ]
{
mTool->setMethod( static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( mMethodComboBox->currentData().toInt() ) );
mTool->setMethod( static_cast< QgsMapToolSimplify::Method >( mMethodComboBox->currentData().toInt() ) );
if ( mMethodComboBox->currentData().toInt() != QgsMapToolSimplify::Smooth )
mOptionsStackedWidget->setCurrentIndex( 0 );
else
mOptionsStackedWidget->setCurrentIndex( 1 );
} );

connect( mOffsetSpin, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mTool, [ = ]( int value ) { mTool->setSmoothOffset( value / 100.0 ); } );
connect( mIterationsSpin, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mTool, [ = ]( int value ) { mTool->setSmoothIterations( value ); } );
connect( okButton, &QAbstractButton::clicked, mTool, &QgsMapToolSimplify::storeSimplified );
}

Expand Down Expand Up @@ -79,8 +97,10 @@ QgsMapToolSimplify::QgsMapToolSimplify( QgsMapCanvas *canvas )
{
QgsSettings settings;
mTolerance = settings.value( QStringLiteral( "digitizing/simplify_tolerance" ), 1 ).toDouble();
mToleranceUnits = settings.enumValue( QStringLiteral( "digitizing/simplify_tolerance_units" ), QgsTolerance::LayerUnits );
mMethod = static_cast< QgsMapToPixelSimplifier::SimplifyAlgorithm >( settings.value( QStringLiteral( "digitizing/simplify_method" ), 0 ).toInt() );
mToleranceUnits = static_cast< QgsTolerance::UnitType >( settings.value( QStringLiteral( "digitizing/simplify_tolerance_units" ), 0 ).toInt() );
mMethod = static_cast< QgsMapToolSimplify::Method >( settings.value( QStringLiteral( "digitizing/simplify_method" ), 0 ).toInt() );
mSmoothIterations = settings.value( QStringLiteral( "digitizing/smooth_iterations" ), 1 ).toInt();
mSmoothOffset = settings.value( QStringLiteral( "digitizing/smooth_offset" ), 0.25 ).toDouble();

mSimplifyDialog = new QgsSimplifyDialog( this, canvas->topLevelWidget() );
}
Expand Down Expand Up @@ -144,25 +164,62 @@ QgsGeometry QgsMapToolSimplify::processGeometry( const QgsGeometry &geometry, do
{
switch ( mMethod )
{
case QgsMapToPixelSimplifier::Distance:
case SimplifyDistance:
return geometry.simplify( tolerance );

case QgsMapToPixelSimplifier::SnapToGrid:
case QgsMapToPixelSimplifier::Visvalingam:
case SimplifySnapToGrid:
case SimplifyVisvalingam:
{
QgsMapToPixelSimplifier simplifier( QgsMapToPixelSimplifier::SimplifyGeometry, tolerance, mMethod );

QgsMapToPixelSimplifier simplifier( QgsMapToPixelSimplifier::SimplifyGeometry, tolerance, mMethod == SimplifySnapToGrid ? QgsMapToPixelSimplifier::SnapToGrid : QgsMapToPixelSimplifier::Visvalingam );
return simplifier.simplify( geometry );
}

case Smooth:
return geometry.smooth( mSmoothIterations, mSmoothOffset );

}
return QgsGeometry(); //no warnings
}

QgsMapToPixelSimplifier::SimplifyAlgorithm QgsMapToolSimplify::method() const
double QgsMapToolSimplify::smoothOffset() const
{
return mSmoothOffset;
}

void QgsMapToolSimplify::setSmoothOffset( double smoothOffset )
{
mSmoothOffset = smoothOffset;

QgsSettings settings;
settings.setValue( QStringLiteral( "digitizing/smooth_offset" ), smoothOffset );

if ( !mSelectedFeatures.isEmpty() )
updateSimplificationPreview();
}

int QgsMapToolSimplify::smoothIterations() const
{
return mSmoothIterations;
}

void QgsMapToolSimplify::setSmoothIterations( int smoothIterations )
{
mSmoothIterations = smoothIterations;

QgsSettings settings;
settings.setValue( QStringLiteral( "digitizing/smooth_iterations" ), smoothIterations );

if ( !mSelectedFeatures.isEmpty() )
updateSimplificationPreview();
}

QgsMapToolSimplify::Method QgsMapToolSimplify::method() const
{
return mMethod;
}

void QgsMapToolSimplify::setMethod( QgsMapToPixelSimplifier::SimplifyAlgorithm method )
void QgsMapToolSimplify::setMethod( QgsMapToolSimplify::Method method )
{
mMethod = method;

Expand Down
25 changes: 21 additions & 4 deletions src/app/qgsmaptoolsimplify.h
Expand Up @@ -23,7 +23,6 @@
#include "qgsfeature.h"
#include "qgstolerance.h"
#include "qgis_app.h"
#include "qgsmaptopixelgeometrysimplifier.h"

class QgsRubberBand;
class QgsMapToolSimplify;
Expand Down Expand Up @@ -56,6 +55,15 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
{
Q_OBJECT
public:

enum Method
{
SimplifyDistance = 0,
SimplifySnapToGrid = 1,
SimplifyVisvalingam = 2,
Smooth = 3
};

QgsMapToolSimplify( QgsMapCanvas *canvas );
~QgsMapToolSimplify() override;

Expand All @@ -72,9 +80,15 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit

QString statusText() const;

QgsMapToPixelSimplifier::SimplifyAlgorithm method() const;
Method method() const;

void setMethod( Method method );

void setMethod( QgsMapToPixelSimplifier::SimplifyAlgorithm method );
int smoothIterations() const;
void setSmoothIterations( int smoothIterations );

double smoothOffset() const;
void setSmoothOffset( double smoothOffset );

public slots:
//! Slot to change display when slidebar is moved
Expand Down Expand Up @@ -125,7 +139,10 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
int mReducedVertexCount = 0;
bool mReducedHasErrors = false;

QgsMapToPixelSimplifier::SimplifyAlgorithm mMethod = QgsMapToPixelSimplifier::Distance;
Method mMethod = SimplifyDistance;

int mSmoothIterations = 1;
double mSmoothOffset = 0.25;

};

Expand Down
42 changes: 7 additions & 35 deletions src/ui/qgisapp.ui
Expand Up @@ -643,12 +643,12 @@
<addaction name="mActionNewSpatiaLiteLayer"/>
<addaction name="mActionNewMemoryLayer"/>
</widget>
<widget class="QToolBar" name="mShapeDigitizeToolBar">
<widget class="QToolBar" name="mRegularShapeDigitizeToolBar">
<property name="windowTitle">
<string>Shape Digitizing Toolbar</string>
<string>Regular Shape Digitizing Toolbar</string>
</property>
<property name="toolTip">
<string>Shape Digitizing Toolbar</string>
<string>Regular Shape Digitizing Toolbar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
Expand Down Expand Up @@ -741,7 +741,7 @@
<action name="mActionExit">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionFileExit.svg</normaloff>:/images/themes/default/mActionFileExit.svg</iconset>
<normaloff>:/images/themes/default/mActionFileExit.png</normaloff>:/images/themes/default/mActionFileExit.png</iconset>
</property>
<property name="text">
<string>Exit QGIS</string>
Expand Down Expand Up @@ -997,7 +997,7 @@
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionMoveVertex.svg</normaloff>:/images/themes/default/mActionMoveVertex.svg</iconset>
<normaloff>:/images/themes/default/mActionMoveVertex.png</normaloff>:/images/themes/default/mActionMoveVertex.png</iconset>
</property>
<property name="text">
<string>Offset Point Symbol</string>
Expand Down Expand Up @@ -1649,7 +1649,7 @@
<action name="mActionProjectProperties">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionProjectProperties.svg</normaloff>:/images/themes/default/mActionProjectProperties.svg</iconset>
<normaloff>:/images/themes/default/mActionProjectProperties.png</normaloff>:/images/themes/default/mActionProjectProperties.png</iconset>
</property>
<property name="text">
<string>&amp;Project Properties...</string>
Expand Down Expand Up @@ -1904,7 +1904,7 @@ Ctrl (Cmd) increments by 15 deg.</string>
<action name="mActionDecorationNorthArrow">
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/north_arrow.svg</normaloff>:/images/themes/default/north_arrow.svg</iconset>
<normaloff>:/images/themes/default/north_arrow.png</normaloff>:/images/themes/default/north_arrow.png</iconset>
</property>
<property name="text">
<string>&amp;North Arrow…</string>
Expand Down Expand Up @@ -2962,34 +2962,6 @@ Acts on currently active editable layer</string>
</widget>
<resources>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>

0 comments on commit 295e1b5

Please sign in to comment.