Most municipalities and utility contractors have their underground infrastructure documented somewhere — in CAD as-built drawings, in PDFs, in someone’s head. Getting it into a proper GIS layer is the difference between calling 811 and hoping versus knowing where a 6-inch water main runs before you start excavating.

QGIS handles this well. It’s free, it imports CAD files, and it exports GeoPDF files that field crews can use offline on a tablet. The setup isn’t complicated, but there are decisions you need to make before you start drawing — particularly around file format, CRS, and attribute schema — that determine whether the data is useful for the next 20 years or becomes another file nobody trusts.

This guide walks through the full setup from a blank project.

Use GeoPackage, Not Shapefiles

The first decision: file format. The default instinct is to create separate shapefiles for each utility, but shapefiles carry a set of limitations that actively make utility data worse:

  • Field names truncated at 10 characters — diameter_in becomes diameter_i, install_year becomes install_yea
  • One file per geometry type per utility type = 12+ files for a simple water/sewer/gas/electric map
  • No ability to store related tables in the same file
  • 2 GB size limit on both geometry and attributes

Use GeoPackage (.gpkg) instead. One file holds all layers, field names up to 63 characters, related tables, styles, and spatial indexes. It’s SQLite-backed, so any SQL-capable tool can query it directly.

Create your project GeoPackage at: Layer → Create Layer → New GeoPackage Layer

Name it something like utilities_[municipality]_[year].gpkg and create all your utility layers inside it. When everything is in one file, you can attach it to an email, copy it to a field tablet, and back it up reliably.

Layer Setup: Geometry Types and Attribute Schema

Different utility assets need different geometry types.

Line layers for pipe runs and conduit:

  • Water mains
  • Sanitary sewer mains (gravity and force)
  • Gas mains
  • Electric conduit
  • Storm drains
  • Telecom conduit

Point layers for discrete assets:

  • Fire hydrants
  • Gate valves, air release valves
  • Manholes, cleanouts
  • Service connections
  • Meter pits, catch basins
  • Utility poles

Polygon layers for areas:

  • Pump station parcels
  • Easements and ROW corridors
FieldTypeNotes
asset_idText (30)Unique identifier, e.g. WM-2023-047
utility_typeText (20)Water / Sewer / Gas / Electric
diameter_inRealNominal pipe diameter in inches
materialText (30)PVC, HDPE, Ductile Iron, Cast Iron, Clay, Concrete, Unknown
depth_ftRealDepth to top of pipe from finished grade
install_yearInteger4-digit year
conditionText (20)Excellent / Good / Fair / Poor / Failed
pressure_zoneText (20)Water mains only
flow_dirText (15)Gravity / Force / Unknown — sewer mains
data_sourceText (50)As-Built / GPS Survey / CAD Import / Estimate
quality_levelText (5)QL-A through QL-D per ASCE 38-22
ownerText (60)Municipality or utility company
last_inspectedDateISO date
notesText (254)Free text

The quality_level field deserves explanation. ASCE 38-22 defines four data quality levels for subsurface utility engineering: QL-D (desktop study from existing records), QL-C (field observation of surface evidence), QL-B (pipe detected by electronic locating), QL-A (physically exposed or potholed). Recording this field prevents future engineering teams from treating an estimated location the same as a surveyed one — a liability distinction that matters when someone hits a pipe.

Attribute schema for point layers

FieldTypeNotes
asset_idText (30)Unique identifier
feature_typeText (30)Fire Hydrant / Gate Valve / Manhole / etc.
rim_elev_ftRealManholes — top of frame elevation
invert_elev_ftRealManholes — pipe invert elevation
install_yearInteger
conditionText (20)
data_sourceText (50)
quality_levelText (5)
ownerText (60)
last_inspectedDate
notesText (254)

Enable Z dimension on line layers when you have invert elevations — Layer → Edit → right-click → Layer Properties → Source → Geometry → Has Z. Storing 3D pipe geometry lets you compute slope, detect grade problems, and model drainage in hydraulic analysis tools later.

