|
|
|
"""export.py
|
|
|
|
|
|
|
|
Export layouts from QGIS project to pdf or jpg.
|
|
|
|
|
|
|
|
Each exported map will contain a different combination of EP/type, e.g.
|
|
|
|
0.05/'ZSA'
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
> export.bat
|
|
|
|
|
|
|
|
This script must be run with the version of python installed with QGIS, that
|
|
|
|
is why 'export.bat' is required.
|
|
|
|
|
|
|
|
D Howe
|
|
|
|
d.howe@wrl.unsw.edu.au
|
|
|
|
2022-05-17
|
|
|
|
"""
|
|
|
|
import re
|
|
|
|
import os
|
|
|
|
from qgis.core import (
|
|
|
|
QgsApplication,
|
|
|
|
QgsProject,
|
|
|
|
QgsLayoutExporter,
|
|
|
|
QgsLayoutItemLabel,
|
|
|
|
)
|
|
|
|
|
|
|
|
QGZ_PATH = 'roches.qgz'
|
|
|
|
OUTPUT_DIR = 'maps'
|
|
|
|
FORMAT = 'jpg'
|
|
|
|
|
|
|
|
# Initialise QGIS
|
|
|
|
qgs = QgsApplication([], False)
|
|
|
|
|
|
|
|
# Load project
|
|
|
|
project = QgsProject.instance()
|
|
|
|
project.read(QGZ_PATH)
|
|
|
|
|
|
|
|
|
|
|
|
def unique_attributes(layer):
|
|
|
|
"""Get unique values for year, EP, and profile"""
|
|
|
|
layer.setSubsetString('') # Remove filter
|
|
|
|
|
|
|
|
# Get all available values for encounter probability and profile type
|
|
|
|
eps = []
|
|
|
|
types = []
|
|
|
|
years = []
|
|
|
|
for f in layer.getFeatures():
|
|
|
|
eps.append(f.attribute('ep'))
|
|
|
|
types.append(f.attribute('type'))
|
|
|
|
years.append(f.attribute('year'))
|
|
|
|
|
|
|
|
# Keep unique values
|
|
|
|
eps = list(set(eps))
|
|
|
|
types = list(set(types))
|
|
|
|
years = list(set(years))
|
|
|
|
|
|
|
|
return eps, types, years
|
|
|
|
|
|
|
|
|
|
|
|
# Get layers with hazard lines (assuming there is a year in the layer name)
|
|
|
|
map_layers = project.mapLayers().items()
|
|
|
|
layers = [v for k, v in map_layers if re.search(r'\d{4}', v.name())]
|
|
|
|
|
|
|
|
# Get all EP values and profile types from first hazard line layer
|
|
|
|
eps, types, years = unique_attributes(layers[0])
|
|
|
|
|
|
|
|
# BUG: repeat first file because of QGIS's incorrect legend placement
|
|
|
|
years = [years[0]] + years
|
|
|
|
|
|
|
|
# Get layouts
|
|
|
|
layouts = project.layoutManager().layouts()
|
|
|
|
|
|
|
|
# Create outout directory
|
|
|
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
|
|
|
|
|
|
|
for layout in layouts:
|
|
|
|
name = layout.name()
|
|
|
|
|
|
|
|
# Set up plot settings
|
|
|
|
if FORMAT == 'pdf':
|
|
|
|
settings = QgsLayoutExporter.PdfExportSettings()
|
|
|
|
# settings.dpi = -1 # Native resolution
|
|
|
|
exporter = QgsLayoutExporter(layout).exportToPdf
|
|
|
|
elif FORMAT == 'jpg':
|
|
|
|
settings = QgsLayoutExporter.ImageExportSettings()
|
|
|
|
exporter = QgsLayoutExporter(layout).exportToImage
|
|
|
|
else:
|
|
|
|
raise ValueError("'FORMAT' must be 'jpg' or 'pdf'")
|
|
|
|
|
|
|
|
for t in types:
|
|
|
|
for e in eps:
|
|
|
|
for layer in layers:
|
|
|
|
year = re.search(r'\d{4}', layer.name()).group()
|
|
|
|
substring = f"ep='{e}' and type='{t}' and year={year}"
|
|
|
|
layer.setSubsetString(substring)
|
|
|
|
|
|
|
|
# Update label
|
|
|
|
label = f'Type: {t}\nEP: {e}'
|
|
|
|
for item in layout.items():
|
|
|
|
if isinstance(item, QgsLayoutItemLabel):
|
|
|
|
item.setText(label)
|
|
|
|
|
|
|
|
map_path = os.path.join(OUTPUT_DIR, f'{name}-{t}-EP={e}.{FORMAT}')
|
|
|
|
print(f'Exporting {os.path.basename(map_path)}...')
|
|
|
|
|
|
|
|
res = exporter(map_path, settings)
|
|
|
|
if res != 0:
|
|
|
|
msg = 'Export failed. Does output folder exist?'
|
|
|
|
raise ValueError(msg)
|