-1

I want to locate or highlight all the holes (invalid interior rings that do not connect at all vertices and edges) and redundant geometry in a polygon shapefile in QGIS so that I can go back and manually correct all the vertices and geometry. I do not want to use the "Delete Holes" tool because I want to do it manually.

4
  • 3
    Please Edit the Question to demonstrate which you mean by "holes", since there are valid "interior rings" and invalid interior rings, and both overlaps and underlaps that damage topologic completeness.
    – Vince
    Commented Jan 16 at 22:19
  • @Vince edited as requested
    – MapDeath
    Commented Jan 17 at 1:08
  • 4
    Well, no. What makes them invalid? Valid interior rings also to not connect at edges. I was really looking for a demonstration. A graphic. If you can't define this mathematically, you can't do it manually.
    – Vince
    Commented Jan 17 at 1:30
  • 2
    Do you mean like the first polygon: i.sstatic.net/0uCM9.png ?
    – Bera
    Commented Jan 17 at 6:24

2 Answers 2

2

You can easily find all invalid polygons by using the "Check validity" tool on the layer. In the output file with invalid polygons of this tool, there will also be a column that specifies why it is invalid:

enter image description here

2

Use QGIS expressions with functions interior_ring_n(), exterior_ring() and is_valid() to get polygons that have holes and/or are invalid/vaild. Combine them to fit your needs like identifying or deleting holes. You have different options as you can see below.

Alternatives are Check validity tool, Geometry Checker Plugin and Topology Checker Plugin.

Automatically delete all holes from polygons

Use Geoemtry Generator or Geometry by expression (see here for both options) with this expression:

make_polygon (exterior_ring ($geometry))

Select polygons with holes

To identify polygons with holes, use Select by Expression and expression function interior_ring_n() to return the first interior ring and if this indeed returns a geometry (and is not NULL), you know the polygon has interior rings.

 interior_ring_n ($geometry, 1) is not NULL

Alternatively, use num_interior_rings() function:

num_interior_rings ($geometry) > 0

Show holes

To show holes, use the following expression with Geometry Generator to create a point marker for each hole (thus showing even very small, invisible holes):

collect_geometries(
    array_foreach (
        generate_series (1, num_interior_rings ($geometry)),
        point_on_surface(make_polygon(interior_ring_n ($geometry, @element)))
    )
)

Each point shows a hole: enter image description here

Select polygons that are (in)valid

To identify polygons that are valid, use is_valid():

is_valid($geometry)

Select polygons with holes and validity combined

If you combine both, you can identify polygon with holes that are not valid:

interior_ring_n ($geometry, 1) is not NULL and 
NOT is_valid($geometry)

Two polygons with invalid interior rings are selected (yellow); the polygon on the upper left is invalid, but not selected as it has no holes: enter image description here

Show invalid interior rings as geometries

collect_geometries(
    array_filter(
        array_foreach (
            generate_series (1, num_interior_rings ($geometry)),
            case
            when not is_valid (make_polygon(interior_ring_n ($geometry, @element)))
            then make_polygon(interior_ring_n ($geometry, @element))
            end
        ),
        @element is not NULL
    )
)

Blue polygons are invalid interior rings: enter image description here

Show invalid interior rings as point markers

Alternatively, you could in line 7 you could enclose the make_polygon() function into a point_on_surface() function to get a point marker where you have invalid interior rings. Like this, you can see even extremely small interior rings (ke slivers) when zoomed out:

Red arrows shows location of point marker where an extremely small, invalid interior ring is located: enter image description here

Not the answer you're looking for? Browse other questions tagged or ask your own question.