25   : mGeometry( geometry )
 
   44 void QgsGeometryValidator::checkRingIntersections( 
int partIndex0, 
int ringIndex0, 
const QgsLineString *ring0, 
int partIndex1, 
int ringIndex1, 
const QgsLineString *ring1 )
 
   46   for ( 
int i = 0; !mStop && i < ring0->
numPoints() - 1; i++ )
 
   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 );
 
   52     for ( 
int j = 0; !mStop && j < ring1->
numPoints() - 1; j++ )
 
   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 );
 
   60       if ( intersectLines( ring0XAti, ring0YAti, v, ring1XAtj, ring1YAtj, w, sX, sY ) )
 
   62         double d = -distLine2Point( ring0XAti, ring0YAti, v.perpVector(), sX, sY );
 
   64         if ( d >= 0 && d <= v.length() )
 
   66           d = -distLine2Point( ring1XAtj, ring1YAtj, w.perpVector(), sX, sY );
 
   67           if ( d > 0 && d < w.length() &&
 
   71             const 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( i ).arg( ringIndex0 ).arg( partIndex0 )
 
   73                                 .arg( j ).arg( ringIndex1 ).arg( partIndex1 )
 
   84 void QgsGeometryValidator::validatePolyline( 
int i, 
const QgsLineString *line, 
bool ring )
 
   93       QString msg = QObject::tr( 
"ring %1 with less than four points" ).arg( i );
 
  107         msg = QObject::tr( 
"ring %1 not closed, Z mismatch: %2 vs %3" ).arg( i ).arg( startPoint.
z() ).arg( endPoint.
z() );
 
  111         msg = QObject::tr( 
"ring %1 not closed" ).arg( i );
 
  121     QString msg = QObject::tr( 
"line %1 with less than two points" ).arg( i );
 
  128   std::unique_ptr< QgsLineString > noDupes;
 
  133   if ( !duplicateNodes.empty() )
 
  135     noDupes.reset( line->
clone() );
 
  136     for ( 
int j = duplicateNodes.size() - 1; j >= 0; j-- )
 
  138       const QgsVertexId duplicateVertex = duplicateNodes.at( j );
 
  139       const QgsPointXY duplicationLocation = noDupes->vertexAt( duplicateVertex );
 
  140       noDupes->deleteVertex( duplicateVertex );
 
  144       for ( 
int k = j - 1; k >= 0; k-- )
 
  146         const QgsVertexId prevDupe = duplicateNodes.at( k );
 
  161       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 );
 
  166     line = noDupes.get();
 
  169   for ( 
int j = 0; !mStop && j < line->
numPoints() - 3; j++ )
 
  171     const double xAtJ = line->
xAt( j );
 
  172     const double yAtJ = line->
yAt( j );
 
  174     double vl = v.length();
 
  178     for ( 
int k = j + 2; !mStop && k < n; k++ )
 
  180       const double xAtK = line->
xAt( k );
 
  181       const double yAtK = line->
yAt( k );
 
  187       if ( !intersectLines( xAtJ, yAtJ, v, xAtK, yAtK, w, sX, sY ) )
 
  193         d = -distLine2Point( xAtJ, yAtJ, v.perpVector(), sX, sY );
 
  201       if ( d < 0 || d > vl )
 
  206         d = -distLine2Point( xAtK, yAtK, w.perpVector(), sX, sY );
 
  215       if ( d <= 0 || d >= w.length() )
 
  218       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 );
 
  226 void QgsGeometryValidator::validatePolygon( 
int partIndex, 
const QgsPolygon *polygon )
 
  233       QString msg = QObject::tr( 
"ring %1 of polygon %2 not in exterior ring" ).arg( i + 1 ).arg( partIndex );
 
  245       checkRingIntersections( partIndex, i + 1, qgsgeometry_cast< QgsLineString * >( polygon->
interiorRing( i ) ),
 
  246                               partIndex, j + 1, qgsgeometry_cast< QgsLineString * >( polygon->
interiorRing( j ) ) );
 
  251   validatePolyline( 0, qgsgeometry_cast< const QgsLineString * >( polygon->
exteriorRing() ), 
true );
 
  254     validatePolyline( i + 1, qgsgeometry_cast< const QgsLineString * >( polygon->
interiorRing( i ) ), 
true );
 
  279       if ( !
geos.isValid( &error, 
true, &errorLoc ) )
 
  306           validatePolyline( 0, qgsgeometry_cast< const QgsLineString * >( mGeometry.
constGet() ) );
 
  312           for ( 
int i = 0; !mStop && i < collection->
numGeometries(); i++ )
 
  313             validatePolyline( i, qgsgeometry_cast< const QgsLineString * >( collection->
geometryN( i ) ) );
 
  318           validatePolygon( 0, qgsgeometry_cast< const QgsPolygon * >( mGeometry.
constGet() ) );
 
  324           for ( 
int i = 0; !mStop && i < collection->
numGeometries(); i++ )
 
  325             validatePolygon( i, qgsgeometry_cast< const QgsPolygon * >( collection->
geometryN( i ) ) );
 
  327           for ( 
int i = 0; !mStop && i < collection->
numGeometries(); i++ )
 
  329             const QgsPolygon *poly = qgsgeometry_cast< const QgsPolygon * >( collection->
geometryN( i ) );
 
  337             for ( 
int j = i + 1;  !mStop && j < collection->
numGeometries(); j++ )
 
  339               const QgsPolygon *poly2 = qgsgeometry_cast< const QgsPolygon * >( collection->
geometryN( j ) );
 
  343               if ( ringInRing( qgsgeometry_cast< const QgsLineString * >( poly->
exteriorRing() ),
 
  344                                qgsgeometry_cast< const QgsLineString * >( poly2->
exteriorRing() ) ) )
 
  357                 checkRingIntersections( i, 0, qgsgeometry_cast< const QgsLineString * >( poly->
exteriorRing() ),
 
  358                                         j, 0, qgsgeometry_cast< const QgsLineString * >( poly2->
exteriorRing() ) );
 
  380       else if ( mErrorCount > 0 )
 
  382         emit 
validationFinished( QObject::tr( 
"Geometry has %1 errors." ).arg( mErrorCount ) );
 
  412 double QgsGeometryValidator::distLine2Point( 
double px, 
double py, 
QgsVector v, 
double qX, 
double qY )
 
  414   const double l = v.
length();
 
  420   return ( v.
x() * ( qY - py ) - v.
y() * ( qX - px ) ) / l;
 
  423 bool QgsGeometryValidator::intersectLines( 
double px, 
double py, 
QgsVector v, 
double qx, 
double qy, 
QgsVector w, 
double &sX, 
double &sY )
 
  425   double d = v.
y() * w.
x() - v.
x() * w.
y();
 
  432   double k = ( dy * w.
x() - dx * w.
y() ) / d;
 
  440 bool QgsGeometryValidator::pointInRing( 
const QgsLineString *ring, 
double pX, 
double pY )
 
  448   for ( 
int i = 0; !mStop && i < ring->
numPoints(); i++ )
 
  450     const double xAti = ring->
xAt( i );
 
  451     const double yAti = ring->
yAt( i );
 
  452     const double xAtj = ring->
xAt( j );
 
  453     const double yAtj = ring->
yAt( j );
 
  458     if ( ( yAti < pY && yAtj >= pY ) ||
 
  459          ( yAtj < pY && yAti >= pY ) )
 
  461       if ( xAti + ( pY - yAti ) / ( yAtj - yAti ) * ( xAtj - xAti ) <= pX )
 
  476   for ( 
int i = 0; !mStop && i < inside->
numPoints(); i++ )
 
  478     if ( !pointInRing( outside, inside->
xAt( i ), inside->
yAt( i ) ) )
 
bool is3D() const SIP_HOLDGIL
Returns true if the geometry is 3D and contains a z-value.
virtual bool isEmpty() const
Returns true if the geometry is empty.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
const QgsCurve * interiorRing(int i) const SIP_HOLDGIL
Retrieves an interior ring from the curve polygon.
const QgsCurve * exteriorRing() const SIP_HOLDGIL
Returns the curve polygon's exterior ring.
int numInteriorRings() const SIP_HOLDGIL
Returns the number of interior rings contained with the curve polygon.
QgsRectangle boundingBox() const override
Returns the minimal bounding box for the geometry.
Defines a QGIS exception class.
int numGeometries() const SIP_HOLDGIL
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
void validationFinished(const QString &summary)
Sent when the validation is finished.
void errorFound(const QgsGeometry::Error &error)
Sent when an error has been found during the validation process.
static void validateGeometry(const QgsGeometry &geometry, QVector< QgsGeometry::Error > &errors, QgsGeometry::ValidationMethod method=QgsGeometry::ValidatorQgisInternal)
Validate geometry and produce a list of geometry errors.
void addError(const QgsGeometry::Error &)
~QgsGeometryValidator() override
QgsGeometryValidator(const QgsGeometry &geometry, QVector< QgsGeometry::Error > *errors=nullptr, QgsGeometry::ValidationMethod method=QgsGeometry::ValidatorQgisInternal)
Constructor for QgsGeometryValidator.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
ValidationMethod
Available methods for validating geometries.
@ ValidatorQgisInternal
Use internal QgsGeometryValidator method.
@ ValidatorGeos
Use GEOS validation methods.
Does vector analysis using the geos library and handles import, export, exception handling*.
Line string geometry type, with support for z-dimension and m-values.
QgsPoint startPoint() const override SIP_HOLDGIL
Returns the starting point of the curve.
bool isClosed() const override SIP_HOLDGIL
Returns true if the curve is closed.
QgsPoint endPoint() const override SIP_HOLDGIL
Returns the end point of the curve.
int numPoints() const override SIP_HOLDGIL
Returns the number of points in the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
bool isClosed2D() const override SIP_HOLDGIL
Returns true if the curve is closed.
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
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.
QgsLineString * clone() const override
Clones the geometry by performing a deep copy.
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
A class to represent a 2D point.
Point geometry type, with support for z-dimension and m-values.
QgsPoint vertexAt(QgsVertexId) const override
Returns the point corresponding to a specified vertex id.
bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
A class to represent a vector.
double y() const SIP_HOLDGIL
Returns the vector's y-component.
double x() const SIP_HOLDGIL
Returns the vector's x-component.
double length() const SIP_HOLDGIL
Returns the length of the vector.
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...
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Contains geos related utilities and functions.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define QgsDebugMsgLevel(str, level)
Utility class for identifying a unique vertex within a geometry.