The short version
In GIS, a geologic map is not one layer but a small relational model: map units live as polygons, contacts and faults live as lines, and structural measurements — bedding, foliation, fault planes — live as oriented points. Each carries attributes that record not just geometry but description, age, kinematics, confidence, and source, and the layers are deliberately coupled so that a polygon boundary is a contact, not a coincidental near-overlap. The USGS GeMS schema is the most widely used target for this structure, and the rest of this article walks through how to model each element so the result can be queried, symbolized, and trusted.
Map units as polygons
A geologic unit becomes a polygon in a feature class conventionally named MapUnitPolys. The essential attribute is a short MapUnit code (for example Qa for Quaternary alluvium or Kc for a Cretaceous formation) that acts as a foreign key into a separate DescriptionOfMapUnits (DMU) table. That table — not the polygon — holds the full unit name, age, lithology, and the hierarchical ordering that drives the legend. Keeping description out of the geometry means you edit a unit's lithologic text once, in one row, instead of across hundreds of polygons.
Two attributes commonly surprise newcomers. IdentityConfidence records whether the unit assignment itself is certain or questionable, drawn from a controlled vocabulary. And the polygon's outline is not authoritative in isolation — it is expected to be coincident with the contact lines that bound it, which is where structure modeling becomes a topology problem (below).
Contacts and faults as lines
All the linework — depositional and intrusive contacts, and every kind of fault — goes into a single ContactsAndFaults line feature class, distinguished by attributes rather than separate layers. The key fields, following GeMS:
- Type — the line's geologic meaning (contact, normal fault, reverse/thrust fault, strike-slip fault), drawn from the Glossary table.
- IsConcealed — a Boolean for linework that runs beneath younger cover; it drives a dotted rendering.
- LocationConfidenceMeters — a real number giving the horizontal positional uncertainty (e.g. 25, 100, 250 m), which is what "approximate" actually means in quantitative terms.
- ExistenceConfidence and IdentityConfidence — controlled-vocabulary fields for whether the structure exists and what it is.
Symbology is then data-driven: solid lines for well-located certain contacts, dashed for approximate (high LocationConfidenceMeters), dotted for concealed, with fault decoration — teeth on the hanging wall of a thrust, ball-and-bar on the downthrown side of a normal fault, paired arrows for strike-slip — keyed to the Type and to a polarity/direction attribute. The line's digitizing direction matters here, because fault ornament sits on one side of the line.
Structural measurements as oriented points
Bedding attitudes, foliations, joints, fold axes, and fault-plane measurements are stored as points in OrientationPoints, and the geometry is only half the data — the orientation is the point. Two numeric fields carry it:
- Azimuth — the compass direction, recorded consistently (GeMS uses dip-direction azimuth, 0–360°; many field datasets use right-hand-rule strike — pick one convention and record which).
- Inclination — the dip angle from horizontal, 0–90°.
A Type field separates bedding from foliation from a fault plane, and an IsOverturned flag handles inverted bedding. The whole value of storing these as data is rotated symbology: in QGIS, set the point marker (a strike-and-dip tee, a foliation symbol, etc.) and bind its rotation to a field expression so the symbol points at the measured azimuth, then label it with the inclination. A thousand attitudes then render correctly and automatically, instead of being hand-rotated one at a time. To analyze them, export Azimuth/Inclination into a stereonet tool (mplstereonet in Python, or Stereonet) to test for fold geometry or fault populations.
Keeping geometry consistent: topology
The recurring failure is treating the three layers as independent drawings. They are not — a MapUnitPolys boundary should be exactly a ContactsAndFaults line. The robust approach is to digitize the contacts and faults first, close them into a planar graph, and build polygons from that linework (QGIS Polygonize, or a geodatabase topology that derives areas) so the boundary and the contact are the same geometry by construction. Then validate:
- Polygons: must not have gaps, must not overlap (QGIS Topology Checker, or an ArcGIS geodatabase topology).
- Lines: must not have dangles — every fault terminates against another line, not in mid-polygon — and snapping tolerance set before editing (e.g. 5 m in a UTM project) so nodes coincide.
A short worked workflow
For a new mapping project in QGIS targeting GeMS:
- Create three layers in a GeoPackage in a projected CRS (e.g. EPSG:32612, UTM 12N):
ContactsAndFaults(line),MapUnitPolys(polygon),OrientationPoints(point). - Set snapping to vertex+segment at ~5 m before digitizing.
- Digitize contacts/faults; attribute Type, IsConcealed, LocationConfidenceMeters.
- Run Polygonize on the closed linework to generate polygons; attribute MapUnit on each.
- Join MapUnit to a DescriptionOfMapUnits table for names, ages, and legend order.
- Enter OrientationPoints with Azimuth/Inclination; bind marker rotation to Azimuth.
- Run Topology Checker (gaps/overlaps on polygons, dangles on lines) and resolve flags.
- Populate DataSources and link every feature's DataSourceID.
Common pitfalls and why they happen
- Mixing strike and dip-direction conventions in the same dataset, because field crews and the schema disagree. A point recorded as strike but symbolized as dip-direction will draw 90° off. Record the convention explicitly and convert once.
- Independent polygon and contact editing, which guarantees slivers and overlaps; the cause is digitizing the map as a picture rather than as a graph. Build polygons from linework instead.
- Confidence stored as prose in a comment field — uncqueryable and unsymbolizable. GeMS replaces it with numeric LocationConfidenceMeters and controlled-vocabulary fields for a reason.
- Shapefile storage truncating GeMS field names to 10 characters; keep the master in GeoPackage or a geodatabase.
Validation summary
You are done when: every polygon has a MapUnit that resolves in the DMU; every line has a Type, IsConcealed, and numeric LocationConfidenceMeters; every orientation point has numeric Azimuth and Inclination and a Type; topology returns zero gaps, overlaps, and dangles; symbology for units, faults, and attitudes is driven entirely by attributes; and DataSources is populated. At that point the map is a queryable structural dataset, not a drawing.
Bathyl perspective
We model geology as a relational structure from the first vertex, because the difference between a drawing and a dataset is whether someone else can ask it a question. Units, faults, and attitudes that share a clean topology and controlled attributes can be filtered, analyzed, and republished long after the original mapping campaign.
Related reading
- Geological Map QA Checklist
- GIS for Mineral Exploration
- Remote Sensing for Geological Mapping
- Geological visualization