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