Exemple #1
0
    def test_read_write_setting(self):
        """Test read and write setting."""
        # General Setting
        set_general_setting('key', 'value', self.qsettings)
        self.assertEqual('value',
                         general_setting('key', qsettings=self.qsettings))
        delete_general_setting('key', qsettings=self.qsettings)
        self.assertEqual(
            'default',
            general_setting('key', default='default',
                            qsettings=self.qsettings))

        set_general_setting('key', 'True', self.qsettings)
        self.assertEqual(
            'True',
            general_setting('key', qsettings=self.qsettings,
                            expected_type=str))
        self.assertEqual(
            True,
            general_setting('key',
                            qsettings=self.qsettings,
                            expected_type=bool))
        delete_general_setting('key', qsettings=self.qsettings)
        self.assertEqual(
            'default',
            general_setting('key', default='default',
                            qsettings=self.qsettings))

        set_general_setting('key', 'false', self.qsettings)
        self.assertEqual(
            'false',
            general_setting('key', qsettings=self.qsettings,
                            expected_type=str))
        self.assertEqual(
            False,
            general_setting('key',
                            qsettings=self.qsettings,
                            expected_type=bool))
        delete_general_setting('key', qsettings=self.qsettings)
        self.assertEqual(
            'default',
            general_setting('key', default='default',
                            qsettings=self.qsettings))

        # Under InaSAFE scope
        set_setting('key', 'value', self.qsettings)
        self.assertEqual('value', setting('key', qsettings=self.qsettings))
        delete_setting('key', qsettings=self.qsettings)
        self.assertEqual(
            'default',
            setting('key', default='default', qsettings=self.qsettings))

        # Using InaSAFE setting default
        key = 'developer_mode'
        actual_value = inasafe_default_settings.get(key)
        self.assertEqual(actual_value, setting(key, qsettings=self.qsettings))
Exemple #2
0
    def test_read_write_setting(self):
        """Test read and write setting."""
        # General Setting
        set_general_setting('key', 'value', self.qsettings)
        self.assertEqual(
            'value', general_setting('key', qsettings=self.qsettings))
        delete_general_setting('key', qsettings=self.qsettings)
        self.assertEqual('default', general_setting(
            'key', default='default', qsettings=self.qsettings))

        set_general_setting('key', 'True', self.qsettings)
        self.assertEqual(
            'True',
            general_setting(
                'key', qsettings=self.qsettings, expected_type=str))
        self.assertEqual(
            True,
            general_setting(
                'key', qsettings=self.qsettings, expected_type=bool))
        delete_general_setting('key', qsettings=self.qsettings)
        self.assertEqual('default', general_setting(
            'key', default='default', qsettings=self.qsettings))

        set_general_setting('key', 'false', self.qsettings)
        self.assertEqual(
            'false',
            general_setting(
                'key', qsettings=self.qsettings, expected_type=str))
        self.assertEqual(
            False,
            general_setting(
                'key', qsettings=self.qsettings, expected_type=bool))
        delete_general_setting('key', qsettings=self.qsettings)
        self.assertEqual('default', general_setting(
            'key', default='default', qsettings=self.qsettings))

        # Under InaSAFE scope
        set_setting('key', 'value', self.qsettings)
        self.assertEqual('value', setting('key', qsettings=self.qsettings))
        delete_setting('key', qsettings=self.qsettings)
        self.assertEqual('default', setting(
            'key', default='default', qsettings=self.qsettings))

        # Using InaSAFE setting default
        key = 'developer_mode'
        actual_value = inasafe_default_settings.get(key)
        self.assertEqual(actual_value, setting(key, qsettings=self.qsettings))
