Skip to content

Commit

Permalink
Add autofixers for geomtries
Browse files Browse the repository at this point in the history
 * Snap to grid
 * Remove duplicate nodes
  • Loading branch information
m-kuhn committed Aug 21, 2018
1 parent c0032f1 commit 256876e
Show file tree
Hide file tree
Showing 5 changed files with 510 additions and 56 deletions.
21 changes: 19 additions & 2 deletions python/core/auto_generated/qgsvectorlayer.sip.in
Expand Up @@ -329,6 +329,16 @@ Constructor for LayerOptions.

};

struct GeometryOptions
{
explicit GeometryOptions( bool removeDuplicateNodes = false, double geometryPrecision = 0.0 );


bool removeDuplicateNodes;

double geometryPrecision;
};

explicit QgsVectorLayer( const QString &path = QString(), const QString &baseName = QString(),
const QString &providerLib = "ogr", const QgsVectorLayer::LayerOptions &options = QgsVectorLayer::LayerOptions() );
%Docstring
Expand Down Expand Up @@ -1062,7 +1072,7 @@ Query the layer for the features which intersect the specified rectangle.
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );


bool updateFeature( const QgsFeature &feature, bool skipDefaultValues = false );
bool updateFeature( QgsFeature &feature, bool skipDefaultValues = false );
%Docstring
Updates an existing ``feature`` in the layer, replacing the attributes and geometry for the feature
with matching QgsFeature.id() with the attributes and geometry from ``feature``.
Expand Down Expand Up @@ -1498,7 +1508,7 @@ Make layer read-only (editing disabled) or not
:return: false if the layer is in editing yet
%End

bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geometry, bool skipDefaultValue = false );
bool changeGeometry( QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue = false );
%Docstring
Changes a feature's ``geometry`` within the layer's edit buffer
(but does not immediately commit the changes). The ``fid`` argument
Expand Down Expand Up @@ -2225,6 +2235,13 @@ Test if an edit command is active
.. versionadded:: 3.0
%End


bool removeDuplicateNodes() const;
void setRemoveDuplicateNodes( bool removeDuplicateNodes );

double geometryPrecision() const;
void setGeometryPrecision( double geometryPrecision );

public slots:

void select( QgsFeatureId featureId );
Expand Down
10 changes: 8 additions & 2 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -289,9 +289,9 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(

//insert existing join info
const QList< QgsVectorLayerJoinInfo > &joins = mLayer->vectorJoins();
for ( int i = 0; i < joins.size(); ++i )
for ( const QgsVectorLayerJoinInfo &join : joins )
{
addJoinToTreeWidget( joins[i] );
addJoinToTreeWidget( join );
}

mOldJoins = mLayer->vectorJoins();
Expand Down Expand Up @@ -423,6 +423,9 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(

updateAuxiliaryStoragePage();

mRemoveDuplicateVerticeCheckbox->setChecked( mLayer->removeDuplicateNodes() );
mGeometryPrecisionSpinBox->setValue( mLayer->geometryPrecision() );

optionsStackedWidget_CurrentChanged( mOptStackedWidget->currentIndex() );
}

Expand Down Expand Up @@ -761,6 +764,9 @@ void QgsVectorLayerProperties::apply()
mVector3DWidget->apply();
#endif

mLayer->setRemoveDuplicateNodes( mRemoveDuplicateVerticeCheckbox->isChecked() );
mLayer->setGeometryPrecision( mGeometryPrecisionSpinBox->value() );

// update symbology
emit refreshLegend( mLayer->id() );

Expand Down
64 changes: 61 additions & 3 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -944,6 +944,20 @@ bool QgsVectorLayer::addFeature( QgsFeature &feature, Flags )
if ( !mValid || !mEditBuffer || !mDataProvider )
return false;


if ( mGeometryOptions.geometryPrecision != 0.0 || mGeometryOptions.removeDuplicateNodes )
{
QgsGeometry geom = feature.geometry();

if ( mGeometryOptions.geometryPrecision != 0.0 )
geom = geom.snappedToGrid( mGeometryOptions.geometryPrecision, mGeometryOptions.geometryPrecision );

if ( mGeometryOptions.removeDuplicateNodes )
geom.removeDuplicateNodes();

feature.setGeometry( geom );
}

bool success = mEditBuffer->addFeature( feature );

if ( success )
Expand All @@ -957,7 +971,7 @@ bool QgsVectorLayer::addFeature( QgsFeature &feature, Flags )
return success;
}

