Enable snapping on intersection introduced

This commit is contained in:
cmoe 2012-10-05 20:31:40 +02:00 committed by Juergen E. Fischer
parent 3c525fdf30
commit e0d47849b9
4 changed files with 155 additions and 28 deletions

View File

@ -72,6 +72,7 @@ QgsSnappingDialog::QgsSnappingDialog( QWidget* parent, QgsMapCanvas* canvas ): Q
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer * > ) ), this, SLOT( addLayers( QList<QgsMapLayer * > ) ) );
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( layersWillBeRemoved( QStringList ) ) );
connect( cbxEnableTopologicalEditingCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( on_cbxEnableTopologicalEditingCheckBox_stateChanged( int ) ) );
connect( cbxEnableIntersectionSnappingCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( on_cbxEnableIntersectionSnappingCheckBox_stateChanged( int ) ) );
reload();
@ -113,12 +114,20 @@ void QgsSnappingDialog::reload()
}
setTopologicalEditingState();
setIntersectionSnapppingState();
}
void QgsSnappingDialog::on_cbxEnableTopologicalEditingCheckBox_stateChanged( int state )
{
int topologicalEditingEnabled = ( state == Qt::Checked ) ? 1 : 0;
QgsProject::instance()->writeEntry( "Digitizing", "/TopologicalEditing", topologicalEditingEnabled );
setTopologicalEditingState();
}
void QgsSnappingDialog::on_cbxEnableIntersectionSnappingCheckBox_stateChanged( int state )
{
int intersectionSnappingEnabled = ( state == Qt::Checked ) ? 1 : 0;
QgsProject::instance()->writeEntry( "Digitizing", "/IntersectionSnapping", intersectionSnappingEnabled );
}
void QgsSnappingDialog::closeEvent( QCloseEvent* event )
@ -188,6 +197,7 @@ void QgsSnappingDialog::apply()
void QgsSnappingDialog::show()
{
setTopologicalEditingState();
setIntersectionSnapppingState();
if ( mDock )
mDock->setVisible( true );
else
@ -317,6 +327,9 @@ void QgsSnappingDialog::addLayer( QgsMapLayer * theMapLayer )
{
connect( cbxAvoidIntersection, SIGNAL( stateChanged( int ) ), this, SLOT( apply() ) );
}
setTopologicalEditingState();
setIntersectionSnapppingState();
}
}
@ -354,3 +367,19 @@ void QgsSnappingDialog::setTopologicalEditingState()
}
cbxEnableTopologicalEditingCheckBox->blockSignals( false );
}
void QgsSnappingDialog::setIntersectionSnapppingState()
{
// read the digitizing settings
int intersectionSnapping = QgsProject::instance()->readNumEntry( "Digitizing", "/IntersectionSnapping", 0 );
cbxEnableIntersectionSnappingCheckBox->blockSignals( true );
if ( intersectionSnapping != 0 )
{
cbxEnableIntersectionSnappingCheckBox->setCheckState( Qt::Checked );
}
else
{
cbxEnableIntersectionSnappingCheckBox->setCheckState( Qt::Unchecked );
}
cbxEnableIntersectionSnappingCheckBox->blockSignals( false );
}

View File

@ -55,6 +55,8 @@ class QgsSnappingDialog: public QDialog, private Ui::QgsSnappingDialogBase
void on_cbxEnableTopologicalEditingCheckBox_stateChanged( int );
void on_cbxEnableIntersectionSnappingCheckBox_stateChanged( int );
protected:
/**Constructor
@param canvas pointer to the map canvas (for detecting which vector layers are loaded
@ -85,6 +87,9 @@ class QgsSnappingDialog: public QDialog, private Ui::QgsSnappingDialogBase
/**Set checkbox value based on project setting*/
void setTopologicalEditingState();
/**Set checkbox value based on project setting*/
void setIntersectionSnapppingState();
};
#endif

View File