Exemple #3
0
def get_qgis_app(requested_locale='en_US', qsetting=''):
    """ Start one QGIS application to test against.

    :param locale: The locale we want the qgis to launch with.
    :type locale: str

    :param qsetting: String to specify the QSettings. By default,
        use empty string.
    :type qsetting: str

    :returns: Handle to QGIS app, canvas, iface and parent. If there are any
        errors the tuple members will be returned as None.
    :rtype: (QgsApplication, CANVAS, IFACE, PARENT)

    If QGIS is already running the handle to that app will be returned.
    """
    global QGIS_APP, PARENT, IFACE, CANVAS  # pylint: disable=W0603

    from qgis.PyQt.QtCore import QSettings
    if qsetting:
        settings = QSettings(qsetting)
    else:
        settings = QSettings()

    default_user_directory = setting('defaultUserDirectory')
    current_locale = general_setting(
        'locale/userLocale', default='en_US', qsettings=settings)
    locale_match = current_locale == requested_locale

    if iface and locale_match:
        from qgis.core import QgsApplication
        QGIS_APP = QgsApplication
        CANVAS = iface.mapCanvas()
        PARENT = iface.mainWindow()
        IFACE = iface

    try:
        from qgis.core import QgsApplication
        from qgis.gui import QgsMapCanvas  # pylint: disable=no-name-in-module
        # noinspection PyPackageRequirements
        from qgis.PyQt import QtWidgets, QtCore  # pylint: disable=W0621
        # noinspection PyPackageRequirements
        from qgis.PyQt.QtCore import QCoreApplication, QSettings
        from safe.test.qgis_interface import QgisInterface
    except ImportError:
        return None, None, None, None

    if qsetting:
        settings = QSettings(qsetting)
    else:
        settings = QSettings()

    if not QGIS_APP:
        gui_flag = True  # All test will run qgis in gui mode

        # AG: For testing purposes, we use our own configuration file
        # instead of using the QGIS apps conf of the host
        # noinspection PyCallByClass,PyArgumentList
        QCoreApplication.setOrganizationName('QGIS')
        # noinspection PyCallByClass,PyArgumentList
        QCoreApplication.setOrganizationDomain('qgis.org')
        # noinspection PyCallByClass,PyArgumentList
        QCoreApplication.setApplicationName('QGIS2InaSAFETesting')

        # We disabled message bars for now for extent selector as
        # we don't have a main window to show them in TS - version 3.2
        set_setting('show_extent_warnings', False, settings)
        set_setting('showRubberBands', True, settings)
        set_setting('show_extent_confirmations', False, settings)
        set_setting('analysis_extents_mode', HAZARD_EXPOSURE, settings)
        if default_user_directory:
            set_setting(
                'defaultUserDirectory', default_user_directory, settings)

        # noinspection PyPep8Naming
        if 'argv' in dir(sys):
            QGIS_APP = QgsApplication([p.encode('utf-8')
                                       for p in sys.argv], gui_flag)
        else:
            QGIS_APP = QgsApplication([], gui_flag)

        # Make sure QGIS_PREFIX_PATH is set in your env if needed!
        QGIS_APP.initQgis()

        # Initialize processing
        processing.Processing.initialize()

        s = QGIS_APP.showSettings()
        LOGGER.debug(s)

    if not locale_match:
        """Setup internationalisation for the plugin."""

        # Save some settings
        set_general_setting('locale/overrideFlag', True, settings)
        set_general_setting('locale/userLocale', requested_locale, settings)

        locale_name = str(requested_locale).split('_')[0]
        # Also set the system locale to the user overridden local
        # so that the inasafe library functions gettext will work
        # .. see:: :py:func:`common.utilities`
        os.environ['LANG'] = str(locale_name)

        inasafe_translation_path = os.path.join(
            safe_dir('i18n'), 'inasafe_' + str(locale_name) + '.qm')

        if os.path.exists(inasafe_translation_path):
            if isinstance(QGIS_APP, sip.wrappertype):
                translator = QTranslator()
            else:
                translator = QTranslator(QGIS_APP)
            result = translator.load(inasafe_translation_path)
            if not result:
                message = 'Failed to load translation for %s' % locale_name
                raise Exception(message)
            # noinspection PyTypeChecker,PyCallByClass
            QCoreApplication.installTranslator(translator)

        # at the end, reload InaSAFE modules so it will get translated too
        reload_inasafe_modules()

    if PARENT is None:
        # noinspection PyPep8Naming
        PARENT = QtWidgets.QWidget()

    if CANVAS is None:
        # noinspection PyPep8Naming
        CANVAS = QgsMapCanvas(PARENT)
        CANVAS.resize(QtCore.QSize(400, 400))

    if IFACE is None:
        # QgisInterface is a stub implementation of the QGIS plugin interface
        # noinspection PyPep8Naming
        IFACE = QgisInterface(CANVAS)

    return QGIS_APP, CANVAS, IFACE, PARENT