bool QgsVectorLayer::updateFeature( const QgsFeature &updatedFeature, bool skipDefaultValues )
bool QgsVectorLayer::updateFeature( QgsFeature &updatedFeature, bool skipDefaultValues )
{
if ( !mEditBuffer || !mDataProvider )
{
Expand All @@ -972,9 +986,11 @@ bool QgsVectorLayer::updateFeature( const QgsFeature &updatedFeature, bool skipD

if ( ( updatedFeature.hasGeometry() || currentFeature.hasGeometry() ) && !updatedFeature.geometry().equals( currentFeature.geometry() ) )
{
if ( changeGeometry( updatedFeature.id(), updatedFeature.geometry(), true ) )
QgsGeometry geometry = updatedFeature.geometry();
if ( changeGeometry( updatedFeature.id(), geometry, true ) )
{
hasChanged = true;
updatedFeature.setGeometry( geometry );
}
else
{
Expand Down Expand Up @@ -2485,13 +2501,19 @@ bool QgsVectorLayer::writeSld( QDomNode &node, QDomDocument &doc, QString &error
}


bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, const QgsGeometry &geom, bool skipDefaultValue )
bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, QgsGeometry &geom, bool skipDefaultValue )
{
if ( !mEditBuffer || !mDataProvider )
{
return false;
}

if ( mGeometryOptions.geometryPrecision != 0.0 )
geom = geom.snappedToGrid( mGeometryOptions.geometryPrecision, mGeometryOptions.geometryPrecision );

if ( mGeometryOptions.removeDuplicateNodes )
geom.removeDuplicateNodes();

updateExtents();

bool result = mEditBuffer->changeGeometry( fid, geom );
Expand Down Expand Up @@ -2960,6 +2982,22 @@ bool QgsVectorLayer::addFeatures( QgsFeatureList &features, Flags )
if ( !mEditBuffer || !mDataProvider )
return false;

if ( mGeometryOptions.geometryPrecision != 0.0 || mGeometryOptions.removeDuplicateNodes )
{
for ( auto feature = features.begin(); feature != features.end(); ++feature )
{
QgsGeometry geom = feature->geometry();

if ( mGeometryOptions.geometryPrecision != 0.0 )
geom = geom.snappedToGrid( mGeometryOptions.geometryPrecision, mGeometryOptions.geometryPrecision );

if ( mGeometryOptions.removeDuplicateNodes )
geom.removeDuplicateNodes();

feature->setGeometry( geom );
}
}

bool res = mEditBuffer->addFeatures( features );
updateExtents();

Expand Down Expand Up @@ -4744,6 +4782,26 @@ QgsAbstractVectorLayerLabeling *QgsVectorLayer::readLabelingFromCustomProperties
return labeling;
}

double QgsVectorLayer::geometryPrecision() const
{
return mGeometryOptions.geometryPrecision;
}

void QgsVectorLayer::setGeometryPrecision( double geometryPrecision )
{
mGeometryOptions.geometryPrecision = geometryPrecision;
}

bool QgsVectorLayer::removeDuplicateNodes() const
{
return mGeometryOptions.removeDuplicateNodes;
}

void QgsVectorLayer::setRemoveDuplicateNodes( bool removeDuplicateNodes )
{
mGeometryOptions.removeDuplicateNodes = removeDuplicateNodes;
}

void QgsVectorLayer::setReadExtentFromXml( bool readExtentFromXml )
{
mReadExtentFromXml = readExtentFromXml;
Expand Down
39 changes: 37 additions & 2 deletions src/core/qgsvectorlayer.h
Expand Up @@ -408,6 +408,32 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte

};

struct GeometryOptions
{
explicit GeometryOptions( bool removeDuplicateNodes = false, double geometryPrecision = 0.0 )
: removeDuplicateNodes( removeDuplicateNodes )
, geometryPrecision( geometryPrecision )
{
}


/**
* Automatically remove duplicate nodes on all geometries which are edited on this layer.
*
* \since QGIS 3.4
*/
bool removeDuplicateNodes = false;

/**
* The precision in which geometries on this layer should be saved.
* Geometries which are edited on this layer will be rounded to multiples of this value (snap to grid).
* Set to 0.0 to disable.
*
* \since QGIS 3.4
*/
double geometryPrecision = 0.0;
};

/**
* Constructor - creates a vector layer
*
Expand Down Expand Up @@ -1069,7 +1095,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \see changeGeometry()
* \see changeAttributeValue()
*/
bool updateFeature( const QgsFeature &feature, bool skipDefaultValues = false );
bool updateFeature( QgsFeature &feature, bool skipDefaultValues = false );

/**
* Insert a new vertex before the given vertex number,
Expand Down Expand Up @@ -1402,7 +1428,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \see changeAttributeValue()
* \see updateFeature()
*/
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geometry, bool skipDefaultValue = false );
bool changeGeometry( QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue = false );

/**
* Changes an attribute value for a feature (but does not immediately commit the changes).
Expand Down Expand Up @@ -1992,6 +2018,13 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
*/
bool isEditCommandActive() const { return mEditCommandActive; }


bool removeDuplicateNodes() const;
void setRemoveDuplicateNodes( bool removeDuplicateNodes );

double geometryPrecision() const;
void setGeometryPrecision( double geometryPrecision );

public slots:

/**
Expand Down Expand Up @@ -2483,6 +2516,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte

QgsVectorLayerFeatureCounter *mFeatureCounter = nullptr;

GeometryOptions mGeometryOptions;

friend class QgsVectorLayerFeatureSource;
};

Expand Down

0 comments on commit 256876e

Please sign in to comment.