11

I have a QGIS project which contains a composer. Of course if I go into the GUI I can export it as a pdf etc. For my make script though I want to have this done via a python script. From reading online here is my attempt:

#!/usr/bin/env python

import sys
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtCore import QFileInfo
from PyQt4.QtXml import QDomDocument
from qgis.core import *

qgs = QgsApplication(sys.argv, True) 
QgsApplication.setPrefixPath("/usr", True) 

qgs.initQgis()

def make_pdf():
  canvas = QgsMapCanvas()
  bridge = QgsLayerTreeMapCanvasBridge(
      QgsProject.instance().layerTreeRoot(), canvas)
  bridge.setCanvasLayers()
  QgsProject.instance().read(QFileInfo('../board.qgs'))

  composition = QgsComposition(canvas.mapSettings())
  map_item = composition.getComposerItemById('board36x48')
  map_item.setMapCanvas(canvas)
  map_item.zoomToExtent(canvas.extent())
  composition.refreshItems()
  composition.exportAsPDF('generated/board.pdf')
  QgsProject.instance().clear()

make_pdf()

This fails, specifically:

i:./assets/generate_board 
QGraphicsScene::addItem: item has already been added to this scene
Traceback (most recent call last):
  File "./assets/generate_board", line 30, in <module>
    make_pdf()
  File "./assets/generate_board", line 24, in make_pdf
    map_item.setMapCanvas(canvas)
AttributeError: 'NoneType' object has no attribute 'setMapCanvas'

I based this off of Save Print/Map QGIS composer view as PNG/PDF using Python (without changing anything in visible layout)? but modified it to simplify as much as possible. It seems like I broke something in the process... I don't have this template file. I simple have a board.qgs project file with a composer board36x48. Any ideas?

  • Try replacing qgs = QgsApplication(sys.argv, True) with app = QtGui.QApplication(sys.argv, True) and qgs.initQgis() with QgsApplication.initQgis()? – Joseph May 19 '17 at 09:43
  • You might find some useful piece of code here in the Maps_printer plugin : https://github.com/DelazJ/MapsPrinter/wiki . Look for def saveFile(self):, def printToRaster(self, cView, folder, name, ext):, def exportCompo(self, cView, folder, title, extension): – gisnside Sep 05 '17 at 13:21
  • did you get it work ? – Hugo Roussaffa Oct 25 '17 at 14:25

1 Answers1

1

You are trying to create the QgsComposerMap item from your complete composer name !

map_item = composition.getComposerItemById('board36x48')

use instead the ID of the map component in your composer (map; map0; map1...). You defined it when you create your composer.

According other piece of code are ok, you should get it work.

Hugo Roussaffa
  • 2,191
  • 15
  • 40