QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsgeometryvalidator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgeometryvalidator.cpp - geometry validation thread
3  -------------------------------------------------------------------
4 Date : 03.01.2012
5 Copyright : (C) 2012 by Juergen E. Fischer
6 email : jef at norbit dot de
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 
16 #include "qgis.h"
17 #include "qgsgeometryvalidator.h"
18 #include "qgsgeometry.h"
19 #include "qgslogger.h"
20 #include "qgsgeos.h"
21 #include "qgsgeometrycollection.h"
22 #include "qgspolygon.h"
23 
24 QgsGeometryValidator::QgsGeometryValidator( const QgsGeometry &geometry, QVector<QgsGeometry::Error> *errors, QgsGeometry::ValidationMethod method )
25  : mGeometry( geometry )
26  , mErrors( errors )
27  , mStop( false )
28  , mErrorCount( 0 )
29  , mMethod( method )
30 {
31 }
32 
34 {
35  stop();
36  wait();
37 }
38 
40 {
41  mStop = true;
42 }
43 
44 void QgsGeometryValidator::checkRingIntersections( int p0, int i0, const QgsLineString *ring0, int p1, int i1, const QgsLineString *ring1 )
45 {
46  for ( int i = 0; !mStop && i < ring0->numPoints() - 1; i++ )
47  {
48  const double ring0XAti = ring0->xAt( i );
49  const double ring0YAti = ring0->yAt( i );
50  QgsVector v( ring0->xAt( i + 1 ) - ring0XAti, ring0->yAt( i + 1 ) - ring0YAti );
51 
52  for ( int j = 0; !mStop && j < ring1->numPoints() - 1; j++ )
53  {
54  const double ring1XAtj = ring1->xAt( j );
55  const double ring1YAtj = ring1->yAt( j );
56  QgsVector w( ring1->xAt( j + 1 ) - ring1XAtj, ring1->yAt( j + 1 ) - ring1YAtj );
57 
58  double sX;
59  double sY;
60  if ( intersectLines( ring0XAti, ring0YAti, v, ring1XAtj, ring1YAtj, w, sX, sY ) )
61  {
62  double d = -distLine2Point( ring0XAti, ring0YAti, v.perpVector(), sX, sY );
63 
64  if ( d >= 0 && d <= v.length() )
65  {
66  d = -distLine2Point( ring1XAtj, ring1YAtj, w.perpVector(), sX, sY );
67  if ( d > 0 && d < w.length() &&
68  ring0[i + 1] != ring1[j + 1] && ring0[i + 1] != ring1[j] &&
69  ring0[i + 0] != ring1[j + 1] && ring0[i + 0] != ring1[j] )
70  {
71  QString msg = QObject::tr( "segment %1 of ring %2 of polygon %3 intersects segment %4 of ring %5 of polygon %6 at %7, %8" )
72  .arg( i0 ).arg( i ).arg( p0 )
73  .arg( i1 ).arg( j ).arg( p1 )
74  .arg( sX ).arg( sY );
75  QgsDebugMsg( msg );
76  emit errorFound( QgsGeometry::Error( msg, QgsPointXY( sX, sY ) ) );
77  mErrorCount++;
78  }
79  }
80  }
81  }
82  }
83 }
84 
85 void QgsGeometryValidator::validatePolyline( int i, const QgsLineString *line, bool ring )
86 {
87  if ( !line )
88  return;
89 
90  if ( ring )
91  {
92  if ( line->numPoints() < 4 )
93  {
94  QString msg = QObject::tr( "ring %1 with less than four points" ).arg( i );
95  QgsDebugMsgLevel( msg, 2 );
96  emit errorFound( QgsGeometry::Error( msg ) );
97  mErrorCount++;
98  return;
99  }
100 
101  if ( !line->isClosed() )
102  {
103  QString msg = QObject::tr( "ring %1 not closed" ).arg( i );
104  QgsDebugMsgLevel( msg, 2 );
105  emit errorFound( QgsGeometry::Error( msg ) );
106  mErrorCount++;
107  return;
108  }
109  }
110  else if ( line->numPoints() < 2 )
111  {
112  QString msg = QObject::tr( "line %1 with less than two points" ).arg( i );
113  QgsDebugMsgLevel( msg, 2 );
114  emit errorFound( QgsGeometry::Error( msg ) );
115  mErrorCount++;
116  return;
117  }
118 
119  std::unique_ptr< QgsLineString > noDupes;
120 
121  // test for duplicate nodes, and if we find any flag errors and then remove them so that the subsequent
122  // tests work OK.
123  const QVector< QgsVertexId > duplicateNodes = line->collectDuplicateNodes( 1E-8 );
124  if ( !duplicateNodes.empty() )
125  {
126  noDupes.reset( line->clone() );
127  for ( int j = duplicateNodes.size() - 1; j >= 0; j-- )
128  {
129  const QgsVertexId duplicateVertex = duplicateNodes.at( j );
130  const QgsPointXY duplicationLocation = noDupes->vertexAt( duplicateVertex );
131  noDupes->deleteVertex( duplicateVertex );
132  int n = 1;
133 
134  // count how many other points exist at this location too
135  for ( int k = j - 1; k >= 0; k-- )
136  {
137  const QgsVertexId prevDupe = duplicateNodes.at( k );
138  const QgsPoint prevPoint = noDupes->vertexAt( prevDupe );
139  if ( qgsDoubleNear( duplicationLocation.x(), prevPoint.x(), 1E-8 ) && qgsDoubleNear( duplicationLocation.y(), prevPoint.y(), 1E-8 ) )
140  {
141  noDupes->deleteVertex( prevDupe );
142  n++;
143  }
144  else
145  {
146  break;
147  }
148  }
149 
150  j -= n - 1;
151 
152  QString msg = QObject::tr( "line %1 contains %n duplicate nodes starting at vertex %2", "number of duplicate nodes", n + 1 ).arg( i + 1 ).arg( duplicateVertex.vertex - n + 1 );
153  QgsDebugMsgLevel( msg, 2 );
154  emit errorFound( QgsGeometry::Error( msg, duplicationLocation ) );
155  mErrorCount++;
156  }
157  line = noDupes.get();
158  }
159 
160  for ( int j = 0; !mStop && j < line->numPoints() - 3; j++ )
161  {
162  const double xAtJ = line->xAt( j );
163  const double yAtJ = line->yAt( j );
164  QgsVector v( line->xAt( j + 1 ) - xAtJ, line->yAt( j + 1 ) - yAtJ );
165  double vl = v.length();
166 
167  int n = ( j == 0 && ring ) ? line->numPoints() - 2 : line->numPoints() - 1;
168 
169  for ( int k = j + 2; !mStop && k < n; k++ )
170  {
171  const double xAtK = line->xAt( k );
172  const double yAtK = line->yAt( k );
173 
174  QgsVector w( line->xAt( k + 1 ) - xAtK, line->yAt( k + 1 ) - yAtK );
175 
176  double sX;
177  double sY;
178  if ( !intersectLines( xAtJ, yAtJ, v, xAtK, yAtK, w, sX, sY ) )
179  continue;
180 
181  double d = 0.0;
182  try
183  {
184  d = -distLine2Point( xAtJ, yAtJ, v.perpVector(), sX, sY );
185  }
186  catch ( QgsException &e )
187  {
188  Q_UNUSED( e )
189  QgsDebugMsg( "Error validating: " + e.what() );
190  continue;
191  }
192  if ( d < 0 || d > vl )
193  continue;
194 
195  try
196  {
197  d = -distLine2Point( xAtK, yAtK, w.perpVector(), sX, sY );
198  }
199  catch ( QgsException &e )
200  {
201  Q_UNUSED( e )
202  QgsDebugMsg( "Error validating: " + e.what() );
203  continue;
204  }
205 
206  if ( d <= 0 || d >= w.length() )
207  continue;
208 
209  QString msg = QObject::tr( "segments %1 and %2 of line %3 intersect at %4, %5" ).arg( j ).arg( k ).arg( i ).arg( sX ).arg( sY );
210  QgsDebugMsgLevel( msg, 2 );
211  emit errorFound( QgsGeometry::Error( msg, QgsPointXY( sX, sY ) ) );
212  mErrorCount++;
213  }
214  }
215 }
216 
217 void QgsGeometryValidator::validatePolygon( int idx, const QgsPolygon *polygon )
218 {
219  // check if holes are inside polygon
220  for ( int i = 0; !mStop && i < polygon->numInteriorRings(); ++i )
221  {
222  if ( !ringInRing( static_cast< const QgsLineString * >( polygon->interiorRing( i ) ), static_cast< const QgsLineString * >( polygon->exteriorRing() ) ) )
223  {
224  QString msg = QObject::tr( "ring %1 of polygon %2 not in exterior ring" ).arg( i + 1 ).arg( idx );
225  QgsDebugMsg( msg );
226  emit errorFound( QgsGeometry::Error( msg ) );
227  mErrorCount++;
228  }
229  }
230 
231  // check holes for intersections
232  for ( int i = 0; !mStop && i < polygon->numInteriorRings(); i++ )
233  {
234  for ( int j = i + 1; !mStop && j < polygon->numInteriorRings(); j++ )
235  {
236  checkRingIntersections( idx, i + 1, qgsgeometry_cast< QgsLineString * >( polygon->interiorRing( i ) ),
237  idx, j + 1, qgsgeometry_cast< QgsLineString * >( polygon->interiorRing( j ) ) );
238  }
239  }
240 
241  // check if rings are self-intersecting
242  validatePolyline( 0, qgsgeometry_cast< const QgsLineString * >( polygon->exteriorRing() ), true );
243  for ( int i = 0; !mStop && i < polygon->numInteriorRings(); i++ )
244  {
245  validatePolyline( i + 1, qgsgeometry_cast< const QgsLineString * >( polygon->interiorRing( i ) ), true );
246  }
247 }
248 
250 {
251  mErrorCount = 0;
252  if ( mGeometry.isNull() )
253  {
254  return;
255  }
256 
257  switch ( mMethod )
258  {
260  {
261  // avoid calling geos for trivial point geometries
263  {
264  return;
265  }
266 
267  QgsGeos geos( mGeometry.constGet() );
268  QString error;
269  QgsGeometry errorLoc;
270  if ( !geos.isValid( &error, true, &errorLoc ) )
271  {
272  if ( errorLoc.isNull() )
273  {
274  emit errorFound( QgsGeometry::Error( error ) );
275  mErrorCount++;
276  }
277  else
278  {
279  const QgsPointXY point = errorLoc.asPoint();
280  emit errorFound( QgsGeometry::Error( error, point ) );
281  mErrorCount++;
282  }
283  }
284 
285  break;
286  }
287 
289  {
290  switch ( QgsWkbTypes::flatType( mGeometry.constGet()->wkbType() ) )
291  {
292  case QgsWkbTypes::Point:
294  break;
295 
297  validatePolyline( 0, qgsgeometry_cast< const QgsLineString * >( mGeometry.constGet() ) );
298  break;
299 
301  {
302  const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( mGeometry.constGet() );
303  for ( int i = 0; !mStop && i < collection->numGeometries(); i++ )
304  validatePolyline( i, qgsgeometry_cast< const QgsLineString * >( collection->geometryN( i ) ) );
305  break;
306  }
307 
309  validatePolygon( 0, qgsgeometry_cast< const QgsPolygon * >( mGeometry.constGet() ) );
310  break;
311 
313  {
314  const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( mGeometry.constGet() );
315  for ( int i = 0; !mStop && i < collection->numGeometries(); i++ )
316  validatePolygon( i, qgsgeometry_cast< const QgsPolygon * >( collection->geometryN( i ) ) );
317 
318  for ( int i = 0; !mStop && i < collection->numGeometries(); i++ )
319  {
320  const QgsPolygon *poly = qgsgeometry_cast< const QgsPolygon * >( collection->geometryN( i ) );
321  if ( !poly->exteriorRing() || poly->exteriorRing()->isEmpty() )
322  {
323  emit errorFound( QgsGeometry::Error( QObject::tr( "Polygon %1 has no rings" ).arg( i ) ) );
324  mErrorCount++;
325  continue;
326  }
327 
328  for ( int j = i + 1; !mStop && j < collection->numGeometries(); j++ )
329  {
330  const QgsPolygon *poly2 = qgsgeometry_cast< const QgsPolygon * >( collection->geometryN( j ) );
331  if ( !poly2->exteriorRing() || poly2->exteriorRing()->isEmpty() )
332  continue;
333 
334  if ( ringInRing( qgsgeometry_cast< const QgsLineString * >( poly->exteriorRing() ),
335  qgsgeometry_cast< const QgsLineString * >( poly2->exteriorRing() ) ) )
336  {
337  emit errorFound( QgsGeometry::Error( QObject::tr( "Polygon %1 lies inside polygon %2" ).arg( i ).arg( j ) ) );
338  mErrorCount++;
339  }
340  else if ( ringInRing( static_cast< const QgsLineString * >( poly2->exteriorRing() ),
341  static_cast< const QgsLineString * >( poly->exteriorRing() ) ) )
342  {
343  emit errorFound( QgsGeometry::Error( QObject::tr( "Polygon %1 lies inside polygon %2" ).arg( j ).arg( i ) ) );
344  mErrorCount++;
345  }
346  else
347  {
348  checkRingIntersections( i, 0, qgsgeometry_cast< const QgsLineString * >( poly->exteriorRing() ),
349  j, 0, qgsgeometry_cast< const QgsLineString * >( poly2->exteriorRing() ) );
350  }
351  }
352  }
353  break;
354  }
355 
357  {
358  emit errorFound( QgsGeometry::Error( QObject::tr( "Unknown geometry type %1" ).arg( mGeometry.wkbType() ) ) );
359  mErrorCount++;
360  break;
361  }
362 
363  default:
364  break;
365  }
366 
367  if ( mStop )
368  {
369  emit validationFinished( QObject::tr( "Geometry validation was aborted." ) );
370  }
371  else if ( mErrorCount > 0 )
372  {
373  emit validationFinished( QObject::tr( "Geometry has %1 errors." ).arg( mErrorCount ) );
374  }
375  else
376  {
377  emit validationFinished( QObject::tr( "Geometry is valid." ) );
378  }
379  break;
380  }
381  }
382 }
383 
385 {
386  if ( mErrors )
387  *mErrors << e;
388 }
389 
390 void QgsGeometryValidator::validateGeometry( const QgsGeometry &geometry, QVector<QgsGeometry::Error> &errors, QgsGeometry::ValidationMethod method )
391 {
392  QgsGeometryValidator *gv = new QgsGeometryValidator( geometry, &errors, method );
394  gv->run();
395  gv->wait();
396 }
397 
398 //
399 // distance of point q from line through p in direction v
400 // return >0 => q lies left of the line
401 // <0 => q lies right of the line
402 //
403 double QgsGeometryValidator::distLine2Point( double px, double py, QgsVector v, double qX, double qY )
404 {
405  const double l = v.length();
406  if ( qgsDoubleNear( l, 0 ) )
407  {
408  throw QgsException( QObject::tr( "invalid line" ) );
409  }
410 
411  return ( v.x() * ( qY - py ) - v.y() * ( qX - px ) ) / l;
412 }
413 
414 bool QgsGeometryValidator::intersectLines( double px, double py, QgsVector v, double qx, double qy, QgsVector w, double &sX, double &sY )
415 {
416  double d = v.y() * w.x() - v.x() * w.y();
417 
418  if ( qgsDoubleNear( d, 0 ) )
419  return false;
420 
421  double dx = qx - px;
422  double dy = qy - py;
423  double k = ( dy * w.x() - dx * w.y() ) / d;
424 
425  sX = px + v.x() * k;
426  sY = py + v.y() * k;
427 
428  return true;
429 }
430 
431 bool QgsGeometryValidator::pointInRing( const QgsLineString *ring, double pX, double pY )
432 {
433  if ( !ring->boundingBox().contains( QgsPointXY( pX, pY ) ) )
434  return false;
435 
436  bool inside = false;
437  int j = ring->numPoints() - 1;
438 
439  for ( int i = 0; !mStop && i < ring->numPoints(); i++ )
440  {
441  const double xAti = ring->xAt( i );
442  const double yAti = ring->yAt( i );
443  const double xAtj = ring->xAt( j );
444  const double yAtj = ring->yAt( j );
445 
446  if ( qgsDoubleNear( xAti, pX ) && qgsDoubleNear( yAti, pY ) )
447  return true;
448 
449  if ( ( yAti < pY && yAtj >= pY ) ||
450  ( yAtj < pY && yAti >= pY ) )
451  {
452  if ( xAti + ( pY - yAti ) / ( yAtj - yAti ) * ( xAtj - xAti ) <= pX )
453  inside = !inside;
454  }
455 
456  j = i;
457  }
458 
459  return inside;
460 }
461 
462 bool QgsGeometryValidator::ringInRing( const QgsLineString *inside, const QgsLineString *outside )
463 {
464  if ( !outside->boundingBox().contains( inside->boundingBox() ) )
465  return false;
466 
467  for ( int i = 0; !mStop && i < inside->numPoints(); i++ )
468  {
469  if ( !pointInRing( outside, inside->xAt( i ), inside->yAt( i ) ) )
470  return false;
471  }
472 
473  return true;
474 }
qgspolygon.h
QgsGeometry::ValidatorGeos
@ ValidatorGeos
Use GEOS validation methods.
Definition: qgsgeometry.h:2115
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsabstractgeometry.h:1137
QgsLineString::xAt
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
Definition: qgslinestring.cpp:762
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsException
Defines a QGIS exception class.
Definition: qgsexception.h:35
QgsGeometryValidator::validationFinished
void validationFinished(const QString &summary)
Sent when the validation is finished.
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
QgsPolygon
Polygon geometry type.
Definition: qgspolygon.h:34
QgsPoint::vertexAt
QgsPoint vertexAt(QgsVertexId) const override
Returns the point corresponding to a specified vertex id.
Definition: qgspoint.cpp:520
QgsWkbTypes::MultiPolygon
@ MultiPolygon
Definition: qgswkbtypes.h:78
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsGeometryValidator::~QgsGeometryValidator
~QgsGeometryValidator() override
Definition: qgsgeometryvalidator.cpp:33
QgsGeometryValidator::addError
void addError(const QgsGeometry::Error &)
Definition: qgsgeometryvalidator.cpp:384
QgsCurvePolygon::exteriorRing
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
Definition: qgscurvepolygon.h:87
QgsGeometry::isNull
Q_GADGET bool isNull
Definition: qgsgeometry.h:126
QgsPointXY::x
Q_GADGET double x
Definition: qgspointxy.h:47
QgsLineString::yAt
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
Definition: qgslinestring.cpp:770
QgsWkbTypes::flatType
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:702
QgsWkbTypes::LineString
@ LineString
Definition: qgswkbtypes.h:73
geos
Contains geos related utilities and functions.
Definition: qgsgeos.h:42
QgsGeometry::Error
Definition: qgsgeometry.h:2059
qgis.h
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsLineString
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:44
QgsGeometryValidator::run
void run() override
Definition: qgsgeometryvalidator.cpp:249
QgsGeometryCollection::numGeometries
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
Definition: qgsgeometrycollection.h:57
QgsLineString::collectDuplicateNodes
QVector< QgsVertexId > collectDuplicateNodes(double epsilon=4 *std::numeric_limits< double >::epsilon(), bool useZValues=false) const
Returns a list of any duplicate nodes contained in the geometry, within the specified tolerance.
Definition: qgslinestring.cpp:366
QgsVector::length
double length() const SIP_HOLDGIL
Returns the length of the vector.
Definition: qgsvector.h:128
QgsCurvePolygon::numInteriorRings
int numInteriorRings() const SIP_HOLDGIL
Returns the number of interior rings contained with the curve polygon.
Definition: qgscurvepolygon.h:77
QgsPoint::y
double y
Definition: qgspoint.h:42
QgsWkbTypes::MultiLineString
@ MultiLineString
Definition: qgswkbtypes.h:77
QgsGeometryCollection
Geometry collection.
Definition: qgsgeometrycollection.h:36
QgsLineString::clone
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
Definition: qgslinestring.cpp:293
QgsAbstractGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Definition: qgsabstractgeometry.h:193
QgsWkbTypes::Unknown
@ Unknown
Definition: qgswkbtypes.h:71
QgsRectangle::contains
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:342
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsVector::x
double x() const SIP_HOLDGIL
Returns the vector's x-component.
Definition: qgsvector.h:147
QgsException::what
QString what() const
Definition: qgsexception.h:48
QgsGeos
Does vector analysis using the geos library and handles import, export, exception handling*.
Definition: qgsgeos.h:104
QgsGeometry::ValidatorQgisInternal
@ ValidatorQgisInternal
Use internal QgsGeometryValidator method.
Definition: qgsgeometry.h:2114
QgsVector::y
double y() const SIP_HOLDGIL
Returns the vector's y-component.
Definition: qgsvector.h:156
QgsGeometryValidator::QgsGeometryValidator
QgsGeometryValidator(const QgsGeometry &geometry, QVector< QgsGeometry::Error > *errors=nullptr, QgsGeometry::ValidationMethod method=QgsGeometry::ValidatorQgisInternal)
Constructor for QgsGeometryValidator.
Definition: qgsgeometryvalidator.cpp:24
QgsPoint::x
Q_GADGET double x
Definition: qgspoint.h:41
QgsCurvePolygon::interiorRing
const QgsCurve * interiorRing(int i) const SIP_HOLDGIL
Retrieves an interior ring from the curve polygon.
Definition: qgscurvepolygon.h:100
QgsAbstractGeometry::isEmpty
virtual bool isEmpty() const
Returns true if the geometry is empty.
Definition: qgsabstractgeometry.cpp:298
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:44
QgsGeometry::asPoint
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
Definition: qgsgeometry.cpp:1544
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsGeometryCollection::geometryN
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
Definition: qgsgeometrycollection.h:85
qgsgeometry.h
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsVector
A class to represent a vector.
Definition: qgsvector.h:30
QgsWkbTypes::Polygon
@ Polygon
Definition: qgswkbtypes.h:74
QgsWkbTypes::MultiPoint
@ MultiPoint
Definition: qgswkbtypes.h:76
QgsCurve::boundingBox
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Definition: qgscurve.cpp:202
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
QgsGeometryValidator::stop
void stop()
Definition: qgsgeometryvalidator.cpp:39
QgsWkbTypes::geometryType
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:938
QgsGeometry::ValidationMethod
ValidationMethod
Available methods for validating geometries.
Definition: qgsgeometry.h:2113
qgsgeometrycollection.h
qgslogger.h
QgsCurve::isClosed
virtual bool isClosed() const SIP_HOLDGIL
Returns true if the curve is closed.
Definition: qgscurve.cpp:40
QgsLineString::numPoints
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
Definition: qgslinestring.cpp:703
QgsGeometryValidator
Definition: qgsgeometryvalidator.h:29
QgsGeometryValidator::validateGeometry
static void validateGeometry(const QgsGeometry &geometry, QVector< QgsGeometry::Error > &errors, QgsGeometry::ValidationMethod method=QgsGeometry::ValidatorQgisInternal)
Validate geometry and produce a list of geometry errors.
Definition: qgsgeometryvalidator.cpp:390
QgsPoint::deleteVertex
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
Definition: qgspoint.cpp:454
QgsGeometryValidator::errorFound
void errorFound(const QgsGeometry::Error &error)
Sent when an error has been found during the validation process.
QgsGeometry::wkbType
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Definition: qgsgeometry.cpp:345
qgsgeometryvalidator.h
qgsgeos.h