@ -23,7 +23,8 @@
#include "qgsvectorlayer.h"
#include "qgstolerance.h"
#include <QSettings>
#include "qgslogger.h"
#include "qgsgeometry.h"
QgsMapCanvasSnapper::QgsMapCanvasSnapper( QgsMapCanvas* canvas ): mMapCanvas( canvas ), mSnapper( 0 )
{
@ -133,15 +134,34 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
{
//topological editing on?
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
//snapping on intersection on?
int intersectionSnapping = QgsProject::instance()->readNumEntry( "Digitizing", "/IntersectionSnapping", 0 );
if ( topologicalEditing == 0 )
{
mSnapper->setSnapMode( QgsSnapper::SnapWithOneResult );
if ( intersectionSnapping == 0 )
{
mSnapper->setSnapMode( QgsSnapper::SnapWithOneResult );
}
else
{
mSnapper->setSnapMode( QgsSnapper::SnapWithResultsWithinTolerances );
}
}
else
{
mSnapper->setSnapMode( QgsSnapper::SnapWithResultsForSamePosition );
if ( intersectionSnapping == 0 )
{
mSnapper->setSnapMode( QgsSnapper::SnapWithResultsForSamePosition );
}
else
{
mSnapper->setSnapMode( QgsSnapper::SnapWithResultsWithinTolerances );
}
}
//read snapping settings from project
bool ok; //todo: take the default snapping tolerance for all vector layers if snapping not defined in project
bool snappingDefinedInProject = true;
@ -252,13 +272,73 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
snapLayers.append( snapLayer );
}
mSnapper->setSnapLayers( snapLayers );
if ( mSnapper->snapPoint( p, results, excludePoints ) != 0 )
{
return 4;
}
if( intersectionSnapping == 1 )
{
QList<QgsSnappingResult>::const_iterator it = results.constBegin();
QList<QgsSnappingResult> segments;
QList<QgsSnappingResult> points;
for ( ; it != results.constEnd(); ++it )
{
if(it->snappedVertexNr==-1)
{
QgsDebugMsg("segment");
segments.push_back(*it);
}
else
{
QgsDebugMsg("no segment");
points.push_back(*it);
}
}
if(segments.length() >=2 )
{
QgsGeometry* intersectionPoint;
QList<QgsSnappingResult> myResults;
QList<QgsSnappingResult>::const_iterator oSegIt = segments.constBegin();
QList<QgsSnappingResult>::iterator iSegIt;
for( ; oSegIt != segments.constEnd(); ++oSegIt)
{
QgsDebugMsg( QString::number(oSegIt->beforeVertexNr) );
QVector<QgsPoint> vertexPoints;
vertexPoints.append( oSegIt->beforeVertex );
vertexPoints.append( oSegIt->afterVertex );
QgsGeometry* lineA = QgsGeometry::fromPolyline( vertexPoints );
for( iSegIt = segments.begin(); iSegIt != segments.end(); ++iSegIt)
{
QVector<QgsPoint> vertexPoints;
vertexPoints.append( iSegIt->beforeVertex );
vertexPoints.append( iSegIt->afterVertex );
QgsGeometry* lineB = QgsGeometry::fromPolyline( vertexPoints );
intersectionPoint = lineA->intersection(lineB);
if( intersectionPoint->type() == QGis::Point)
{
iSegIt->snappedVertex = intersectionPoint->asPoint();
myResults.append(*iSegIt);
}
}
}
if( myResults.length() > 0 )
{
results.clear();
results = myResults;
}
}
}
return 0;
}
else

View File

@ -14,30 +14,7 @@
<string>Snapping options</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QCheckBox" name="cbxEnableTopologicalEditingCheckBox">
<property name="text">
<string>Enable topological editing</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<item row="0" column="0" colspan="3">
<widget class="QTreeWidget" name="mLayerTreeWidget">
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
@ -89,6 +66,42 @@
</column>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="cbxEnableTopologicalEditingCheckBox">
<property name="text">
<string>Enable topological editing</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="cbxEnableIntersectionSnappingCheckBox">
<property name="text">
<string>Enable snapping on intersection</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>