Set the Project CRS Before Drawing Anything

This is the step people skip and regret. If you draw utility lines in the wrong CRS and discover it six months later, the fix is painful.

Do not use WGS84 (EPSG:4326) for utility mapping. WGS84 is a geographic CRS — its units are decimal degrees. At 40°N latitude, one degree of longitude is about 83 km. Buffers, distance measurements, and any spatial analysis in WGS84 return results in degrees, not feet or meters, and those numbers are unusable.

Use your local State Plane Coordinate System (NAD83). State Plane zones use feet or meters, and they’re what your county or city GIS department almost certainly requires for submitted data. Find your zone:

RegionEPSG Code
New England (MA, CT, RI)26986 (meters) or 6492 (feet)
New York City / Long Island2263 (feet)
New Jersey3424 (feet)
Pennsylvania East2271 (feet)
Virginia North3968 (feet)
Georgia East (Atlanta, Savannah)2239 (feet)
Florida East2236 (feet)
Illinois East (Chicago)3435 (feet)
Ohio North3734 (feet)
Texas Central2278 (feet)
California Zone 4 (LA)2229 (feet)
Washington State North (Seattle)2926 (feet)

For projects that span multiple state plane zones, use UTM NAD83: EPSG:26917 (Zone 17N, eastern US), EPSG:26914 (Zone 14N, central US), EPSG:26910 (Zone 10N, Pacific coast). UTM uses meters.

Check your municipality’s website — many publish a required EPSG code for submitted GIS data. If they do, use exactly that.

Set project CRS: Project → Properties → CRS tab → type the EPSG code → OK.

Critical gotcha: QGIS “on-the-fly” reprojection makes layers display aligned in the map canvas even when stored in different CRS. It does not transform the stored coordinates. If you import a layer in a different CRS and start editing, you’re editing in the wrong coordinate system. Always use Vector → Data Management Tools → Reproject Layer to actually transform data into your project CRS before editing it.

Add a Basemap

You can’t map utilities accurately without seeing where the streets are.

Method 1 — XYZ Tiles (no plugin needed, built into QGIS 3.x):

Browser panel (left sidebar) → XYZ Tiles → right-click → New Connection

NameURLMax Zoom
ESRI World Imageryhttps://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}22
Google Satellitehttps://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}22
Google Hybridhttps://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}22
OpenStreetMaphttps://tile.openstreetmap.org/{z}/{x}/{y}.png19

Note the ESRI URL uses {z}/{y}/{x} order while Google uses {x}/{y}/{z}. Getting the order wrong produces a blank or scrambled tile layer.

Method 2 — QuickMapServices plugin (easiest for Bing):

Plugins → Manage and Install Plugins → search “NextGIS QuickMapServices” → Install

After installing: Web → QuickMapServices → Settings → More Services → “Get Contributed Pack” → this unlocks 650+ services including Bing Aerial, Bing Hybrid, and country-specific imagery providers.

Add the basemap tile layer to your project and drag it to the bottom of the Layers panel so utility lines render on top.

Color Coding: Use the APWA Standard

QGIS doesn’t enforce utility colors — you set them manually. Use the APWA (American Public Works Association) Uniform Color Code. This is the same color standard used by 811 locating crews, so your GIS maps match what field crews paint on the ground:

UtilityColorHex
Potable waterBlue#0070FF
Sanitary sewer / storm drainGreen#00A651
Natural gas / petroleum / steamYellow#FFD700
Electric power / conduit / lightingRed#FF0000
Communications / telecom / fiberOrange#FF6600
Reclaimed / recycled water / irrigationPurple#9400D3

Set per layer: right-click layer → Properties → Symbology → Simple Line → Color. Use 0.66mm line width for mains, 0.26mm for service lines. For point layers (manholes, valves, hydrants), use Simple Marker with the matching color and a distinct shape per feature type: circle for manholes, triangle for hydrants, diamond for valves.