Exemple #4
0
def atlas_renderer(composition, coverage_layer, output_path, file_format):
    """Extract composition using atlas generation.

    :param composition: QGIS Composition object used for producing the report.
    :type composition: qgis.core.QgsComposition

    :param coverage_layer: Coverage Layer used for atlas map.
    :type coverage_layer: QgsMapLayer

    :param output_path: The output path of the product.
    :type output_path: str

    :param file_format: File format of map output, 'pdf' or 'png'.
    :type file_format: str

    :return: Generated output path(s).
    :rtype: str, list
    """
    # set the composer map to be atlas driven
    composer_map = composition_item(composition, 'impact-map', QgsComposerMap)
    composer_map.setAtlasDriven(True)
    composer_map.setAtlasScalingMode(QgsComposerMap.Auto)

    # setup the atlas composition and composition atlas mode
    atlas_composition = composition.atlasComposition()
    atlas_composition.setCoverageLayer(coverage_layer)
    atlas_composition.setComposerMap(composer_map)
    atlas_composition.prepareMap(composer_map)
    atlas_on_single_file = atlas_composition.singleFile()
    composition.setAtlasMode(QgsComposition.ExportAtlas)

    if file_format == QgisComposerComponentsMetadata.OutputFormat.PDF:
        if not atlas_composition.filenamePattern():
            atlas_composition.setFilenamePattern(
                "'output_'||@atlas_featurenumber")
        output_directory = os.path.dirname(output_path)

        printer = QPrinter(QPrinter.HighResolution)
        painter = QPainter()

        # we need to set the predefined scales for atlas
        project_scales = []
        scales = QgsProject.instance().readListEntry(
            "Scales", "/ScalesList")[0]
        has_project_scales = QgsProject.instance().readBoolEntry(
            "Scales", "/useProjectScales")[0]
        if not has_project_scales or not scales:
            scales_string = str(general_setting("Map/scales", PROJECT_SCALES))
            scales = scales_string.split(',')
        for scale in scales:
            parts = scale.split(':')
            if len(parts) == 2:
                project_scales.append(float(parts[1]))
        atlas_composition.setPredefinedScales(project_scales)

        if not atlas_composition.beginRender() and (
                atlas_composition.featureFilterErrorString()):
            msg = 'Atlas processing error: {error}'.format(
                error=atlas_composition.featureFilterErrorString())
            LOGGER.error(msg)
            return

        if atlas_on_single_file:
            atlas_composition.prepareForFeature(0)
            composition.beginPrintAsPDF(printer, output_path)
            composition.beginPrint(printer)
            if not painter.begin(printer):
                msg = ('Atlas processing error: '
                       'Cannot write to {output}.').format(output=output_path)
                LOGGER.error(msg)
                return

        LOGGER.info('Exporting Atlas')

        atlas_output = []
        for feature_index in range(atlas_composition.numFeatures()):
            if not atlas_composition.prepareForFeature(feature_index):
                msg = ('Atlas processing error: Exporting atlas error at '
                       'feature number {index}').format(index=feature_index)
                LOGGER.error(msg)
                return
            if not atlas_on_single_file:
                # we need another printer object fot multi file atlas
                multi_file_printer = QPrinter(QPrinter.HighResolution)
                current_filename = atlas_composition.currentFilename()
                output_path = os.path.join(
                    output_directory, current_filename + '.pdf')
                composition.beginPrintAsPDF(multi_file_printer, output_path)
                composition.beginPrint(multi_file_printer)
                if not painter.begin(multi_file_printer):
                    msg = ('Atlas processing error: Cannot write to '
                           '{output}.').format(output=output_path)
                    LOGGER.error(msg)
                    return
                composition.doPrint(multi_file_printer, painter)
                painter.end()
                composition.georeferenceOutput(output_path)
                atlas_output.append(output_path)
            else:
                composition.doPrint(printer, painter, feature_index > 0)

        atlas_composition.endRender()

        if atlas_on_single_file:
            painter.end()
            return output_path

        return atlas_output
Exemple #5
0
def atlas_renderer(layout, coverage_layer, output_path, file_format):
    """Extract composition using atlas generation.

    :param layout: QGIS Print Layout object used for producing the report.
    :type layout: qgis.core.QgsPrintLayout

    :param coverage_layer: Coverage Layer used for atlas map.
    :type coverage_layer: QgsMapLayer

    :param output_path: The output path of the product.
    :type output_path: str

    :param file_format: File format of map output, 'pdf' or 'png'.
    :type file_format: str

    :return: Generated output path(s).
    :rtype: str, list
    """
    # set the composer map to be atlas driven
    composer_map = layout_item(
        layout, 'impact-map', QgsLayoutItemMap)
    composer_map.setAtlasDriven(True)
    composer_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)

    # setup the atlas composition and composition atlas mode
    atlas_composition = layout.atlas()
    atlas_composition.setCoverageLayer(coverage_layer)
    atlas_on_single_file = layout.customProperty('singleFile', True)

    if file_format == QgisComposerComponentsMetadata.OutputFormat.PDF:
        if not atlas_composition.filenameExpression():
            atlas_composition.setFilenameExpression(
                "'output_'||@atlas_featurenumber")
        output_directory = os.path.dirname(output_path)

        # we need to set the predefined scales for atlas
        project_scales = []
        scales = QgsProject.instance().readListEntry(
            "Scales", "/ScalesList")[0]
        has_project_scales = QgsProject.instance().readBoolEntry(
            "Scales", "/useProjectScales")[0]
        if not has_project_scales or not scales:
            scales_string = str(general_setting("Map/scales", PROJECT_SCALES))
            scales = scales_string.split(',')
        for scale in scales:
            parts = scale.split(':')
            if len(parts) == 2:
                project_scales.append(float(parts[1]))
        layout.reportContext().setPredefinedScales(project_scales)

        settings = QgsLayoutExporter.PdfExportSettings()

        LOGGER.info('Exporting Atlas')
        atlas_output = []
        if atlas_on_single_file:
            res, error = QgsLayoutExporter.exportToPdf(
                atlas_composition, output_path, settings)
            atlas_output.append(output_path)
        else:
            res, error = QgsLayoutExporter.exportToPdfs(
                atlas_composition, output_directory, settings)

        if res != QgsLayoutExporter.Success:
            LOGGER.error(error)

        return atlas_output
Exemple #6
0
def atlas_renderer(layout, coverage_layer, output_path, file_format):
    """Extract composition using atlas generation.

    :param layout: QGIS Print Layout object used for producing the report.
    :type layout: qgis.core.QgsPrintLayout

    :param coverage_layer: Coverage Layer used for atlas map.
    :type coverage_layer: QgsMapLayer

    :param output_path: The output path of the product.
    :type output_path: str

    :param file_format: File format of map output, 'pdf' or 'png'.
    :type file_format: str

    :return: Generated output path(s).
    :rtype: str, list
    """
    # set the composer map to be atlas driven
    composer_map = layout_item(
        layout, 'impact-map', QgsLayoutItemMap)
    composer_map.setAtlasDriven(True)
    composer_map.setAtlasScalingMode(QgsLayoutItemMap.Auto)

    # setup the atlas composition and composition atlas mode
    atlas_composition = layout.atlas()
    atlas_composition.setCoverageLayer(coverage_layer)
    atlas_on_single_file = layout.customProperty('singleFile', True)

    if file_format == QgisComposerComponentsMetadata.OutputFormat.PDF:
        if not atlas_composition.filenameExpression():
            atlas_composition.setFilenameExpression(
                "'output_'||@atlas_featurenumber")
        output_directory = os.path.dirname(output_path)

        # we need to set the predefined scales for atlas
        project_scales = []
        scales = QgsProject.instance().readListEntry(
            "Scales", "/ScalesList")[0]
        has_project_scales = QgsProject.instance().readBoolEntry(
            "Scales", "/useProjectScales")[0]
        if not has_project_scales or not scales:
            scales_string = str(general_setting("Map/scales", PROJECT_SCALES))
            scales = scales_string.split(',')
        for scale in scales:
            parts = scale.split(':')
            if len(parts) == 2:
                project_scales.append(float(parts[1]))
        layout.reportContext().setPredefinedScales(project_scales)

        settings = QgsLayoutExporter.PdfExportSettings()

        LOGGER.info('Exporting Atlas')
        atlas_output = []
        if atlas_on_single_file:
            res, error = QgsLayoutExporter.exportToPdf(
                atlas_composition, output_path, settings)
            atlas_output.append(output_path)
        else:
            res, error = QgsLayoutExporter.exportToPdfs(
                atlas_composition, output_directory, settings)

        if res != QgsLayoutExporter.Success:
            LOGGER.error(error)

        return atlas_output
