Short answer

A consultant-grade QGIS workflow is built so the next version of the same map is cheap and the handover is painless. Concretely: a fixed folder structure, working data consolidated into a GeoPackage, an intentional project CRS, named processing outputs (not temporary scratch layers), reusable print layout templates (.qpt), atlas generation for multi-sheet appendices, and a packaged project with relative paths, embedded styles, and a short README. That structure is what separates a deliverable a reviewer can audit from a project that only opens on the laptop that made it.

Project structure: decide it before importing anything

QGIS will happily let a project sprawl across a download folder, a desktop, and three shapefiles with the same name. Impose a layout first:

project-name/
  01_raw/         # untouched source data, never edited
  02_processed/   # working.gpkg (all derived layers)
  03_project/     # project.qgz, layout templates, qml styles
  04_outputs/     # exported PDFs, PNGs, deliverable GeoPackages
  README.md       # CRS, sources + dates, processing notes

Keep 01_raw read-only in spirit — it is the chain of custody for your data. Everything you create lands in 02_processed. This separation is what lets a reviewer answer "where did this layer come from?" months later.

Use a GeoPackage, not loose shapefiles

Store all working vector layers in one GeoPackage (working.gpkg). It is a single SQLite file that holds many layers, long field names, proper data types, and — importantly — layer styles in its gpkg_contents/style tables. Shapefiles truncate field names to 10 characters, split each layer across .shp/.shx/.dbf/.prj siblings that get separated, and cannot carry styling. To bring a layer in:

Right-click layer → Export → Save Features As → GeoPackage, choosing the existing working.gpkg and a clean layer name. Or on the command line:

ogr2ogr -f GPKG working.gpkg source.shp -nln boreholes -t_srs EPSG:27700

Set the CRS deliberately

Set the project CRS to your analysis grid (a UTM zone or national grid such as British National Grid, EPSG:27700) under Project → Properties → CRS, and disable surprises by knowing that QGIS reprojects layers to the project CRS on the fly for display only — the stored data keeps its own CRS. For any measurement or processing, reproject the data itself with Vector → Reproject Layer (or ogr2ogr -t_srs) so areas, lengths, and buffers are computed in metres. Confirm each layer's CRS in the Layers panel; a layer with a guessed or missing CRS will sit in the wrong place and quietly poison a buffer or area field.

Make the analysis reproducible

  • Name your outputs. When you run a Processing algorithm (Buffer, Clip, Difference), save the result into working.gpkg with a real name instead of leaving it as a Temporary (memory) layer. Temporary layers vanish on close and cannot be audited.
  • Keep the Processing history. Processing → History logs the exact algorithm and parameters for every run. For anything you will repeat, drag those steps into the Graphical Modeler to build a model (.model3) you can re-run on next year's data.
  • Save styles. Export each layer's symbology as a .qml into 03_project, or save it into the GeoPackage (Properties → Style → Save Style → in database). This is what makes the look reproducible.

Print layouts: build a template, reuse it everywhere

Hand-building each figure guarantees inconsistency. Instead, build one layout template:

  1. Project → New Print Layout. Set the page size and orientation (e.g. A4 landscape).
  2. Add the map frame, then a title block, scale bar, north arrow, legend, and a credits/metadata text box (data source, CRS, date, drawn-by). Use the Item Properties to fix the map scale (e.g. 1:10,000) so every figure shares a scale.
  3. Layout → Save as Templatereport_figure.qpt in 03_project.

Every subsequent figure starts from New Layout from Template, so the title block, fonts, scale bar style, and margins are identical across the whole report. Use dynamic text ([% @project_title %], [% format_date(now(),'yyyy-MM-dd') %]) in the title block so dates and project names fill themselves in.

Atlas: one layout, many pages

When the report needs a map per site, per borehole cluster, or per map sheet, do not copy the layout N times. Use the Atlas:

  1. In the layout, open the Atlas panel and set a coverage layer (e.g. a grid of map sheets, or the sites layer).
  2. Enable Controlled by atlas on the map frame and set it to follow each feature with a fixed scale or a margin around the feature.
  3. Drive titles and labels from feature attributes with expressions like 'Site ' || "site_id".
  4. Atlas → Export Atlas as PDF produces one page per feature — a clean, uniform appendix of dozens of maps generated in a single pass.

This is the single biggest time saver for multi-site geotechnical or environmental reports, and it removes the human inconsistency of hand-laying each sheet.

Export settings that survive printing

  • Export figures to PDF with vector content preserved (avoid rasterising unless you have blend modes that require it) so text stays sharp and selectable.
  • For raster-heavy figures (hillshade, imagery), set a sensible export DPI (300 for print) and export those frames as raster while keeping vectors crisp.
  • Embed or supply fonts; a layout using a font the client lacks reflows on their machine.

Package the project for handover

A deliverable must open on someone else's computer. Two reliable routes:

  • Save the project into a GeoPackage: Project → Save To → GeoPackage stores the project and its layers in one file.
  • Consolidate / package layers: use Processing → Package layers to copy all layers into a single GeoPackage, then save the .qgz with relative paths (Project → Properties → General → Save paths: Relative). Zip the whole project-name/ folder.

Include the README noting: project CRS, each source dataset and its acquisition date, the key processing steps (with the model file if you built one), and any fonts required. The test of a good package: a colleague unzips it on a clean machine, opens the .qgz, and every layer loads with correct styling and the layouts render. If anything shows a red "unavailable layer," the paths were absolute or a layer lived outside the package.

Validation before delivery

  • Topology and geometry: run Vector → Geometry Tools → Check Validity and the Topology Checker on edited layers; fix self-intersections and gaps before they show up in area calculations.
  • Attribute completeness: check for null keys, duplicate IDs, and unit consistency in computed fields.
  • CRS confirmation: verify each layer's CRS and that measured fields were computed in a projected grid.
  • Clean-machine open: actually reopen the packaged project from 04_outputs to prove the handover works.

Common pitfalls and why they happen

  • Temporary layers in the final map. They were never saved, so the project reopens with missing data. Save outputs to the GeoPackage.
  • Inconsistent figures. Each map was built by hand; small differences in scale bar, fonts, and margins accumulate. Use a .qpt template and the atlas.
  • "Layer unavailable" on the client's machine. Absolute paths or data left outside the project folder. Set relative paths and package layers.
  • Wrong areas/lengths in attribute tables. Fields computed while the data was in a geographic CRS. Reproject the data, not just the display, before calculating.
  • Reflowed or missing text in the PDF. A font the recipient lacks. Embed fonts or stick to common ones.

Bathyl perspective

We build QGIS projects as if a stranger will inherit them — because for a consultant deliverable, someone usually does. A fixed structure, GeoPackage-backed data, template-driven layouts, atlas-generated appendices, and a packaged, relative-path project mean the report can be reopened, re-run, and defended a year later. The discipline is in the structure, not the software.

Related reading

Sources