QGIS API Documentation 3.39.0-Master (47f7b3a4989)
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
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
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
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.
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)
Fetch next feature and stores in f, returns true on success.
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: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
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< Qgis::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.
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.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:82
QString id
Definition qgsmaplayer.h:78
A class to represent 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.
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
A list of layers and feature ids for each of these layers.
QMap< QString, QgsFeatureIds > toMap() const