7

I'm looking out for a way to batch export to PDF or image many composers spread in many QGS projects, the same way the plugin Map Printer does, but on a large number of projects at the same time. There's no modification needed, i just need to batch export them all.

The manual solution we have right now is to open each project and launch Map printer plugin within each, but it's too long.

A similar question would be for example Arcgis batch export from mxd to PDF but within QGIS.

****THE WORKING ANSWER FROM @Germán Carrillo (below) ****

You can as well follow the instructions mentioned in his answer and/or go to his Github space : https://github.com/gacarrillor/QGIS-Resources.git

In the processing panel of QGIS, go to the Script Area, click on Tools, then double-click on "Create new script". Paste this code into the resulting windows. you can change the first two lines to fit your need or naming preferences :

##Document_tools=group
##Batch_Export_QGS_folder = name

##Projects_folder=folder
##Output_folder=folder
##Extension=selection PDF format (*.pdf *.PDF);JPG format (*.jpg *.JPG);JPEG format (*.jpeg *.JPEG);TIF format (*.tif *.TIF);TIFF format (*.tiff *.TIFF);PNG format (*.png *.PNG);BMP format (*.bmp *.BMP);ICO format (*.ico *.ICO);PPM format (*.ppm *.PPM));XBM format (*.xbm *.XBM);XPM format (*.xpm *.XPM)
##nomodeler

import os.path
import glob 
import qgis
from qgis.core import QgsProject
from PyQt4.QtCore import QFileInfo
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException

if not Projects_folder or not Output_folder:
    raise GeoAlgorithmExecutionException("Please specify both, projects folder and output folder.")

# Settings
projectPaths = glob.glob( os.path.join( Projects_folder, '*.qgs' ) )
formats=['.pdf','.jpg','.jpeg','.tif','.tiff','.png','.bmp','.ico','.ppm','.xbm','.xpm']
count=0

if not 'MapsPrinter' in qgis.utils.plugins:
    raise GeoAlgorithmExecutionException("The 'Maps Printer' plugin  is required!")

mp = qgis.utils.plugins['MapsPrinter']
project = QgsProject.instance()
qgis.utils.iface.mapCanvas().setRenderFlag( False )
extension = formats[Extension]

# Do the work!
for projectPath in projectPaths:
    qgis.utils.iface.newProject() # Needed to reset composer manager
    project.read( QFileInfo( projectPath ) )
    progress.setInfo( projectPath + " project read!" )
    progress.setPercentage( count * 100 / len( projectPaths ) ) 
    count+=1

    for composer in qgis.utils.iface.activeComposers():
        progress.setInfo( "    Composer found:  " + composer.composerWindow().windowTitle() )
        title = composer.composerWindow().windowTitle()
        title = project.fileInfo().baseName() + '_' + title
        mp.exportCompo( composer, Output_folder, title, extension )
        progress.setInfo( "        Composer exported!" )

qgis.utils.iface.mapCanvas().setRenderFlag( True )
gisnside
  • 7,818
  • 2
  • 29
  • 73
  • Seems the author of Map Printer has been asked for this specific improvement : "Add print all composers in all projects in directory" -> https://github.com/DelazJ/MapsPrinter/issues/1, but it was never developped, it seems. – gisnside Aug 17 '16 at 14:48
  • I found related old unanswered questions here : http://gis.stackexchange.com/questions/141927/qgis-atlas-generation-batch-process-for-many-atlasesand here : http://gis.stackexchange.com/questions/98158/qgis-launch-atlas-composer-generation-from-command-line – gisnside Aug 22 '16 at 09:03

1 Answers1

7

First try.

Thanks to PyQGIS, we can call the Maps Printer plugin's functions to achieve what you want! So, having such plugin installed, adjust your own settings in Your settings section of the following code snippet. Open a new QGIS project and run the code in the QGIS Python console.

from PyQt4.QtCore import QFileInfo

# Your settings
projectPaths = ['/path/to/project1.qgs','/path/to/project2.qgs']
folder = '/path/to/export_folder/'
extension = '.png' # Any extension supported by the plugin

# Some useful object instances that we need
mp = qgis.utils.plugins['MapsPrinter']
project = QgsProject.instance()

# Do the work!
for projectPath in projectPaths:
    iface.newProject() # Needed to reset composer manager
    project.read( QFileInfo( projectPath ) )
    for composer in iface.activeComposers():
        title = composer.composerWindow().windowTitle()
        mp.exportCompo( composer, folder, title, extension )

It'll take a while.

NOTES:

  • If composer names are repeated across projects, you'd need to differentiate their title (second to last line in the code), for example, by appending the project name. Otherwise files will be overwritten.
  • If you just need to export certain composers, you could filter them using their name. It would need an extra if clause in the inner for loop.

I just test this with a couple of projects. Give it a try, I hope it works for you.


EDIT:

I acknowledge a PyQGIS script is not very user-friendly, so I've created a Processing Script that a user can run from the Processing Toolbox with its own GUI:

enter image description here

