Skip to content

Commit

Permalink
Add 3 new parameters per layers to the advance snapping settings :
Browse files Browse the repository at this point in the history
- LimitToScaleRange : Allows to enable snapping only when current scale on the canvas is in a specified range. This range is controled by the two parameters scale min and scale max.
- MinScale : Minimum scale in which the snapping is enabled
- MaxScale : Maximum scale in which the snapping is enabled

When LimitToScaleRange is set to true, snapping is disabled if the current scale out of [MinScale, MaxScale].
When LimitToScaleRange is set to false, the behavior remain unchanged and snapping is enabled whatever the scale.

This allows to limit the costly cache refresh for some heavy layers when panning said layer at a level where the snapping is not useful.
  • Loading branch information
obrix committed Apr 7, 2020
1 parent 1e05545 commit 8ec744a
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 28 deletions.
34 changes: 32 additions & 2 deletions python/core/auto_generated/qgssnappingconfig.sip.in
Expand Up @@ -73,7 +73,7 @@ This is a container of advanced configuration (per layer) of the snapping of the
%End
public:

IndividualLayerSettings( bool enabled, SnappingType type, double tolerance, QgsTolerance::UnitType units ) /Deprecated/;
IndividualLayerSettings( bool enabled, SnappingType type, double tolerance, QgsTolerance::UnitType units, bool limitToScaleRange, double minScale, double maxScale ) /Deprecated/;
%Docstring
IndividualLayerSettings

Expand All @@ -86,7 +86,7 @@ IndividualLayerSettings
use the method with SnappingTypeFlag instead.
%End

IndividualLayerSettings( bool enabled, SnappingTypeFlag type, double tolerance, QgsTolerance::UnitType units );
IndividualLayerSettings( bool enabled, SnappingTypeFlag type, double tolerance, QgsTolerance::UnitType units, bool limitToScaleRange, double minScale, double maxScale );
%Docstring
IndividualLayerSettings

Expand Down Expand Up @@ -166,6 +166,36 @@ Returns the type of units
void setUnits( QgsTolerance::UnitType units );
%Docstring
Sets the type of units
%End

bool limitToScaleRange() const;
%Docstring
Returns whether the snapping is limited on a scale iterval
%End

void setLimitToScaleRange( bool p_uselimit );
%Docstring
Sets whether the scale limites are used or not
%End

double minScale() const;
%Docstring
Returns min scale on which snapping is limited
%End

void setMinScale( double p_minScale );
%Docstring
Sets the min scale value on which snapping is used
%End

double maxScale() const;
%Docstring
Returns max scale on which snapping is limite
%End

void setMaxScale( double p_maxScale );
%Docstring
Sets the max scale value on which snapping is used
%End

bool operator!= ( const QgsSnappingConfig::IndividualLayerSettings &other ) const;
Expand Down
169 changes: 168 additions & 1 deletion src/app/qgssnappinglayertreemodel.cpp
Expand Up @@ -100,6 +100,31 @@ QWidget *QgsSnappingLayerDelegate::createEditor( QWidget *parent, const QStyleOp
return w;
}

if ( index.column() == QgsSnappingLayerTreeModel::LimitToScaleRangeColumn )
{
QCheckBox *cbUseLimit = new QCheckBox( parent );
cbUseLimit->setChecked( false );
return cbUseLimit;
}

if ( index.column() == QgsSnappingLayerTreeModel::MinScaleColumn )
{
QDoubleSpinBox *minLimitSp = new QDoubleSpinBox( parent );
minLimitSp->setDecimals( 5 );
minLimitSp->setMaximum( 99999999.990000 );
minLimitSp->setToolTip( tr( "Snapping scale range min" ) );
return minLimitSp;
}

if ( index.column() == QgsSnappingLayerTreeModel::MaxScaleColumn )
{
QDoubleSpinBox *maxLimitSp = new QDoubleSpinBox( parent );
maxLimitSp->setDecimals( 5 );
maxLimitSp->setMaximum( 99999999.990000 );
maxLimitSp->setToolTip( tr( "Snapping scale range max" ) );
return maxLimitSp;
}

return nullptr;
}

Expand Down Expand Up @@ -141,6 +166,23 @@ void QgsSnappingLayerDelegate::setEditorData( QWidget *editor, const QModelIndex
w->setCurrentIndex( w->findData( units ) );
}
}
else if ( index.column() == QgsSnappingLayerTreeModel::LimitToScaleRangeColumn )
{
QCheckBox *w = qobject_cast<QCheckBox *>( editor );
if ( w )
{
w->setChecked( val.toBool() );
}
}
else if ( index.column() == QgsSnappingLayerTreeModel::MinScaleColumn ||
index.column() == QgsSnappingLayerTreeModel::MaxScaleColumn )
{
QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( editor );
if ( w )
{
w->setValue( val.toDouble() );
}
}
}

void QgsSnappingLayerDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
Expand Down Expand Up @@ -183,6 +225,23 @@ void QgsSnappingLayerDelegate::setModelData( QWidget *editor, QAbstractItemModel
model->setData( index, w->value(), Qt::EditRole );
}
}
else if ( index.column() == QgsSnappingLayerTreeModel::LimitToScaleRangeColumn )
{
QCheckBox *w = qobject_cast<QCheckBox *>( editor );
if ( w )
{
model->setData( index, w->isChecked(), Qt::EditRole );
}
}
else if ( index.column() == QgsSnappingLayerTreeModel::MinScaleColumn ||
index.column() == QgsSnappingLayerTreeModel::MaxScaleColumn )
{
QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( editor );
if ( w )
{
model->setData( index, w->value(), Qt::EditRole );
}
}
}


