Skip to content

Instantly share code, notes, and snippets.

@tobwen
Last active September 18, 2024 23:47
Show Gist options
  • Save tobwen/d5cd21baf042def33566f0e715689f39 to your computer and use it in GitHub Desktop.
Save tobwen/d5cd21baf042def33566f0e715689f39 to your computer and use it in GitHub Desktop.
QGIS: MapExporter using QPainter()
from qgis.core import QgsProject, QgsMapSettings, QgsRectangle, QgsMapRendererCustomPainterJob
from qgis.PyQt.QtGui import QImage, QPainter
from PyQt5.QtCore import QSize
from pathlib import Path
import time
class MapExporter:
def __init__(self, canvas):
self.canvas = canvas
self.project = QgsProject.instance()
def calculate_size_from_extent(self, extent, scale, dpi):
width_meters = extent.width()
height_meters = extent.height()
width_pixels = int((width_meters * dpi) / (scale * 0.0254))
height_pixels = int((height_meters * dpi) / (scale * 0.0254))
return width_pixels, height_pixels
def export_map_to_image(self, output_path, extent, scale=2500, dpi=96, width_px=None, height_px=None):
if not width_px or not height_px:
width_px, height_px = self.calculate_size_from_extent(extent, scale, dpi)
map_settings = self.canvas.mapSettings()
map_settings.setExtent(extent)
map_settings.setOutputSize(QSize(width_px, height_px))
map_settings.setOutputDpi(dpi)
# Use the canvas's current layer set
map_settings.setLayers(self.canvas.layers())
image = QImage(width_px, height_px, QImage.Format_ARGB32_Premultiplied)
image.setDotsPerMeterX(int(dpi / 25.4 * 1000))
image.setDotsPerMeterY(int(dpi / 25.4 * 1000))
painter = QPainter(image)
job = QgsMapRendererCustomPainterJob(map_settings, painter)
job.start()
job.waitForFinished()
image.save(str(output_path), "png")
painter.end()
def export_layer_extent(self, output_path, layer_name):
layer = self.project.mapLayersByName(layer_name)[0]
extent = layer.extent()
self.export_map_to_image(output_path, extent)
# Usage example:
canvas = iface.mapCanvas()
exporter = MapExporter(canvas)
# Set filename with Unix timestamp
timestamp = int(time.time())
filename = f"export_{timestamp}.png"
output_path = Path(r'/tmp/') / filename
# Export current canvas extent
exporter.export_map_to_image(output_path, canvas.extent())
# Or export using layer extent
# exporter.export_layer_extent(output_path, "export area")
# Or export using custom extent
# custom_extent = QgsRectangle(243154.6823, 4681314.4688, 243624.3177, 4681714.5313)
# exporter.export_map_to_image(output_path, custom_extent)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment