[QGIS-Developer] Unable to export map with PyQGIS 3

Raymond Nijssen r.nijssen at terglobo.nl
Wed Oct 24 02:03:55 PDT 2018


There is the cookbook, but it is quite outdated since qgis3:

https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/index.html


There is the python api docummentation, I think you already found it:

https://qgis.org/pyqgis/master/index.html


There are many unit tests in python that can act like examples:

https://github.com/qgis/QGIS/tree/master/tests/src/python


Then there are many python plugins you can use as examples. Just find 
one that does something you need and look into the code.




On 24-10-18 10:21, Dimitris Kar wrote:
> Hey Raymond,
> 
> Thank you very much for your answer. It worked. Are you aware of any 
> resources, online trainings, books or anything else which focuses on the 
> pyqgis3? What would be your recommendation on this.
> 
> Cheers
> Dimitris
> 
> On Wed, Oct 24, 2018 at 10:09 AM Raymond Nijssen <r.nijssen at terglobo.nl 
> <mailto:r.nijssen at terglobo.nl>> wrote:
> 
>     Hi Dimitris,
> 
>     It is indeed hard to learn pyqgis 3 with outdated docs.
> 
>     The following code worked for me (suggested by Martin Dobias):
> 
>     settings = QgsMapSettings()
>     settings.setOutputSize(QSize(512,512))
>     settings.setExtent(layer.extent())
>     settings.setLayers([layer])
> 
>     job = QgsMapRendererSequentialJob(settings)
>     job.start()
>     job.waitForFinished()
>     img = job.renderedImage()
>     img.save("/tmp/rendered.png")
> 
>     When you call job.start(), it will start rendering in background and
>     immediately return. That's why you need to call job.waitForFinished()
>     to block your code until the final image is ready. This approach has a
>     downside that it blocks the main thread and therefore the GUI will be
>     blocked until rendering has finished. If you would like to avoid this
>     blocking, after job.start() you could have a slot that would listen to
>     finished() signal coming from "job" - and save the image there. This
>     approach makes the code a bit more complex, but the GUI does not get
>     blocked and you can even start multiple jobs at a time in parallel.
> 
>     Hope it helps you. Good luck learning pyqgis!
> 
>     Raymond
> 
> 
> 
>     On 24-10-18 09:47, Dimitris Kar wrote:
>      > 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][1].
>      >
>      > 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 <http://layer.id> <http://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?
>      >
>      >    [1]:
>      >
>     https://docs.qgis.org/testing/pdf/en/QGIS-testing-PyQGISDeveloperCookbook-en.pdf
>      >
>      > _______________________________________________
>      > QGIS-Developer mailing list
>      > QGIS-Developer at lists.osgeo.org
>     <mailto:QGIS-Developer at lists.osgeo.org>
>      > List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>      > Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>      >
> 
>     -- 
>     Terglobo
>     Fahrenheitstraat 1
>     5223 BJ 's-Hertogenbosch
>     The Netherlands
>     +31 (0) 6 25 31 49 83
>     _______________________________________________
>     QGIS-Developer mailing list
>     QGIS-Developer at lists.osgeo.org <mailto:QGIS-Developer at lists.osgeo.org>
>     List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
>     Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer
> 

-- 
Terglobo
Fahrenheitstraat 1
5223 BJ 's-Hertogenbosch
The Netherlands
+31 (0) 6 25 31 49 83


More information about the QGIS-Developer mailing list