Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] New snapping mode to snap to all layers
  • Loading branch information
wonder-sk committed Jan 23, 2015
1 parent 6419a7b commit 23c776e
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 11 deletions.
5 changes: 3 additions & 2 deletions python/core/qgssnappingutils.sip
Expand Up @@ -37,8 +37,9 @@ class QgsSnappingUtils : QObject
//! modes for "snap to background"
enum SnapToMapMode
{
SnapCurrentLayer, //!< snap just to current layer (tolerance+type from QSettings)
SnapPerLayerConfig, //!< snap according to the configuration set in setLayers()
SnapCurrentLayer, //!< snap just to current layer (tolerance and type from defaultSettings())
SnapAllLayers, //!< snap to all rendered layers (tolerance and type from defaultSettings())
SnapAdvanced, //!< snap according to the configuration set in setLayers()
};

/** Set how the snapping to map is done */
Expand Down
14 changes: 11 additions & 3 deletions src/app/qgssnappingdialog.cpp
Expand Up @@ -167,7 +167,7 @@ void QgsSnappingDialog::on_cbxEnableIntersectionSnappingCheckBox_stateChanged( i

void QgsSnappingDialog::onSnappingModeIndexChanged( int index )
{
if ( index == 0 )
if ( index == 0 || index == 1 )
mStackedWidget->setCurrentIndex( 0 );
else
mStackedWidget->setCurrentIndex( 1 );
Expand Down Expand Up @@ -203,7 +203,13 @@ void QgsSnappingDialog::closeEvent( QCloseEvent* event )

void QgsSnappingDialog::apply()
{
QString snapMode = mSnapModeComboBox->currentIndex() == 0 ? "current_layer" : "advanced";
QString snapMode;
switch ( mSnapModeComboBox->currentIndex() )
{
case 0: snapMode = "current_layer"; break;
case 1: snapMode = "all_layers"; break;
default: snapMode = "advanced"; break;
}
QgsProject::instance()->writeEntry( "Digitizing", "/SnappingMode", snapMode );

QString snapType = mDefaultSnapToComboBox->itemData( mDefaultSnapToComboBox->currentIndex() ).toString();
Expand Down Expand Up @@ -486,7 +492,9 @@ void QgsSnappingDialog::setSnappingMode()
QString snapMode = QgsProject::instance()->readEntry( "Digitizing", "/SnappingMode" );
if ( snapMode == "current_layer" )
mSnapModeComboBox->setCurrentIndex( 0 );
else // "advanced" or empty (backward compatibility)
else if ( snapMode == "all_layers" )
mSnapModeComboBox->setCurrentIndex( 1 );
else // "advanced" or empty (backward compatibility)
mSnapModeComboBox->setCurrentIndex( 2 );
}

35 changes: 33 additions & 2 deletions src/core/qgssnappingutils.cpp
Expand Up @@ -225,7 +225,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPoint& pointMap, Qg

return bestMatch;
}
else if ( mSnapToMapMode == SnapPerLayerConfig )
else if ( mSnapToMapMode == SnapAdvanced )
{
QgsPointLocator::Match bestMatch;
QgsPointLocator::MatchList edges; // for snap on intersection
Expand All @@ -251,6 +251,35 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPoint& pointMap, Qg

return bestMatch;
}
else if ( mSnapToMapMode == SnapAllLayers )
{
// data from project
double tolerance = QgsTolerance::toleranceInMapUnits( mDefaultTolerance, mMapSettings, mDefaultUnit );
int type = mDefaultType;

QgsPointLocator::MatchList edges; // for snap on intersection
QgsPointLocator::Match bestMatch;

foreach( const QString& layerID, mMapSettings.layers() )
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerID ) );
if ( !vl )
continue;

if ( QgsPointLocator* loc = locatorForLayerUsingStrategy( vl, pointMap, tolerance ) )
{
_updateBestMatch( bestMatch, pointMap, loc, type, tolerance, filter );

if ( mSnapOnIntersection )
edges << loc->edgesInRect( pointMap, tolerance );
}
}

if ( mSnapOnIntersection )
_replaceIfBetter( bestMatch, _findClosestSegmentIntersection( pointMap, edges ), tolerance );