Exemple #7
0
def get_qgis_app(requested_locale='en_US', qsetting=''):
    """ Start one QGIS application to test against.

    :param locale: The locale we want the qgis to launch with.
    :type locale: str

    :param qsetting: String to specify the QSettings. By default,
        use empty string.
    :type qsetting: str

    :returns: Handle to QGIS app, canvas, iface and parent. If there are any
        errors the tuple members will be returned as None.
    :rtype: (QgsApplication, CANVAS, IFACE, PARENT)

    If QGIS is already running the handle to that app will be returned.
    """
    global QGIS_APP, PARENT, IFACE, CANVAS  # pylint: disable=W0603

    from qgis.PyQt.QtCore import QSettings
    if qsetting:
        settings = QSettings(qsetting)
    else:
        settings = QSettings()

    default_user_directory = setting('defaultUserDirectory')
    current_locale = general_setting(
        'locale/userLocale', default='en_US', qsettings=settings)
    locale_match = current_locale == requested_locale

    if iface and locale_match:
        from qgis.core import QgsApplication
        QGIS_APP = QgsApplication
        CANVAS = iface.mapCanvas()
        PARENT = iface.mainWindow()
        IFACE = iface

    try:
        from qgis.core import QgsApplication
        from qgis.gui import QgsMapCanvas  # pylint: disable=no-name-in-module
        # noinspection PyPackageRequirements
        from qgis.PyQt import QtWidgets, QtCore  # pylint: disable=W0621
        # noinspection PyPackageRequirements
        from qgis.PyQt.QtCore import QCoreApplication, QSettings
        from safe.test.qgis_interface import QgisInterface
    except ImportError:
        return None, None, None, None

    if qsetting:
        settings = QSettings(qsetting)
    else:
        settings = QSettings()

    if not QGIS_APP:
        gui_flag = True  # All test will run qgis in gui mode

        # AG: For testing purposes, we use our own configuration file
        # instead of using the QGIS apps conf of the host
        # noinspection PyCallByClass,PyArgumentList
        QCoreApplication.setOrganizationName('QGIS')
        # noinspection PyCallByClass,PyArgumentList
        QCoreApplication.setOrganizationDomain('qgis.org')
        # noinspection PyCallByClass,PyArgumentList
        QCoreApplication.setApplicationName('QGIS2InaSAFETesting')

        # We disabled message bars for now for extent selector as
        # we don't have a main window to show them in TS - version 3.2
        set_setting('show_extent_warnings', False, settings)
        set_setting('showRubberBands', True, settings)
        set_setting('show_extent_confirmations', False, settings)
        set_setting('analysis_extents_mode', HAZARD_EXPOSURE, settings)
        if default_user_directory:
            set_setting(
                'defaultUserDirectory', default_user_directory, settings)

        # noinspection PyPep8Naming
        if 'argv' in dir(sys):
            QGIS_APP = QgsApplication([p.encode('utf-8')
                                       for p in sys.argv], gui_flag)
        else:
            QGIS_APP = QgsApplication([], gui_flag)

        # Make sure QGIS_PREFIX_PATH is set in your env if needed!
        QGIS_APP.initQgis()

        # Initialize processing
        processing.Processing.initialize()

        s = QGIS_APP.showSettings()
        LOGGER.debug(s)

    if not locale_match:
        """Setup internationalisation for the plugin."""

        # Save some settings
        set_general_setting('locale/overrideFlag', True, settings)
        set_general_setting('locale/userLocale', requested_locale, settings)

        locale_name = str(requested_locale).split('_')[0]
        # Also set the system locale to the user overridden local
        # so that the inasafe library functions gettext will work
        # .. see:: :py:func:`common.utilities`
        os.environ['LANG'] = str(locale_name)

        inasafe_translation_path = os.path.join(
            safe_dir('i18n'), 'inasafe_' + str(locale_name) + '.qm')

        if os.path.exists(inasafe_translation_path):
            if isinstance(QGIS_APP, sip.wrappertype):
                translator = QTranslator()
            else:
                translator = QTranslator(QGIS_APP)
            result = translator.load(inasafe_translation_path)
            if not result:
                message = 'Failed to load translation for %s' % locale_name
                raise Exception(message)
            # noinspection PyTypeChecker,PyCallByClass
            QCoreApplication.installTranslator(translator)

        # at the end, reload InaSAFE modules so it will get translated too
        reload_inasafe_modules()

    if PARENT is None:
        # noinspection PyPep8Naming
        PARENT = QtWidgets.QWidget()

    if CANVAS is None:
        # noinspection PyPep8Naming
        CANVAS = QgsMapCanvas(PARENT)
        CANVAS.resize(QtCore.QSize(400, 400))

    if IFACE is None:
        # QgisInterface is a stub implementation of the QGIS plugin interface
        # noinspection PyPep8Naming
        IFACE = QgisInterface(CANVAS)

    return QGIS_APP, CANVAS, IFACE, PARENT
