Randarea hărților și imprimarea

Există, în general, două abordări atunci când datele de intrare ar trebui să fie randate într-o hartă: fie o modalitate rapidă, folosind QgsMapRenderer, fie producerea unei ieșiri mai rafinate, prin compunerea hărții cu ajutorul clasei QgsComposition.

Randarea simplă

Randați mai multe straturi, folosind QgsMapRenderer — creați destinația dispozitivului de colorare (QImage, QPainter etc), setați stratul, limitele sale, dimensiunea de ieșire și efectuați randarea

# 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.getLayerID()]  # add ID of every layer
render.setLayerSet(lst)

# set extent
rect = QgsRect(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")

Randarea straturilor cu diferite CRS-uri

Dacă aveți mai mult de un singur strat, iar dacă acestea au CRS-uri diferite, exemplul simplu de mai sus nu va funcționa: pentru a obține valorile corecte din extinderile calculate, va trebui să setați în mod explicit CRS-ul destinație și să activați reproiectarea OTF ca în exemplul de mai jos (numai partea de configurare a randării se raportează)

...
# 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)
...

Generarea folosind Compozitorul de hărți

Compozitorul de hărți reprezintă un instrument foarte util în cazul în care doriți să elaborați ceva mai sofisticat decât simpla randare de mai sus. Utilizănd Constructorului este posibilă crearea unor machete complexe de hărți, conținând extrase de hartă, etichete, legendă, tabele și alte elemente care sunt de obicei prezente pe hărțile tipărite. Machetele pot fi apoi exportate în format PDF, ca imagini raster sau pot fi transmise direct la o imprimantă.

The composer consists of a bunch of classes. They all belong to the core library. QGIS application has a convenient GUI for placement of the elements, though it is not available in the GUI library. If you are not familiar with Qt Graphics View framework, then you are encouraged to check the documentation now, because the composer is based on it.

Clasa centrală a Compozitorului este QgsComposition, care este derivată din QGraphicsScene. Să creăm una

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

Rețineți: compoziția este o instanță a QgsMapRenderer. În cod, ne așteptăm să rulăm în interiorul aplicației QGIS și, astfel, să folosim render-ul suportului de hartă. Compoziția utilizează diverși parametri ai render-ului, cei mai importanți fiind setul implicit de straturi de hartă și granițele curente. Atunci când utilizați compozitorul într-o aplicație independentă, vă puteți crea propria dvs. instanță de render de hărți, în același mod cum s-a arătat în secțiunea de mai sus, și să-l transmiteți compoziției.

Este posibilă adăugarea diferitelor elemente (hartă, etichete, ...) în compoziție — aceste elemente trebuie să fie descendenți ai clasei QgsComposerItem. Elementele suportate în prezent sunt:

  • harta — acest element indică bibliotecilor unde să pună harta. Vom crea o hartă și o vom întinde peste întreaga dimensiune a hârtiei

    x, y = 0, 0
    w, h = c.paperWidth(), c.paperHeight()
    composerMap = QgsComposerMap(c, x ,y, w, h)
    c.addItem(composerMap)
    
  • eticheta — permite afișarea textelor. Este posibilă modificarea fontului, culoarea, alinierea și marginea

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

    legend = QgsComposerLegend(c)
    legend.model().setLayerSet(mapRenderer.layerSet())
    c.addItem(legend)
    
  • scara grafică

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

  • imagine

  • formă

  • tabelă

În mod implicit, elementele compozitorului nou creat au poziția zero (colțul din stânga sus a paginii) și dimensiunea zero. Poziția și dimensiunea sunt măsurate întotdeauna în milimetri

# 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)

În jurul fiecărui element este desenat, în mod implicit, un cadru. Astfel se elimină cadrul

composerLabel.setFrame(False)

Pe lângă crearea manuală a elementele compozitorului, QGIS are suport pentru șabloane, care sunt, în esență, compoziții cu toate elementele lor salvate într-un fișier .qpt (cu sintaxă XML). Din păcate, această funcționalitate nu este încă disponibilă în API.

Odată ce compoziția este gata (elementele compozitorului au fost create și adăugate la compoziție), putem trece la producerea unui raster și/sau a unei ieșiri vectoriale.

Setările de ieșire implicite pentru compoziție sunt pentru o pagină A4 și o rezoluție de 300 DPI. Le puteți modifica, atunci când este necesar. Dimensiunea hârtiei este specificată în milimetri

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

Ieșire ca imagine raster

Următorul fragment de cod arată cum se randează o compoziție într-o imagine raster

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)
sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight())
targetArea = QRectF(0, 0, width, height)
c.render(imagePainter, targetArea, sourceArea)
imagePainter.end()

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

Ieșire în format PDF

Următorul fragment de cod randează o compoziție într-un fișier 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()