return bestMatch;
}

return QgsPointLocator::Match();
}
Expand Down Expand Up @@ -346,8 +375,10 @@ void QgsSnappingUtils::readConfigFromProject()
// Use snapping information from the project
if ( snapMode == "current_layer" )
mSnapToMapMode = SnapCurrentLayer;
else if ( snapMode == "all_layers" )
mSnapToMapMode = SnapAllLayers;
else // either "advanced" or empty (for background compatibility)
mSnapToMapMode = SnapPerLayerConfig;
mSnapToMapMode = SnapAdvanced;



Expand Down
5 changes: 3 additions & 2 deletions src/core/qgssnappingutils.h
Expand Up @@ -73,8 +73,9 @@ class CORE_EXPORT QgsSnappingUtils : public QObject
//! modes for "snap to background"
enum SnapToMapMode
{
SnapCurrentLayer, //!< snap just to current layer (tolerance+type from QSettings)
SnapPerLayerConfig, //!< snap according to the configuration set in setLayers()
SnapCurrentLayer, //!< snap just to current layer (tolerance and type from defaultSettings())
SnapAllLayers, //!< snap to all rendered layers (tolerance and type from defaultSettings())
SnapAdvanced, //!< snap according to the configuration set in setLayers()
};

/** Set how the snapping to map is done */
Expand Down
5 changes: 5 additions & 0 deletions src/ui/qgssnappingdialogbase.ui
Expand Up @@ -36,6 +36,11 @@
<string>Current layer</string>
</property>
</item>
<item>
<property name="text">
<string>All layers</string>
</property>
</item>
<item>
<property name="text">
<string>Advanced</string>
Expand Down
30 changes: 28 additions & 2 deletions tests/src/core/testqgssnappingutils.cpp
Expand Up @@ -111,7 +111,7 @@ class TestQgsSnappingUtils : public QObject
QVERIFY( !m3.isValid() );
}

void testSnapModePerLayer()
void testSnapModeAll()
{
QgsMapSettings mapSettings;
mapSettings.setOutputSize( QSize( 100, 100 ) );
Expand All @@ -120,7 +120,32 @@ class TestQgsSnappingUtils : public QObject

QgsSnappingUtils u;
u.setMapSettings( mapSettings );
u.setSnapToMapMode( QgsSnappingUtils::SnapPerLayerConfig );
u.setSnapToMapMode( QgsSnappingUtils::SnapAllLayers );

// right now there are no layers in map settings - snapping will fail

QgsPointLocator::Match m = u.snapToMap( QPoint( 100, 100 ) );
QVERIFY( !m.isValid() );

// now check with our layer
mapSettings.setLayers( QStringList() << mVL->id() );
u.setMapSettings( mapSettings );

QgsPointLocator::Match m2 = u.snapToMap( QPoint( 100, 100 ) );
QVERIFY( m2.isValid() );
QCOMPARE( m2.point(), QgsPoint( 1, 0 ) );
}

void testSnapModeAdvanced()
{
QgsMapSettings mapSettings;
mapSettings.setOutputSize( QSize( 100, 100 ) );
mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) );
QVERIFY( mapSettings.hasValidSettings() );

QgsSnappingUtils u;
u.setMapSettings( mapSettings );
u.setSnapToMapMode( QgsSnappingUtils::SnapAdvanced );
QList<QgsSnappingUtils::LayerConfig> layers;
layers << QgsSnappingUtils::LayerConfig( mVL, QgsPointLocator::Vertex, 10, QgsTolerance::Pixels );
u.setLayers( layers );
Expand All @@ -135,6 +160,7 @@ class TestQgsSnappingUtils : public QObject
QgsPointLocator::Match m2 = u.snapToMap( QPoint( 100, 100 ), &myFilter );
QVERIFY( !m2.isValid() );
}

};

QTEST_MAIN( TestQgsSnappingUtils )
Expand Down

1 comment on commit 23c776e

@3nids
Copy link
Member

@3nids 3nids commented on 23c776e Jan 23, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!!!!!!!

Please sign in to comment.