Short answer

Turning a static geological map into a spatial dataset means moving from a picture of geology to a queryable model of it: georeference the scan to real-world coordinates, then capture the geology as structured vector layers — units as polygons, contacts and faults as lines, structural measurements as points — each attributed with a consistent schema and validated for clean topology. The destination is not "a coloured image in GIS" but data you can intersect with a DEM, query by lithology or age, restyle, and reuse.

The work splits into four stages: georeferencing, digitizing, attribution against a schema (GeMS is the de facto standard), and quality control of topology and attributes. Each stage has failure modes that quietly degrade the result, so the discipline is in doing them deliberately rather than tracing colours.

Stage 1: Georeferencing

A scan is just pixels until it is tied to a coordinate system. Scan the sheet at high resolution (300-600 dpi for a printed map) so linework is crisp, then georeference in QGIS (Georeferencer) or ArcGIS Pro (Georeference ribbon).

Use the right control points. The strongest are the printed graticule intersections or grid tick marks, because their true coordinates are known exactly from the map collar — not roads or rivers, whose modern positions may differ from the historic survey. Enter each tick's coordinates in the map's original projection and datum (read the collar: e.g. a sheet may be on a national grid with an older datum), not whatever your project happens to use.

Pick at least 6-10 points spread across the whole sheet, including the corners, so error is not concentrated. Choose a transformation matched to the distortion: a first-order (affine) polynomial for a flat, well-printed sheet; thin-plate spline only if the paper is genuinely warped, since high-order transforms can introduce wild distortion between control points. Watch the RMS residual — keep it within the map's own positional tolerance (for a 1:50,000 sheet, ~25 m at the standard 0.5 mm drafting accuracy). A low RMS with poorly distributed points is a false comfort; distribution matters as much as the number.

# After collecting GCPs, warp the scan to a projected CRS
gdalwarp -r bilinear -t_srs EPSG:32633 -tps map_gcps.tif map_georef.tif

Stage 2: Digitizing

Digitize contacts and faults as a connected line network first, then build polygons from those lines. This is the single most important structural decision, because it guarantees that adjacent units share exactly the same boundary instead of two slightly different traces. In QGIS, enable snapping (vertex and segment, with a tolerance of a few pixels) and topological editing so shared vertices move together. Capture:

  • MapUnitPolys — one polygon per mapped exposure of a unit.
  • ContactsAndFaults — every contact, fault, and concealed/inferred boundary as a line, with a type and a confidence/existence attribute.
  • OrientationPoints — strike/dip, foliation, lineation as points with azimuth and inclination values.

Digitize at a zoom consistent with the source scale. Tracing a 1:100,000 sheet at street-level zoom invents detail the source never had; match your capture density to the line weight on the original.

Stage 3: Attribution with a schema

Colours are not a data model. Replace them with attributes. The USGS GeMS (Geologic Map Schema) is the established framework and worth adopting even outside the USGS context because it forces the right structure:

  • DescriptionOfMapUnits (DMU): the authoritative list of units with MapUnit key, name, age, lithology, and description. MapUnitPolys carry only the MapUnit key and join to the DMU, so a unit is described once.
  • Glossary and DataSources tables: every term and every source (the map citation, a cross-cutting study) is recorded and referenced by ID, so provenance travels with the geometry.
  • Existence/Identity confidence fields on contacts and faults capture whether a boundary is observed, approximate, inferred, or concealed — the difference between a measured contact and an educated guess.

Implement it in a GeoPackage or PostGIS so the related tables, keys, and domains live together:

ogr2ogr -f GPKG geology.gpkg map_unit_polys.shp -nln MapUnitPolys

The payoff: you can now query "all polygons of Jurassic age within 500 m of a fault" instead of eyeballing colours.

Stage 4: Topology and QA

Run explicit topology validation before anything is published:

  • No gaps, no overlaps between MapUnitPolys (every point on the map belongs to exactly one unit). In QGIS use the Topology Checker with "must not have gaps" and "must not overlap" rules; in PostGIS, ST_IsValid, and ST_Overlaps/ST_Union checks across the coverage.
  • No dangles on the contact network except where a contact legitimately terminates (e.g. fault tip).
  • Polygon-line coincidence: unit boundaries must follow the digitized contacts, not float beside them.
  • Attribute completeness: every MapUnit key in the polygons exists in the DMU; no null lithology where it is required.
-- Find invalid geometries
SELECT fid, ST_IsValidReason(geom) FROM "MapUnitPolys" WHERE NOT ST_IsValid(geom);

Fix invalid geometries with ST_MakeValid (PostGIS) or the Fix geometries tool (QGIS) and re-run the checks.

Worked sequence

  1. Scan at 400 dpi; record the collar projection, datum, and scale.
  2. Georeference to a projected CRS using graticule ticks; confirm RMS within tolerance; warp with gdalwarp -tps.
  3. Digitize the contact/fault network with snapping and topological editing on.
  4. Build MapUnitPolys from the contact network; attribute each with its MapUnit key.
  5. Create the DMU, DataSources, and Glossary tables; join and populate confidence fields.
  6. Run Topology Checker and ST_IsValid across the coverage; fix and re-check.
  7. Store in GeoPackage/PostGIS; export display copies (GeoJSON/TopoJSON or vector tiles) as needed, keeping the source provenance attached.

Common pitfalls and why they happen

  • Georeferencing to roads and rivers. Their modern positions differ from the historic survey, so the whole sheet shears; use graticule ticks with known coordinates.
  • Wrong datum. Entering control coordinates in the project CRS instead of the map's original datum introduces a systematic shift of tens to hundreds of metres.
  • Digitizing polygons independently. Tracing each unit separately produces mismatched shared borders — slivers and gaps; build polygons from one shared contact network instead.
  • Treating colour as the attribute. A colour cannot encode age, confidence, or source; without a schema the dataset is just a recoloured image.
  • Over-digitizing fine detail. Capturing at a zoom far beyond the source scale fabricates precision the original map never claimed.
  • Dropping confidence. Collapsing inferred and observed contacts into one class erases the most geologically important distinction on the map.

Validation and QA

Beyond topology, overlay the digitized layers back on the georeferenced scan at full resolution and confirm contacts trace the original ink. Spot-check structural readings against the printed symbols (a transposed strike/dip is common). Verify the DMU join is complete and that ages and lithologies are internally consistent. Where a neighbouring sheet exists, check the units match across the shared edge. Keep the georeferenced raster and the GCP list archived so the digitization can be audited or re-warped later.

Bathyl perspective

We digitize geology as a structured model, not a tracing exercise: a shared contact network, a GeMS-style schema, and confidence fields that preserve what the original cartographer actually knew versus inferred. That is what lets a century-old sheet be intersected with a modern DEM, queried by age and lithology, and republished as an interactive layer without losing its scientific intent.

Related reading

Sources