I am trying to learn and work with PyQGIS 3.

It is a very challenging task cause documentation is really limited and out of date.

What I am trying to do is to:

  1. create a project
  2. add a layer
  3. save the project
  4. export it as a png

I have done the first 3 steps (see code below).

import sys
import qgis
from qgis.core import QgsVectorLayer
from qgis.core import QgsApplication
from qgis.core import QgsProject
from qgis.core import QgsMapRendererJob, QgsMapSettings
from qgis.gui import QgsMapCanvas
from PyQt5.QtGui import QImage, QColor, QPainter
from PyQt5.QtCore import QSize

# PYTHON APPLICATIONS

# prefix path: the location where qgis is installed in the system
# the easiest way to find the prefix path to run the following commaand from the python console of qgis: QgsApplication.prefixPath()

#1. CREATE THE APPLICATION
QgsApplication.setPrefixPath('/usr', True)
# second parameter into false disables the gui
qgs = QgsApplication([], False)
#load providers
qgs.initQgis()

#2. CREATE THE PROJECT
# create project
project_name = '/home/dkar/workspaces/qgis/data/test_project_2.qgz'
project = QgsProject.instance()
new_project = project.write(project_name)

#3. READ/OPEN THE PROJECT
# modify the project e.g. adding more layers and save it.
new_project = project.read(project.fileName())


#4. ADD A VECTORLAYER
# add a layer in the QgsProviderRegistry
layer=QgsVectorLayer("/home/dkar/workspaces/qgis/data/pakistan_1.shp", "pakistan", "ogr")

if not layer.isValid():
    print("Layer failed")

#5. ADD LAYER TO THE REGISTRY
project.addMapLayer(layer, True)
project.write('/home/dkar/workspaces/qgis/data/test_project_2.qgz')

#6. SAVE THE PROJECT
all_layers = QgsProject.instance().mapLayers()


img = QImage(QSize (800, 600), QImage.Format_ARGB32_Premultiplied)
# set image's backgroud color
color = QColor(255, 255, 255)
img.fill(color.rgb())

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

# THIS IS WHERE THE ISSUE APPEARS
# THIS IS WHERE THE ISSUE APPEARS
render = QgsMapRendererJob() # THIS IS WHERE THE ISSUE APPEARS

# set layer set (am I using here the prohect?)
lst = [layer.id()] # cause "layer" is the name of the variable
render.setLayerSet(lst)

# to remove the provider and layer registries from memory
qgs.exitQgis()

But when I try to do the last part, following the instructions from the existing documentation. I get issues because the specific function (QgsMapRenderer) doesn't exist anymore in QGIS 3.

I am not sure how to solve the issue.

I see in the documentation that this function:

QgsMapRenderer

was replaced by

QgsMapRendererJob

But then when I try to import and use it in the code as:

from qgis.core import QgsMapRendererJob, QgsMapSettings
    render = QgsMapRendererJob()

I get an error message:

TypeError: qgis._core.QgsMapRendererJob represents a C++ abstract class and cannot be instantiated

Any idea how to proceed with this?

Well, the error message is correct. According to the QGIS API documentation, QgsMapRendererJob is an abstract class. So you cannot directly use it. Instead you need to use one of the subclasses:

QgsMapRendererSequentialJob - renders map in one background thread to an image
QgsMapRendererParallelJob - renders map in multiple background threads to an image
QgsMapRendererCustomPainterJob - renders map with given QPainter in one background thread

https://www.qgis.org/api/classQgsMapRendererJob.html#details

  • Thanks @Thomas Would you recommend and book or online source with examples of pyqgis3? It is quite hard to start since the official cookbook is not fully updated. – user1919 Oct 24 at 7:42

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.