QGIS mapping
River Architect’s map production runs on QGIS print layouts. The former ArcGIS Pro
implementation (arcpy.mp, .aprx projects, .lyrx layer files, PDFDocumentCreate page
stitching) has been removed; riverarchitect.mapping no longer imports arcpy.
Requirements
QGIS 3.x with its Python bindings. Verified against QGIS 3.44.7.
sudo apt install qgis python3-qgis # Debian, Ubuntu
They cannot be installed from PyPI, and a distribution installs them for the system
interpreter rather than for the ra-env analysis environment. River Architect looks for them
itself and adds them to the end of its module search path, so the Maps tab normally works
from ra-env too - see Finding QGIS in Maps for the search order, the
RIVERARCHITECT_QGIS_PATH and QGIS_PREFIX_PATH overrides, and why PYTHONPATH is the
wrong tool for this.
Check what the running interpreter sees:
python -c "from riverarchitect.mapping import qgis_status; print(qgis_status()[1])"
mapping sets QT_QPA_PLATFORM=offscreen itself, so it renders headless without a display.
What replaced what
ArcGIS Pro |
QGIS |
|---|---|
|
|
|
|
|
|
layouts stored inside the template |
|
|
QGIS Atlas + |
|
one multi-page PDF in a single call |
|
|
|
a clean layer stack per map sheet |
The page series is the substantive change. The old code zoomed the map frame to each centre point, exported a temporary PDF, appended it to a growing document and deleted the temp file. QGIS models this natively: a coverage layer holds one rectangle per page, the map frame is marked atlas-driven, and the exporter writes every page in one operation.
Layout
The layout is composed programmatically in Mapper.build_layout(), so no binary template is
needed. It contains a map frame, a legend filtered to the visible layers, a scale bar, a north
arrow, a title, and a footer carrying condition and page N of M.
Default page size is ANSI E landscape (1117.6 x 863.6 mm), reproducing the former arcpy
format. Override per instance with mapper.page_size = (width_mm, height_mm).
If templates/river_template.qgz exists it is used as the starting project instead,
so a hand-built QGIS template can carry corporate styling, base layers or a custom layout.
Symbology
Styles are read from the packaged symbology directory (riverarchitect/templates/symbology/<name>.qml). Mapper.choose_ref_layer()
maps a raster name onto a style name (lf_sym, ds_sym, …).
The published lifespan symbology was migrated from the original .lyrx with
riverarchitect.tools.lyrx2qml. .lyrx is JSON (Esri CIM), so class breaks, colours and labels convert
exactly:
python -m riverarchitect.tools.lyrx2qml LifespanRasterSymbology.lyrx
That produced LifespanRasterSymbology.qml (also copied to lf_sym.qml), preserving all nine
lifespan classes and their red-to-green ramp, with NoData transparent. The converter handles
CIMRasterClassifyColorizer (to singlebandpseudocolor, DISCRETE) and
CIMRasterUniqueValueColorizer (to paletted), and converts RGB, HSV, CMYK and gray CIM
colours.
When no .qml matches, the layer keeps QGIS defaults and a warning is logged; maps are still
produced, just unstyled.
API
Unchanged, so existing callers work as they are:
mapper = cMp.Mapper(condition, "lf") # or "ds", "mlf", "mt"
mapper.prepare_layout(True, map_items=[...]) # True -> export immediately
mapper.make_pdf_maps("lf_grains", extent="raster")
if not mapper.error:
...
extent accepts "raster" (use the mapped raster’s extent), "MAXOF", or
[xmin, ymin, xmax, ymax]. For a multi-page series, set mapper.xy_center_points to a list of
[x, y] page centres together with mapper.dx / mapper.dy, exactly as before.
The Mapping tab of the graphical interface drives the same API.
Verification
Exercised end to end against sample-data/01_Conditions/2100_sample on Linux
with no Esri software present:
single-raster map: 1-page PDF, 3168 x 2448 pt (ANSI E landscape), 192 dpi
three-window reach series: 3-page PDF from one atlas export
.qgzproject and per-layer.qmlwritten alongside the PDFsrendered pages checked visually: title, map, north arrow, legend with all nine lifespan classes, scale bar, no overlap; NoData transparent
Known gaps
Only
LifespanRasterSymbology.lyrxexisted to convert. Design-stage (ds_sym) and MaxLifespan styles fall back to QGIS defaults until.qmlfiles are supplied.config.pynow builds platform-neutral paths, but individual modules still concatenate hard-coded"\\"sub-paths, so the rest of River Architect remains Windows-only for now.cMappernormalises separators internally and runs on both.