Expand All @@ -200,7 +259,7 @@ QgsSnappingLayerTreeModel::QgsSnappingLayerTreeModel( QgsProject *project, QgsMa
int QgsSnappingLayerTreeModel::columnCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent )
return 5;
return 8;
}

Qt::ItemFlags QgsSnappingLayerTreeModel::flags( const QModelIndex &idx ) const
Expand Down Expand Up @@ -400,6 +459,12 @@ QVariant QgsSnappingLayerTreeModel::headerData( int section, Qt::Orientation ori
return tr( "Units" );
case 4:
return tr( "Avoid overlap" );
case 5:
return tr( "Activate snapping on scale range" );
case 6:
return tr( "Range min" );
case 7:
return tr( "Range max" );
default:
return QVariant();
}
Expand Down Expand Up @@ -579,6 +644,45 @@ QVariant QgsSnappingLayerTreeModel::data( const QModelIndex &idx, int role ) con
}
}
}

if ( idx.column() == LimitToScaleRangeColumn )
{
if ( role == Qt::DisplayRole )
{
return QString::number( ls.limitToScaleRange() );
}

if ( role == Qt::UserRole )
{
return ls.limitToScaleRange();
}
}

if ( idx.column() == MinScaleColumn )
{
if ( role == Qt::DisplayRole )
{
return QString::number( ls.minScale() );
}

if ( role == Qt::UserRole )
{
return ls.minScale();
}
}

if ( idx.column() == MaxScaleColumn )
{
if ( role == Qt::DisplayRole )
{
return QString::number( ls.maxScale() );
}

if ( role == Qt::UserRole )
{
return ls.maxScale();
}
}
}

return QVariant();
Expand Down Expand Up @@ -712,5 +816,68 @@ bool QgsSnappingLayerTreeModel::setData( const QModelIndex &index, const QVarian
}
}

if ( index.column() == LimitToScaleRangeColumn && role == Qt::EditRole )
{
QgsVectorLayer *vl = vectorLayer( index );
if ( vl )
{
if ( !mIndividualLayerSettings.contains( vl ) )
return false;

QgsSnappingConfig::IndividualLayerSettings ls = mIndividualLayerSettings.value( vl );
if ( !ls.valid() )
return false;

ls.setLimitToScaleRange( value.toBool() );
QgsSnappingConfig config = mProject->snappingConfig();
config.setIndividualLayerSettings( vl, ls );
mProject->setSnappingConfig( config );
emit dataChanged( index, index );
return true;
}
}

if ( index.column() == MinScaleColumn && role == Qt::EditRole )
{
QgsVectorLayer *vl = vectorLayer( index );
if ( vl )
{
if ( !mIndividualLayerSettings.contains( vl ) )
return false;

QgsSnappingConfig::IndividualLayerSettings ls = mIndividualLayerSettings.value( vl );
if ( !ls.valid() )
return false;

ls.setMinScale( value.toDouble() );
QgsSnappingConfig config = mProject->snappingConfig();
config.setIndividualLayerSettings( vl, ls );
mProject->setSnappingConfig( config );
emit dataChanged( index, index );
return true;
}
}

if ( index.column() == MaxScaleColumn && role == Qt::EditRole )
{
QgsVectorLayer *vl = vectorLayer( index );
if ( vl )
{
if ( !mIndividualLayerSettings.contains( vl ) )
return false;

QgsSnappingConfig::IndividualLayerSettings ls = mIndividualLayerSettings.value( vl );
if ( !ls.valid() )
return false;

ls.setMaxScale( value.toDouble() );
QgsSnappingConfig config = mProject->snappingConfig();
config.setIndividualLayerSettings( vl, ls );
mProject->setSnappingConfig( config );
emit dataChanged( index, index );
return true;
}
}

return false;
}
5 changes: 4 additions & 1 deletion src/app/qgssnappinglayertreemodel.h
Expand Up @@ -56,7 +56,10 @@ class APP_EXPORT QgsSnappingLayerTreeModel : public QSortFilterProxyModel
TypeColumn,
ToleranceColumn,
UnitsColumn,
AvoidIntersectionColumn
AvoidIntersectionColumn,
LimitToScaleRangeColumn,
MinScaleColumn,
MaxScaleColumn
};

QgsSnappingLayerTreeModel( QgsProject *project, QgsMapCanvas *canvas, QObject *parent = nullptr );
Expand Down
4 changes: 2 additions & 2 deletions src/app/vertextool/qgsvertextool.cpp
Expand Up @@ -769,7 +769,7 @@ QgsPointLocator::Match QgsVertexTool::snapToEditableLayer( QgsMapMouseEvent *e )
continue;

config.setIndividualLayerSettings( vlayer, QgsSnappingConfig::IndividualLayerSettings(
vlayer == currentVlayer, static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag ), tol, QgsTolerance::ProjectUnits ) );
vlayer == currentVlayer, static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag ), tol, QgsTolerance::ProjectUnits, false, 0.0, 0.0 ) );
}

snapUtils->setConfig( config );
Expand All @@ -796,7 +796,7 @@ QgsPointLocator::Match QgsVertexTool::snapToEditableLayer( QgsMapMouseEvent *e )
continue;

config.setIndividualLayerSettings( vlayer, QgsSnappingConfig::IndividualLayerSettings(
vlayer->isEditable(), static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag ), tol, QgsTolerance::ProjectUnits ) );
vlayer->isEditable(), static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag ), tol, QgsTolerance::ProjectUnits, false, 0.0, 0.0 ) );
}

snapUtils->setConfig( config );
Expand Down

0 comments on commit 8ec744a

Please sign in to comment.