QGIS API Documentation 3.41.0-Master (af5edcb665c)
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
28QgsGeometryCheck::QgsGeometryCheck( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
29 : mContext( context )
30 , mConfiguration( configuration )
31{}
32
33void QgsGeometryCheck::prepare( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
34{
35 Q_UNUSED( context )
36 Q_UNUSED( configuration )
37}
38
40{
41 return compatibleGeometryTypes().contains( layer->geometryType() );
42}
43
48
49void QgsGeometryCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, QgsGeometryCheck::Changes &changes ) const
50{
51 Q_UNUSED( featurePools )
52 Q_UNUSED( error )
53 Q_UNUSED( method )
54 Q_UNUSED( mergeAttributeIndices )
55 Q_UNUSED( changes )
56}
57
58QList<QgsGeometryCheckResolutionMethod> QgsGeometryCheck::availableResolutionMethods() const
59{
60 QList<QgsGeometryCheckResolutionMethod> fixes;
61 // Once the deprecated `resolutionMethods()` function is gone, this default implementation
62 // should be removed and each check will need to implement this method instead of resolutionMethods().
64 const QStringList methods = resolutionMethods();
66
67 int i = 0;
68 for ( const QString &method : methods )
69 {
70 fixes.append( QgsGeometryCheckResolutionMethod( i++, method, QString(), false ) );
71 }
72
73 return fixes;
74}
75
77{
78 return QStringList();
79}
80
81QMap<QString, QgsFeatureIds> QgsGeometryCheck::allLayerFeatureIds( const QMap<QString, QgsFeaturePool *> &featurePools ) const
82{
83 QMap<QString, QgsFeatureIds> featureIds;
84 for ( QgsFeaturePool *pool : featurePools )
85 {
86 featureIds.insert( pool->layerId(), pool->allFeatureIds() );
87 }
88 return featureIds;
89}
90
91void QgsGeometryCheck::replaceFeatureGeometryPart( const QMap<QString, QgsFeaturePool *> &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, QgsAbstractGeometry *newPartGeom, Changes &changes ) const
92{
93 QgsFeaturePool *featurePool = featurePools[layerId];
94 QgsGeometry featureGeom = feature.geometry();
95 QgsAbstractGeometry *geom = featureGeom.get();
96 if ( QgsGeometryCollection *geomCollection = dynamic_cast<QgsGeometryCollection *>( geom ) )
97 {
98 geomCollection->removeGeometry( partIdx );
99 geomCollection->addGeometry( newPartGeom );
100 changes[layerId][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( partIdx ) ) );
101 changes[layerId][feature.id()].append( Change( ChangePart, ChangeAdded, QgsVertexId( geomCollection->partCount() - 1 ) ) );
102 feature.setGeometry( featureGeom );
103 }
104 else
105 {
106 feature.setGeometry( QgsGeometry( newPartGeom ) );
107 changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeChanged ) );
108 }
109 featurePool->updateFeature( feature );
110}
111
112void QgsGeometryCheck::deleteFeatureGeometryPart( const QMap<QString, QgsFeaturePool *> &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, Changes &changes ) const
113{
114 QgsFeaturePool *featurePool = featurePools[layerId];
115 QgsGeometry featureGeom = feature.geometry();
116 QgsAbstractGeometry *geom = featureGeom.get();
117 if ( dynamic_cast<QgsGeometryCollection *>( geom ) )
118 {
119 static_cast<QgsGeometryCollection *>( geom )->removeGeometry( partIdx );
120 if ( static_cast<QgsGeometryCollection *>( geom )->numGeometries() == 0 )
121 {
122 featurePool->deleteFeature( feature.id() );
123 changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
124 }
125 else
126 {
127 feature.setGeometry( featureGeom );
128 featurePool->updateFeature( feature );
129 changes[layerId][feature.id()].append( Change( ChangePart, ChangeRemoved, QgsVertexId( partIdx ) ) );
130 }
131 }
132 else
133 {
134 featurePool->deleteFeature( feature.id() );
135 changes[layerId][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) );
136 }
137}
138
139void QgsGeometryCheck::deleteFeatureGeometryRing( const QMap<QString, QgsFeaturePool *> &featurePools, const QString &layerId, QgsFeature &feature, int partIdx, int ringIdx, Changes &changes ) const
140{
141 QgsFeaturePool *featurePool = featurePools[layerId];
142 QgsGeometry featureGeom = feature.geometry();
143 QgsAbstractGeometry *partGeom = QgsGeometryCheckerUtils::getGeomPart( featureGeom.get(), partIdx );
144 if ( dynamic_cast<QgsCurvePolygon *>( partGeom ) )
145 {
146 // If we delete the exterior ring of a polygon, it makes no sense to keep the interiors
147 if ( ringIdx == 0 )
148 {
149 deleteFeatureGeometryPart( featurePools, layerId, feature, partIdx, changes );
150 }
151 else
152 {
153 static_cast<QgsCurvePolygon *>( partGeom )->removeInteriorRing( ringIdx - 1 );
154 feature.setGeometry( featureGeom );
155 featurePool->updateFeature( feature );
156 changes[layerId][feature.id()].append( Change( ChangeRing, ChangeRemoved, QgsVertexId( partIdx, ringIdx ) ) );
157 }
158 }
159 // Other geometry types do not have rings, remove the entire part
160 else
161 {
162 deleteFeatureGeometryPart( featurePools, layerId, feature, partIdx, changes );
163 }
164}
165
166double QgsGeometryCheck::scaleFactor( const QPointer<QgsVectorLayer> &layer ) const
167{
168 double scaleFactor = 1.0;
169
170 QgsVectorLayer *lyr = layer.data();
171 if ( lyr )
172 {
174 scaleFactor = ct.scaleFactor( lyr->extent() );
175 }
176 return scaleFactor;
177}
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:6643
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:6642
Descripts a change to fix a geometry.
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:30