Skip to content

Commit

Permalink
Merge pull request #33796 from m-kuhn/new_gap_fixes
Browse files Browse the repository at this point in the history
Improved resolution methods for geometry validation
  • Loading branch information
m-kuhn committed Jan 17, 2020
2 parents 0fa5a8f + ff7302e commit bc2fa38
Show file tree
Hide file tree
Showing 35 changed files with 388 additions and 57 deletions.
1 change: 1 addition & 0 deletions python/analysis/analysis_auto.sip
Expand Up @@ -32,6 +32,7 @@
%Include auto_generated/raster/qgstotalcurvaturefilter.sip
%Include auto_generated/vector/geometry_checker/qgsfeaturepool.sip
%Include auto_generated/vector/geometry_checker/qgsgeometrycheck.sip
%Include auto_generated/vector/geometry_checker/qgsgeometrycheckresolutionmethod.sip
%Include auto_generated/vector/geometry_checker/qgsgeometrycheckcontext.sip
%Include auto_generated/vector/geometry_checker/qgsgeometrycheckerror.sip
%Include auto_generated/vector/geometry_checker/qgsgeometrycheckerutils.sip
Expand Down
Expand Up @@ -213,9 +213,20 @@ Progress should be reported to ``feedback``. Only features and layers listed in
%End


virtual QStringList resolutionMethods() const = 0;
virtual QList<QgsGeometryCheckResolutionMethod> availableResolutionMethods() const;
%Docstring
Returns a list of descriptions for available resolutions for errors. The index will be passed as ``method`` to :py:func:`fixError`.
Returns a list of available resolution methods.

.. versionadded:: 3.12
%End

virtual QStringList resolutionMethods() const /Deprecated/;
%Docstring
Returns a list of descriptions for available resolutions for errors.
The index will be passed as ``method`` to :py:func:`fixError`.

.. deprecated:: QGIS 3.12
use availableResolutionMethods() instead

