QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 QgsGeometryGapCheck::QgsGeometryGapCheck( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
32  : QgsGeometryCheck( context, configuration )
33  , mGapThresholdMapUnits( configuration.value( QStringLiteral( "gapThreshold" ) ).toDouble() )
34 {
35 }
36 
37 void QgsGeometryGapCheck::prepare( const QgsGeometryCheckContext *context, const QVariantMap &configuration )
38 {
39  if ( configuration.value( QStringLiteral( "allowedGapsEnabled" ) ).toBool() )
40  {
41  QgsVectorLayer *layer = context->project()->mapLayer<QgsVectorLayer *>( configuration.value( "allowedGapsLayer" ).toString() );
42  if ( layer )
43  {
44  mAllowedGapsLayer = layer;
45  mAllowedGapsSource = std::make_unique<QgsVectorLayerFeatureSource>( layer );
46 
47  mAllowedGapsBuffer = configuration.value( QStringLiteral( "allowedGapsBuffer" ) ).toDouble();
48  }
49  }
50  else
51  {
52  mAllowedGapsSource.reset();
53  }
54 }
55 
56 void QgsGeometryGapCheck::collectErrors( const QMap<QString, QgsFeaturePool *> &featurePools, QList<QgsGeometryCheckError *> &errors, QStringList &messages, QgsFeedback *feedback, const LayerFeatureIds &ids ) const
57 {
58  if ( feedback )
59  feedback->setProgress( feedback->progress() + 1.0 );
60 
61  std::unique_ptr<QgsAbstractGeometry> allowedGapsGeom;
62  std::unique_ptr<QgsGeometryEngine> allowedGapsGeomEngine;
63 
64  if ( mAllowedGapsSource )
65  {
66  QVector<QgsGeometry> allowedGaps;
67  QgsFeatureRequest request;
69  QgsFeatureIterator iterator = mAllowedGapsSource->getFeatures( request );
70  QgsFeature feature;
71 
72  while ( iterator.nextFeature( feature ) )
73  {
74  const QgsGeometry geom = feature.geometry();
75  const QgsGeometry gg = geom.buffer( mAllowedGapsBuffer, 20 );
76  allowedGaps.append( gg );
77  }
78 
79  std::unique_ptr< QgsGeometryEngine > allowedGapsEngine = QgsGeometryCheckerUtils::createGeomEngine( nullptr, mContext->tolerance );
80 
81  // Create union of allowed gaps
82  QString errMsg;
83  allowedGapsGeom.reset( allowedGapsEngine->combine( allowedGaps, &errMsg ) );
84  allowedGapsGeomEngine = QgsGeometryCheckerUtils::createGeomEngine( allowedGapsGeom.get(), mContext->tolerance );
85  allowedGapsGeomEngine->prepareGeometry();
86  }
87 
88  QVector<QgsGeometry> geomList;
89  const QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds( featurePools ) : ids.toMap();
90  const QgsGeometryCheckerUtils::LayerFeatures layerFeatures( featurePools, featureIds, compatibleGeometryTypes(), nullptr, mContext, true );
91  for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
92  {
93  geomList.append( layerFeature.geometry() );
94 
95  if ( feedback && feedback->isCanceled() )
96  {
97  geomList.clear();
98  break;
99  }
100  }
101 
102  if ( geomList.isEmpty() )
103  {
104  return;
105  }
106 
107  std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( nullptr, mContext->tolerance );
108 
109  // Create union of geometry
110  QString errMsg;
111  const std::unique_ptr<QgsAbstractGeometry> unionGeom( geomEngine->combine( geomList, &errMsg ) );
112  if ( !unionGeom )
113  {
114  messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
115  return;
116  }
117 
118  // Get envelope of union
119  geomEngine = QgsGeometryCheckerUtils::createGeomEngine( unionGeom.get(), mContext->tolerance );
120  geomEngine->prepareGeometry();
121  std::unique_ptr<QgsAbstractGeometry> envelope( geomEngine->envelope( &errMsg ) );
122  if ( !envelope )
123  {
124  messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
125  return;
126  }
127 
128  // Buffer envelope
129  geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope.get(), mContext->tolerance );
130  geomEngine->prepareGeometry();
131  QgsAbstractGeometry *bufEnvelope = geomEngine->buffer( 2, 0, Qgis::EndCapStyle::Square, Qgis::JoinStyle::Miter, 4. ); //#spellok //#spellok
132  envelope.reset( bufEnvelope );
133 
134  // Compute difference between envelope and union to obtain gap polygons
135  geomEngine = QgsGeometryCheckerUtils::createGeomEngine( envelope.get(), mContext->tolerance );
136  geomEngine->prepareGeometry();
137  std::unique_ptr<QgsAbstractGeometry> diffGeom( geomEngine->difference( unionGeom.get(), &errMsg ) );
138  if ( !diffGeom )
139  {
140  messages.append( tr( "Gap check: %1" ).arg( errMsg ) );
141  return;
142  }
143 
144  // For each gap polygon which does not lie on the boundary, get neighboring polygons and add error
145  QgsGeometryPartIterator parts = diffGeom->parts();
146  while ( parts.hasNext() )
147  {
148  const QgsAbstractGeometry *gapGeom = parts.next();
149  // Skip the gap between features and boundingbox
150  const double spacing = context()->tolerance;
151  if ( gapGeom->boundingBox().snappedToGrid( spacing ) == envelope->boundingBox().snappedToGrid( spacing ) )
152  {
153  continue;
154  }
155 
156  // Skip gaps above threshold
157  if ( ( mGapThresholdMapUnits > 0 && gapGeom->area() > mGapThresholdMapUnits ) || gapGeom->area() < mContext->reducedTolerance )
158  {
159  continue;
160  }
161 
162  QgsRectangle gapAreaBBox = gapGeom->boundingBox();
163 
164  // Get neighboring polygons
165  QMap<QString, QgsFeatureIds> neighboringIds;
166  const QgsGeometryCheckerUtils::LayerFeatures layerFeatures( featurePools, featureIds.keys(), gapAreaBBox, compatibleGeometryTypes(), mContext );
167  std::unique_ptr< QgsGeometryEngine > gapGeomEngine = QgsGeometryCheckerUtils::createGeomEngine( gapGeom, mContext->tolerance );
168  gapGeomEngine->prepareGeometry();
169  for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
170  {
171  const QgsGeometry geom = layerFeature.geometry();
172  if ( gapGeomEngine->distance( geom.constGet() ) < mContext->tolerance )
173  {
174  neighboringIds[layerFeature.layer()->id()].insert( layerFeature.feature().id() );
175  gapAreaBBox.combineExtentWith( geom.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  const double area = gapGeom->area();
191  const 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  const 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  const 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  const 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() );
317  const QgsCoordinateTransform ct( featurePool->crs(), mContext->mapCrs, mContext->transformContext );
318  errLayerGeom->transform( ct, Qgis::TransformDirection::Reverse );
319 
320  const auto featureIds = err->neighbors().value( layerId );
321 
322  for ( const 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  // We might get a neighbour where we touch only a corner
352  val = QgsGeometryCheckerUtils::getGeomPart( testGeom, iPart )->area();
353  break;
354  }
355 
356  if ( val > maxVal )
357  {
358  maxVal = val;
359  mergeFeature = testFeature;
360  mergePartIdx = iPart;
361  mergeLayerId = layerId;
362  }
363  }
364  }
365  }
366 
367  if ( maxVal == 0. )
368  {
369  return false;
370  }
371 
372  // Create an index of all neighbouring vertices
373  QgsSpatialIndex neighbourVerticesIndex( QgsSpatialIndex::Flag::FlagStoreFeatureGeometries );
374  int id = 0;
375  for ( const QgsFeature &neighbour : neighbours )
376  {
377  QgsVertexIterator vit = neighbour.geometry().vertices();
378  while ( vit.hasNext() )
379  {
380  const QgsPoint pt = vit.next();
381  QgsFeature f;
382  f.setId( id ); // required for SpatialIndex to return the correct result
383  f.setGeometry( QgsGeometry( pt.clone() ) );
384  neighbourVerticesIndex.addFeature( f );
385  id++;
386  }
387  }
388 
389  // Snap to the closest vertex
390  QgsPolyline snappedRing;
391  QgsVertexIterator iterator = errGeometry->vertices();
392  while ( iterator.hasNext() )
393  {
394  const QgsPoint pt = iterator.next();
395  const QgsGeometry closestGeom = neighbourVerticesIndex.geometry( neighbourVerticesIndex.nearestNeighbor( QgsPointXY( pt ) ).first() );
396  if ( !closestGeom.isEmpty() )
397  {
398  snappedRing.append( QgsPoint( closestGeom.vertexAt( 0 ) ) );
399  }
400  }
401 
402  std::unique_ptr<QgsPolygon> snappedErrGeom = std::make_unique<QgsPolygon>();
403  snappedErrGeom->setExteriorRing( new QgsLineString( snappedRing ) );
404 
405  // Merge geometries
406  QgsFeaturePool *featurePool = featurePools[ mergeLayerId ];
407  std::unique_ptr<QgsAbstractGeometry> errLayerGeom( snappedErrGeom->clone() );
408  const QgsCoordinateTransform ct( featurePool->crs(), mContext->mapCrs, mContext->transformContext );
409  errLayerGeom->transform( ct, Qgis::TransformDirection::Reverse );
410  const QgsGeometry mergeFeatureGeom = mergeFeature.geometry();
411  const QgsAbstractGeometry *mergeGeom = mergeFeatureGeom.constGet();
412  std::unique_ptr< QgsGeometryEngine > geomEngine = QgsGeometryCheckerUtils::createGeomEngine( errLayerGeom.get(), 0 );
413  std::unique_ptr<QgsAbstractGeometry> combinedGeom( geomEngine->combine( QgsGeometryCheckerUtils::getGeomPart( mergeGeom, mergePartIdx ), &errMsg ) );
414  if ( !combinedGeom || combinedGeom->isEmpty() || !QgsWkbTypes::isSingleType( combinedGeom->wkbType() ) )
415  {
416  return false;
417  }
418 
419  // Add merged polygon to destination geometry
420  replaceFeatureGeometryPart( featurePools, mergeLayerId, mergeFeature, mergePartIdx, combinedGeom.release(), changes );
421 
422  return true;
423 }
424 
425 
427 {
428  QStringList methods = QStringList()
429  << tr( "Add gap area to neighboring polygon with longest shared edge" )
430  << tr( "No action" );
431  if ( mAllowedGapsSource )
432  methods << tr( "Add gap to allowed exceptions" );
433 
434  return methods;
435 }
436 
437 QList<QgsGeometryCheckResolutionMethod> QgsGeometryGapCheck::availableResolutionMethods() const
438 {
439  QList<QgsGeometryCheckResolutionMethod> fixes
440  {
441  QgsGeometryCheckResolutionMethod( MergeLongestEdge, tr( "Add to longest shared edge" ), tr( "Add the gap area to the neighbouring polygon with the longest shared edge." ), false ),
442  QgsGeometryCheckResolutionMethod( CreateNewFeature, tr( "Create new feature" ), tr( "Create a new feature from the gap area." ), false ),
443  QgsGeometryCheckResolutionMethod( MergeLargestArea, tr( "Add to largest neighbouring area" ), tr( "Add the gap area to the neighbouring polygon with the largest area." ), false )
444  };
445 
446  if ( mAllowedGapsSource )
447  fixes << QgsGeometryCheckResolutionMethod( AddToAllowedGaps, tr( "Add Gap to Allowed Exceptions" ), tr( "Create a new feature from the gap geometry on the allowed exceptions layer." ), true );
448 
449  fixes << QgsGeometryCheckResolutionMethod( NoChange, tr( "No action" ), tr( "Do not perform any action and mark this error as fixed." ), false );
450 
451  return fixes;
452 }
453 
455 {
456  return factoryDescription();
457 }
458 
459 QString QgsGeometryGapCheck::id() const
460 {
461  return factoryId();
462 }
463 
464 QgsGeometryCheck::Flags QgsGeometryGapCheck::flags() const
465 {
466  return factoryFlags();
467 }
468 
470 QString QgsGeometryGapCheck::factoryDescription()
471 {
472  return tr( "Gap" );
473 }
474 
475 QString QgsGeometryGapCheck::factoryId()
476 {
477  return QStringLiteral( "QgsGeometryGapCheck" );
478 }
479 
480 QgsGeometryCheck::Flags QgsGeometryGapCheck::factoryFlags()
481 {
483 }
484 
485 QList<QgsWkbTypes::GeometryType> QgsGeometryGapCheck::factoryCompatibleGeometryTypes()
486 {
488 }
489 
490 bool QgsGeometryGapCheck::factoryIsCompatible( QgsVectorLayer *layer ) SIP_SKIP
491 {
492  return factoryCompatibleGeometryTypes().contains( layer->geometryType() );
493 }
494 
495 QgsGeometryCheck::CheckType QgsGeometryGapCheck::factoryCheckType()
496 {
498 }
500 
502 {
503  return mContextBoundingBox;
504 }
505 
507 {
508  QgsGeometryGapCheckError *err = dynamic_cast<QgsGeometryGapCheckError *>( other );
510 }
511 
513 {
514  QgsGeometryGapCheckError *err = dynamic_cast<QgsGeometryGapCheckError *>( other );
515  return err && err->layerId() == layerId() && err->neighbors() == neighbors();
516 }
517 
519 {
521  // Static cast since this should only get called if isEqual == true
522  const QgsGeometryGapCheckError *err = static_cast<const QgsGeometryGapCheckError *>( other );
523  mNeighbors = err->mNeighbors;
524  mGapAreaBBox = err->mGapAreaBBox;
525 }
526 
528 {
529  return true;
530 }
531 
533 {
534  return mGapAreaBBox;
535 }
536 
537 QMap<QString, QgsFeatureIds> QgsGeometryGapCheckError::involvedFeatures() const
538 {
539  return mNeighbors;
540 }
541 
543 {
544 
546  return QgsApplication::getThemeIcon( QStringLiteral( "/algorithms/mAlgorithmCheckGeometry.svg" ) );
547  else
548  return QgsApplication::getThemeIcon( QStringLiteral( "/checks/SliverOrGap.svg" ) );
549 }
qgspolygon.h
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
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:852
QgsVectorLayer::addFeatures
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a list of features to the sink.
Definition: qgsvectorlayer.cpp:3658
QgsGeometryGapCheckError::handleChanges
bool handleChanges(const QgsGeometryCheck::Changes &) override
Apply a list of changes.
Definition: qgsgeometrygapcheck.cpp:527
qgsexpressioncontextutils.h
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:76
QgsGeometryCheckerUtils::getGeomPart
static QgsAbstractGeometry * getGeomPart(QgsAbstractGeometry *geom, int partIdx)
Definition: qgsgeometrycheckerutils.cpp:268
QgsGeometryGapCheck::availableResolutionMethods
QList< QgsGeometryCheckResolutionMethod > availableResolutionMethods() const override
Returns a list of available resolution methods.
Definition: qgsgeometrygapcheck.cpp:437
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:740
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:391
QgsGeometryGapCheck::AddToAllowedGaps
@ AddToAllowedGaps
Add gap geometry to allowed gaps layer.
Definition: qgsgeometrygapcheck.h:100
qgsgeometrygapcheck.h
QgsFeature::setId
void setId(QgsFeatureId id)
Sets the feature id for this feature.
Definition: qgsfeature.cpp:122
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:48
QgsGeometryCheckError::StatusFixed
@ StatusFixed
The error is fixed.
Definition: qgsgeometrycheckerror.h:46
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
QgsGeometryCheck::Changes
QMap< QString, QMap< QgsFeatureId, QList< QgsGeometryCheck::Change > > > Changes
A collection of changes.
Definition: qgsgeometrycheck.h:220
QgsGeometryGapCheckError::isEqual
bool isEqual(QgsGeometryCheckError *other) const override
Check if this error is equal to other.
Definition: qgsgeometrygapcheck.cpp:506
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:71
QgsGeometryPartIterator::hasNext
bool hasNext() const SIP_HOLDGIL
Find out whether there are more parts.
Definition: qgsabstractgeometry.h:1222
QgsFeedback::isCanceled
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:67
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:480
QgsGeometryCheck::context
const QgsGeometryCheckContext * context() const
Returns the context.
Definition: qgsgeometrycheck.h:329
QgsGeometryGapCheckError::contextBoundingBox
QgsRectangle contextBoundingBox() const override
The context of the error.
Definition: qgsgeometrygapcheck.cpp:501
QgsExpressionContextUtils::globalProjectLayerScopes
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Definition: qgsexpressioncontextutils.cpp:377
QgsVectorLayer::startEditing
Q_INVOKABLE bool startEditing()
Makes the layer editable.
Definition: qgsvectorlayer.cpp:1491
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:228
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:3680
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:2050
QgsFeaturePool::getFeature
bool getFeature(QgsFeatureId id, QgsFeature &feature)
Retrieves the feature with the specified id into feature.
Definition: qgsfeaturepool.cpp:41
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
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:3728
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:103
qgsfeaturepool.h
QgsPoint::clone
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgspoint.cpp:104
qgsapplication.h
QgsGeometryCheck
This class implements a geometry check.
Definition: qgsgeometrycheck.h:91
QgsAbstractGeometry::area
virtual double area() const
Returns the planar, 2-dimensional area of the geometry.
Definition: qgsabstractgeometry.cpp:176
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
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:170
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:31
QgsGeometryCheckResolutionMethod
This class implements a resolution for problems detected in geometry checks.
Definition: qgsgeometrycheckresolutionmethod.h:28
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:31
QgsGeometryCheckContext::mapCrs
const QgsCoordinateReferenceSystem mapCrs
The coordinate system in which calculations should be done.
Definition: qgsgeometrycheckcontext.h:74
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:882
QgsGeometryCheckerUtils::LayerFeature
A layer feature combination to uniquely identify and access a feature in a set of layers.
Definition: qgsgeometrycheckerutils.h:51
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:67
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:379
QgsGeometryCheckContext::reducedTolerance
const double reducedTolerance
The tolerance to allow for in geometry checks.
Definition: qgsgeometrycheckcontext.h:69
QgsGeometryCheck::LayerFeatureIds
A list of layers and feature ids for each of these layers.
Definition: qgsgeometrycheck.h:104
QgsGeometryGapCheck::resolutionMethods
Q_DECL_DEPRECATED QStringList resolutionMethods() const override
Returns a list of descriptions for available resolutions for errors.
Definition: qgsgeometrygapcheck.cpp:426
QgsVertexIterator::next
QgsPoint next()
Returns next vertex of the geometry (undefined behavior if hasNext() returns false before calling nex...
Definition: qgsabstractgeometry.cpp:505
QgsGeometryGapCheckError::closeMatch
bool closeMatch(QgsGeometryCheckError *other) const override
Check if this error is almost equal to other.
Definition: qgsgeometrygapcheck.cpp:512
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsGeometryGapCheck::id
QString id() const override
Returns an id for this check.
Definition: qgsgeometrygapcheck.cpp:459
QgsFeaturePool::crs
QgsCoordinateReferenceSystem crs() const
The coordinate reference system of this layer.
Definition: qgsfeaturepool.cpp:171
QgsAbstractGeometry
Abstract base class for all geometries.
Definition: qgsabstractgeometry.h:79
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:478
QgsGeometryCheck::mContext
const QgsGeometryCheckContext * mContext
Definition: qgsgeometrycheck.h:365
QgsGeometry::vertexAt
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
Definition: qgsgeometry.cpp:683
qgsvectorlayer.h
QgsPolyline
QgsPointSequence QgsPolyline
Polyline as represented as a vector of points.
Definition: qgsgeometry.h:72
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
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:518
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:37
QgsGeometryGapCheckError::icon
QIcon icon() const override
Returns an icon that should be shown for this kind of error.
Definition: qgsgeometrygapcheck.cpp:542
QgsGeometryGapCheck::MergeLargestArea
@ MergeLargestArea
Merge with neighbouring polygon with largest area.
Definition: qgsgeometrygapcheck.h:102
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
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:1207
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsGeometryCheckerUtils::LayerFeatures
Contains a set of layers and feature ids in those layers to pass to a geometry check.
Definition: qgsgeometrycheckerutils.h:112
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:324
QgsGeometryCheck::CheckType
CheckType
The type of a check.
Definition: qgsgeometrycheck.h:154
QgsGeometryPartIterator::next
QgsAbstractGeometry * next()
Returns next part of the geometry (undefined behavior if hasNext() returns false before calling next(...
Definition: qgsabstractgeometry.cpp:561
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:61
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:76
QgsGeometryGapCheck::flags
QgsGeometryCheck::Flags flags() const override
Flags for this geometry check.
Definition: qgsgeometrygapcheck.cpp:464
QgsGeometryCheckError::mCheck
const QgsGeometryCheck * mCheck
Definition: qgsgeometrycheckerror.h:226
QgsVertexIterator
Java-style iterator for traversal of vertices of a geometry.
Definition: qgsabstractgeometry.h:1158
QgsGeometryCheckerUtils::createGeomEngine
static std::unique_ptr< QgsGeometryEngine > createGeomEngine(const QgsAbstractGeometry *geometry, double tolerance)
Definition: qgsgeometrycheckerutils.cpp:263
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:1080
qgsgeometrycollection.h
QgsVertexIterator::hasNext
bool hasNext() const
Find out whether there are more vertices.
Definition: qgsabstractgeometry.h:1173
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Definition: qgsapplication.cpp:693
QgsFeedback::progress
double progress() const SIP_HOLDGIL
Returns the current progress reported by the feedback object.
Definition: qgsfeedback.h:93
QgsGeometryGapCheckError::affectedAreaBBox
QgsRectangle affectedAreaBBox() const override
The bounding box of the affected area of the error.
Definition: qgsgeometrygapcheck.cpp:532
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:96
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:57
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
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:56
QgsVectorLayer::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) FINAL
Adds a single feature to the sink.
Definition: qgsvectorlayer.cpp:1070
QgsGeometryGapCheckError::involvedFeatures
QMap< QString, QgsFeatureIds > involvedFeatures() const override
Returns a list of involved features.
Definition: qgsgeometrygapcheck.cpp:537
qgsfeedback.h
QgsGeometryCheckError
This represents an error reported by a geometry check.
Definition: qgsgeometrycheckerror.h:35
QgsGeometryGapCheck::description
QString description() const override
Returns a human readable description for this check.
Definition: qgsgeometrygapcheck.cpp:454
QgsGeometryCheckContext::transformContext
const QgsCoordinateTransformContext transformContext
The coordinate transform context with which transformations will be done.
Definition: qgsgeometrycheckcontext.h:79
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:37
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:31
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