QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
qgsgeometrycheck.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsgeometrycheck.cpp
3 ---------------------
4 begin : September 2015
5 copyright : (C) 2014 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 "qgscurvepolygon.h"
19#include "qgsgeometrycheck.h"
20#include "moc_qgsgeometrycheck.cpp"
22#include "qgsfeaturepool.h"
23#include "qgsvectorlayer.h"
24#include "qgsreadwritelocker.h"
25#include "qgsthreadingutils.h"
26
27
28
29
30QgsGeometryCheck::QgsGeometryCheck( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
31 : mContext( context )
32 , mConfiguration( configuration )
33{}
34
35void QgsGeometryCheck::prepare( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
36{
37 Q_UNUSED( context )
38 Q_UNUSED( configuration )
39}
40
42{
43 return compatibleGeometryTypes().contains( layer->geometryType() );
44}
45
50
51void QgsGeometryCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, QgsGeometryCheck::Changes &changes ) const
52{
53 Q_UNUSED( featurePools )
54 Q_UNUSED( error )
55 Q_UNUSED( method )
56 Q_UNUSED( mergeAttributeIndices )
57 Q_UNUSED( changes )
58}
59
60QList<QgsGeometryCheckResolutionMethod> QgsGeometryCheck::availableResolutionMethods() const
61{
62 QList<QgsGeometryCheckResolutionMethod> fixes;
63 // Once the deprecated `resolutionMethods()` function is gone, this default implementation
64 // should be removed and each check will need to implement this method instead of resolutionMethods().
66 const QStringList methods = resolutionMethods();
68
69 int i = 0;
70 for ( const QString &method : methods )
71 {
72 fixes.append( QgsGeometryCheckResolutionMethod( i++, method, QString(), false ) );
73 }
74
75 return fixes;
76}
77
79{
80 return QStringList();
81}
82
83QMap<QString, QgsFeatureIds> QgsGeometryCheck::allLayerFeatureIds( const QMap<QString, QgsFeaturePool *> &featurePools ) const
84{
85 QMap<QString, QgsFeatureIds> featureIds;
86 for ( QgsFeaturePool *pool : featurePools )
87 {
88 featureIds.insert( pool->layerId(), pool->allFeatureIds() );
89 }
90 return featureIds;
91}
92
93void QgsGeometryCheck::replaceFeatureGeometryPart( const QMap<QString, QgsFeaturePool *> &featurePools,
94 const QString &layerId, QgsFeature &feature,
95 int partIdx, QgsAbstractGeometry *newPartGeom, Changes &changes ) const
96{
97 QgsFeaturePool *featurePool = featurePools[layerId];
98 QgsGeometry featureGeom = feature.geometry();
99 QgsAbstractGeometry *geom = featureGeom.get();
100 if ( QgsGeometryCollection *geomCollection = dynamic_cast< QgsGeometryCollection *>( geom ) )
101 {
102 geomCollection->removeGeometry( partIdx );
103 geomCollection->addGeometry( newPartGeom );
104 changes[layerId][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( partIdx ) ) );
105 changes[layerId][feature.id()].append( Change( ChangePart, ChangeAdded, QgsVertexId( geomCollection->partCount() - 1 ) ) );
106 feature.setGeometry( featureGeom );
107 }
108 else
109 {
110 feature.setGeometry( QgsGeometry( newPartGeom ) );
111 changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
112 }
113 featurePool->updateFeature( feature );
114}
115
116void QgsGeometryCheck::deleteFeatureGeometryPart( const QMap<QString, QgsFeaturePool *> &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, Changes &changes ) const
117{
118 QgsFeaturePool *featurePool = featurePools[layerId];
119 QgsGeometry featureGeom = feature.geometry();
120 QgsAbstractGeometry *geom = featureGeom.get();
121 if ( dynamic_cast<QgsGeometryCollection *>( geom ) )
122 {
123 static_cast<QgsGeometryCollection *>( geom )->removeGeometry( partIdx );
124 if ( static_cast<QgsGeometryCollection *>( geom )->numGeometries() == 0 )
125 {
126 featurePool->deleteFeature( feature.id() );
127 changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
128 }
129 else
130 {
131 feature.setGeometry( featureGeom );
132 featurePool->updateFeature( feature );
133 changes[layerId][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( partIdx ) ) );
134 }
135 }
136 else
137 {
138 featurePool->deleteFeature( feature.id() );
139 changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
140 }
141}
142
143void QgsGeometryCheck::deleteFeatureGeometryRing( const QMap<QString, QgsFeaturePool *> &featurePools,
144 const QString &layerId, QgsFeature &feature,
145 int partIdx, int ringIdx, Changes &changes ) const
146{
147 QgsFeaturePool *featurePool = featurePools[layerId];
148 QgsGeometry featureGeom = feature.geometry();
149 QgsAbstractGeometry *partGeom = QgsGeometryCheckerUtils::getGeomPart( featureGeom.get(), partIdx );
150 if ( dynamic_cast<QgsCurvePolygon *>( partGeom ) )
151 {
152 // If we delete the exterior ring of a polygon, it makes no sense to keep the interiors
153 if ( ringIdx == 0 )
154 {
155 deleteFeatureGeometryPart( featurePools, layerId, feature, partIdx, changes );
156 }
157 else
158 {
159 static_cast<QgsCurvePolygon *>( partGeom )->removeInteriorRing( ringIdx - 1 );
160 feature.setGeometry( featureGeom );
161 featurePool->updateFeature( feature );
162 changes[layerId][feature.id()].append( Change( ChangeRing, ChangeRemoved, QgsVertexId( partIdx, ringIdx ) ) );
163 }
164 }
165 // Other geometry types do not have rings, remove the entire part
166 else
167 {
168 deleteFeatureGeometryPart( featurePools, layerId, feature, partIdx, changes );
169 }
170}
171
172double QgsGeometryCheck::scaleFactor( const QPointer<QgsVectorLayer> &layer ) const
173{
174 double scaleFactor = 1.0;
175
176 QgsVectorLayer *lyr = layer.data();
177 if ( lyr )
178 {
180 scaleFactor = ct.scaleFactor( lyr->extent() );
181 }
182 return scaleFactor;
183}
184
185
Abstract base class for all geometries.
Class for doing transforms between two map coordinate systems.
double scaleFactor(const QgsRectangle &referenceExtent) const
Computes an estimated conversion factor between source and destination units:
Curve polygon geometry type.
A feature pool is based on a vector layer and caches features.
virtual void updateFeature(QgsFeature &feature)=0
Updates a feature in this pool.
virtual void deleteFeature(QgsFeatureId fid)=0
Removes a feature from this pool.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFeatureId id
Definition qgsfeature.h:66
QgsGeometry geometry
Definition qgsfeature.h:69
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base configuration for geometry checks.
const QgsCoordinateTransformContext transformContext
The coordinate transform context with which transformations will be done.
const QgsCoordinateReferenceSystem mapCrs
The coordinate system in which calculations should be done.
This represents an error reported by a geometry check.
This class implements a resolution for problems detected in geometry checks.
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
QFlags< Flag > Flags
void deleteFeatureGeometryPart(const QMap< QString, QgsFeaturePool * > &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, Changes &changes) const
Deletes a part of a feature geometry.
virtual QList< QgsGeometryCheckResolutionMethod > availableResolutionMethods() const
Returns a list of available resolution methods.
void deleteFeatureGeometryRing(const QMap< QString, QgsFeaturePool * > &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, int ringIdx, Changes &changes) const
Deletes a ring in a feature geometry.
void replaceFeatureGeometryPart(const QMap< QString, QgsFeaturePool * > &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, QgsAbstractGeometry *newPartGeom, Changes &changes) const
Replaces a part in a feature geometry.
virtual Q_DECL_DEPRECATED QStringList resolutionMethods() const
Returns a list of descriptions for available resolutions for errors.
const QgsGeometryCheckContext * mContext
@ ChangeRing
This change happens on ring level.
@ ChangeFeature
This change happens on feature level.
@ ChangePart
This change happens on part level.
QMap< QString, QgsFeatureIds > allLayerFeatureIds(const QMap< QString, QgsFeaturePool * > &featurePools) const
Returns all layers and feature ids.
@ ChangeChanged
Something has been updated.
@ ChangeAdded
Something has been added.
@ ChangeRemoved
Something has been removed.
double scaleFactor(const QPointer< QgsVectorLayer > &layer) const
Determines the scale factor of a layer to the map coordinate reference system.
virtual QgsGeometryCheck::Flags flags() const
Flags for this geometry check.
virtual void fixError(const QMap< QString, QgsFeaturePool * > &featurePools, QgsGeometryCheckError *error, int method, const QMap< QString, int > &mergeAttributeIndices, Changes &changes) const
Fixes the error error with the specified method.
virtual QList< Qgis::GeometryType > compatibleGeometryTypes() const =0
A list of geometry types for which this check can be performed.
QgsGeometryCheck(const QgsGeometryCheckContext *context, const QVariantMap &configuration)
Create a new geometry check.
const QgsGeometryCheckContext * context() const
Returns the context.
virtual bool isCompatible(QgsVectorLayer *layer) const
Returns if this geometry check is compatible with layer.
virtual void prepare(const QgsGeometryCheckContext *context, const QVariantMap &configuration)
Will be run in the main thread before collectErrors() is called (which may be run from a background t...
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
int numGeometries() const
Returns the number of geometries within the collection.
A geometry is the spatial representation of a feature.
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:83
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
QgsRectangle extent() const FINAL
Returns the extent of the layer.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:6535
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:6534
Descripts a change to fix a geometry.
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:30