.. versionadded:: 3.4
%End
Expand Down
@@ -0,0 +1,57 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/vector/geometry_checker/qgsgeometrycheckresolutionmethod.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsGeometryCheckResolutionMethod
{
%Docstring
This class implements a resolution for problems detected in geometry checks.

.. versionadded:: 3.12
%End

%TypeHeaderCode
#include "qgsgeometrycheckresolutionmethod.h"
%End
public:

QgsGeometryCheckResolutionMethod( int id, const QString &name, const QString &description, bool isStable = true );
%Docstring
Creates a new method with the specified parameters.
%End

int id() const;
%Docstring
An id that is unique per check. This will be used to trigger resolutions.
%End

bool isStable() const;
%Docstring
If this fix is stable enough to be listed by default.
%End

QString name() const;
%Docstring
A human readable and translated name for this fix.
%End

QString description() const;
%Docstring
A human readable and translated description for this fix.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/analysis/vector/geometry_checker/qgsgeometrycheckresolutionmethod.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
2 changes: 2 additions & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -208,6 +208,7 @@ SET(QGIS_ANALYSIS_SRCS
vector/geometry_checker/qgsgeometryanglecheck.cpp
vector/geometry_checker/qgsgeometryareacheck.cpp
vector/geometry_checker/qgsgeometrycheck.cpp
vector/geometry_checker/qgsgeometrycheckresolutionmethod.cpp
vector/geometry_checker/qgsgeometrycheckcontext.cpp
vector/geometry_checker/qgsgeometrychecker.cpp
vector/geometry_checker/qgsgeometrycheckerror.cpp
Expand Down Expand Up @@ -300,6 +301,7 @@ SET(QGIS_ANALYSIS_HDRS
vector/geometry_checker/qgsgeometryanglecheck.h
vector/geometry_checker/qgsgeometryareacheck.h
vector/geometry_checker/qgsgeometrycheck.h
vector/geometry_checker/qgsgeometrycheckresolutionmethod.h
vector/geometry_checker/qgsgeometrycheckcontext.h
vector/geometry_checker/qgsgeometrychecker.h
vector/geometry_checker/qgsgeometrycheckerror.h
Expand Down
Expand Up @@ -41,7 +41,7 @@ class ANALYSIS_EXPORT QgsGeometryAngleCheck : public QgsGeometryCheck
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;

QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override;
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
QString id() const override;
QString description() const override;
QgsGeometryCheck::CheckType checkType() const override;
Expand Down
Expand Up @@ -37,7 +37,7 @@ class ANALYSIS_EXPORT QgsGeometryAreaCheck : public QgsGeometryCheck
QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
void collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids = LayerFeatureIds() ) const override;
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
QString id() const override { return factoryId(); }
QgsGeometryCheck::CheckType checkType() const override { return factoryCheckType(); }

Expand Down
23 changes: 23 additions & 0 deletions src/analysis/vector/geometry_checker/qgsgeometrycheck.cpp
Expand Up @@ -56,6 +56,29 @@ void QgsGeometryCheck::fixError( const QMap<QString, QgsFeaturePool *> &featureP
Q_UNUSED( changes )
}

QList<QgsGeometryCheckResolutionMethod> QgsGeometryCheck::availableResolutionMethods() const
{
QList<QgsGeometryCheckResolutionMethod> fixes;
// Once the deprecated `resolutionMethods()` function is gone, this default implementation
// should be removed and each check will need to implement this method instead of resolutionMethods().
Q_NOWARN_DEPRECATED_PUSH
const QStringList methods = resolutionMethods();
Q_NOWARN_DEPRECATED_POP

int i = 0;
for ( const QString &method : methods )
{
fixes.append( QgsGeometryCheckResolutionMethod( i, method, QString(), false ) );
}

return fixes;
}

QStringList QgsGeometryCheck::resolutionMethods() const
{
return QStringList();
}

QMap<QString, QgsFeatureIds> QgsGeometryCheck::allLayerFeatureIds( const QMap<QString, QgsFeaturePool *> &featurePools ) const
{
QMap<QString, QgsFeatureIds> featureIds;
Expand Down
17 changes: 14 additions & 3 deletions src/analysis/vector/geometry_checker/qgsgeometrycheck.h
Expand Up @@ -24,8 +24,9 @@
#include "qgis_analysis.h"
#include "qgsfeature.h"
#include "qgsvectorlayer.h"
#include "geometry/qgsgeometry.h"
#include "qgsgeometry.h"
#include "qgsgeometrycheckerutils.h"
#include "qgsgeometrycheckresolutionmethod.h"
#include "qgssettings.h"

class QgsGeometryCheckError;
Expand Down Expand Up @@ -307,16 +308,26 @@ class ANALYSIS_EXPORT QgsGeometryCheck
* Fixes the error \a error with the specified \a method.
* Is executed on the main thread.
*
* \see availableResolutionMethods()
* \since QGIS 3.4
*/
virtual void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes SIP_INOUT ) const SIP_SKIP;

/**
* Returns a list of descriptions for available resolutions for errors. The index will be passed as ``method`` to \see fixError().
* Returns a list of available resolution methods.
*
* \since QGIS 3.12
*/
virtual QList<QgsGeometryCheckResolutionMethod> availableResolutionMethods() const;

/**
* Returns a list of descriptions for available resolutions for errors.
* The index will be passed as ``method`` to \see fixError().
*
* \deprecated since QGIS 3.12, use availableResolutionMethods() instead
* \since QGIS 3.4
*/
virtual QStringList resolutionMethods() const = 0;
Q_DECL_DEPRECATED virtual QStringList resolutionMethods() const SIP_DEPRECATED;

/**
* Returns a human readable description for this check.
Expand Down
Expand Up @@ -98,8 +98,12 @@ QgsRectangle QgsGeometryCheckError::affectedAreaBBox() const
void QgsGeometryCheckError::setFixed( int method )
{
mStatus = StatusFixed;
const QStringList methods = mCheck->resolutionMethods();
mResolutionMessage = methods[method];
const QList<QgsGeometryCheckResolutionMethod> methods = mCheck->availableResolutionMethods();
for ( const QgsGeometryCheckResolutionMethod &fix : methods )
{
if ( fix.id() == method )
mResolutionMessage = fix.name();
}
}

void QgsGeometryCheckError::setFixFailed( const QString &reason )
Expand Down
@@ -0,0 +1,44 @@
/***************************************************************************
qgsgeometrycheckresolutionmethod.cpp
--------------------------------------
Date : January 2020
Copyright : (C) 2020 Matthias Kuhn
Email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsgeometrycheckresolutionmethod.h"

QgsGeometryCheckResolutionMethod::QgsGeometryCheckResolutionMethod( int id, const QString &name, const QString &description, bool isStable )
: mId( id )
, mIsStable( isStable )
, mName( name )
, mDescription( description )
{
}

int QgsGeometryCheckResolutionMethod::id() const
{
return mId;
}

bool QgsGeometryCheckResolutionMethod::isStable() const
{
return mIsStable;
}

QString QgsGeometryCheckResolutionMethod::name() const
{
return mName;
}

QString QgsGeometryCheckResolutionMethod::description() const
{
return mDescription;
}
@@ -0,0 +1,64 @@
/***************************************************************************
qgsgeometrycheckresolutionmethod.h
--------------------------------------
Date : January 2020
Copyright : (C) 2020 Matthias Kuhn
Email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSGEOMETRYCHECKRESOLUTIONMETHOD_H
#define QGSGEOMETRYCHECKRESOLUTIONMETHOD_H

#include <QString>
#include "qgis_analysis.h"

/**
* \ingroup analysis
* This class implements a resolution for problems detected in geometry checks.
*
* \since QGIS 3.12
*/
class ANALYSIS_EXPORT QgsGeometryCheckResolutionMethod
{
public:

/**
* Creates a new method with the specified parameters.
*/
QgsGeometryCheckResolutionMethod( int id, const QString &name, const QString &description, bool isStable = true );

/**
* An id that is unique per check. This will be used to trigger resolutions.
*/
int id() const;

/**
* If this fix is stable enough to be listed by default.
*/
bool isStable() const;

/**
* A human readable and translated name for this fix.
*/
QString name() const;

/**
* A human readable and translated description for this fix.
*/
QString description() const;

private:
int mId = -1;
bool mIsStable = false;
QString mName;
QString mDescription;
};

#endif // QGSGEOMETRYCHECKRESOLUTIONMETHOD_H
Expand Up @@ -62,7 +62,7 @@ class ANALYSIS_EXPORT QgsGeometryContainedCheck : public QgsGeometryCheck
QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
void collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids = LayerFeatureIds() ) const override;
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
QString id() const override { return factoryId(); }
QString description() const override { return factoryDescription(); }
QgsGeometryCheck::CheckType checkType() const override { return factoryCheckType(); }
Expand Down
Expand Up @@ -33,7 +33,7 @@ class ANALYSIS_EXPORT QgsGeometryDangleCheck : public QgsGeometryCheck

QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
void collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids = LayerFeatureIds() ) const override;
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
QString description() const override { return factoryDescription(); }
QString id() const override { return factoryId(); }
QgsGeometryCheck::CheckType checkType() const override { return factoryCheckType(); }
Expand Down
Expand Up @@ -35,7 +35,7 @@ class ANALYSIS_EXPORT QgsGeometryDegeneratePolygonCheck : public QgsGeometryChec
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;

QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
QString description() const override { return factoryDescription(); }
QString id() const override { return factoryId(); }
QgsGeometryCheck::CheckType checkType() const override { return factoryCheckType(); }
Expand Down
Expand Up @@ -65,7 +65,7 @@ class ANALYSIS_EXPORT QgsGeometryDuplicateCheck : public QgsGeometryCheck
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;

QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
QString description() const override { return factoryDescription(); }
QString id() const override { return factoryId(); }
QgsGeometryCheck::CheckType checkType() const override { return factoryCheckType(); }
Expand Down
Expand Up @@ -33,7 +33,7 @@ class ANALYSIS_EXPORT QgsGeometryDuplicateNodesCheck : public QgsGeometryCheck
QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
void collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids = LayerFeatureIds() ) const override;
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
static QString factoryDescription() { return tr( "Duplicate node" ); }
QString description() const override { return factoryDescription(); }
static QString factoryId() { return QStringLiteral( "QgsGeometryDuplicateNodesCheck" ); }
Expand Down
Expand Up @@ -36,7 +36,7 @@ class ANALYSIS_EXPORT QgsGeometryFollowBoundariesCheck : public QgsGeometryCheck
QList<QgsWkbTypes::GeometryType> compatibleGeometryTypes() const override { return factoryCompatibleGeometryTypes(); }
void collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids = LayerFeatureIds() ) const override;
void fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
QStringList resolutionMethods() const override;
Q_DECL_DEPRECATED QStringList resolutionMethods() const override;
static QString factoryDescription() { return tr( "Polygon does not follow boundaries" ); }
QString description() const override { return factoryDescription(); }
static QString factoryId() { return QStringLiteral( "QgsGeometryFollowBoundariesCheck" ); }
Expand Down

0 comments on commit bc2fa38

Please sign in to comment.