Topology Errors in a GeoJSON: Detect Without Fixing

tool
geometry
bilingual
Upload a GeoJSON and find overlaps, gaps, slivers, duplicates and dangles — a report, not an automatic repair, in Python and R on the same map.
Published

August 31, 2026

In Geometry validity of a GeoJSON we repaired polygons that were individually invalid with make_valid()/st_make_valid(). Here the problem is different: every single feature’s geometry can be perfectly valid, and the dataset can still be broken — two polygons that overlap, a gap between two areas that should touch, a line that ends a millimeter from another without connecting.

This tool doesn’t fix anything. It detects, describes and locates the errors — closing a gap or assigning an overlap is a semantic decision (which polygon is the “correct” one?) that no algorithm can make for you. It’s a data-quality report, not an automatic repair tool.

On load, the code detects whether your data is polygons or lines and runs only the checks that make sense for that type:

Just want to quickly check a file, without the rest of the reading? Use the standalone tool — same engine, less prose.

1. Upload your file

A .geojson, or a shapefile: either as a single .zip, or as the individual .shp/.dbf/.shx files (and optionally .prj) selected together.

2. What we look for

Five recurring categories, drawn from the USGS catalog and from the QGIS Topology Checker:

  • Overlap — two polygons that should be adjacent instead overlap over a portion of surface.
  • Gap — a gap remains between polygons that should continuously cover an area.
  • Sliver — a leftover polygon, thin and with no real geographic meaning, often the result of an overlay.
  • Duplicates — two features with identical geometry (applies to both polygons and lines).
  • Dangle — the end of a line that should connect to another line stays isolated.

3. Shared map and table

3.1 First run (once only)

Defines all the detection functions — no Python/R map here, that’s already ready above and knows nothing about these calculations. Run it once before the examples below.

3.2 Reusable cell pair

The code below changes with every “Load this example” button further down.

4. Five errors, five examples

4.1 Overlap

Two polygons that should be adjacent instead overlap over a portion of surface — the example already loaded by default in the cell pair above.

4.2 Gap

Two aligned polygons that should cover a single continuous area instead leave a gap between them — detected by comparing the union of the polygons with the convex hull containing both.

Note

The gap is shown as its own feature (a synthetic geometry, not one of yours), colored like the other error rows. The check only looks at polygon pairs that are close and not already overlapping, using the convex hull of the single pair — not of the whole dataset, which would flag as “gap” even the simple fact that two distant or overlapping shapes aren’t aligned with each other. For a real dataset with a known study area, that area is still the more correct reference, not a convex hull.

4.3 Sliver

An extremely thin polygon — 0.1° wide, 0.001° tall — a typical leftover from an overlay between nearly coincident boundaries. Detected with the Polsby-Popper compactness index (4π·area/perimeter²): below 0.15 is considered a sliver.

4.4 Duplicates

Two features with identical geometry — happens often during merges or repeated imports. The check applies the same way to polygons and lines (topological equality), shown here on polygons.

4.5 Dangle

A line network where three segments form a closed loop — each end touches exactly the next segment’s end, no dangle — and a fourth stays isolated, with both ends “dangling”. Notice how the layer on the map switches from fill to line: the code itself decides that, based on the geometry type you feed it.

5. Apply to your file

The cells below try to read /uploaded.geojson, then an uploaded shapefile (/uploaded.shp), then a zipped shapefile (or, without an upload, use the overlap example as test data), detect the geometry type and automatically apply only the relevant checks — same detect_and_check() function as every example above, no duplicated logic.

6. Knowing what’s broken is already a result

A report that says “23 overlaps, 8 gaps, 4 slivers” isn’t half a tool: it’s a legitimate, complete quality-assurance step in its own right. Fixing these errors almost always requires a human decision — which polygon to move, who to assign a gap to, whether a 2 m² sliver is noise or a real island. A future article may cover repair strategies; this one deliberately stops before that, where geometry alone can no longer answer the question.