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 )
7
+100

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.

  • 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
  • 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
  • 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
  • 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
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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