QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsgeometryfollowboundariescheck.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometryfollowboundariescheck.cpp
3 ---------------------
4 begin : September 2017
5 copyright : (C) 2017 by Sandro Mani / Sourcepole AG
6 email : smani at sourcepole dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
18#include "qgsgeometryengine.h"
19#include "qgsproject.h"
20#include "qgsspatialindex.h"
21#include "qgsvectorlayer.h"
23
25 : QgsGeometryCheck( context, configuration )
26{
27 mCheckLayer = checkLayer;
28 if ( mCheckLayer )
29 {
30 mIndex = new QgsSpatialIndex( *mCheckLayer->dataProvider() );
31 }
32}
33
35{
36 delete mIndex;
37}
38
39void QgsGeometryFollowBoundariesCheck::collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids ) const
40{
41 Q_UNUSED( messages )
42
43 if ( !mIndex || !mCheckLayer )
44 {
45 return;
46 }
47
48 QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds( featurePools ) : ids.toMap();
49 featureIds.remove( mCheckLayer->id() ); // Don't check layer against itself
50 const QgsGeometryCheckerUtils::LayerFeatures layerFeatures( featurePools, featureIds, compatibleGeometryTypes(), feedback, mContext );
51 for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
52 {
53 const QgsAbstractGeometry *geom = layerFeature.geometry().constGet();
54
55 // The geometry to crs of the check layer
56 const QgsCoordinateTransform crst( layerFeature.layer()->crs(), mCheckLayer->crs(), QgsProject::instance() );
57 QgsGeometry geomt( geom->clone() );
58 geomt.transform( crst );
59
60 std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geomt.constGet(), mContext->tolerance );
61
62 // Get potential reference features
63 QgsRectangle searchBounds = geomt.constGet()->boundingBox();
64 searchBounds.grow( mContext->tolerance );
65 const QgsFeatureIds refFeatureIds = qgis::listToSet( mIndex->intersects( searchBounds ) );
66
67 const QgsFeatureRequest refFeatureRequest = QgsFeatureRequest().setFilterFids( refFeatureIds ).setNoAttributes();
68 QgsFeatureIterator refFeatureIt = mCheckLayer->getFeatures( refFeatureRequest );
69
70 if ( refFeatureIds.isEmpty() )
71 {
72 // If no potential reference features are found, the geometry is definitely not following boundaries of reference layer features
73 errors.append( new QgsGeometryCheckError( this, layerFeature, QgsPointXY( geom->centroid() ) ) );
74 }
75 else
76 {
77 // All reference features must be either contained or disjoint from tested geometry
78 QgsFeature refFeature;
79 while ( refFeatureIt.nextFeature( refFeature ) )
80 {
81 const QgsAbstractGeometry *refGeom = refFeature.geometry().constGet();
82 std::unique_ptr<QgsGeometryEngine> refgeomEngine( QgsGeometryCheckerUtils::createGeomEngine( refGeom, mContext->tolerance ) );
83 const QgsGeometry reducedRefGeom( refgeomEngine->buffer( -mContext->tolerance, 0 ) );
84 if ( !( geomEngine->contains( reducedRefGeom.constGet() ) || geomEngine->disjoint( reducedRefGeom.constGet() ) ) )
85 {
86 errors.append( new QgsGeometryCheckError( this, layerFeature, QgsPointXY( geom->centroid() ) ) );
87 break;
88 }
89 }
90 }
91 }
92}
93
94void QgsGeometryFollowBoundariesCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes & /*changes*/ ) const
95{
96 Q_UNUSED( featurePools )
97
98 if ( method == NoChange )
99 {
100 error->setFixed( method );
101 }
102 else
103 {
104 error->setFixFailed( tr( "Unknown method" ) );
105 }
106}
107
109{
110 static const QStringList methods = QStringList() << tr( "No action" );
111 return methods;
112}
113
115{
117}
Abstract base class for all geometries.
virtual QgsRectangle boundingBox() const =0
Returns the minimal bounding box for the geometry.
virtual QgsPoint centroid() const
Returns the centroid of the geometry.
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
Class for doing transforms between two map coordinate systems.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsGeometry geometry
Definition: qgsfeature.h:67
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
Base configuration for geometry checks.
const double tolerance
The tolerance to allow for in geometry checks.
This represents an error reported by a geometry check.
void setFixed(int method)
Set the status to fixed and specify the method that has been used to fix the error.
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
This class implements a geometry check.
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
const QgsGeometryCheckContext * mContext
CheckType
The type of a check.
@ FeatureNodeCheck
The check controls individual nodes.
QMap< QString, QgsFeatureIds > allLayerFeatureIds(const QMap< QString, QgsFeaturePool * > &featurePools) const
Returns all layers and feature ids.
A layer feature combination to uniquely identify and access a feature in a set of layers.
Contains a set of layers and feature ids in those layers to pass to a geometry check.
static std::unique_ptr< QgsGeometryEngine > createGeomEngine(const QgsAbstractGeometry *geometry, double tolerance)
static QgsGeometryCheck::CheckType factoryCheckType()
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
QList< QgsWkbTypes::GeometryType > compatibleGeometryTypes() const override
A list of geometry types for which this check can be performed.
QgsGeometryFollowBoundariesCheck(QgsGeometryCheckContext *context, const QVariantMap &configuration, QgsVectorLayer *checkLayer)
void fixError(const QMap< QString, QgsFeaturePool * > &featurePools, QgsGeometryCheckError *error, int method, const QMap< QString, int > &mergeAttributeIndices, Changes &changes) const override
Fixes the error error with the specified method.
void collectErrors(const QMap< QString, QgsFeaturePool * > &featurePools, QList< QgsGeometryCheckError * > &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids=LayerFeatureIds()) const override
The main worker method.
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
A class to represent a 2D point.
Definition: qgspointxy.h:59
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:477
A rectangle specified with double values.
Definition: qgsrectangle.h:42
void grow(double delta)
Grows the rectangle in place by the specified amount.
Definition: qgsrectangle.h:296
A spatial index for QgsFeature objects.
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle.
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
A list of layers and feature ids for each of these layers.
QMap< QString, QgsFeatureIds > toMap() const