Save and reuse symbology: right-click layer → Export → Save as QGIS Layer Style File (.qml). Apply to future layers: right-click → Properties → Symbology → Style → Load Style.

Set Up Attribute Forms for Field Entry

Raw QGIS attribute forms are clunky for field data entry — you get a text box for every field, which produces typos and inconsistent values. Fix this before you give anyone a tablet.

Right-click layer → Properties → Attributes Form tab. Change from “Autogenerate” to “Drag and Drop Designer” at the top dropdown.

Key widget types to configure:

  • material field → Widget Type: Value Map → add entries: PVC / Ductile Iron / Cast Iron / HDPE / Clay / Concrete / Unknown. Creates a dropdown; prevents "d.i.", "DI", "duct iron" in the same column.
  • condition field → Widget Type: Value Map → Excellent / Good / Fair / Poor / Failed
  • quality_level field → Widget Type: Value Map → QL-A / QL-B / QL-C / QL-D
  • install_year field → Widget Type: Range → Min: 1850, Max: 2030, Step: 1
  • depth_ft field → Widget Type: Range → Min: 0, Max: 50, Step: 0.1
  • last_inspected field → Widget Type: Date/Time → calendar popup
  • asset_id field → Widget Type: Unique Values → warns on duplicate
  • notes field → Widget Type: Text Edit → enable “Multiline”

Group fields into tabs using “Add a new tab” in the Drag and Drop Designer: “Asset Info”, “Physical Properties”, “Condition”, “Notes”. This keeps the form navigable on a 10-inch tablet.

Import Existing CAD As-Built Data

Most utility systems have some documentation in CAD drawings that predates any GIS effort. QGIS can import DXF files natively.

Project → Import/Export → Import Layers from DWG/DXF

  1. Browse to the DXF/DWG file
  2. Set CRS — this is the critical step. Ask the CAD drafter what coordinate system the drawing uses. Common options: State Plane NAD83, local project grid (arbitrary), or the drawing may not be georeferenced at all
  3. Import → QGIS shows all CAD layers → select only the ones you need
  4. Assign a group name → OK

Known QGIS DWG limitations: QGIS reads DWG up to the R2000/AutoCAD 2000 format (ACAD1015). Newer DWG files (2004 onward, ACAD1800–1812 formats) may not import correctly. Fix: open in Autodesk DWG TrueView (free) → Save As → DXF 2000 → reimport. Or use ODA File Converter (free command-line tool) for batch conversion.

The georeferencing problem: Most utility as-built drawings have no real-world coordinate system — the CAD origin is at (0,0) in an arbitrary local grid. When QGIS imports this, the layer lands somewhere near Null Island (0°N, 0°E in the Gulf of Guinea). You need to georeference it before it’s usable.

If the drawing contains any identifiable features — road intersections, property corners, building corners — that you can locate on your basemap:

  1. Install the AnotherDXFImporter plugin (Plugins → Manage and Install Plugins → search “AnotherDXF2Shape”)
  2. Identify 3–4 control points visible in both the CAD drawing and your basemap
  3. Record coordinates from both sources for each point (these are Ground Control Points)
  4. In AnotherDXFImporter: enable “Use Coordinate Transformation” → provide your GCP pairs → import
  5. After import: Reproject Layer to your project CRS

If the drawing has no identifiable features at all, you’ll need the original surveyor’s data or a field GPS survey to establish reference points.

For the common case of converting CAD files that do have a known coordinate system to GIS-friendly formats, the CAD-GIS format gap post covers the translation issues that persist even when CRS is known.

Create a Print Layout for Field Maps

The print layout engine produces field maps that field crews can mark up on paper or navigate on a tablet.

Project → New Print Layout → name it (e.g., “Field Map 11x17”)

Recommended paper size for field work: 11×17 (Tabloid) landscape. Fits in standard truck clipboards, provides enough area context. For tablet/iPad: 8.5×11 landscape.

