Supongo que ejecuta su contexto de renderización de mapas en una aplicación independiente. No estoy seguro de si usted quiere producir imágenes de alta resolución o establecer sólo el número de DPI.
Si quieres producir imágenes de alta resolución, puedes poner mapCanvas()mapSettings().setDevicePixelRatio(scaleFactor)
antes de llamar mapCanvas().saveAsImage('FILENAME.PNG')
. La función activa QgsMapSettings::updateDerived()
y calcula el mapUnitsPerPixel
y el nuevo número de DPI.
# line 170
// calculate the translation and scaling parameters
const double mapUnitsPerPixelY = mExtent.height() / myHeight;
const double mapUnitsPerPixelX = mExtent.width() / myWidth;
mMapUnitsPerPixel = mapUnitsPerPixelY > mapUnitsPerPixelX ? mapUnitsPerPixelY : mapUnitsPerPixelX;
...
# Line 192
...
// update the scale
mScaleCalculator.setDpi( mDpi * mDevicePixelRatio );
mScale = mScaleCalculator.calculate( mVisibleExtent, mSize.width() );
No he probado esto antes porque, personalmente, trato de evitar la representación en un contexto de imagen y utilizar un contexto de impresora pdf en su lugar. En el contexto de la impresora tienes todas las propiedades para renderizar tu mapa en una página bien definida. Puedes usar imagemagick
o ghostscript
para crear imágenes correctas en DPI y con antialiasing posteriormente.
Ejemplo de fragmento de código de uno de mis proyectos
#!/usr/bin/env python3
import sys
from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtXml import *
# ---------------------------------------------------
# Constants
# ---------------------------------------------------
SHP_DATA = 'ogr'
QGIS_PATH = '/usr'
PAGE_WIDTH = 300 # mm
PAGE_HEIGHT = 300 # mm
MAP_WIDTH = 130
MAP_HEIGHT = 130
MAP_LEFT = 25
MAP_TOP = 10
MAP_RIGHT = MAP_LEFT + MAP_WIDTH
MAP_BOTTOM = MAP_TOP + MAP_HEIGHT
GAP = 40
LEG_TOP = MAP_TOP
LEG_LEFT = MAP_RIGHT + GAP
# -----------------------------------------------------
# Keys for the map frame
# -----------------------------------------------------
# Label inside or outside of the map
GRID_ANNON_INMAP = 0
GRID_ANNON_OUTMAP = 1
GRID_ANNON_NONE = 2
# Keys for the grid annotation side
GRID_SIDE_RIGHT = 0
GRID_SIDE_LEFT = 1
GRID_SIDE_BOTTOM = 2
GRID_SIDE_TOP = 3
# Keys for the label direction
GRID_ANNON_DIR_0 = 0
GRID_ANNON_DIR_90 = 1
GRID_ANNON_DIR_180 = 2
GRID_ANNON_DIR_270 = 3
# Keys for the axis format
GRID_ANNON_FMT_DEC = 0 # Dezimalzahlen + N, E
GRID_ANNON_FMT_DM = 1 # D°M'N und D°M'E
GRID_ANNON_FMT_DMS = 2 # D°M'S"N und D°M'S"E
GRID_ANNON_FMT_DEC_NONSWE = 3 # Ohne Dezimalzahlen
GRID_ANNON_FMT_DM_NONSWE = 4 # D°M'
# Gridd type
GRID_FRAME_PLAIN = 0 # einfache Linie
GRID_FRAME_ZEBRA = 1 # Kästchen
# -----------------------------------------------------
# Settings for the map frame
# -----------------------------------------------------
# Schrittweite der Label 10km
GRID_FRAME_STEP_LABX = 1/3.0
GRID_FRAME_STEP_LABY = 1/6.0
# Fonts font for the map labels
GRID_FRAME_FONT = QFont('Arial',11,0)
# Precisiion of the labels
GRID_FRAME_PRECISION = 0
# Size of the map crosses 0 if you don't want
GRID_FRAME_CROSS_SIZE = 0
# Breite des Rahmens
GRID_FRAME_WIDTH = 1
# Colors for the frame
GRID_COLOR_LIGHT = QColor('#ffffff')
GRID_COLOR_DARK = QColor('#040404')
# ---------------------------------------------------
# Create a map
# ---------------------------------------------------
# @param page - Composer page
# @param upper - Upper border of the sheet in mm
# @param left - Left border of the sheet in mm
# @param lower - Lower border of the sheet in mm
# @param right - Right border of the sheet in mm
# @param extent - Extent of the map info world coordinates only
# @return Map with border config (..see also GRID_FRAME_*)
# ---------------------------------------------------
def createMap(page, upper, left, lower, right, extent):
# Karte bauen
print "Create ma sheet: (%d, %d) (%d, %d) [mm]" % (upper, left, lower, right)
print " Size UTM: (%2.0f,%2.0f) (%2.0f, %2.0f) [m]" \
% (extent.xMinimum(), extent.yMinimum(), \
extent.xMaximum(), extent.yMaximum())
cmap = QgsComposerMap(page, upper, left, lower, right)
# Kartenabdeckung eintragen
cmap.setNewExtent(extent)
# Create frame and cosses ----------------------
cmap.setGridStyle(GRID_FRAME_ZEBRA)
# Label font
cmap.setGridAnnotationFont(GRID_FRAME_FONT)
# Size of the crosses
cmap.setCrossLength(GRID_FRAME_CROSS_SIZE)
# Intervalabstand setzten
cmap.grid().setCrs(tk.epsgCrs(4326))
cmap.setGridIntervalX(GRID_FRAME_STEP_LABX)
cmap.setGridIntervalY(GRID_FRAME_STEP_LABY)
# Label format
cmap.setGridAnnotationFormat(GRID_ANNON_FMT_DM_NONSWE)
# Precision of the label format
cmap.setGridAnnotationPrecision(GRID_FRAME_PRECISION)
# Ausrichtung des Labels fuer die ensprechende Achse
cmap.setGridAnnotationDirection(GRID_ANNON_DIR_90,
GRID_SIDE_LEFT)
cmap.setGridAnnotationDirection(GRID_ANNON_DIR_90,
GRID_SIDE_RIGHT)
# Label per axis Labelposition
cmap.setGridAnnotationPosition(GRID_ANNON_OUTMAP,
GRID_SIDE_TOP)
cmap.setGridAnnotationPosition(GRID_ANNON_OUTMAP,
GRID_SIDE_RIGHT)
cmap.setGridAnnotationPosition(GRID_ANNON_OUTMAP,
GRID_SIDE_LEFT)
cmap.setGridAnnotationPosition(GRID_ANNON_OUTMAP,
GRID_SIDE_BOTTOM)
# Activate annotation
cmap.setShowGridAnnotation(1)
# Frame style -----------------------------
cmap.setGridFrameStyle(GRID_FRAME_ZEBRA)
# Frame width
cmap.setGridFrameWidth(GRID_FRAME_WIDTH)
# Frame color (hell & dunkel)
cmap.setGridFrameFillColor1(GRID_COLOR_LIGHT)
cmap.setGridFrameFillColor2(GRID_COLOR_DARK)
# Enable frame
cmap.setFrameEnabled(True)
return cmap
# ------------------------------------------------------
# Start application ...
# ------------------------------------------------------
application = QgsApplication([], True)
QgsApplication.setPrefixPath(QGIS_PATH, True)
QgsApplication.initQgis()
# ------------------------------------------------------
# Service function print a page into a pdf
# ------------------------------------------------------
def writePdfFullPage(page, width, height, fileName='out.pdf'):
print "Schreibe PDF: "+fileName
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(fileName)
printer.setPaperSize(QSizeF(width, height), QPrinter.Millimeter)
printer.setFullPage(True)
printer.setColorMode(QPrinter.Color)
printer.setResolution(page.printResolution())
pdfPainter = QPainter(printer)
paperRectMM = printer.pageRect(QPrinter.Millimeter)
paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
page.render(pdfPainter, paperRectPixel, paperRectMM)
pdfPainter.end()
# ------------------------------------------------------
# Calculate the map extent
# ------------------------------------------------------
def calcMapExt(lyr, offs=0.01):
result = lyr.extent()
print "Map extent:", result.xMinimum(), result.yMinimum(), result.xMaximum(), result.yMaximum()
result.setXMinimum(result.xMinimum()-offs)
result.setYMinimum(result.yMinimum()-offs)
result.setXMaximum(result.xMaximum()+offs)
result.setYMaximum(result.yMaximum()+offs)
print "Map extent:", result.xMinimum(), result.yMinimum(), result.xMaximum(), result.yMaximum()
return result;
# ---------------------------------------------------
# Open a vector layer
# ---------------------------------------------------
def openVectorLayer(uri, name):
print "Open layer: %s " % (name)
layer = QgsVectorLayer(uri.uri(),name,SHP_DATA)
if not layer.isValid():
msg = "Cannot open layer '"+name+"'\n"
msg += "File: "+uri+"\n"
msg += "Filter: "+where+"\n"
raise ValueError(msg)
print " %d Object(s)" % (layer.featureCount())
return layer
# ----------------------------------------------
# Create the legend
# ----------------------------------------------
def createLegend (page, layers, x, y, title, \
titleFont = QFont('Arial',12,2), \
groupFont = QFont('Arial',11,1),
itemFont = QFont('Arial',10,1) ):
print "Create legend: %s %d %d " % (title, x, y)
cleg = QgsComposerLegend(page)
cleg.setTitle(title)
cleg.rstyle(QgsComposerLegendStyle.Symbol).setMargin(QgsComposerLegendStyle.Top, 1)
cleg.setStyleFont(QgsComposerLegendStyle.Title, titleFont)
cleg.setStyleFont(QgsComposerLegendStyle.Subgroup, groupFont)
cleg.setStyleFont(QgsComposerLegendStyle.SymbolLabel, itemFont)
cleg.setX(x)
cleg.setY(y)
cleg.model().setLayerSet(layers)
return cleg
# ---------------------------------------------------
# Read some layers and add a renderer
# ---------------------------------------------------
# Region of interest
lyrRoi = openVectorLayer('roi.shp','roi')
symRoi = QgsSimpleLineSymbolLayerV2()
symRoi.setColor(QColor('#dd4433'))
symRoi.setWidth(1)
lyrRoi.rendererV2().symbols()[0].changeSymbolLayer(0, symRoi)
# Special protection area
lyrSPA = openVectorLayer('SPA.shp','SPA')
symSPAa = QgsSimpleLineSymbolLayerV2()
colSPA = QColor('#aaaaaa');
symSPAa.setColor(colSPA)
symSPAa.setWidth(0.5)
symSPAb = QgsLinePatternFillSymbolLayer()
symSPAb.setColor(colSPA)
symSPAb.setLineWidth(0.5)
symSPAb.setLineAngle(45.0)
symSPAb.setDistance(1.5);
lyrSPA.rendererV2().symbols()[0].changeSymbolLayer(0, symSPAa)
lyrSPA.rendererV2().symbols()[0].appendSymbolLayer(symSPAb)
# -------------------------------------------
# Open the render engine
# -------------------------------------------
renderer = QgsMapRenderer()
mapCrs = tk.epsgCrs(3395)
renderer.setDestinationCrs(mapCrs)
renderer.setProjectionsEnabled(True)
mapset = []
mapset.append(lyrRoi.id())
mapset.append(lyrContent.id())
...
renderer.setLayerSet(mapset)
mapExtent = calcMapExt(lyrRoi);
mapTrfm = QgsCoordinateTransform(lyrRoi.crs(), mapCrs)
mapExtent = mapTrfm.transform(mapExtent)
renderer.setExtent(mapExtent)
# --------------------------------------------------
# Declare a page and store the PDF
# --------------------------------------------------
page = QgsComposition(renderer)
page.setPlotStyle(QgsComposition.Print)
# Create the map...
cmap= createMap(page, MAP_LEFT, MAP_TOP, \
MAP_RIGHT, MAP_BOTTOM, mapExtent)
...
# Legende
cleg = createLegend( page, mapset, \
LEG_LEFT, LEG_TOP, \
'')
writePdfFullPage(page,PAGE_WIDTH, PAGE_HEIGHT, \
fileName='example.pdf')
print "OK."
QgsApplication.exitQgis()
# EOF