23 : mGeometry( geometry )
42 void QgsGeometryValidator::checkRingIntersections(
46 for (
int i = 0; !mStop && i < ring0.size() - 1; i++ )
50 for (
int j = 0; !mStop && j < ring1.size() - 1; j++ )
55 if ( intersectLines( ring0[i], v, ring1[j], w, s ) )
57 double d = -distLine2Point( ring0[i], v.
perpVector(), s );
59 if ( d >= 0 && d <= v.
length() )
61 d = -distLine2Point( ring1[j], w.
perpVector(), s );
62 if ( d > 0 && d < w.
length() &&
63 ring0[i + 1] != ring1[j + 1] && ring0[i + 1] != ring1[j] &&
64 ring0[i + 0] != ring1[j + 1] && ring0[i + 0] != ring1[j] )
66 QString msg = QObject::tr(
"segment %1 of ring %2 of polygon %3 intersects segment %4 of ring %5 of polygon %6 at %7" )
67 .arg( i0 ).arg( i ).arg( p0 )
68 .arg( i1 ).arg( j ).arg( p1 )
80 void QgsGeometryValidator::validatePolyline(
int i,
QgsPolylineXY line,
bool ring )
84 if ( line.size() < 4 )
86 QString msg = QObject::tr(
"ring %1 with less than four points" ).arg( i );
93 if ( line[0] != line[ line.size() - 1 ] )
95 QString msg = QObject::tr(
"ring %1 not closed" ).arg( i );
102 else if ( line.size() < 2 )
104 QString msg = QObject::tr(
"line %1 with less than two points" ).arg( i );
112 while ( j < line.size() - 1 )
115 while ( j < line.size() - 1 && line[j] == line[j + 1] )
123 QString msg = QObject::tr(
"line %1 contains %n duplicate node(s) at %2",
"number of duplicate nodes", n ).arg( i ).arg( j );
132 for ( j = 0; !mStop && j < line.size() - 3; j++ )
137 int n = ( j == 0 && ring ) ? line.size() - 2 : line.size() - 1;
139 for (
int k = j + 2; !mStop && k < n; k++ )
144 if ( !intersectLines( line[j], v, line[k], w, s ) )
150 d = -distLine2Point( line[j], v.
perpVector(), s );
158 if ( d < 0 || d > vl )
163 d = -distLine2Point( line[k], w.
perpVector(), s );
172 if ( d <= 0 || d >= w.
length() )
175 QString msg = QObject::tr(
"segments %1 and %2 of line %3 intersect at %4" ).arg( j ).arg( k ).arg( i ).arg( s.
toString() );
183 void QgsGeometryValidator::validatePolygon(
int idx,
const QgsPolygonXY &polygon )
186 for (
int i = 1; !mStop && i < polygon.size(); i++ )
188 if ( !ringInRing( polygon[i], polygon[0] ) )
190 QString msg = QObject::tr(
"Ring %1 of polygon %2 not in exterior ring" ).arg( i ).arg( idx );
198 for (
int i = 1; !mStop && i < polygon.size(); i++ )
200 for (
int j = i + 1; !mStop && j < polygon.size(); j++ )
202 checkRingIntersections( idx, i, polygon[i], idx, j, polygon[j] );
207 for (
int i = 0; !mStop && i < polygon.size(); i++ )
209 validatePolyline( i, polygon[i],
true );
234 if ( !
geos.isValid( &error,
true, &errorLoc ) )
259 validatePolyline( 0, mGeometry.
asPolyline() );
264 for (
int i = 0; !mStop && i < mp.size(); i++ )
265 validatePolyline( i, mp[i] );
269 validatePolygon( 0, mGeometry.
asPolygon() );
274 for (
int i = 0; !mStop && i < mp.size(); i++ )
276 validatePolygon( i, mp[i] );
279 for (
int i = 0; !mStop && i < mp.size(); i++ )
281 if ( mp[i].isEmpty() )
288 for (
int j = i + 1; !mStop && j < mp.size(); j++ )
290 if ( mp[j].isEmpty() )
293 if ( ringInRing( mp[i][0], mp[j][0] ) )
298 else if ( ringInRing( mp[j][0], mp[i][0] ) )
305 checkRingIntersections( i, 0, mp[i][0], j, 0, mp[j][0] );
321 else if ( mErrorCount > 0 )
323 emit
validationFinished( QObject::tr(
"Geometry has %1 errors." ).arg( mErrorCount ) );
360 return ( v.
x() * ( q.
y() - p.
y() ) - v.
y() * ( q.
x() - p.
x() ) ) / v.
length();
365 double d = v.
y() * w.
x() - v.
x() * w.
y();
370 double dx = q.
x() - p.
x();
371 double dy = q.
y() - p.
y();
372 double k = ( dy * w.
x() - dx * w.
y() ) / d;
382 int j = ring.size() - 1;
384 for (
int i = 0; !mStop && i < ring.size(); i++ )
389 if ( ( ring[i].y() < p.
y() && ring[j].y() >= p.
y() ) ||
390 ( ring[j].y() < p.
y() && ring[i].y() >= p.
y() ) )
392 if ( ring[i].x() + ( p.
y() - ring[i].y() ) / ( ring[j].y() - ring[i].y() ) * ( ring[j].x() - ring[i].x() ) <= p.
x() )
404 for (
int i = 0; !mStop && i < inside.size(); i++ )
406 if ( !pointInRing( outside, inside[i] ) )
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 validationFinished(const QString &summary)
Sent when the validation is finished.
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
Use GEOS validation methods.
void addError(const QgsGeometry::Error &)
A class to represent a 2D point.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
double y() const
Returns the vector's y-component.
A geometry is the spatial representation of a feature.
~QgsGeometryValidator() override
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
QgsMultiPolygonXY asMultiPolygon() const
Returns contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty list.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Type
The WKB type describes the number of dimensions a geometry has.
QgsVector perpVector() const
Returns the perpendicular vector to this vector (rotated 90 degrees counter-clockwise) ...
QgsPolylineXY asPolyline() const
Returns the contents of the geometry as a polyline.
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Use internal QgsGeometryValidator method.
QgsMultiPolylineXY asMultiPolyline() const
Returns contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
Does vector analysis using the geos library and handles import, export, exception handling*...
A class to represent a vector.
Contains geos related utilities and functions.
double length() const
Returns the length of the vector.
QgsGeometryValidator(const QgsGeometry &geometry, QVector< QgsGeometry::Error > *errors=nullptr, QgsGeometry::ValidationMethod method=QgsGeometry::ValidatorQgisInternal)
Constructor for QgsGeometryValidator.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
ValidationMethod
Available methods for validating geometries.
double x() const
Returns the vector's x-component.
static Type flatType(Type type)
Returns the flat type for a WKB type.
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
Defines a QGIS exception class.
void errorFound(const QgsGeometry::Error &error)
Sent when an error has been found during the validation process.
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.