QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsgeometrygapcheck.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometrygapcheck.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 "qgsgeometryengine.h"
18 #include "qgsgeometrygapcheck.h"
19 #include "qgsgeometrycollection.h"
20 #include "qgsfeaturepool.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsvectorlayerutils.h"
23 #include "qgsfeedback.h"
24 #include "qgsapplication.h"
25 #include "qgsproject.h"
27 #include "qgspolygon.h"
28 #include "qgscurve.h"
29 #include "qgssnappingutils.h"
30 
31 #include "geos_c.h"
32 
33 QgsGeometryGapCheck::QgsGeometryGapCheck( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
34  : QgsGeometryCheck( context, configuration )
35  , mGapThresholdMapUnits( configuration.value( QStringLiteral( "gapThreshold" ) ).toDouble() )
36 {
37 }
38 
39 void QgsGeometryGapCheck::prepare( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
40 {
41  if ( configuration.value( QStringLiteral( "allowedGapsEnabled" ) ).toBool() )
42  {
43  QgsVectorLayer *layer = context->project()->mapLayer<QgsVectorLayer *>( configuration.value( "allowedGapsLayer" ).toString() );
44  if ( layer )
45  {
46  mAllowedGapsLayer = layer;
47  mAllowedGapsSource = qgis::make_unique<QgsVectorLayerFeatureSource>( layer );
48 
49  mAllowedGapsBuffer = configuration.value( QStringLiteral( "allowedGapsBuffer" ) ).toDouble();
50  }
51  }
52  else
53  {
54  mAllowedGapsSource.reset();
55  }
56 }
57 
58 void QgsGeometryGapCheck::collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids ) const
59 {
60  if ( feedback )
61  feedback->setProgress( feedback->progress() + 1.0 );
62 
63  std::unique_ptr<QgsAbstractGeometry> allowedGapsGeom;
64  std::unique_ptr<QgsGeometryEngine> allowedGapsGeomEngine;
65 
66  if ( mAllowedGapsSource )
67  {
68  QVector<QgsGeometry> allowedGaps;
69  QgsFeatureRequest request;
71  QgsFeatureIterator iterator = mAllowedGapsSource->getFeatures( request );
72  QgsFeature feature;
73 
74  while ( iterator.nextFeature( feature ) )
75  {
76  QgsGeometry geom = feature.geometry();
77  QgsGeometry gg = geom.buffer( mAllowedGapsBuffer, 20 );
78  allowedGaps.append( gg );
79  }
80 
81  std::unique_ptr< QgsGeometryEngine > allowedGapsEngine = QgsGeometryCheckerUtils::createGeomEngine( nullptr, mContext->tolerance );
82 
83  // Create union of allowed gaps
84  QString errMsg;
85  allowedGapsGeom.reset( allowedGapsEngine->combine( allowedGaps, &errMsg ) );
86  allowedGapsGeomEngine = QgsGeometryCheckerUtils::createGeomEngine( allowedGapsGeom.get(), mContext->tolerance );
87  allowedGapsGeomEngine->prepareGeometry();
88  }
89 
90  QVector<QgsGeometry> geomList;
91  QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds( featurePools ) : ids.toMap();
92  const QgsGeometryCheckerUtils::LayerFeatures layerFeatures( featurePools, featureIds, compatibleGeometryTypes(), nullptr, mContext, true );
93  for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
94  {
95  geomList.append( layerFeature.geometry() );
96 
97  if ( feedback && feedback->isCanceled() )
98  {
99  geomList.clear();
100  break;
101  }
102  }
103 
104  if ( geomList.isEmpty() )
105  {
106  return;
107  }
108 
109  std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( nullptr, mContext->tolerance );
110 
111  // Create union of geometry
112  QString errMsg;
113  std::unique_ptr<QgsAbstractGeometry> unionGeom( geomEngine->combine( geomList, &errMsg ) );
114  if ( !unionGeom )
115  {
116  messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
117  return;
118  }
119 
120  // Get envelope of union
121  geomEngine = QgsGeometryCheckerUtils::createGeomEngine( unionGeom.get(), mContext->tolerance );
122  geomEngine->prepareGeometry();
123  std::unique_ptr<QgsAbstractGeometry> envelope( geomEngine->envelope( &errMsg ) );
124  if ( !envelope )
125  {
126  messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
127  return;
128  }
129 
130  // Buffer envelope
131  geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope.get(), mContext->tolerance );
132  geomEngine->prepareGeometry();
133  QgsAbstractGeometry *bufEnvelope = geomEngine->buffer( 2, 0, GEOSBUF_CAP_SQUARE, GEOSBUF_JOIN_MITRE, 4. ); //#spellok //#spellok
134  envelope.reset( bufEnvelope );
135 
136  // Compute difference between envelope and union to obtain gap polygons
137  geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope.get(), mContext->tolerance );
138  geomEngine->prepareGeometry();
139  std::unique_ptr<QgsAbstractGeometry> diffGeom( geomEngine->difference( unionGeom.get(), &errMsg ) );
140  if ( !diffGeom )
141  {
142  messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
143  return;
144  }
145 
146  // For each gap polygon which does not lie on the boundary, get neighboring polygons and add error
147  QgsGeometryPartIterator parts = diffGeom->parts();
148  while ( parts.hasNext() )
149  {
150  const QgsAbstractGeometry *gapGeom = parts.next();
151  // Skip the gap between features and boundingbox
152  const double spacing = context()->tolerance;
153  if ( gapGeom->boundingBox().snappedToGrid( spacing ) == envelope->boundingBox().snappedToGrid( spacing ) )
154  {
155  continue;
156  }
157 
158  // Skip gaps above threshold
159  if ( ( mGapThresholdMapUnits > 0 && gapGeom->area() > mGapThresholdMapUnits ) || gapGeom->area() < mContext->reducedTolerance )
160  {
161  continue;
162  }
163 
164  QgsRectangle gapAreaBBox = gapGeom->boundingBox();
165 
166  // Get neighboring polygons
167  QMap<QString, QgsFeatureIds> neighboringIds;
168  const QgsGeometryCheckerUtils::LayerFeatures layerFeatures( featurePools, featureIds.keys(), gapAreaBBox, compatibleGeometryTypes(), mContext );
169  for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
170  {
171  const QgsGeometry geom = layerFeature.geometry();
173  {
174  neighboringIds[layerFeature.layer()->id()].insert( layerFeature.feature().id() );
175  gapAreaBBox.combineExtentWith( layerFeature.geometry().boundingBox() );
176  }
177  }
178 
179  if ( neighboringIds.isEmpty() )
180  {
181  continue;
182  }
183 
184  if ( allowedGapsGeomEngine && allowedGapsGeomEngine->contains( gapGeom ) )
185  {
186  continue;
187  }
188 
189  // Add error
190  double area = gapGeom->area();
191  QgsRectangle gapBbox = gapGeom->boundingBox();
192  errors.append( new QgsGeometryGapCheckError( this, QString(), QgsGeometry( gapGeom->clone() ), neighboringIds, area, gapBbox, gapAreaBBox ) );
193  }
194 }
195 
196 void QgsGeometryGapCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const
197 {
198  QMetaEnum metaEnum = QMetaEnum::fromType<QgsGeometryGapCheck::ResolutionMethod>();
199  if ( !metaEnum.isValid() || !metaEnum.valueToKey( method ) )
200  {
201  error->setFixFailed( tr( "Unknown method" ) );
202  }
203  else
204  {
205  ResolutionMethod methodValue = static_cast<ResolutionMethod>( method );
206  switch ( methodValue )
207  {
208  case NoChange:
209  error->setFixed( method );
210  break;
211 
212  case MergeLongestEdge:
213  {
214  QString errMsg;
215  if ( mergeWithNeighbor( featurePools, static_cast<QgsGeometryGapCheckError *>( error ), changes, errMsg, LongestSharedEdge ) )
216  {
217  error->setFixed( method );
218  }
219  else
220  {
221  error->setFixFailed( tr( "Failed to merge with neighbor: %1" ).arg( errMsg ) );
222  }
223  break;
224  }
225 
226  case AddToAllowedGaps:
227  {
228  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mAllowedGapsLayer.data() );
229  if ( layer )
230  {
231  if ( !layer->isEditable() && !layer->startEditing() )
232  {
233  error->setFixFailed( tr( "Could not start editing layer %1" ).arg( layer->name() ) );
234  }
235  else
236  {
237  QgsFeature feature = QgsVectorLayerUtils::createFeature( layer, error->geometry() );
238  QgsFeatureList features = QgsVectorLayerUtils::makeFeatureCompatible( feature, layer );
239  if ( !layer->addFeatures( features ) )
240  {
241  error->setFixFailed( tr( "Could not add feature to layer %1" ).arg( layer->name() ) );
242  }
243  else
244  {
245  error->setFixed( method );
246  }
247  }
248  }
249  else
250  {
251  error->setFixFailed( tr( "Allowed gaps layer could not be resolved" ) );
252  }
253  break;
254  }
255 
256  case CreateNewFeature:
257  {
258  QgsGeometryGapCheckError *gapCheckError = static_cast<QgsGeometryGapCheckError *>( error );
259  QgsProject *project = QgsProject::instance();
260  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( project->mapLayer( gapCheckError->neighbors().keys().first() ) );
261  if ( layer )
262  {
263  const QgsGeometry geometry = error->geometry();
265  QgsFeature feature = QgsVectorLayerUtils::createFeature( layer, geometry, QgsAttributeMap(), &context );
266  if ( !layer->addFeature( feature ) )
267  {
268  error->setFixFailed( tr( "Could not add feature" ) );
269  }
270  else
271  {
272  error->setFixed( method );
273  }
274  }
275  else
276  {
277  error->setFixFailed( tr( "Could not resolve target layer %1 to add feature" ).arg( error->layerId() ) );
278  }
279  break;
280  }
281 
282  case MergeLargestArea:
283  {
284  QString errMsg;
285  if ( mergeWithNeighbor( featurePools, static_cast<QgsGeometryGapCheckError *>( error ), changes, errMsg, LargestArea ) )
286  {
287  error->setFixed( method );
288  }
289  else
290  {
291  error->setFixFailed( tr( "Failed to merge with neighbor: %1" ).arg( errMsg ) );
292  }
293  break;
294  }
295  }
296  }
297 }
298 
299 bool QgsGeometryGapCheck::mergeWithNeighbor( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryGapCheckError *err, Changes &changes, QString &errMsg, Condition condition ) const
300 {
301  double maxVal = 0.;
302  QString mergeLayerId;
303  QgsFeature mergeFeature;
304  int mergePartIdx = -1;
305 
306  const QgsGeometry geometry = err->geometry();
307  const QgsAbstractGeometry *errGeometry = QgsGeometryCheckerUtils::getGeomPart( geometry.constGet(), 0 );
308 
309  const auto layerIds = err->neighbors().keys();
310  QList<QgsFeature> neighbours;
311 
312  // Search for touching neighboring geometries
313  for ( const QString &layerId : layerIds )
314  {
315  QgsFeaturePool *featurePool = featurePools.value( layerId );
316  std::unique_ptr<QgsAbstractGeometry> errLayerGeom( errGeometry->clone() );
318  errLayerGeom->transform( ct, QgsCoordinateTransform::ReverseTransform );
319 
320  const auto featureIds = err->neighbors().value( layerId );
321 
322  for ( QgsFeatureId testId : featureIds )
323  {
324  QgsFeature feature;
325  if ( !featurePool->getFeature( testId, feature ) )
326  {
327  continue;
328  }
329 
330  QgsGeometry transformedGeometry = feature.geometry();
331  transformedGeometry.transform( ct );
332  feature.setGeometry( transformedGeometry );
333  neighbours.append( feature );
334  }
335 
336  for ( const QgsFeature &testFeature : neighbours )
337  {
338  const QgsGeometry featureGeom = testFeature.geometry();
339  const QgsAbstractGeometry *testGeom = featureGeom.constGet();
340  for ( int iPart = 0, nParts = testGeom->partCount(); iPart < nParts; ++iPart )
341  {
342  double val = 0;
343  switch ( condition )
344  {
345  case LongestSharedEdge:
347  break;
348 
349  case LargestArea:
350  val = QgsGeometryCheckerUtils::getGeomPart( testGeom, iPart )->area();
351  break;
352  }
353 
354  if ( val > maxVal )
355  {
356  maxVal = val;
357  mergeFeature = testFeature;
358  mergePartIdx = iPart;
359  mergeLayerId = layerId;
360  }
361  }
362  }
363  }
364 
365  if ( maxVal == 0. )
366  {
367  return false;
368  }
369 
370  QgsSpatialIndex neighbourIndex( QgsSpatialIndex::Flag::FlagStoreFeatureGeometries );
371  neighbourIndex.addFeatures( neighbours );
372 
373  QgsPolyline snappedRing;
374  QgsVertexIterator iterator = errGeometry->vertices();
375  while ( iterator.hasNext() )
376  {
377  QgsPoint pt = iterator.next();
378  QgsVertexId id;
379  QgsGeometry closestGeom = neighbourIndex.geometry( neighbourIndex.nearestNeighbor( QgsPointXY( pt ) ).first() );
380  if ( !closestGeom.isEmpty() )
381  {
382  QgsPoint closestPoint = QgsGeometryUtils::closestVertex( *closestGeom.constGet(), pt, id );
383  snappedRing.append( closestPoint );
384  }
385  }
386 
387  std::unique_ptr<QgsPolygon> snappedErrGeom = qgis::make_unique<QgsPolygon>();
388  snappedErrGeom->setExteriorRing( new QgsLineString( snappedRing ) );
389 
390  // Merge geometries
391  QgsFeaturePool *featurePool = featurePools[ mergeLayerId ];
392  std::unique_ptr<QgsAbstractGeometry> errLayerGeom( snappedErrGeom->clone() );
394  errLayerGeom->transform( ct, QgsCoordinateTransform::ReverseTransform );
395  const QgsGeometry mergeFeatureGeom = mergeFeature.geometry();
396  const QgsAbstractGeometry *mergeGeom = mergeFeatureGeom.constGet();
397  std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errLayerGeom.get(), 0 );
398  std::unique_ptr<QgsAbstractGeometry> combinedGeom( geomEngine->combine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), &errMsg ) );
399  if ( !combinedGeom || combinedGeom->isEmpty() || !QgsWkbTypes::isSingleType( combinedGeom->wkbType() ) )
400  {
401  return false;
402  }
403 
404  // Add merged polygon to destination geometry
405  replaceFeatureGeometryPart( featurePools, mergeLayerId, mergeFeature, mergePartIdx, combinedGeom.release(), changes );
406 
407  return true;
408 }
409 
410 
412 {
413  QStringList methods = QStringList()
414  << tr( "Add gap area to neighboring polygon with longest shared edge" )
415  << tr( "No action" );
416  if ( mAllowedGapsSource )
417  methods << tr( "Add gap to allowed exceptions" );
418 
419  return methods;
420 }
421 
422 QList<QgsGeometryCheckResolutionMethod> QgsGeometryGapCheck::availableResolutionMethods() const
423 {
424  QList<QgsGeometryCheckResolutionMethod> fixes
425  {
426  QgsGeometryCheckResolutionMethod( MergeLongestEdge, tr( "Add to longest shared edge" ), tr( "Add the gap area to the neighbouring polygon with the longest shared edge." ), false ),
427  QgsGeometryCheckResolutionMethod( CreateNewFeature, tr( "Create new feature" ), tr( "Create a new feature from the gap area." ), false ),
428  QgsGeometryCheckResolutionMethod( MergeLargestArea, tr( "Add to largest neighbouring area" ), tr( "Add the gap area to the neighbouring polygon with the largest area." ), false )
429  };
430 
431  if ( mAllowedGapsSource )
432  fixes << QgsGeometryCheckResolutionMethod( AddToAllowedGaps, tr( "Add gap to allowed exceptions" ), tr( "Create a new feature from the gap geometry on the allowed exceptions layer." ), false );
433 
434  fixes << QgsGeometryCheckResolutionMethod( NoChange, tr( "No action" ), tr( "Do not perform any action and mark this error as fixed." ), false );
435 
436  return fixes;
437 }
438 
440 {
441  return factoryDescription();
442 }
443 
444 QString QgsGeometryGapCheck::id() const
445 {
446  return factoryId();
447 }
448 
449 QgsGeometryCheck::Flags QgsGeometryGapCheck::flags() const
450 {
451  return factoryFlags();
452 }
453 
455 QString QgsGeometryGapCheck::factoryDescription()
456 {
457  return tr( "Gap" );
458 }
459 
460 QString QgsGeometryGapCheck::factoryId()
461 {
462  return QStringLiteral( "QgsGeometryGapCheck" );
463 }
464 
465 QgsGeometryCheck::Flags QgsGeometryGapCheck::factoryFlags()
466 {
468 }
469 
470 QList<QgsWkbTypes::GeometryType> QgsGeometryGapCheck::factoryCompatibleGeometryTypes()
471 {
473 }
474 
475 bool QgsGeometryGapCheck::factoryIsCompatible( QgsVectorLayer *layer ) SIP_SKIP
476 {
477  return factoryCompatibleGeometryTypes().contains( layer->geometryType() );
478 }
479 
480 QgsGeometryCheck::CheckType QgsGeometryGapCheck::factoryCheckType()
481 {
483 }
485 
487 {
488  return mContextBoundingBox;
489 }
490 
492 {
493  QgsGeometryGapCheckError *err = dynamic_cast<QgsGeometryGapCheckError *>( other );
495 }
496 
498 {
499  QgsGeometryGapCheckError *err = dynamic_cast<QgsGeometryGapCheckError *>( other );
500  return err && err->layerId() == layerId() && err->neighbors() == neighbors();
501 }
502 
504 {
506  // Static cast since this should only get called if isEqual == true
507  const QgsGeometryGapCheckError *err = static_cast<const QgsGeometryGapCheckError *>( other );
508  mNeighbors = err->mNeighbors;
509  mGapAreaBBox = err->mGapAreaBBox;
510 }
511 
513 {
514  return true;
515 }
516 
518 {
519  return mGapAreaBBox;
520 }
521 
522 QMap<QString, QgsFeatureIds> QgsGeometryGapCheckError::involvedFeatures() const
523 {
524  return mNeighbors;
525 }
526 
528 {
529 
531  return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmCheckGeometry.svg" ) );
532  else
533  return QgsApplication::getThemeIcon( QStringLiteral( "/checks/SliverOrGap.svg" ) );
534 }
qgspolygon.h
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
QgsGeometryCheckError::setFixFailed
void setFixFailed(const QString &reason)
Set the error status to failed and specify the reason for failure.
Definition: qgsgeometrycheckerror.cpp:109
QgsWkbTypes::isSingleType
static bool isSingleType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a single type.
Definition: qgswkbtypes.h:822
QgsVectorLayer::addFeatures
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a list of features to the sink.
Definition: qgsvectorlayer.cpp:3492
QgsGeometryGapCheckError::handleChanges
bool handleChanges(const QgsGeometryCheck::Changes &) override
Apply a list of changes.
Definition: qgsgeometrygapcheck.cpp:512
qgsexpressioncontextutils.h
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:62
QgsGeometry::transform
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:2813
QgsGeometryCheckerUtils::getGeomPart
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
Definition: qgsgeometrycheckerutils.cpp:268
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:626
QgsGeometryGapCheck::availableResolutionMethods
QList< QgsGeometryCheckResolutionMethod > availableResolutionMethods() const override
Returns a list of available resolution methods.
Definition: qgsgeometrygapcheck.cpp:422
QgsGeometryGapCheckError::neighbors
const QMap< QString, QgsFeatureIds > & neighbors() const
A map of layers and feature ids of the neighbors of the gap.
Definition: qgsgeometrygapcheck.h:60
QgsVectorLayerUtils::makeFeatureCompatible
static QgsFeatureList makeFeatureCompatible(const QgsFeature &feature, const QgsVectorLayer *layer, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Converts input feature to be compatible with the given layer.
Definition: qgsvectorlayerutils.cpp:738
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:359
QgsGeometryGapCheck::AddToAllowedGaps
@ AddToAllowedGaps
Add gap geometry to allowed gaps layer.
Definition: qgsgeometrygapcheck.h:100
qgsgeometrygapcheck.h
QgsGeometryGapCheck::compatibleGeometryTypes
QList< QgsWkbTypes::GeometryType > compatibleGeometryTypes() const override
A list of geometry types for which this check can be performed.
Definition: qgsgeometrygapcheck.h:116
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsGeometryCheckError::StatusFixed
@ StatusFixed
The error is fixed.
Definition: qgsgeometrycheckerror.h:46
QgsGeometryCheck::Changes
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
Definition: qgsgeometrycheck.h:213
QgsFeedback::progress
double progress() const
Returns the current progress reported by the feedback object.
Definition: qgsfeedback.h:79
QgsGeometryGapCheckError::isEqual
bool isEqual(QgsGeometryCheckError *other) const override
Check if this error is equal to other.
Definition: qgsgeometrygapcheck.cpp:491
QgsGeometryCheck::replaceFeatureGeometryPart
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.
Definition: qgsgeometrycheck.cpp:92
QgsGeometryCheck::allLayerFeatureIds
QMap< QString, QgsFeatureIds > allLayerFeatureIds(const QMap< QString, QgsFeaturePool * > &featurePools) const
Returns all layers and feature ids.
Definition: qgsgeometrycheck.cpp:82
QgsGeometryCheck::LayerFeatureIds::isEmpty
bool isEmpty() const
Definition: qgsgeometrycheck.h:117
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsGeometryPartIterator::hasNext
bool hasNext() const SIP_HOLDGIL
Find out whether there are more parts.
Definition: qgsabstractgeometry.h:1233
QgsGeometryCheck::LayerCheck
@ LayerCheck
The check controls a whole layer (topology checks)
Definition: qgsgeometrycheck.h:158
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsGeometryCheck::context
const QgsGeometryCheckContext * context() const
Returns the context.
Definition: qgsgeometrycheck.h:322
QgsGeometryGapCheckError::contextBoundingBox
QgsRectangle contextBoundingBox() const override
The context of the error.
Definition: qgsgeometrygapcheck.cpp:486
QgsExpressionContextUtils::globalProjectLayerScopes
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Definition: qgsexpressioncontextutils.cpp:307
QgsVectorLayer::startEditing
Q_INVOKABLE bool startEditing()
Makes the layer editable.
Definition: qgsvectorlayer.cpp:1428
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
QgsAbstractGeometry::partCount
virtual int partCount() const =0
Returns count of parts contained in the geometry.
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsProject::mapLayer
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Definition: qgsproject.cpp:3208
QgsAttributeList
QList< int > QgsAttributeList
Definition: qgsfield.h:26
QgsGeometry::buffer
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
Definition: qgsgeometry.cpp:1904
QgsFeaturePool::getFeature
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
Definition: qgsfeaturepool.cpp:39
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsCoordinateTransform::ReverseTransform
@ ReverseTransform
Transform from destination to source CRS.
Definition: qgscoordinatetransform.h:61
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsGeometryCheck::LayerFeatureIds::toMap
QMap< QString, QgsFeatureIds > toMap() const
Definition: qgsgeometrycheck.h:112
QgsGeometryGapCheck::CreateNewFeature
@ CreateNewFeature
Create a new feature with the gap geometry.
Definition: qgsgeometrygapcheck.h:101
QgsVectorLayer::isEditable
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
Definition: qgsvectorlayer.cpp:3594
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:95
qgsfeaturepool.h
qgsapplication.h
QgsGeometryCheck
This class implements a geometry check.
Definition: qgsgeometrycheck.h:92
QgsAbstractGeometry::area
virtual double area() const
Returns the planar, 2-dimensional area of the geometry.
Definition: qgsabstractgeometry.cpp:142
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
qgsgeometryengine.h
SIP_SKIP
#define SIP_SKIP
Definition: qgis_sip.h:126
qgsgeometrycheckcontext.h
QgsGeometryGapCheck::NoChange
@ NoChange
Do not handle the error.
Definition: qgsgeometrygapcheck.h:99
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:139
QgsGeometryCheckerUtils::sharedEdgeLength
static double sharedEdgeLength(const QgsAbstractGeometry *geom1, const QgsAbstractGeometry *geom2, double tol)
Definition: qgsgeometrycheckerutils.cpp:364
QgsGeometryCheckError::setFixed
void setFixed(int method)
Set the status to fixed and specify the method that has been used to fix the error.
Definition: qgsgeometrycheckerror.cpp:98
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
QgsGeometryGapCheckError
An error produced by a QgsGeometryGapCheck.
Definition: qgsgeometrygapcheck.h:32
QgsGeometryCheckResolutionMethod
This class implements a resolution for problems detected in geometry checks.
Definition: qgsgeometrycheckresolutionmethod.h:29
QgsGeometryCheckError::location
const QgsPointXY & location() const
The location of the error in map units.
Definition: qgsgeometrycheckerror.h:121
QgsRectangle::snappedToGrid
QgsRectangle snappedToGrid(double spacing) const
Returns a copy of this rectangle that is snapped to a grid with the specified spacing between the gri...
Definition: qgsrectangle.cpp:185
QgsAbstractGeometry::clone
virtual QgsAbstractGeometry * clone() const =0
Clones the geometry by performing a deep copy.
QgsGeometryGapCheck::MergeLongestEdge
@ MergeLongestEdge
Merge the gap with the polygon with the longest shared edge.
Definition: qgsgeometrygapcheck.h:98
QgsGeometryCheckContext
Base configuration for geometry checks.
Definition: qgsgeometrycheckcontext.h:32
QgsGeometryCheckContext::mapCrs
const QgsCoordinateReferenceSystem mapCrs
The coordinate system in which calculations should be done.
Definition: qgsgeometrycheckcontext.h:61
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:583
QgsGeometryCheckerUtils::LayerFeature
A layer feature combination to uniquely identify and access a feature in a set of layers.
Definition: qgsgeometrycheckerutils.h:52
QgsAttributeMap
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
QgsGeometryCheckError::status
Status status() const
The status of the error.
Definition: qgsgeometrycheckerror.h:145
qgsvectorlayerutils.h
QgsSpatialIndex
A spatial index for QgsFeature objects.
Definition: qgsspatialindex.h:68
QgsGeometry::isEmpty
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Definition: qgsgeometry.cpp:367
QgsGeometryCheckContext::reducedTolerance
const double reducedTolerance
The tolerance to allow for in geometry checks.
Definition: qgsgeometrycheckcontext.h:56
QgsGeometryCheck::LayerFeatureIds
A list of layers and feature ids for each of these layers.
Definition: qgsgeometrycheck.h:105
QgsGeometryGapCheck::resolutionMethods
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
Definition: qgsgeometrygapcheck.cpp:411
QgsVertexIterator::next
QgsPoint next()
Returns next vertex of the geometry (undefined behavior if hasNext() returns false before calling nex...
Definition: qgsabstractgeometry.cpp:420
QgsGeometryGapCheckError::closeMatch
bool closeMatch(QgsGeometryCheckError *other) const override
Check if this error is almost equal to other.
Definition: qgsgeometrygapcheck.cpp:497
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsGeometryGapCheck::id
QString id() const override
Returns an id for this check.
Definition: qgsgeometrygapcheck.cpp:444
QgsFeaturePool::crs
QgsCoordinateReferenceSystem crs() const
The coordinate reference system of this layer.
Definition: qgsfeaturepool.cpp:169
QgsGeometryUtils::closestVertex
static QgsPoint closestVertex(const QgsAbstractGeometry &geom, const QgsPoint &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified point.
Definition: qgsgeometryutils.cpp:67
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:74
QgsVectorLayerUtils::createFeature
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
Definition: qgsvectorlayerutils.cpp:476
QgsGeometryCheck::mContext
const QgsGeometryCheckContext * mContext
Definition: qgsgeometrycheck.h:358
qgsvectorlayer.h
QgsPolyline
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:71
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsGeometryCheck::AvailableInValidation
@ AvailableInValidation
This geometry check should be available in layer validation on the vector layer peroperties.
Definition: qgsgeometrycheck.h:166
QgsGeometryGapCheckError::update
void update(const QgsGeometryCheckError *other) override
Update this error with the information from other.
Definition: qgsgeometrygapcheck.cpp:503
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QgsAbstractGeometry::boundingBox
virtual QgsRectangle boundingBox() const =0
Returns the minimal bounding box for the geometry.
QgsGeometryGapCheck::prepare
void prepare(const QgsGeometryCheckContext *context, const QVariantMap &configuration) override
Will be run in the main thread before collectErrors is called (which may be run from a background thr...
Definition: qgsgeometrygapcheck.cpp:39
QgsGeometryGapCheckError::icon
QIcon icon() const override
Returns an icon that should be shown for this kind of error.
Definition: qgsgeometrygapcheck.cpp:527
QgsGeometryGapCheck::MergeLargestArea
@ MergeLargestArea
Merge with neighbouring polygon with largest area.
Definition: qgsgeometrygapcheck.h:102
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
qgscurve.h
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsGeometryPartIterator
Java-style iterator for traversal of parts of a geometry.
Definition: qgsabstractgeometry.h:1219
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsGeometryCheckerUtils::LayerFeatures
Contains a set of layers and feature ids in those layers to pass to a geometry check.
Definition: qgsgeometrycheckerutils.h:113
QgsGeometryCheckContext::project
const QgsProject * project() const
The project can be used to resolve additional layers.
Definition: qgsgeometrycheckcontext.cpp:28
QgsAbstractGeometry::vertices
QgsVertexIterator vertices() const
Returns a read-only, Java-style iterator for traversal of vertices of all the geometry,...
Definition: qgsabstractgeometry.cpp:282
QgsGeometryCheck::CheckType
CheckType
The type of a check.
Definition: qgsgeometrycheck.h:155
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
QgsGeometryPartIterator::next
QgsAbstractGeometry * next()
Returns next part of the geometry (undefined behavior if hasNext() returns false before calling next(...
Definition: qgsabstractgeometry.cpp:476
QgsGeometryCheckError::update
virtual void update(const QgsGeometryCheckError *other)
Update this error with the information from other.
Definition: qgsgeometrycheckerror.cpp:207
QgsGeometryCheckContext::tolerance
const double tolerance
The tolerance to allow for in geometry checks.
Definition: qgsgeometrycheckcontext.h:48
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:86
QgsGeometryGapCheck::flags
QgsGeometryCheck::Flags flags() const override
Flags for this geometry check.
Definition: qgsgeometrygapcheck.cpp:449
QgsGeometryCheckError::mCheck
const QgsGeometryCheck * mCheck
Definition: qgsgeometrycheckerror.h:226
QgsVertexIterator
Java-style iterator for traversal of vertices of a geometry.
Definition: qgsabstractgeometry.h:1170
QgsGeometryCheckerUtils::createGeomEngine
static std::unique_ptr< QgsGeometryEngine > createGeomEngine(const QgsAbstractGeometry *geometry, double tolerance)
Definition: qgsgeometrycheckerutils.cpp:263
qgsgeometrycollection.h
QgsVertexIterator::hasNext
bool hasNext() const
Find out whether there are more vertices.
Definition: qgsabstractgeometry.h:1184
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsGeometryGapCheckError::affectedAreaBBox
QgsRectangle affectedAreaBBox() const override
The bounding box of the affected area of the error.
Definition: qgsgeometrygapcheck.cpp:517
QgsGeometryCheckError::layerId
const QString & layerId() const
The id of the layer on which this error has been detected.
Definition: qgsgeometrycheckerror.h:85
QgsGeometryGapCheck::ResolutionMethod
ResolutionMethod
Resolution methods for geometry gap checks.
Definition: qgsgeometrygapcheck.h:97
QgsGeometryGapCheck::fixError
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.
Definition: qgsgeometrygapcheck.cpp:196
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:53
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsGeometryGapCheck::collectErrors
void collectErrors(const QMap< QString, QgsFeaturePool * > &featurePools, QList< QgsGeometryCheckError * > &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids=LayerFeatureIds()) const override
The main worker method.
Definition: qgsgeometrygapcheck.cpp:58
QgsVectorLayer::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
Definition: qgsvectorlayer.cpp:1011
QgsGeometryGapCheckError::involvedFeatures
QMap< QString, QgsFeatureIds > involvedFeatures() const override
Returns a list of involved features.
Definition: qgsgeometrygapcheck.cpp:522
qgsfeedback.h
QgsGeometryCheckError
This represents an error reported by a geometry check.
Definition: qgsgeometrycheckerror.h:36
QgsGeometryGapCheck::description
QString description() const override
Returns a human readable description for this check.
Definition: qgsgeometrygapcheck.cpp:439
QgsGeometryCheckContext::transformContext
const QgsCoordinateTransformContext transformContext
The coordinate transform context with which transformations will be done.
Definition: qgsgeometrycheckcontext.h:66
qgsproject.h
QgsGeometryCheckError::geometry
QgsGeometry geometry() const
The geometry of the error in map units.
Definition: qgsgeometrycheckerror.cpp:83
QgsFeaturePool
A feature pool is based on a vector layer and caches features.
Definition: qgsfeaturepool.h:38
qgssnappingutils.h
QgsFeatureId
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
QgsGeometryGapCheck::QgsGeometryGapCheck
QgsGeometryGapCheck(const QgsGeometryCheckContext *context, const QVariantMap &configuration)
The configuration accepts a "gapThreshold" key which specifies the maximum gap size in squared map un...
Definition: qgsgeometrygapcheck.cpp:33
QgsGeometryCheckerUtils::pointsFuzzyEqual
static bool pointsFuzzyEqual(const QgsPointXY &p1, const QgsPointXY &p2, double tol)
Determine whether two points are equal up to the specified tolerance.
Definition: qgsgeometrycheckerutils.h:261