Representación del Mapa e Impresión

Generalmente hay dos maneras de importar datos para renderizar en el mapa; hacerlo rápido usando QgsMapRenderer o producir una salida afinada componiendo el mapa con QgsComposition clase y amigos.

Representación Simple

Hacer algunas capas usando QgsMapRenderer — crea un destino en el dispositivo de pintura (QImage, QPainter etc.), establecer conjunto de capas, extensión, salida y renderizar.

# create image
img = QImage(QSize(800, 600), QImage.Format_ARGB32_Premultiplied)

# set image's background color
color = QColor(255, 255, 255)
img.fill(color.rgb())

# create painter
p = QPainter()
p.begin(img)
p.setRenderHint(QPainter.Antialiasing)

render = QgsMapRenderer()

# set layer set
lst = [layer.id()]  # add ID of every layer
render.setLayerSet(lst)

# set extent
rect = QgsRectangle(render.fullExtent())
rect.scale(1.1)
render.setExtent(rect)

# set output size
render.setOutputSize(img.size(), img.logicalDpiX())

# do the rendering
render.render(p)

p.end()

# save image
img.save("render.png","png")

Representando capas con diferente SRC

Si tiene más de una capa y ellas tienen diferente SRC, el sencillo ejemplo de arriba probablemente no funcionará: para obtener los valores correctos en los cálculos de dimensiones, tiene que fijar explicitamente el SRC de destino y activar reproyección al vuelo como en el ejemplo de abajo (solo la parte de configuración de representación se indica)

...
# set layer set
layers = QgsMapLayerRegistry.instance().mapLayers()
lst = layers.keys()
render.setLayerSet(lst)

# Set destination CRS to match the CRS of the first layer
render.setDestinationCrs(layers.values()[0].crs())
# Enable OTF reprojection
render.setProjectionsEnabled(True)
...

Producción usando el Diseñador de impresión

El Diseñador de Mapas es una herramienta muy útil si desea hacer diseños más sofisticados que la representación simple mostrada arriba. Usando el diseñador es posible crear diseños complejos de mapa incluyendo vistas de mapas, etiquetas, leyendas, tablas y otros elementos que usalmente están presentes en mapas impresos. Los diseños pueden exportarse a PDF, imágenes ráster o directamente impresos en una impresora.

El diseñador consiste de un grupo de clases. Todos ellos pertenecen a la biblioteca central. La aplicación QGIS tiene un GUI conveniente para colocar elementos, a pesar de que no esta disponible en la biblioteca GUI. Si no esta familiarizado con Qt Graphics View framework, se le recomienda que revise la documentación ahora, porque el diseñador esta basada en ella. También revise Documentación de Python de la implementación de QGraphicView.

El compositior central de clase es: QgsComposition which is derived from QGraphicsScene. Vamos a crear uno

mapRenderer = iface.mapCanvas().mapRenderer()
c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)

Anote que la composición toma una instancia de:class:QgsMapRenderer. El el código esperamos que se corra dentro de la aplicación de QGIS y así crear los mapas dentro del cambas. La composición utiliza varios parámetros dentro del creador de mapas, mas importante las capas de mapa y el tamaño se pone por defecto. Cuanto se utiliza el compositor como aplicación independiente se puede crear su propio renderizador como se demuestra en la selección arriba y pasar al compositor.

Es posible agregar carios elementos (mapa, etiquetas, ...) a la composicion – estos elemenos tienen que descender de QgsComposerItem class.. Actualmente el apoyo a estos itemes son:

  • mapa — este elemento dice a las bibliotecas dónde ponen el propio mapa. Aquí creamos un mapa y estiramos sobre el tamaño de papel

    x, y = 0, 0
    w, h = c.paperWidth(), c.paperHeight()
    composerMap = QgsComposerMap(c, x ,y, w, h)
    c.addItem(composerMap)
    
  • etiqueta — permite mostrar etiquetas. Es posible modificar su letra, color, alineación y margen.

    composerLabel = QgsComposerLabel(c)
    composerLabel.setText("Hello world")
    composerLabel.adjustSizeToText()
    c.addItem(composerLabel)
    
  • leyenda

    legend = QgsComposerLegend(c)
    legend.model().setLayerSet(mapRenderer.layerSet())
    c.addItem(legend)
    
  • barra de escala

    item = QgsComposerScaleBar(c)
    item.setStyle('Numeric') # optionally modify the style
    item.setComposerMap(composerMap)
    item.applyDefaultSize()
    c.addItem(item)
    
  • flecha

  • imagen

  • basic shape

  • nodes based shape

    polygon = QPolygonF()
    polygon.append(QPointF(0.0, 0.0))
    polygon.append(QPointF(100.0, 0.0))
    polygon.append(QPointF(200.0, 100.0))
    polygon.append(QPointF(100.0, 200.0))
    
    composerPolygon = QgsComposerPolygon(polygon, c)
    c.addItem(composerPolygon)
    
    props = {}
    props["color"] = "green"
    props["style"] = "solid"
    props["style_border"] = "solid"
    props["color_border"] = "black"
    props["width_border"] = "10.0"
    props["joinstyle"] = "miter"
    
    style = QgsFillSymbolV2.createSimple(props)
    composerPolygon.setPolygonStyleSymbol(style)
    
  • tabla

Por defecto el los ítemes del compositor nuevo no tienen posición (esquina superior izquierda de la pagina) ademas de un tamaño de cero. La posición y el tamaño siempre se miden en milímetros.

# set label 1cm from the top and 2cm from the left of the page
composerLabel.setItemPosition(20, 10)
# set both label's position and size (width 10cm, height 3cm)
composerLabel.setItemPosition(20, 10, 100, 30)

Un marco es dibujado alrededor de cada elemento por defecto. Cómo quitar el marco

composerLabel.setFrame(False)

Además de crear a mano los elementos del diseñador, QGIS soporta las plantillas de composición que escencialmente son diseños con todos sus elementos guardados en un archivo .qpt (con formato XML). Por desgracia esta funcionalidad no está disponible todavía en la API.

Una vez que la composición está lista (los elemntos del compositor han sido añadidos al diseño), podemos proceder a producir una salida ráster y/o vectorial.

La configuración por defecto para el dseño son: tamaño de página A4 con una resolución de 300 DPI. Se puede cambiar de ser necesario. El tamaño de papel está especificado en milímetros.

c.setPaperSize(width, height)
c.setPrintResolution(dpi)

Exportar como imagen ráster

El siguiente fragmento de código muestra cómo exportar una composición a una imagen ráster

dpi = c.printResolution()
dpmm = dpi / 25.4
width = int(dpmm * c.paperWidth())
height = int(dpmm * c.paperHeight())

# create output image and initialize it
image = QImage(QSize(width, height), QImage.Format_ARGB32)
image.setDotsPerMeterX(dpmm * 1000)
image.setDotsPerMeterY(dpmm * 1000)
image.fill(0)

# render the composition
imagePainter = QPainter(image)
c.renderPage( imagePainter, 0 )
imagePainter.end()

image.save("out.png", "png")

Exportar como PDF

El siguiente fragmento de código exporta una composición a un archivo PDF

printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName("out.pdf")
printer.setPaperSize(QSizeF(c.paperWidth(), c.paperHeight()), QPrinter.Millimeter)
printer.setFullPage(True)
printer.setColorMode(QPrinter.Color)
printer.setResolution(c.printResolution())

pdfPainter = QPainter(printer)
paperRectMM = printer.pageRect(QPrinter.Millimeter)
paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
c.render(pdfPainter, paperRectPixel, paperRectMM)
pdfPainter.end()