Validating Polygon Self-Intersections in QGIS

Validating polygon self-intersections in QGIS requires detecting boundary crossings that violate topological rules, then either flagging or repairing the geometry before downstream analysis. Self-intersections occur when a polygon’s exterior or interior ring crosses itself, creating invalid topology that breaks spatial indexing, area calculations, and OGC compliance. In QGIS, you can identify these defects using the native Check Validity algorithm, which leverages the GEOS library to scan features and export invalid geometries to a separate layer. For automated pipelines, PyQGIS provides QgsGeometry.isGeosValid() for detection and QgsGeometry.makeValid() for programmatic repair. Data stewards and QA engineers should run these checks immediately after coordinate transformations, bulk imports, or topology edits to prevent cascading failures in spatial databases.

Native GUI Validation Workflows

The most accessible method for GIS analysts is the Check Validity tool (Vector > Geometry Tools > Check Validity or via the Processing Toolbox). This algorithm evaluates each polygon against strict topological rules and outputs a validity report layer containing an is_valid boolean field and an error_message string. You can select the validation engine in the tool parameters:

  • GEOS: Strict OGC compliance. Flags self-intersections, duplicate vertices, and ring orientation issues. Ideal for production-grade datasets.
  • QGIS Native: More tolerant of minor precision artifacts; useful for legacy datasets that fail GEOS but render correctly.
  • GRASS v.clean: Runs topology cleaning alongside validation, but requires manual threshold tuning and is slower on large datasets.

For real-time editing, enable the background validity checker under Settings > Options > Digitizing > Geometry Validation. This highlights self-intersecting polygons in red as you digitize, preventing invalid features from entering your dataset. When working with large administrative boundaries or cadastral parcels, pair the validity check with Extract Invalid Geometries to isolate problematic features for manual review. This workflow aligns with established Geometry Validity Checks for Vector Data practices and ensures audit-ready outputs.

Automated PyQGIS Implementation

Platform teams and compliance officers require repeatable, headless validation. The following PyQGIS script scans a loaded polygon layer, logs self-intersections, and optionally applies a safe repair routine. It runs directly in the QGIS Python Console or via standalone qgis_process.

from qgis.core import (
    QgsProject, QgsVectorLayer, QgsGeometry, QgsFeature, QgsWkbTypes
)
import logging

logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

def validate_and_fix_polygons(layer_name: str, auto_fix: bool = False):
    """Scan a polygon layer for self-intersections and optionally repair them."""
    layers = QgsProject.instance().mapLayersByName(layer_name)
    if not layers:
        logging.error(f"Layer '{layer_name}' not found in current project.")
        return

    layer = layers[0]
    if QgsWkbTypes.geometryType(layer.wkbType()) != QgsWkbTypes.PolygonGeometry:
        logging.error("Target layer must contain polygon geometries.")
        return

    invalid_count = 0
    fixed_count = 0

    layer.startEditing()
    for feature in layer.getFeatures():
        geom = feature.geometry()
        if geom.isNull() or geom.isEmpty():
            continue

        if not geom.isGeosValid():
            invalid_count += 1
            logging.warning(f"Feature {feature.id()} contains invalid geometry (self-intersection, ring error, etc.)")

            if auto_fix:
                fixed_geom = geom.makeValid()
                if fixed_geom and not fixed_geom.isNull():
                    # makeValid() can output multi-part geometries; preserve type compatibility
                    if fixed_geom.type() == geom.type():
                        feature.setGeometry(fixed_geom)
                        layer.updateFeature(feature)
                        fixed_count += 1
                    else:
                        logging.info(f"Feature {feature.id()} repaired but geometry type changed. Skipping commit.")
                else:
                    logging.error(f"Failed to repair feature {feature.id()}.")

    if auto_fix:
        layer.commitChanges()
        logging.info(f"Validation complete. Found {invalid_count} invalid features. Repaired {fixed_count}.")
    else:
        logging.info(f"Validation complete. Found {invalid_count} invalid features. Run with auto_fix=True to repair.")

Run the function with validate_and_fix_polygons("my_polygon_layer", auto_fix=False) for a dry run, or set auto_fix=True to commit repairs. Note that makeValid() relies on the underlying GEOS topology engine and may split complex self-intersecting polygons into multi-part features. Always back up source data before bulk repairs.

Pipeline Integration & Best Practices

Validating polygon self-intersections in QGIS should be treated as a mandatory gate in spatial ETL pipelines. Coordinate reference system (CRS) transformations frequently introduce micro-intersections due to floating-point rounding. To mitigate this, apply a small tolerance buffer (QgsGeometry.buffer()) before validation, or use the QgsGeometryValidator class for granular error reporting when debugging complex cadastral datasets.

When integrating with PostGIS or GeoPackage backends, enforce validity at the database level using ST_IsValid() and ST_MakeValid() constraints. QGIS validation aligns with the OGC Simple Features specification, which mandates that polygon boundaries must not self-intersect and interior rings must lie entirely within exterior rings. For detailed parameter tuning and batch processing configurations, consult the official QGIS Processing Toolbox documentation.

Automated validation workflows should be scheduled after:

  1. CRS transformations (especially UTM to geographic or vice versa)
  2. CAD-to-GIS conversions (DWG/DXF imports frequently contain unclosed or overlapping rings)
  3. Spatial joins or unions (overlay operations compound topological errors)
  4. Bulk attribute edits that trigger geometry regeneration

By embedding these checks into CI/CD pipelines or QGIS project macros, teams maintain Core Spatial QC Fundamentals & Standards compliance without manual intervention. Always log validation results to a centralized audit table, track error rates per data source, and establish rollback thresholds before committing repaired geometries to production.