You can install it using the QGIS Resource Sharing plugin and adding my repository:

enter image description here

URL: https://github.com/gacarrillor/QGIS-Resources.git

Or, you can download the script directly from here and use the Add script from file tool from the Toolbox.

Germán Carrillo
  • 36,307
  • 5
  • 123
  • 178
  • 1
    I didn't think you could access a plugin from the outside with pyqgis... it gives me some ideas ! :) Thanks a lot for this suggestion. I'll give you some feedback as soon as possible (probably on friday, i'm unavailable tomorrow). – gisnside Sep 14 '16 at 18:42
  • Yes, you can access plugins' functions from the console. That you can actually use plugin's functions would depend on how well structured is the plugin. Maps Printer seems to be well separated, allowing you to reuse parts of it. – Germán Carrillo Sep 15 '16 at 13:24
  • I'm trying to recode your script, because one needs to write down the 1 to n projects you want into the text by hand , and that's not very "non-expert" user friendly. Do you have some bit of code where I could just tell qgis what folder and it would just create the projectpaths list based on a single folder path (I would like to pass that as an argument in pyqgis script ##inputfolder = folder – gisnside Sep 16 '16 at 16:22
  • 1
    You can get a list of QGIS projects from a folder using the glob module: import glob glob.glob('/path/to/projects/*.qgs') Just to give you a complementary idea, you could save an empty QGIS project (say, 'Export.qgs') and configure it to run the code snippet every time it is opened. So, a non-expert user could just open the 'Export.qgs' project and have everything exported. – Germán Carrillo Sep 16 '16 at 22:01
  • Actually, i'm trying to create a script that would do the job from the pyqgis python scripts (processing panel). The user would just have to select the folder and the script would export all the PDFs. I'm looking as well into a solution to deal with the similar composer names, thus renaming witht the project name for example (myproject01_composer01.pdf, myproject02_composer02.pdf, myproject02_composer01.pdf, etc) – gisnside Sep 17 '16 at 08:10
  • 1
    In that case you could add something like title = project.fileInfo().baseName() + '_' + title before the last line of the code snippet. – Germán Carrillo Sep 19 '16 at 16:06
  • Bounty time expires, one answer, so you win ! I'll keep on on this subject by editing my answer with more info as I work on it, especially if I make up my python script that works correctly. – gisnside Sep 21 '16 at 08:20
  • Is there anything else missing? Are you struggling with the Processing script? – Germán Carrillo Sep 21 '16 at 12:14
  • Thanks for asking... In fact, yes ! I didn't want to make it sound like I didn't try and wanted a ready to do script, so I'm trying but it doesn't seem I'm very strong in pyqgis programming yet. For example, something like ##Myvar = folder doesn't seem to recognize a folder path ("Myvar is not defined") and I can't find out why. So I'm looking into different strategies, but I'm not succeeding much, i admit... – gisnside Sep 21 '16 at 12:21
  • 1
    I like the way you want to solve the problem, providing users with a Processing GUI. Since all the logic is already there, I'll have a look at Processing scripts and let you know, I think we are close to a final solution. – Germán Carrillo Sep 21 '16 at 12:26
  • It would be very kind of you. However, i don't stop looking, if I find something working, i'll post it. – gisnside Sep 21 '16 at 12:28
  • I've updated the answer. Honestly, don't feel bad about your attempts, I spent entire hours figuring out how Processing Scripts work. It turns out the code snippet is special because it refreshes the canvas constantly. I had to tweak the script a bit making sure we avoid a couple of potential QGIS crashes. I hope you can use the final script from the Toolbox. I agree that's a much better way of implementing the solution. – Germán Carrillo Sep 22 '16 at 00:04
  • It works ! I installed your script from within the community Ressources, but I couldn't find where it was supposed to appear in QGIS, so I finally selected : create new script and paste your code into the file i recorded near the other ones. – gisnside Sep 22 '16 at 08:29
  • Your script was missing this at the top :
    
    ##Batch_Export_Project = name```
    
    – gisnside Sep 22 '16 at 08:34
  • Great! Didn't know the two lines you've mentioned. I've updated the script in my repository. – Germán Carrillo Sep 22 '16 at 14:37
  • 1
    Those line are used to position your script into the list of existing scripts once it's loaded. You can set any names you wish, like Project_tools if you prefer and Batch_Composer_export for example. – gisnside Sep 22 '16 at 19:37
  • 1
    Hello, thanks a lot for all the works done! I believe this will this will totally resolve this other long lasting question http://gis.stackexchange.com/questions/144792/save-print-map-qgis-composer-view-as-png-pdf-using-python-without-changing-anyt/164196#164196. Also it look like there is a small glitch remaining for installation under windows due to the accent. I filled an issue on your repo to describe https://github.com/gacarrillor/QGIS-Resources/issues/1 – MarHoff Sep 23 '16 at 12:15
  • Thanks for the valuable feedback @MarHoff, I've posted an answer on that GIS.SE topic and updated the GitHub issue (please have a look at it). – Germán Carrillo Sep 24 '16 at 17:13