Skip to content

Instantly share code, notes, and snippets.

@jtrive84
Created April 23, 2024 16:08
Show Gist options
  • Save jtrive84/fac4d0f5c6bbb171f1a920717801a6c1 to your computer and use it in GitHub Desktop.
Save jtrive84/fac4d0f5c6bbb171f1a920717801a6c1 to your computer and use it in GitHub Desktop.
Create static map images via QGIS.
"""
Script to use for creating static map images in QGIS.
A dictionary of bounding boxes is required, with key representing the
linkId and value a list of four coordinates representing the region that
encloses the link. The dictionary for Charlotte has been included in the
repository.
Author: James D. Triveri
Date: 2024-02
"""
from math import radians, sin, asin, cos, sqrt, pi, log, tan
import os
from pathlib import Path
import pickle
import sys
import time
import numpy as np
import qgis.utils
from qgis.core import (
QgsGeometry, QgsMapSettings, QgsPrintLayout, QgsMapSettings,
QgsMapRendererParallelJob, QgsLayoutItemLabel, QgsLayoutItemLegend,
QgsLayoutItemMap, QgsLayoutItemPolygon, QgsLayoutItemScaleBar,
QgsLayoutExporter, QgsLayoutItem, QgsLayoutPoint, QgsLayoutSize,
QgsUnitTypes, QgsProject, QgsFillSymbol
)
from qgis.PyQt.QtGui import QPolygonF, QColor
from qgis.PyQt.QtCore import QPointF, QRectF, QSize
from qgis.PyQt.QtCore import QEventLoop
# Configuration ----------------------------------------------------------------
img_basis = 256
tiles = "osm"
m = .0000005
bboxes_path = "charlotte-linkid-bboxes.pkl"
output_dirname = f"charlotte-linkid-images/{tiles}-{img_basis}"
# Declarations -----------------------------------------------------------------
def convert(lat: float, lon: float):
"""
Convert lat-lon pair into EPSG:3857 representation.
"""
x = (lon * 20037508.34 / 180.)
y = ((log(tan(((90. + lat) * pi) / 360)) / (pi / 180)) * 20037508.34) / 180
return((y, x))
# ------------------------------------------------------------------------------
# Create output directory.
output_dir = Path(output_dirname)
if not output_dir.exists():
os.makedirs(output_dir)
# Load linkId bounding coordinates.
with open(bboxes_path, "rb") as fpkl:
dparts = pickle.load(fpkl)
# Bind reference to layers.
layers = iface.mapCanvas().layers()
nbr_links = len(dparts)
for indx, link_id in enumerate(dparts, start=1):
dbbox = dparts[link_id]
img_path = output_dir.joinpath(f"{link_id}.png")
if not img_path.exists():
lat0, lon0, lat1, lon1 = dbbox["lat0"], dbbox["lon0"], dbbox["lat1"], dbbox["lon1"]
lat0 = (1 - m) * lat0
lon0 = (1 + m) * lon0
lat1 = (1 + m) * lat1
lon1 = (1 - m) * lon1
img_h = img_basis
img_w = img_basis
ymin, xmin = convert(lat0, lon0)
ymax, xmax = convert(lat1, lon1)
bbox = QgsRectangle(xmin, ymin, xmax, ymax)
settings = QgsMapSettings()
settings.setOutputSize(QSize(img_w, img_h))
settings.setLayers(layers)
settings.setBackgroundColor(QColor(255, 255, 255))
settings.setOutputSize(QSize(img_w, img_h))
settings.setExtent(bbox)
settings.visibleExtent()
render = QgsMapRendererParallelJob(settings)
def _finished():
img = render.renderedImage()
img.save(str(img_path), "png")
render.finished.connect(_finished)
render.start()
loop = QEventLoop()
render.finished.connect(loop.quit)
loop.exec_()
print(f"[{indx}-of-{nbr_links}] Created {img_path}.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment