Short answer

For geological mapping the best default format is GeoPackage (.gpkg): a single OGC-standard SQLite file that holds many vector layers, optional rasters, full-length field names, real data types, NULLs, and styling — so the entire geological data model travels in one container. The shapefile should be avoided for primary geological data because its format limits (10-character field names, 254-character text, no real NULLs, ~2 GB cap, multi-file fragility) quietly mutilate rich attributes. Use GeoJSON only for small web extracts, and graduate to PostGIS when the dataset becomes shared, multi-user infrastructure. The deciding question is never "which opens?" but "which preserves the meaning?"

A geological map is a relational data model, not just geometry

A real geological map carries far more than polygons. It typically includes:

  • Unit polygons with stratigraphic name, code, age, lithology, and a long free-text description
  • Contacts and faults as lines, each with a type (depositional, intrusive, fault) and a positional/existence confidence (observed, inferred, concealed)
  • Structural measurements as points: strike/dip, plunge, foliation, with azimuth precision
  • Sample and observation points with lab results, photos, and field notes
  • Lineage: source map, scale, surveyor, date

The format must keep these layers together and keep each attribute's type and full text intact. The moment a format truncates a field name or clips a description, you have lost geological meaning, not just bytes.

Why the shapefile fails geology specifically

The shapefile is robust and universal, which is why it persists, but its 1990s constraints collide directly with geological attributes:

  • 10-character field names. stratigraphic_unit becomes stratigrap; fault_confidence becomes fault_conf. Two long names can collide and silently merge.
  • 254-character text limit. Unit descriptions and field notes are routinely longer; they get truncated on write, often without warning.
  • No native NULL. "Not measured" and "measured as zero" become indistinguishable — fatal for dip values or sample concentrations.
  • No real date-time type. Survey dates degrade.
  • ~2 GB per component cap and multi-file structure (.shp, .shx, .dbf, .prj, .cpg). Lose the .prj and the CRS is gone; lose the .dbf and the attributes are gone. Email "the shapefile" and you often send one file of seven.
  • One geometry type per file, so units, contacts, and structure points cannot share a container.
  • Encoding ambiguity in the .dbf mangles accented place names and special characters unless the .cpg is correct.

None of these matter for a quick scratch layer. All of them matter for a geological map you intend to keep.

GeoPackage: the right default

GeoPackage (OGC standard, a defined SQLite schema) fixes essentially every shapefile limitation:

  • One file, multiple vector layers and rasters in the same container
  • Full-length field names, proper SQL types (TEXT, INTEGER, REAL, DATETIME, BLOB), and true NULLs
  • UTF-8 text, no encoding guessing
  • Spatial indexing (R-tree) for fast queries
  • Stores its own CRS and can carry styling (QGIS layer styles)
  • Effectively unlimited size for practical work (SQLite scales to terabytes)

Build one cleanly with ogr2ogr, appending each layer:

ogr2ogr -f GPKG geology.gpkg units.shp -nln units
ogr2ogr -f GPKG -update geology.gpkg faults.shp -nln faults
ogr2ogr -f GPKG -update geology.gpkg structure.shp -nln structure_points

The result is a single geology.gpkg a colleague can open in QGIS or ArcGIS Pro with every layer, type, and long field name intact.

PostGIS: when the map becomes infrastructure

A GeoPackage is a file — superb for capture, single-author work, and delivery, but SQLite allows only one writer at a time. When several geologists edit concurrently, when you need enforced topology (no gaps/overlaps between units, contacts that snap to unit boundaries), versioned history, or serving to apps and APIs, move the system of record to PostGIS:

ogr2ogr -f PostgreSQL "PG:dbname=geo user=mapper" geology.gpkg \
  -lco GEOMETRY_NAME=geom -lco FID=id -nlt PROMOTE_TO_MULTI

In PostGIS you get GIST spatial indexes, topology validation (ST_IsValid, the topology extension), constraints, transactional multi-user editing, and the ability to publish via OGC API - Features or vector tiles. PostGIS is not a file format; it is where the data lives and is operated.

GeoJSON: web extracts only

GeoJSON is human-readable and ideal for web maps and small interchange, but RFC 7946 fixes the CRS to WGS84 longitude/latitude. That means projected analytical coordinates must be transformed on export, precision is text-based, and large datasets become bloated and slow. Use it for a published subset (e.g., the unit polygons feeding a web viewer), never as the master store for a projected geological dataset. For larger web payloads, prefer vector tiles; for analytical columnar storage, GeoParquet.

A practical decision frame

  • Field capture and single-author project: GeoPackage.
  • Delivering a complete dataset to a client: GeoPackage (plus a metadata/README record).
  • Shared, multi-user, edited or served continuously: PostGIS.
  • Small web-facing extract: GeoJSON or vector tiles.
  • Heavy analytical/columnar workloads: GeoParquet.
  • Scratch/throwaway layer or required by a legacy recipient: shapefile, knowingly accepting the limits.

Common pitfalls and why they happen

  • Sending only the .shp. The format is multi-file; the others get left behind. GeoPackage's single file removes the failure mode.
  • Trusting that export "worked" because a file appeared. Truncation and NULL loss are silent on shapefile write. Always re-open and inspect field names and a few long descriptions.
  • Using GeoJSON for the master dataset. The WGS84 mandate forces lossy reprojection of projected data and bloats large files.
  • Choosing PostGIS for a one-person field project. Operational overhead with no benefit; a GeoPackage is simpler and portable.
  • Letting symbology stand in for the data model. Map colors are display, not attributes. Encode unit, age, and confidence as fields, not just as a style.

QA and validation

  • After any conversion, run ogrinfo -al -so out.gpkg and confirm field names, types, and feature counts match the source.
  • Spot-check long text fields and accented characters for truncation and encoding damage.
  • Validate geometries (ST_IsValid in PostGIS, "Fix Geometries"/"Check Validity" in QGIS) — conversions can introduce self-intersections.
  • Confirm the CRS is present and correct in the output, not just assumed.
  • Ship a metadata record (source, scale, CRS, schema, date, license) alongside the data.

Bathyl perspective

We pick the format by what must survive the handoff, not by what opens fastest today. For geological mapping that almost always means a GeoPackage for portable, complete delivery and PostGIS once the dataset becomes something a team edits and serves. A dataset is finished not when it renders on your screen but when another geologist can open it years later and still read every unit description, confidence flag, and source note.

Related reading

Sources