QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
17
18#include "qgsfeedback.h"
21#include "qgsgeometryengine.h"
22#include "qgsproject.h"
23#include "qgsspatialindex.h"
24#include "qgsvectorlayer.h"
25
27 : QgsGeometryCheck( context, configuration )
28{
29 mCheckLayer = checkLayer;
30 if ( mCheckLayer )
31 {
32 mIndex = new QgsSpatialIndex( *mCheckLayer->dataProvider() );
33 }
34}
35
40
41QgsGeometryCheck::Result QgsGeometryFollowBoundariesCheck::collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids ) const
42{
43 Q_UNUSED( messages )
44
45 if ( !mIndex || !mCheckLayer )
46 {
48 }
49
50 QMap<QString, QSet<QVariant>> uniqueIds;
51 QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds( featurePools ) : ids.toMap();
52 featureIds.remove( mCheckLayer->id() ); // Don't check layer against itself
53 const QgsGeometryCheckerUtils::LayerFeatures layerFeatures( featurePools, featureIds, compatibleGeometryTypes(), feedback, mContext );
54 for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
55 {
56 if ( feedback && feedback->isCanceled() )
57 {
59 }
60
61 if ( context()->uniqueIdFieldIndex != -1 )
62 {
63 QgsGeometryCheck::Result result = checkUniqueId( layerFeature, uniqueIds );
65 {
66 return result;
67 }
68 }
69
70 const QgsAbstractGeometry *geom = layerFeature.geometry().constGet();
71
72 // The geometry to crs of the check layer
73 const QgsCoordinateTransform crst( layerFeature.layer()->crs(), mCheckLayer->crs(), QgsProject::instance() );
74 QgsGeometry geomt( geom->clone() );
75 geomt.transform( crst );
76
77 std::unique_ptr<QgsGeometryEngine> geomEngine( QgsGeometry::createGeometryEngine( geomt.constGet(), mContext->tolerance ) );
78
79 // Get potential reference features
80 QgsRectangle searchBounds = geomt.constGet()->boundingBox();
81 searchBounds.grow( mContext->tolerance );
82 const QgsFeatureIds refFeatureIds = qgis::listToSet( mIndex->intersects( searchBounds ) );
83
84 const QgsFeatureRequest refFeatureRequest = QgsFeatureRequest().setFilterFids( refFeatureIds ).setNoAttributes();
85 QgsFeatureIterator refFeatureIt = mCheckLayer->getFeatures( refFeatureRequest );
86
87 if ( refFeatureIds.isEmpty() )
88 {
89 // If no potential reference features are found, the geometry is definitely not following boundaries of reference layer features
90 errors.append( new QgsGeometryCheckError( this, layerFeature, QgsPointXY( geom->centroid() ) ) );
91 }
92 else
93 {
94 // All reference features must be either contained or disjoint from tested geometry
95 QgsFeature refFeature;
96 while ( refFeatureIt.nextFeature( refFeature ) )
97 {
98 if ( feedback && feedback->isCanceled() )
99 {
101 }
102
103 const QgsAbstractGeometry *refGeom = refFeature.geometry().constGet();
104 std::unique_ptr<QgsGeometryEngine> refgeomEngine( QgsGeometry::createGeometryEngine( refGeom, mContext->tolerance ) );
105 const QgsGeometry reducedRefGeom( refgeomEngine->buffer( -mContext->tolerance, 0 ) );
106 if ( !( geomEngine->contains( reducedRefGeom.constGet() ) || geomEngine->disjoint( reducedRefGeom.constGet() ) ) )
107 {
108 errors.append( new QgsGeometryCheckError( this, layerFeature, QgsPointXY( geom->centroid() ) ) );
109 break;
110 }
111 }
112 }
113 }
115}
116
117void QgsGeometryFollowBoundariesCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes & /*changes*/ ) const
118{
119 Q_UNUSED( featurePools )
120
121 if ( method == NoChange )
122 {
123 error->setFixed( method );
124 }
125 else
126 {
127 error->setFixFailed( tr( "Unknown method" ) );
128 }
129}
130
132{
133 static const QStringList methods = QStringList() << tr( "No action" );
134 return methods;
135}
136
Abstract base class for all geometries.
virtual QgsRectangle boundingBox() const
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.
Handles coordinate transforms between two coordinate systems.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
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:58
QgsGeometry geometry
Definition qgsfeature.h:69
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
Base configuration for 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.
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.
Result checkUniqueId(const QgsGeometryCheckerUtils::LayerFeature layerFeature, QMap< QString, QSet< QVariant > > &uniqueIds) const
Checks that there are no duplicated unique IDs.
Result
Result of the geometry checker operation.
@ Canceled
User canceled calculation.
@ Success
Operation completed successfully.
@ InvalidReferenceLayer
Missed or invalid reference layer.
QgsGeometryCheck(const QgsGeometryCheckContext *context, const QVariantMap &configuration)
Create a new geometry check.
const QgsGeometryCheckContext * context() const
Returns the context.
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 QgsGeometryCheck::CheckType factoryCheckType()
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
QList< Qgis::GeometryType > compatibleGeometryTypes() const override
A list of geometry types for which this check can be performed.
QgsGeometryCheck::Result collectErrors(const QMap< QString, QgsFeaturePool * > &featurePools, QList< QgsGeometryCheckError * > &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids=LayerFeatureIds()) const override
The main worker method.
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.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
Represents a 2D point.
Definition qgspointxy.h:60
static QgsProject * instance()
Returns the QgsProject singleton instance.
A rectangle specified with double values.
void grow(double delta)
Grows the rectangle in place by the specified amount.
A spatial index for QgsFeature objects.
Represents a vector layer which manages a vector based dataset.
QSet< QgsFeatureId > QgsFeatureIds
A list of layers and feature ids for each of these layers.
QMap< QString, QgsFeatureIds > toMap() const