Exemple #8
0
def atlas_renderer(composition, coverage_layer, output_path, file_format):
    """Extract composition using atlas generation.

    :param composition: QGIS Composition object used for producing the report.
    :type composition: qgis.core.QgsComposition

    :param coverage_layer: Coverage Layer used for atlas map.
    :type coverage_layer: QgsMapLayer

    :param output_path: The output path of the product.
    :type output_path: str

    :param file_format: File format of map output, 'pdf' or 'png'.
    :type file_format: str

    :return: Generated output path(s).
    :rtype: str, list
    """
    # set the composer map to be atlas driven
    composer_map = composition_item(composition, 'impact-map', QgsComposerMap)
    composer_map.setAtlasDriven(True)
    composer_map.setAtlasScalingMode(QgsComposerMap.Auto)

    # setup the atlas composition and composition atlas mode
    atlas_composition = composition.atlasComposition()
    atlas_composition.setCoverageLayer(coverage_layer)
    atlas_composition.setComposerMap(composer_map)
    atlas_composition.prepareMap(composer_map)
    atlas_on_single_file = atlas_composition.singleFile()
    composition.setAtlasMode(QgsComposition.ExportAtlas)

    if file_format == QgisComposerComponentsMetadata.OutputFormat.PDF:
        if not atlas_composition.filenamePattern():
            atlas_composition.setFilenamePattern(
                "'output_'||@atlas_featurenumber")
        output_directory = os.path.dirname(output_path)

        printer = QPrinter(QPrinter.HighResolution)
        painter = QPainter()

        # we need to set the predefined scales for atlas
        project_scales = []
        scales = QgsProject.instance().readListEntry(
            "Scales", "/ScalesList")[0]
        has_project_scales = QgsProject.instance().readBoolEntry(
            "Scales", "/useProjectScales")[0]
        if not has_project_scales or not scales:
            scales_string = str(general_setting("Map/scales", PROJECT_SCALES))
            scales = scales_string.split(',')
        for scale in scales:
            parts = scale.split(':')
            if len(parts) == 2:
                project_scales.append(float(parts[1]))
        atlas_composition.setPredefinedScales(project_scales)

        if not atlas_composition.beginRender() and (
                atlas_composition.featureFilterErrorString()):
            msg = 'Atlas processing error: {error}'.format(
                error=atlas_composition.featureFilterErrorString())
            LOGGER.error(msg)
            return

        if atlas_on_single_file:
            atlas_composition.prepareForFeature(0)
            composition.beginPrintAsPDF(printer, output_path)
            composition.beginPrint(printer)
            if not painter.begin(printer):
                msg = ('Atlas processing error: '
                       'Cannot write to {output}.').format(output=output_path)
                LOGGER.error(msg)
                return

        LOGGER.info('Exporting Atlas')

        atlas_output = []
        for feature_index in range(atlas_composition.numFeatures()):
            if not atlas_composition.prepareForFeature(feature_index):
                msg = ('Atlas processing error: Exporting atlas error at '
                       'feature number {index}').format(index=feature_index)
                LOGGER.error(msg)
                return
            if not atlas_on_single_file:
                # we need another printer object fot multi file atlas
                multi_file_printer = QPrinter(QPrinter.HighResolution)
                current_filename = atlas_composition.currentFilename()
                output_path = os.path.join(
                    output_directory, current_filename + '.pdf')
                composition.beginPrintAsPDF(multi_file_printer, output_path)
                composition.beginPrint(multi_file_printer)
                if not painter.begin(multi_file_printer):
                    msg = ('Atlas processing error: Cannot write to '
                           '{output}.').format(output=output_path)
                    LOGGER.error(msg)
                    return
                composition.doPrint(multi_file_printer, painter)
                painter.end()
                composition.georeferenceOutput(output_path)
                atlas_output.append(output_path)
            else:
                composition.doPrint(printer, painter, feature_index > 0)

        atlas_composition.endRender()

        if atlas_on_single_file:
            painter.end()
            return output_path

        return atlas_output