Add elements using the Add Items menu or left toolbar:

1. Map frame: Add Map → draw a rectangle covering ~70% of the page → Item Properties → set scale manually (1:2400 = 1 inch per 200 feet, or 1:1200 for denser urban areas) → check “Lock layers” and “Lock layer styles” to prevent the print from changing when you edit the map.

2. Scale bar: Add Scale Bar → Item Properties → Style: “Line Ticks Down” → Units: Feet or Meters (match your project CRS) → Segments: 2 left + 4 right → Fixed width per segment: 100 ft.

3. North arrow: Add North Arrow → select SVG arrow style. If your map is rotated to align with the street grid, set Rotation: “Sync with map” so the arrow points to true north.

4. Legend: Add Legend → Item Properties → uncheck “Auto update” → manually remove basemap layer from legend → rename layers to human-readable names: “Water Mains 8″ DI” instead of the raw layer name.

5. Title block: Add text box with: project name, municipality, date, scale, CRS name. In the bottom margin.

Export as PDF: Layout → Export as PDF → check “Always export as vectors” (lines stay crisp at any zoom level in a PDF viewer) → check “Create geospatial PDF (GeoPDF)”.

GeoPDF for field tablets: GeoPDF embeds coordinate metadata so the PDF knows its real-world position. Open in Avenza Maps (free iOS/Android app) and field crews see their GPS location as a dot overlaid on the utility map. They can tap features to see attribute data. No internet required in the field.

Save the layout as a template for reuse across future projects: Layout → Save as Template → load later via Layout → Add Items from Template.

Atlas for block-by-block field books: Enable the Atlas panel → Coverage layer: a grid shapefile or polygon layer of your service area → each coverage polygon becomes one PDF page → Export Atlas as PDF → QGIS generates one PDF per block automatically. A 50-block service area becomes a 50-page PDF with each page showing the correct scale and coverage for that block.

Field Data Collection with QField

QField is the QGIS field collection app (free, from the QGIS organization). Your complete QGIS project — layers, symbology, attribute forms, value maps — transfers directly to a tablet with no reconfiguration.

  1. Copy your .qgs project file and the .gpkg data file to a tablet
  2. Open in QField — all symbology, dropdowns, and form tabs appear exactly as configured
  3. Field crew creates new features by tapping the map, fills the form using the value map dropdowns
  4. Copy the .gpkg back to the office machine, open in QGIS — all new features and edits appear

For teams with multiple field tablets, QField Sync (the QGIS QFieldCloud connector) handles merge conflicts. For simple single-crew deployments, the manual copy workflow above is sufficient and requires no cloud accounts.

Validating Your Data Before It Goes Anywhere

Before sending utility data to a municipal GIS, an engineer, or a contractor:

  1. Check for features with no CRS: Layer → Properties → Information — “Coordinate Reference System” must not be blank or “Invalid”
  2. Validate geometry: Vector → Geometry Tools → Check Validity — run on every layer, fix all invalid geometries before export
  3. Check for duplicate asset IDs: Layer → Open Attribute Table → Field Calculator → count(asset_id, asset_id) — any value > 1 is a duplicate
  4. Verify depth values are reasonable: filter depth_ft < 0 or depth_ft > 40 and review
  5. Check data source field completeness: any NULL values in data_source or quality_level reduce data trustworthiness for downstream use

The GIS file conversion silent failures post covers the validation checks that matter when the validated data is converted to another format for submission — particularly field truncation and CRS mismatch issues that appear only at export time.

Summary

Utility GIS setups fail when the file format, CRS, and attribute schema aren’t established before anyone starts drawing. Getting these right at the start takes two hours. Fixing them after six months of data collection takes weeks.

The decisions that matter most: GeoPackage over shapefiles, State Plane CRS matched to your municipality’s requirements, APWA color standards, and attribute forms with value maps before field collection begins. Everything else — basemaps, print layouts, field apps — builds cleanly on that foundation.