예제 #1
0
    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As PDF'), '',
            self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()),
                             QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage("",
                             self.tr("Model was correctly exported as PDF"),
                             level=Qgis.Success,
                             duration=5)
        self.repaintModel(controls=True)
예제 #2
0
    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As PDF'), '',
                                                           self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage("", self.tr("Successfully exported model as PDF to <a href=\"{}\">{}</a>").format(QUrl.fromLocalFile(filename).toString(), QDir.toNativeSeparators(filename)), level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)
예제 #3
0
    def testPrintIterator(self):
        project, layout = self.prepareIteratorLayout()
        atlas = layout.atlas()

        # setup settings
        settings = QgsLayoutExporter.PrintExportSettings()
        settings.dpi = 80
        settings.rasterizeWholeImage = False

        pdf_path = os.path.join(self.basetestpath, 'test_printiterator.pdf')
        # make a qprinter directed to pdf
        printer = QPrinter()
        printer.setOutputFileName(pdf_path)
        printer.setOutputFormat(QPrinter.PdfFormat)

        result, error = QgsLayoutExporter.print(atlas, printer, settings)
        self.assertEqual(result, QgsLayoutExporter.Success, error)

        rendered_page_1 = os.path.join(self.basetestpath, 'test_printiterator1.png')
        pdfToPng(pdf_path, rendered_page_1, dpi=80, page=1)
        self.assertTrue(self.checkImage('printeriterator1', 'iteratortoimage1', rendered_page_1, size_tolerance=2))

        rendered_page_2 = os.path.join(self.basetestpath, 'test_printiterator2.png')
        pdfToPng(pdf_path, rendered_page_2, dpi=80, page=2)
        self.assertTrue(self.checkImage('printiterator2', 'iteratortoimage2', rendered_page_2, size_tolerance=2))

        rendered_page_3 = os.path.join(self.basetestpath, 'test_printiterator3.png')
        pdfToPng(pdf_path, rendered_page_3, dpi=80, page=3)
        self.assertTrue(os.path.exists(rendered_page_3))
        rendered_page_4 = os.path.join(self.basetestpath, 'test_printiterator4.png')
        pdfToPng(pdf_path, rendered_page_4, dpi=80, page=4)
        self.assertTrue(os.path.exists(rendered_page_4))
예제 #4
0
def save_pdf_format(settings_path, title, text):
    settings = QSettings()
    new_filename, filter = QFileDialog.getSaveFileName(
        None,
        QCoreApplication.translate("Asistente-LADM-COL", "Export to PDF"),
        settings.value(settings_path, '.'),
        filter="PDF (*.pdf)")

    if new_filename:
        settings.setValue(settings_path, os.path.dirname(new_filename))
        new_filename = new_filename if new_filename.lower().endswith(
            ".pdf") else "{}.pdf".format(new_filename)

        txt_log = QTextEdit()
        txt_log.setHtml("{}<br>{}".format(title, text))

        printer = QPrinter()
        printer.setPageSize(QPrinter.Letter)
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(new_filename)
        txt_log.print(printer)

        msg = QCoreApplication.translate(
            "Asistente-LADM-COL",
            "Report successfully generated in folder <a href='file:///{normalized_path}'>{path}</a>!"
        ).format(normalized_path=normalize_local_url(new_filename),
                 path=new_filename)
        Logger().success_msg(__name__, msg)
예제 #5
0
    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(self,
                                                           self.tr('Save Model As PDF'), '',
                                                           self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()), QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage("", "Model was correctly exported as PDF", level=Qgis.Success, duration=5)
        self.repaintModel(controls=True)
예제 #6
0
    def testPrintIterator(self):
        project, layout = self.prepareIteratorLayout()
        atlas = layout.atlas()

        # setup settings
        settings = QgsLayoutExporter.PrintExportSettings()
        settings.dpi = 80
        settings.rasterizeWholeImage = False

        pdf_path = os.path.join(self.basetestpath, 'test_printiterator.pdf')
        # make a qprinter directed to pdf
        printer = QPrinter()
        printer.setOutputFileName(pdf_path)
        printer.setOutputFormat(QPrinter.PdfFormat)

        result, error = QgsLayoutExporter.print(atlas, printer, settings)
        self.assertEqual(result, QgsLayoutExporter.Success, error)

        rendered_page_1 = os.path.join(self.basetestpath, 'test_printiterator1.png')
        pdfToPng(pdf_path, rendered_page_1, dpi=80, page=1)
        self.assertTrue(self.checkImage('printeriterator1', 'iteratortoimage1', rendered_page_1, size_tolerance=2))

        rendered_page_2 = os.path.join(self.basetestpath, 'test_printiterator2.png')
        pdfToPng(pdf_path, rendered_page_2, dpi=80, page=2)
        self.assertTrue(self.checkImage('printiterator2', 'iteratortoimage2', rendered_page_2, size_tolerance=2))

        rendered_page_3 = os.path.join(self.basetestpath, 'test_printiterator3.png')
        pdfToPng(pdf_path, rendered_page_3, dpi=80, page=3)
        self.assertTrue(os.path.exists(rendered_page_3))
        rendered_page_4 = os.path.join(self.basetestpath, 'test_printiterator4.png')
        pdfToPng(pdf_path, rendered_page_4, dpi=80, page=4)
        self.assertTrue(os.path.exists(rendered_page_4))
예제 #7
0
    def export_dock_content(self, output_format: OutputFormats):
        """ Export the current displayed metadata sheet to the given format. """
        layer_name = iface.activeLayer().name()

        file_path = os.path.join(
            self.settings.value("UI/lastFileNameWidgetDir"),
            '{name}.{ext}'.format(name=layer_name,
                                  ext=output_format.value['ext']))
        output_file = QFileDialog.getSaveFileName(
            self,
            tr("Save File as {format}").format(
                format=output_format.value['label']), file_path,
            "{label} (*.{ext})".format(
                label=output_format.value['label'],
                ext=output_format.value['ext'],
            ))
        if output_file[0] == '':
            return

        self.settings.setValue("UI/lastFileNameWidgetDir",
                               os.path.dirname(output_file[0]))

        if output_format == OutputFormats.Pdf:
            printer = QPrinter()
            printer.setOutputFormat(QPrinter.PdfFormat)
            printer.setPageMargins(20, 20, 20, 20, QPrinter.Millimeter)
            printer.setOutputFileName(output_file[0])
            self.viewer.print(printer)
            iface.messageBar().pushSuccess(
                tr("Export PDF"),
                tr("The metadata has been exported as PDF successfully"))

        elif output_format in [OutputFormats.Html, OutputFormats.Dcat]:
            if output_format == OutputFormats.Html:
                data_str = self.viewer.page().currentFrame().toHtml()
            else:
                sql = self.sql_for_layer(self.current_datasource_uri,
                                         output_format=OutputFormats.Dcat)
                data = self.current_connection.executeSql(sql)
                with open(resources_path('xml', 'dcat.xml')) as xml_file:
                    xml_template = xml_file.read()

                locale = QgsSettings().value("locale/userLocale",
                                             QLocale().name())
                locale = locale.split('_')[0].lower()

                xml = parseString(
                    xml_template.format(locale=locale, content=data[0][0]))
                data_str = xml.toprettyxml()

            file_writer = open(output_file[0], "w")
            file_writer.write(data_str)
            file_writer.close()
            iface.messageBar().pushSuccess(
                tr("Export") + ' ' + output_format.value['label'],
                tr("The metadata has been exported as {format} successfully").
                format(format=output_format.value['label']))
예제 #8
0
    def testPrint(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize('A5')
        l.pageCollection().addPage(page2)

        # add some items
        item1 = QgsLayoutItemShape(l)
        item1.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.green)
        fill.setStrokeStyle(Qt.NoPen)
        item1.setSymbol(fill_symbol)
        l.addItem(item1)

        item2 = QgsLayoutItemShape(l)
        item2.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        item2.attemptMove(QgsLayoutPoint(10, 20), page=1)
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.cyan)
        fill.setStrokeStyle(Qt.NoPen)
        item2.setSymbol(fill_symbol)
        l.addItem(item2)

        exporter = QgsLayoutExporter(l)
        # setup settings
        settings = QgsLayoutExporter.PrintExportSettings()
        settings.dpi = 80
        settings.rasterizeWholeImage = False

        pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf')
        # make a qprinter directed to pdf
        printer = QPrinter()
        printer.setOutputFileName(pdf_file_path)
        printer.setOutputFormat(QPrinter.PdfFormat)

        self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success)
        self.assertTrue(os.path.exists(pdf_file_path))

        rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png')
        dpi = 80
        pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1)
        rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png')
        pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2)

        self.assertTrue(self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1))
        self.assertTrue(self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
예제 #9
0
    def testPrint(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize('A5')
        l.pageCollection().addPage(page2)

        # add some items
        item1 = QgsLayoutItemShape(l)
        item1.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.green)
        fill.setStrokeStyle(Qt.NoPen)
        item1.setSymbol(fill_symbol)
        l.addItem(item1)

        item2 = QgsLayoutItemShape(l)
        item2.attemptSetSceneRect(QRectF(10, 20, 100, 150))
        item2.attemptMove(QgsLayoutPoint(10, 20), page=1)
        fill = QgsSimpleFillSymbolLayer()
        fill_symbol = QgsFillSymbol()
        fill_symbol.changeSymbolLayer(0, fill)
        fill.setColor(Qt.cyan)
        fill.setStrokeStyle(Qt.NoPen)
        item2.setSymbol(fill_symbol)
        l.addItem(item2)

        exporter = QgsLayoutExporter(l)
        # setup settings
        settings = QgsLayoutExporter.PrintExportSettings()
        settings.dpi = 80
        settings.rasterizeWholeImage = False

        pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf')
        # make a qprinter directed to pdf
        printer = QPrinter()
        printer.setOutputFileName(pdf_file_path)
        printer.setOutputFormat(QPrinter.PdfFormat)

        self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success)
        self.assertTrue(os.path.exists(pdf_file_path))

        rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png')
        dpi = 80
        pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1)
        rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png')
        pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2)

        self.assertTrue(self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1))
        self.assertTrue(self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def export_title_text_to_pdf(filepath, title, text):
    filepath = filepath if filepath.lower().endswith(
        ".pdf") else "{}.pdf".format(filepath)

    txt_log = QTextEdit()
    txt_log.setHtml("{}<br>{}".format(title, text))

    printer = QPrinter()
    printer.setPageSize(QPrinter.Letter)
    printer.setOutputFormat(QPrinter.PdfFormat)
    printer.setOutputFileName(filepath)
    txt_log.print(printer)
예제 #11
0
 def outPDF(self, iface, wdg, mdl, library):
     for i in range(0, mdl.rowCount()):
         if mdl.item(i, 0).data(Qt.CheckStateRole):
             name = str(mdl.item(i, 2).data(Qt.EditRole))
             break
     fileName, _ = QFileDialog.getSaveFileName(
         iface.mainWindow(), "Save As", "Profile of " + name + ".pdf",
         "Portable Document Format (*.pdf)")
     if fileName:
         if library == "Qwt5" and has_qwt:
             printer = QPrinter()
             printer.setCreator('QGIS Profile Plugin')
             printer.setOutputFileName(fileName)
             printer.setOutputFormat(QPrinter.PdfFormat)
             printer.setOrientation(QPrinter.Landscape)
             wdg.plotWdg.print_(printer)
         elif library == "Matplotlib" and has_mpl:
             wdg.plotWdg.figure.savefig(str(fileName))
예제 #12
0
 def outPrint(
         self, iface, wdg, mdl,
         library):  # Postscript file rendering doesn't work properly yet.
     for i in range(0, mdl.rowCount()):
         if mdl.item(i, 0).data(Qt.CheckStateRole):
             name = str(mdl.item(i, 2).data(Qt.EditRole))
             #return
     fileName, __, __ = QFileDialog.getSaveFileName(
         iface.mainWindow(), "Save As", "Profile of " + name + ".ps",
         "PostScript Format (*.ps)")
     if fileName:
         if library == "Qwt5" and has_qwt:
             printer = QPrinter()
             printer.setCreator("QGIS Profile Plugin")
             printer.setDocName("QGIS Profile")
             printer.setOutputFileName(fileName)
             printer.setColorMode(QPrinter.Color)
             printer.setOrientation(QPrinter.Portrait)
             dialog = QPrintDialog(printer)
             if dialog.exec_():
                 wdg.plotWdg.print_(printer)
         elif library == "Matplotlib" and has_mpl:
             wdg.plotWdg.figure.savefig(str(fileName))
예제 #13
0
    def _get_layout_pdf_image(self, width, height, dpi):
        pdfpath = getTempfilePath('pdf')
        temp_size = os.path.getsize(pdfpath)

        p = QPrinter()
        p.setOutputFormat(QPrinter.PdfFormat)
        p.setOutputFileName(pdfpath)
        p.setPaperSize(
            QSizeF(self._c.pageCollection().page(0).sizeWithUnits().width(),
                   self._c.pageCollection().page(0).sizeWithUnits().height()),
            QPrinter.Millimeter)
        p.setFullPage(True)
        p.setColorMode(QPrinter.Color)
        p.setResolution(self._c.renderContext().dpi())

        pdf_p = QPainter(p)
        # page_mm = p.pageRect(QPrinter.Millimeter)
        # page_px = p.pageRect(QPrinter.DevicePixel)
        # self._c.render(pdf_p, page_px, page_mm)
        exporter = QgsLayoutExporter(self._c)
        exporter.renderPage(pdf_p, 0)
        pdf_p.end()

        if temp_size == os.path.getsize(pdfpath):
            return False, ''

        filepath = getTempfilePath('png')
        # Poppler (pdftocairo or pdftoppm):
        # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase
        # muPDF (mudraw):
        # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf
        if PDFUTIL.strip().endswith('pdftocairo'):
            filebase = os.path.join(
                os.path.dirname(filepath),
                os.path.splitext(os.path.basename(filepath))[0])
            call = [
                PDFUTIL, '-png', '-singlefile', '-r',
                str(dpi), '-x', '0', '-y', '0', '-W',
                str(width), '-H',
                str(height), pdfpath, filebase
            ]
        elif PDFUTIL.strip().endswith('mudraw'):
            call = [
                PDFUTIL,
                '-c',
                'rgba',
                '-r',
                str(dpi),
                '-w',
                str(width),
                '-h',
                str(height),
                # '-b', '8',
                '-o',
                filepath,
                pdfpath
            ]
        else:
            return False, ''

        qDebug("_get_layout_pdf_image call: {0}".format(' '.join(call)))
        res = False
        try:
            subprocess.check_call(call)
            res = True
        except subprocess.CalledProcessError as e:
            qDebug("_get_layout_pdf_image failed!\n"
                   "cmd: {0}\n"
                   "returncode: {1}\n"
                   "message: {2}".format(e.cmd, e.returncode, e.message))

        if not res:
            os.unlink(filepath)
            filepath = ''

        return res, filepath
예제 #14
0
class WeightDataDialog(QDialog, FORM_CLASS):
    """
    Modal dialog allowing to select weights in a d3.js visualization
    """

    #   QVariantMap is to map a JSON to dict see:
    #   http://pyqt.sourceforge.net/Docs/PyQt4/incompatibilities.html#pyqt4-v4-7-4
    #   this is for javascript to emit when it changes the json
    json_updated = pyqtSignal(['QVariantMap'], name='json_updated')
    # Python classes should connect to json_cleaned
    json_cleaned = pyqtSignal(['QVariantMap'], name='json_cleaned')

    def __init__(self, iface, project_definition):
        self.iface = iface
        QDialog.__init__(self)

        # Set up the user interface from Designer.
        self.setupUi(self)
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)

        self.added_attrs_ids = set()
        self.discarded_feats = set()
        self.any_changes_made = False

        # keep track of changes made to the tree while on-the-fly calculations
        # are off (the tree has changed, but indices haven't been recalculated)
        self.modified_project_definition = None

        self.active_layer_numeric_fields = []
        self.active_layer_numeric_fields_aliases = []
        self.update_active_layer_numeric_fields()
        # keep track of the fact that the user has explicitly selected a field
        # to base the style on. Note that also the selection of the empty item
        # means that the user explicitly wants the system to use the default
        # behavior.
        self.style_by_field_selected = False

        self.project_definition = deepcopy(project_definition)
        try:
            proj_title = self.project_definition['title']
        except KeyError:
            proj_title = 'Untitled'
        dialog_title = ('Set weights and operators for project: "%s"' %
                        proj_title)
        self.setWindowTitle(dialog_title)

        self.web_view = self.web_view
        self.web_view.page().mainFrame().setScrollBarPolicy(
            Qt.Vertical, Qt.ScrollBarAlwaysOff)
        self.web_view.page().mainFrame().setScrollBarPolicy(
            Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.web_view.load(QUrl('qrc:/plugins/irmt/weight_data.html'))

        self.printer = QPrinter(QPrinter.HighResolution)
        self.printer.setPageSize(QPrinter.A4)
        self.printer.setOutputFormat(QPrinter.PdfFormat)
        self.printer.setPrintRange(QPrinter.AllPages)
        self.printer.setOrientation(QPrinter.Portrait)
        self.printer.setDocName(proj_title)
        self.printer.setCreator(
            'GEM Integrated Risk Modelling Toolkit QGIS Plugin')

        self.frame = self.web_view.page().mainFrame()

        self.frame.javaScriptWindowObjectCleared.connect(self.setup_js)
        self.web_view.loadFinished.connect(self.show_tree)
        self.json_updated.connect(self.handle_json_updated)
        self.populate_style_by_field_cbx()

        if not DEBUG:
            self.web_view.setContextMenuPolicy(Qt.NoContextMenu)

        self.web_view.settings().setAttribute(QWebSettings.JavascriptEnabled,
                                              True)

    def closeEvent(self, event):
        confirmation_on_close(self, event)

    def reject(self):
        confirmation_on_close(self)

    def update_project_definition(self, project_definition):
        self.project_definition = deepcopy(project_definition)
        self.populate_style_by_field_cbx()

    def update_active_layer_numeric_fields(self):
        self.active_layer_numeric_fields = [
            field.name() for field in self.iface.activeLayer().fields()
            if field.typeName() in NUMERIC_FIELD_TYPES
        ]
        self.active_layer_numeric_fields_aliases = [
            self.iface.activeLayer().attributeAlias(field_idx) for field_idx,
            field in enumerate(self.iface.activeLayer().fields())
            if field.typeName() in NUMERIC_FIELD_TYPES
        ]

    def populate_style_by_field_cbx(self):
        self.update_active_layer_numeric_fields()
        fields_in_proj_def = get_field_names(self.project_definition)
        fields_for_styling = [
            field for field in self.active_layer_numeric_fields
            if field in fields_in_proj_def
        ]
        # block signals to avoid performing the onchange actions while adding
        # items programmatically
        self.style_by_field_cbx.blockSignals(True)
        self.style_by_field_cbx.clear()
        self.style_by_field_cbx.addItem('')
        self.style_by_field_cbx.addItems(fields_for_styling)
        if 'style_by_field' in self.project_definition:
            idx = self.style_by_field_cbx.findText(
                self.project_definition['style_by_field'])
            self.style_by_field_cbx.setCurrentIndex(idx)
        # reactivate the signals, so the user's changes will trigger something
        self.style_by_field_cbx.blockSignals(False)

    def setup_js(self):
        # pass a reference (called qt_page) of self to the JS world
        # to expose a member of self to js you need to declare it as property
        # see for example self.json_str()

        if DEBUG:
            log_msg("######################### for weight_data_debug.html")
            self.print_self_for_debug()
            log_msg("######################### end for weight_data_debug.html")

        self.frame.addToJavaScriptWindowObject('qt_page', self)

    def show_tree(self):
        # start the tree
        self.frame.evaluateJavaScript('init_tree()')

    def handle_json_updated(self, data):
        self.any_changes_made = True
        if DEBUG:
            import pprint
            ppdata = pprint.pformat(data, indent=4)
            log_msg('in handle_json_updated, data=\n%s' % ppdata)

        if self.on_the_fly_ckb.isChecked():
            self.project_definition = self.clean_json([data])
            self._manage_style_by_field()
            self.json_cleaned.emit(self.project_definition)

            # nothing has changed since the last recalculation
            self.modified_project_definition = None
        else:
            # keep track of the current status of the project definition
            # as it is in the d3 tree, so it can be used when OK is pressed
            self.modified_project_definition = self.clean_json([data])

    def _manage_style_by_field(self):
        if self.style_by_field_selected:
            if self.style_by_field_cbx.currentText():
                self.project_definition['style_by_field'] = \
                    self.style_by_field_cbx.currentText()
            elif 'style_by_field' in self.project_definition:
                # if the empty item is selected, clean the project definition
                del self.project_definition['style_by_field']

    def clean_json(self, data):
        # this method takes a list of dictionaries and removes some unneeded
        # keys. It recurses into the children elements

        if data == []:
            return data

        ignore_keys = ['depth', 'x', 'y', 'id', 'x0', 'y0', 'parent']
        for element in data:
            for key in ignore_keys:
                element.pop(key, None)
            if 'children' in element:
                self.clean_json(element['children'])
        # return the main element
        return data[0]

    @pyqtSlot()
    def on_print_btn_clicked(self):
        dest_full_path_name = ask_for_destination_full_path_name(
            self, filter='Pdf files (*.pdf)')
        if not dest_full_path_name:
            return
        self.printer.setOutputFileName(dest_full_path_name)
        try:
            self.web_view.print_(self.printer)
        except Exception as exc:
            msg = 'It was impossible to create the pdf'
            log_msg(msg,
                    level='C',
                    message_bar=self.iface.messageBar(),
                    exception=exc)
        else:
            msg = ('Project definition printed as pdf and saved to: %s' %
                   dest_full_path_name)
            log_msg(msg, level='S', message_bar=self.iface.messageBar())

    @pyqtSlot(str)
    def on_style_by_field_cbx_currentIndexChanged(self):
        self.style_by_field_selected = True
        self._manage_style_by_field()
        self.json_updated.emit(self.project_definition)

    @pyqtProperty(str)
    def json_str(self):
        # This method gets exposed to JS thanks to @pyqtProperty(str)
        return json.dumps(self.project_definition,
                          sort_keys=False,
                          indent=2,
                          separators=(',', ': '))

    @pyqtProperty(str)
    def DEFAULT_OPERATOR(self):
        return DEFAULT_OPERATOR

    @pyqtProperty(bool)
    def DEV_MODE(self):
        developer_mode = QSettings().value('/irmt/developer_mode',
                                           True,
                                           type=bool)

        return developer_mode

    @pyqtProperty(str)
    def OPERATORS(self):
        return ';'.join(list(OPERATORS_DICT.values()))

    @pyqtProperty(str)
    def ACTIVE_LAYER_NUMERIC_FIELDS(self):
        return ';'.join(self.active_layer_numeric_fields)

    @pyqtProperty(str)
    def ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES(self):
        return ';'.join(self.active_layer_numeric_fields_aliases)

    @pyqtProperty(str)
    def NODE_TYPES(self):
        return ';'.join(["%s:%s" % (k, v) for k, v in NODE_TYPES.items()])

    def print_self_for_debug(self):
        msg = """
        var qt_page = {
            ACTIVE_LAYER_NUMERIC_FIELDS: "%s",
            ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES: "%s",
            DEFAULT_OPERATOR: "%s",
            NODE_TYPES: "%s",
            OPERATORS: "%s",
            json_str: '%s',
            json_updated: function (updated_json_str) {
                console.log("json_updated signal emitted with this JSON:");
                console.log(updated_json_str)
            },
            DEV_MODE: %s
        };""" % (self.ACTIVE_LAYER_NUMERIC_FIELDS,
                 self.ACTIVE_LAYER_NUMERIC_FIELDS_ALIASES,
                 self.DEFAULT_OPERATOR, self.NODE_TYPES, self.OPERATORS,
                 self.json_str.replace('\n', ''), str(self.DEV_MODE).lower())
        log_msg(msg)
예제 #15
0
    def _get_composer_pdf_image(self, width, height, dpi):
        pdfpath = getTempfilePath('pdf')
        temp_size = os.path.getsize(pdfpath)

        p = QPrinter()
        p.setOutputFormat(QPrinter.PdfFormat)
        p.setOutputFileName(pdfpath)
        p.setPaperSize(QSizeF(self._c.paperWidth(), self._c.paperHeight()),
                       QPrinter.Millimeter)
        p.setFullPage(True)
        p.setColorMode(QPrinter.Color)
        p.setResolution(self._c.printResolution())

        pdf_p = QPainter(p)
        # page_mm = p.pageRect(QPrinter.Millimeter)
        # page_px = p.pageRect(QPrinter.DevicePixel)
        # self._c.render(pdf_p, page_px, page_mm)
        self._c.renderPage(pdf_p, 0)
        pdf_p.end()

        if temp_size == os.path.getsize(pdfpath):
            return False, ''

        filepath = getTempfilePath('png')
        # Poppler (pdftocairo or pdftoppm):
        # PDFUTIL -png -singlefile -r 72 -x 0 -y 0 -W 420 -H 280 in.pdf pngbase
        # muPDF (mudraw):
        # PDFUTIL -c rgb[a] -r 72 -w 420 -h 280 -o out.png in.pdf
        if PDFUTIL.strip().endswith('pdftocairo'):
            filebase = os.path.join(
                os.path.dirname(filepath),
                os.path.splitext(os.path.basename(filepath))[0]
            )
            call = [
                PDFUTIL, '-png', '-singlefile', '-r', str(dpi),
                '-x', '0', '-y', '0', '-W', str(width), '-H', str(height),
                pdfpath, filebase
            ]
        elif PDFUTIL.strip().endswith('mudraw'):
            call = [
                PDFUTIL, '-c', 'rgba',
                '-r', str(dpi), '-w', str(width), '-h', str(height),
                # '-b', '8',
                '-o', filepath, pdfpath
            ]
        else:
            return False, ''

        qDebug("_get_composer_pdf_image call: {0}".format(' '.join(call)))
        res = False
        try:
            subprocess.check_call(call)
            res = True
        except subprocess.CalledProcessError as e:
            qDebug("_get_composer_pdf_image failed!\n"
                   "cmd: {0}\n"
                   "returncode: {1}\n"
                   "message: {2}".format(e.cmd, e.returncode, e.message))

        if not res:
            os.unlink(filepath)
            filepath = ''

        return res, filepath
예제 #16
0
    def CreatePDF(self, task, out, timestamp, data, frame, rows, columns, fileName, VManager):
        ''' Create PDF QgsTask '''

        font_normal = QFont("Helvetica", 8, QFont.Normal)
        font_bold = QFont("Helvetica", 9, QFont.Bold)

        printer = QPrinter(QPrinter.HighResolution)
        printer.setOutputFormat(QPrinter.PdfFormat)

        printer.setPageSize(QPrinter.A4)
        printer.setOutputFileName(out)
        printer.setFullPage(True)

        document = QTextDocument()
        document.setDefaultFont(font_normal)
        document.setPageSize(printer.paperSize(QPrinter.Point));

        cursor = QTextCursor(document)
        video_t = QCoreApplication.translate("QgsFmvMetadata", "Video : ")
        time_t = QCoreApplication.translate("QgsFmvMetadata", "TimeStamp : ")
        
        cursor.insertHtml(
            """
            <p style='text-align: center;'>
            <img style='display: block; margin-left: auto; margin-right: auto;' 
            src=\':/imgFMV/images/header_logo.png\' width='200' height='25' />
            <p style='text-align: center;'>
            <strong>%s</strong>%s<strong>
            <p style='text-align: center;'>
            <strong>%s</strong>%s
            <p></p>
            """
            % (video_t, fileName, time_t, timestamp))

        tableFormat = QTextTableFormat()
        tableFormat.setBorderBrush(QBrush(Qt.black))
        tableFormat.setAlignment(Qt.AlignHCenter)
        tableFormat.setHeaderRowCount(1)
        tableFormat.setCellPadding(2)
        tableFormat.setCellSpacing(2)

        cursor.insertTable(rows + 1, columns, tableFormat)

        tableHeaderFormat = QTextCharFormat()
        tableHeaderFormat.setFont(font_bold)
        tableHeaderFormat.setBackground(QColor("#67b03a"))
        tableHeaderFormat.setForeground(Qt.white)
        tableHeaderFormat.setVerticalAlignment(QTextCharFormat.AlignMiddle)

        alternate_background = QTextCharFormat()
        alternate_background.setBackground(QColor("#DDE9ED"))
        
        for column in range(columns):
            cursor.mergeBlockCharFormat(tableHeaderFormat)
            cursor.insertText(VManager.horizontalHeaderItem(
                column).text())
            cursor.movePosition(QTextCursor.NextCell)

        row = 1
        for key in sorted(data.keys()):
            values = [str(key), str(data[key][0]),str(data[key][1])]
            for column in range(columns):
                cursor.insertText(values[column])
                if (row) % 2 == 0:
                    cursor.mergeBlockCharFormat(alternate_background)
                
                cursor.movePosition(QTextCursor.NextCell)
            row += 1

        cursor.movePosition(QTextCursor.End)

        current_t = QCoreApplication.translate("QgsFmvMetadata", "Current Frame")
        
        self.TextBlockCenter(cursor, TextFormat= QTextFormat.PageBreak_AlwaysBefore)
        
        cursor.insertHtml("""
                          <br><p style='text-align: center;'><strong>""" + current_t +"""</strong></p><br>
                          """)
         
        self.TextBlockCenter(cursor)
        cursor.insertImage(frame.scaledToWidth(500, Qt.SmoothTransformation))
        
        document.print_(printer)
        
        if task.isCanceled():
            return None
        return {'task': task.description()}
예제 #17
0
class ReportWorker(AbstractWorker):
    """Worker class handling report generation"""
    def __init__(self, out_dir):
        super().__init__()
        self.out_dir = out_dir
        self.current_step = 1

        # setup QPrinter
        self.printer = QPrinter()
        self.printer.setPageSize(QPrinter.A4)
        self.printer.setFullPage(True)
        self.printer.setOutputFormat(QPrinter.PdfFormat)

        templates_path = os.path.join(os.path.dirname(__file__),
                                      "report_templates")

        # load templates
        with open(os.path.join(templates_path, "infrastrutture_tmpl.html"),
                  "r") as f:
            self.infrastrutture_tmpl = Template(f.read())
        with open(os.path.join(templates_path, "aree_emerg_tmpl.html"),
                  "r") as f:
            self.aree_emerg_tmpl = Template(f.read())
        with open(os.path.join(templates_path, "aggregati_tmpl.html"),
                  "r") as f:
            self.aggregati_tmpl = Template(f.read())
        with open(os.path.join(templates_path, "edifici_tmpl.html"), "r") as f:
            self.edifici_tmpl = Template(f.read())
        with open(os.path.join(templates_path, "unita_strutt_tmpl.html"),
                  "r") as f:
            self.unita_strutt_tmpl = Template(f.read())

        # load lookup tables
        self.tipo_infra_dict = self._gen_codes_dict("vw_tipo_infra")
        self.pav_per_dict = self._gen_codes_dict("vw_pav_per")
        self.ost_disc_dict = self._gen_codes_dict("vw_ost_disc")
        self.morf_dict = self._gen_codes_dict("vw_morf")
        self.zona_ms_dict = self._gen_codes_dict("vw_zona_ms")
        self.falda_dict = self._gen_codes_dict("vw_falda")
        self.acq_sup_dict = self._gen_codes_dict("vw_acq_sup")
        self.pai_dict = self._gen_codes_dict("vw_pai")
        self.tipo_area_dict = self._gen_codes_dict("vw_tipo_area")
        self.piano_dict = self._gen_codes_dict("vw_piano")
        self.infra_acq_dict = self._gen_codes_dict("vw_infra_acq")
        self.infra_ele_dict = self._gen_codes_dict("vw_infra_ele")
        self.infra_fog_dict = self._gen_codes_dict("vw_infra_fog")
        self.posizio_dict = self._gen_codes_dict("vw_posizio")
        self.specialis_dict = self._gen_codes_dict("vw_specialis")
        self.n_interr_dict = self._gen_codes_dict("vw_n_interr")
        self.alt_piano_dict = self._gen_codes_dict("vw_alt_piano")
        self.strutt_ver_dict = self._gen_codes_dict("vw_strutt_ver")
        self.tipo_mur_dict = self._gen_codes_dict("vw_tipo_mur")
        self.danno_dict = self._gen_codes_dict("vw_danno")
        self.stato_man_dict = self._gen_codes_dict("vw_stato_man")
        self.id_edif_dict = self._gen_codes_dict("vw_id_edif")
        self.uso_att_dict = self._gen_codes_dict("vw_uso_att")
        self.evento_dict = self._gen_codes_dict("vw_evento")
        self.tipo_evento_dict = self._gen_codes_dict("vw_tipo")
        self.verif_sism_dict = self._gen_codes_dict("vw_verif_sism")
        self.utilizz_dict = self._gen_codes_dict("vw_utilizz")

    def _gen_codes_dict(self, lookup_table_name):
        """Generate dictionary with codes from lookup table"""
        lookup_table = QgsProject.instance().mapLayersByName(
            lookup_table_name)[0]
        dict = {}
        for f in lookup_table.getFeatures():
            dict[f["cod"]] = f["descrizione"]
        return dict

    def work(self):
        root = QgsProject.instance().layerTreeRoot()
        cle_group = root.findGroup("CLE")
        cle_layer_nodes = cle_group.children()

        for node in cle_layer_nodes:
            self.set_message.emit(
                f"Generating reports for {node.layer().name()}...")
            features = node.layer().getFeatures()
            cnt = 0

            for feature in features:
                self.generate_report(node.layer().name(), feature)
                cnt += 1
                self.progress.emit(int(cnt * 100 /
                                       node.layer().featureCount()))

                if self.killed:
                    break

            if self.killed:
                raise UserAbortedNotification("User aborted")

        return "Task completed!"

    def generate_report(self, layer_name, feature):
        # self.set_message.emit(f'Generating report for {feature["ID_AC"]} ({layer_name})')

        # dictionary with field names and values of the feature
        attrs_dict = dict(zip(feature.fields().names(), feature.attributes()))

        html = None

        if layer_name.startswith("Infrastrutture"):
            pdf_name = f"{feature['ID_AC']}.pdf"
            if not os.path.exists(os.path.join(self.out_dir,
                                               "Infrastrutture")):
                os.mkdir(os.path.join(self.out_dir, "Infrastrutture"))
            pdf_path = os.path.join(self.out_dir, "Infrastrutture", pdf_name)
            self.printer.setOutputFileName(pdf_path)

            # substitute codes with corresponding values from lookup tables
            attrs_dict["tipo_infra"] = self.tipo_infra_dict[
                attrs_dict["tipo_infra"]]
            attrs_dict["strade_a"] = "&#9745;" if attrs_dict[
                "strade_a"] == "true" else "&#9744;"
            attrs_dict["strade_b"] = "&#9745;" if attrs_dict[
                "strade_b"] == "true" else "&#9744;"
            attrs_dict["strade_c"] = "&#9745;" if attrs_dict[
                "strade_c"] == "true" else "&#9744;"
            attrs_dict["strade_d"] = "&#9745;" if attrs_dict[
                "strade_d"] == "true" else "&#9744;"
            attrs_dict["strade_e"] = "&#9745;" if attrs_dict[
                "strade_e"] == "true" else "&#9744;"
            attrs_dict["strade_f"] = "&#9745;" if attrs_dict[
                "strade_f"] == "true" else "&#9744;"
            attrs_dict["pav_per"] = self.pav_per_dict[attrs_dict["pav_per"]]
            attrs_dict["ost_disc"] = self.ost_disc_dict[attrs_dict["ost_disc"]]
            attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]]
            attrs_dict["ubic_sotto"] = "&#9745;" if attrs_dict[
                "ubic_sotto"] == "true" else "&#9744;"
            attrs_dict["ubic_sopra"] = "&#9745;" if attrs_dict[
                "ubic_sopra"] == "true" else "&#9744;"
            attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]]
            attrs_dict["inst_fran"] = "&#9745;" if attrs_dict[
                "inst_fran"] == "true" else "&#9744;"
            attrs_dict["inst_liq"] = "&#9745;" if attrs_dict[
                "inst_liq"] == "true" else "&#9744;"
            attrs_dict["inst_fag"] = "&#9745;" if attrs_dict[
                "inst_fag"] == "true" else "&#9744;"
            attrs_dict["inst_ced"] = "&#9745;" if attrs_dict[
                "inst_ced"] == "true" else "&#9744;"
            attrs_dict["inst_cav"] = "&#9745;" if attrs_dict[
                "inst_cav"] == "true" else "&#9744;"
            attrs_dict["frana_AC"] = "&#9745;" if attrs_dict[
                "frana_AC"] == "true" else "&#9744;"
            attrs_dict["frana_mon"] = "&#9745;" if attrs_dict[
                "frana_mon"] == "true" else "&#9744;"
            attrs_dict["frana_val"] = "&#9745;" if attrs_dict[
                "frana_val"] == "true" else "&#9744;"
            attrs_dict["falda"] = self.falda_dict[attrs_dict["falda"]]
            attrs_dict["acq_sup"] = self.acq_sup_dict[attrs_dict["acq_sup"]]
            attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]]
            attrs_dict["alluvio"] = "&#9745;" if attrs_dict[
                "alluvio"] == "true" else "&#9744;"

            html = self.infrastrutture_tmpl.substitute(attrs_dict)

        elif layer_name.startswith("Aree"):
            pdf_name = f"{feature['ID_AE']}.pdf"
            if not os.path.exists(os.path.join(self.out_dir,
                                               "Aree_emergenza")):
                os.mkdir(os.path.join(self.out_dir, "Aree_emergenza"))
            pdf_path = os.path.join(self.out_dir, "Aree_emergenza", pdf_name)
            self.printer.setOutputFileName(pdf_path)

            # substitute codes with corresponding values from lookup tables
            attrs_dict["tipo_area"] = self.tipo_area_dict[
                attrs_dict["tipo_area"]]
            attrs_dict["piano"] = self.piano_dict[attrs_dict["piano"]]
            attrs_dict["pav_per"] = self.pav_per_dict[attrs_dict["pav_per"]]
            attrs_dict["infra_acq"] = self.infra_acq_dict[
                attrs_dict["infra_acq"]]
            attrs_dict["infra_ele"] = self.infra_ele_dict[
                attrs_dict["infra_ele"]]
            attrs_dict["infra_fog"] = self.infra_fog_dict[
                attrs_dict["infra_fog"]]
            attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]]
            attrs_dict["ubic_sotto"] = "&#9745;" if attrs_dict[
                "ubic_sotto"] == "true" else "&#9744;"
            attrs_dict["ubic_sopra"] = "&#9745;" if attrs_dict[
                "ubic_sopra"] == "true" else "&#9744;"
            attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]]
            attrs_dict["inst_fran"] = "&#9745;" if attrs_dict[
                "inst_fran"] == "true" else "&#9744;"
            attrs_dict["inst_liq"] = "&#9745;" if attrs_dict[
                "inst_liq"] == "true" else "&#9744;"
            attrs_dict["inst_fag"] = "&#9745;" if attrs_dict[
                "inst_fag"] == "true" else "&#9744;"
            attrs_dict["inst_ced"] = "&#9745;" if attrs_dict[
                "inst_ced"] == "true" else "&#9744;"
            attrs_dict["inst_cav"] = "&#9745;" if attrs_dict[
                "inst_cav"] == "true" else "&#9744;"
            attrs_dict["frana_AE"] = "&#9745;" if attrs_dict[
                "frana_AE"] == "true" else "&#9744;"
            attrs_dict["frana_mon"] = "&#9745;" if attrs_dict[
                "frana_mon"] == "true" else "&#9744;"
            attrs_dict["frana_val"] = "&#9745;" if attrs_dict[
                "frana_val"] == "true" else "&#9744;"
            attrs_dict["falda"] = self.falda_dict[attrs_dict["falda"]]
            attrs_dict["acq_sup"] = self.acq_sup_dict[attrs_dict["acq_sup"]]
            attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]]
            attrs_dict["alluvio"] = "&#9745;" if attrs_dict[
                "alluvio"] == "true" else "&#9744;"

            html = self.aree_emerg_tmpl.substitute(attrs_dict)

        elif layer_name.startswith("Aggregati"):
            pdf_name = f"{feature['ID_AS']}.pdf"
            if not os.path.exists(
                    os.path.join(self.out_dir, "Aggregati_strutturali")):
                os.mkdir(os.path.join(self.out_dir, "Aggregati_strutturali"))
            pdf_path = os.path.join(self.out_dir, "Aggregati_strutturali",
                                    pdf_name)
            self.printer.setOutputFileName(pdf_path)

            # substitute codes with corresponding values from lookup tables
            attrs_dict["conn_volte"] = "&#9745;" if attrs_dict[
                "conn_volte"] == "true" else "&#9744;"
            attrs_dict["conn_rifus"] = "&#9745;" if attrs_dict[
                "conn_rifus"] == "true" else "&#9744;"
            attrs_dict["regol_1"] = "&#9745;" if attrs_dict[
                "regol_1"] == "true" else "&#9744;"
            attrs_dict["regol_2"] = "&#9745;" if attrs_dict[
                "regol_2"] == "true" else "&#9744;"
            attrs_dict["regol_3"] = "&#9745;" if attrs_dict[
                "regol_3"] == "true" else "&#9744;"
            attrs_dict["regol_4"] = "&#9745;" if attrs_dict[
                "regol_4"] == "true" else "&#9744;"
            attrs_dict["regol_5"] = "&#9745;" if attrs_dict[
                "regol_5"] == "true" else "&#9744;"
            attrs_dict["vuln_1"] = "&#9745;" if attrs_dict[
                "vuln_1"] == "true" else "&#9744;"
            attrs_dict["vuln_2"] = "&#9745;" if attrs_dict[
                "vuln_2"] == "true" else "&#9744;"
            attrs_dict["vuln_3"] = "&#9745;" if attrs_dict[
                "vuln_3"] == "true" else "&#9744;"
            attrs_dict["vuln_4"] = "&#9745;" if attrs_dict[
                "vuln_4"] == "true" else "&#9744;"
            attrs_dict["vuln_5"] = "&#9745;" if attrs_dict[
                "vuln_5"] == "true" else "&#9744;"
            attrs_dict["vuln_6"] = "&#9745;" if attrs_dict[
                "vuln_6"] == "true" else "&#9744;"
            attrs_dict["rinfor_1"] = "&#9745;" if attrs_dict[
                "rinfor_1"] == "true" else "&#9744;"
            attrs_dict["rinfor_2"] = "&#9745;" if attrs_dict[
                "rinfor_2"] == "true" else "&#9744;"
            attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]]
            attrs_dict["ubic_sotto"] = "&#9745;" if attrs_dict[
                "ubic_sotto"] == "true" else "&#9744;"
            attrs_dict["ubic_sopra"] = "&#9745;" if attrs_dict[
                "ubic_sopra"] == "true" else "&#9744;"
            attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]]
            attrs_dict["inst_fran"] = "&#9745;" if attrs_dict[
                "inst_fran"] == "true" else "&#9744;"
            attrs_dict["inst_liq"] = "&#9745;" if attrs_dict[
                "inst_liq"] == "true" else "&#9744;"
            attrs_dict["inst_fag"] = "&#9745;" if attrs_dict[
                "inst_fag"] == "true" else "&#9744;"
            attrs_dict["inst_ced"] = "&#9745;" if attrs_dict[
                "inst_ced"] == "true" else "&#9744;"
            attrs_dict["inst_cav"] = "&#9745;" if attrs_dict[
                "inst_cav"] == "true" else "&#9744;"
            attrs_dict["frana_AS"] = "&#9745;" if attrs_dict[
                "frana_AS"] == "true" else "&#9744;"
            attrs_dict["frana_mon"] = "&#9745;" if attrs_dict[
                "frana_mon"] == "true" else "&#9744;"
            attrs_dict["frana_val"] = "&#9745;" if attrs_dict[
                "frana_val"] == "true" else "&#9744;"
            attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]]
            attrs_dict["alluvio"] = "&#9745;" if attrs_dict[
                "alluvio"] == "true" else "&#9744;"

            html = self.aggregati_tmpl.substitute(attrs_dict)

        elif layer_name.startswith("Edifici"):
            pdf_name = f"{feature['ID_ES']}.pdf"
            if not os.path.exists(
                    os.path.join(self.out_dir, "Edifici_strategici")):
                os.mkdir(os.path.join(self.out_dir, "Edifici_strategici"))
            pdf_path = os.path.join(self.out_dir, "Edifici_strategici",
                                    pdf_name)
            self.printer.setOutputFileName(pdf_path)

            # substitute codes with corresponding values from lookup tables
            attrs_dict["isolato"] = "&#9745;" if attrs_dict[
                "isolato"] == "true" else "&#9744;"
            attrs_dict["posizio"] = self.posizio_dict[attrs_dict["posizio"]]
            attrs_dict["fronte"] = "&#9745;" if attrs_dict[
                "fronte"] == "true" else "&#9744;"
            attrs_dict["specialis"] = self.specialis_dict[attrs_dict[
                "specialis"]] if attrs_dict["spec"] == "true" else ""
            attrs_dict["spec"] = "&#9745;" if attrs_dict[
                "spec"] == "true" else "&#9744;"
            attrs_dict["n_interr"] = self.n_interr_dict[attrs_dict["n_interr"]]
            attrs_dict["alt_piano"] = self.alt_piano_dict[
                attrs_dict["alt_piano"]]
            attrs_dict["vol_unico"] = "&#9745;" if attrs_dict[
                "vol_unico"] == "true" else "&#9744;"
            attrs_dict["strutt_ver"] = self.strutt_ver_dict[
                attrs_dict["strutt_ver"]]
            attrs_dict["tipo_mur"] = self.tipo_mur_dict[attrs_dict["tipo_mur"]]
            attrs_dict["cord_cat"] = "&#9745;" if attrs_dict[
                "cord_cat"] == "true" else "&#9744;"
            attrs_dict["pilastri"] = "&#9745;" if attrs_dict[
                "pilastri"] == "true" else "&#9744;"
            attrs_dict["pilotis"] = "&#9745;" if attrs_dict[
                "pilotis"] == "true" else "&#9744;"
            attrs_dict["sopraelev"] = "&#9745;" if attrs_dict[
                "sopraelev"] == "true" else "&#9744;"
            attrs_dict["danno"] = self.danno_dict[attrs_dict["danno"]]
            attrs_dict["stato_man"] = self.stato_man_dict[
                attrs_dict["stato_man"]]
            attrs_dict["pr_pubb"] = "&#9745;" if attrs_dict[
                "pr_pubb"] == "true" else "&#9744;"
            attrs_dict["pr_priv"] = "&#9745;" if attrs_dict[
                "pr_priv"] == "true" else "&#9744;"
            attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]]
            attrs_dict["ubic_sotto"] = "&#9745;" if attrs_dict[
                "ubic_sotto"] == "true" else "&#9744;"
            attrs_dict["ubic_sopra"] = "&#9745;" if attrs_dict[
                "ubic_sopra"] == "true" else "&#9744;"
            attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]]
            attrs_dict["inst_fran"] = "&#9745;" if attrs_dict[
                "inst_fran"] == "true" else "&#9744;"
            attrs_dict["inst_liq"] = "&#9745;" if attrs_dict[
                "inst_liq"] == "true" else "&#9744;"
            attrs_dict["inst_fag"] = "&#9745;" if attrs_dict[
                "inst_fag"] == "true" else "&#9744;"
            attrs_dict["inst_ced"] = "&#9745;" if attrs_dict[
                "inst_ced"] == "true" else "&#9744;"
            attrs_dict["inst_cav"] = "&#9745;" if attrs_dict[
                "inst_cav"] == "true" else "&#9744;"
            attrs_dict["frana_ar"] = "&#9745;" if attrs_dict[
                "frana_ar"] == "true" else "&#9744;"
            attrs_dict["frana_mon"] = "&#9745;" if attrs_dict[
                "frana_mon"] == "true" else "&#9744;"
            attrs_dict["frana_val"] = "&#9745;" if attrs_dict[
                "frana_val"] == "true" else "&#9744;"
            attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]]
            attrs_dict["alluvio"] = "&#9745;" if attrs_dict[
                "alluvio"] == "true" else "&#9744;"
            attrs_dict["ID_edif"] = self.id_edif_dict[attrs_dict["ID_edif"]]
            attrs_dict["emerg_1"] = "&#9745;" if attrs_dict[
                "emerg_1"] == "true" else "&#9744;"
            attrs_dict["emerg_2"] = "&#9745;" if attrs_dict[
                "emerg_2"] == "true" else "&#9744;"
            attrs_dict["emerg_3"] = "&#9745;" if attrs_dict[
                "emerg_3"] == "true" else "&#9744;"
            attrs_dict["emerg_4"] = "&#9745;" if attrs_dict[
                "emerg_4"] == "true" else "&#9744;"
            attrs_dict["emerg_5"] = "&#9745;" if attrs_dict[
                "emerg_5"] == "true" else "&#9744;"
            attrs_dict["emerg_6"] = "&#9745;" if attrs_dict[
                "emerg_6"] == "true" else "&#9744;"
            attrs_dict["uso_orig"] = self.uso_att_dict[attrs_dict["uso_orig"]]
            attrs_dict["uso_att"] = self.uso_att_dict[attrs_dict["uso_att"]]
            attrs_dict["interv"] = "&#9745;" if attrs_dict[
                "interv"] == "true" else "&#9744;"
            attrs_dict["interv_1"] = "&#9745;" if attrs_dict[
                "interv_1"] == "true" else "&#9744;"
            attrs_dict["interv_2"] = "&#9745;" if attrs_dict[
                "interv_2"] == "true" else "&#9744;"
            attrs_dict["interv_3"] = "&#9745;" if attrs_dict[
                "interv_3"] == "true" else "&#9744;"
            attrs_dict["interv_4"] = "&#9745;" if attrs_dict[
                "interv_4"] == "true" else "&#9744;"
            attrs_dict["interv_5"] = "&#9745;" if attrs_dict[
                "interv_5"] == "true" else "&#9744;"
            attrs_dict["interv_6"] = "&#9745;" if attrs_dict[
                "interv_6"] == "true" else "&#9744;"
            attrs_dict["interv_7"] = "&#9745;" if attrs_dict[
                "interv_7"] == "true" else "&#9744;"
            attrs_dict["evento_1"] = self.evento_dict[
                attrs_dict["evento_1"]] if attrs_dict["evento_1"] else ""
            attrs_dict["data_ev_1"] = attrs_dict["data_ev_1"] if attrs_dict[
                "evento_1"] else ""
            attrs_dict["tipo_1"] = self.tipo_evento_dict[
                attrs_dict["tipo_1"]] if attrs_dict["evento_1"] else ""
            attrs_dict["evento_2"] = self.evento_dict[
                attrs_dict["evento_2"]] if attrs_dict["evento_2"] else ""
            attrs_dict["data_ev_2"] = attrs_dict["data_ev_2"] if attrs_dict[
                "evento_2"] else ""
            attrs_dict["tipo_2"] = self.tipo_evento_dict[
                attrs_dict["tipo_2"]] if attrs_dict["evento_2"] else ""
            attrs_dict["evento_3"] = self.evento_dict[
                attrs_dict["evento_3"]] if attrs_dict["evento_3"] else ""
            attrs_dict["data_ev_3"] = attrs_dict["data_ev_3"] if attrs_dict[
                "evento_3"] else ""
            attrs_dict["tipo_3"] = self.tipo_evento_dict[
                attrs_dict["tipo_3"]] if attrs_dict["evento_3"] else ""
            attrs_dict["verif_sism"] = self.verif_sism_dict[
                attrs_dict["verif_sism"]]

            html = self.edifici_tmpl.substitute(attrs_dict)

        elif layer_name.startswith("Unita"):
            pdf_name = f"{feature['ID_US']}.pdf"
            if not os.path.exists(
                    os.path.join(self.out_dir, "Unita_strutturali")):
                os.mkdir(os.path.join(self.out_dir, "Unita_strutturali"))
            pdf_path = os.path.join(self.out_dir, "Unita_strutturali",
                                    pdf_name)
            self.printer.setOutputFileName(pdf_path)

            # substitute codes with corresponding values from lookup tables
            attrs_dict["isolato"] = "&#9745;" if attrs_dict[
                "isolato"] == "true" else "&#9744;"
            attrs_dict["posizio"] = self.posizio_dict[attrs_dict["posizio"]]
            attrs_dict["fronte"] = "&#9745;" if attrs_dict[
                "fronte"] == "true" else "&#9744;"
            attrs_dict["specialis"] = self.specialis_dict[attrs_dict[
                "specialis"]] if attrs_dict["spec"] == "true" else ""
            attrs_dict["spec"] = "&#9745;" if attrs_dict[
                "spec"] == "true" else "&#9744;"
            attrs_dict["n_interr"] = self.n_interr_dict[attrs_dict["n_interr"]]
            attrs_dict["alt_piano"] = self.alt_piano_dict[
                attrs_dict["alt_piano"]]
            attrs_dict["vol_unico"] = "&#9745;" if attrs_dict[
                "vol_unico"] == "true" else "&#9744;"
            attrs_dict["strutt_ver"] = self.strutt_ver_dict[
                attrs_dict["strutt_ver"]]
            attrs_dict["tipo_mur"] = self.tipo_mur_dict[attrs_dict["tipo_mur"]]
            attrs_dict["cord_cat"] = "&#9745;" if attrs_dict[
                "cord_cat"] == "true" else "&#9744;"
            attrs_dict["pilastri"] = "&#9745;" if attrs_dict[
                "pilastri"] == "true" else "&#9744;"
            attrs_dict["pilotis"] = "&#9745;" if attrs_dict[
                "pilotis"] == "true" else "&#9744;"
            attrs_dict["sopraelev"] = "&#9745;" if attrs_dict[
                "sopraelev"] == "true" else "&#9744;"
            attrs_dict["danno"] = self.danno_dict[attrs_dict["danno"]]
            attrs_dict["stato_man"] = self.stato_man_dict[
                attrs_dict["stato_man"]]
            attrs_dict["pr_pubb"] = "&#9745;" if attrs_dict[
                "pr_pubb"] == "true" else "&#9744;"
            attrs_dict["pr_priv"] = "&#9745;" if attrs_dict[
                "pr_priv"] == "true" else "&#9744;"
            attrs_dict["morf"] = self.morf_dict[attrs_dict["morf"]]
            attrs_dict["ubic_sotto"] = "&#9745;" if attrs_dict[
                "ubic_sotto"] == "true" else "&#9744;"
            attrs_dict["ubic_sopra"] = "&#9745;" if attrs_dict[
                "ubic_sopra"] == "true" else "&#9744;"
            attrs_dict["zona_ms"] = self.zona_ms_dict[attrs_dict["zona_ms"]]
            attrs_dict["inst_fran"] = "&#9745;" if attrs_dict[
                "inst_fran"] == "true" else "&#9744;"
            attrs_dict["inst_liq"] = "&#9745;" if attrs_dict[
                "inst_liq"] == "true" else "&#9744;"
            attrs_dict["inst_fag"] = "&#9745;" if attrs_dict[
                "inst_fag"] == "true" else "&#9744;"
            attrs_dict["inst_ced"] = "&#9745;" if attrs_dict[
                "inst_ced"] == "true" else "&#9744;"
            attrs_dict["inst_cav"] = "&#9745;" if attrs_dict[
                "inst_cav"] == "true" else "&#9744;"
            attrs_dict["frana_ar"] = "&#9745;" if attrs_dict[
                "frana_ar"] == "true" else "&#9744;"
            attrs_dict["frana_mon"] = "&#9745;" if attrs_dict[
                "frana_mon"] == "true" else "&#9744;"
            attrs_dict["frana_val"] = "&#9745;" if attrs_dict[
                "frana_val"] == "true" else "&#9744;"
            attrs_dict["pai"] = self.pai_dict[attrs_dict["pai"]]
            attrs_dict["alluvio"] = "&#9745;" if attrs_dict[
                "alluvio"] == "true" else "&#9744;"
            attrs_dict["uso_att"] = self.uso_att_dict[attrs_dict["uso_att"]]
            attrs_dict["uso_a"] = "&#9745;" if attrs_dict[
                "uso_a"] == "true" else "&#9744;"
            attrs_dict["uso_a_1"] = attrs_dict[
                "uso_a_1"] if attrs_dict["uso_a_1"] > 0 else "-"
            attrs_dict["uso_b"] = "&#9745;" if attrs_dict[
                "uso_b"] == "true" else "&#9744;"
            attrs_dict["uso_b_1"] = attrs_dict[
                "uso_b_1"] if attrs_dict["uso_b_1"] > 0 else "-"
            attrs_dict["uso_c"] = "&#9745;" if attrs_dict[
                "uso_c"] == "true" else "&#9744;"
            attrs_dict["uso_c_1"] = attrs_dict[
                "uso_c_1"] if attrs_dict["uso_c_1"] > 0 else "-"
            attrs_dict["uso_d"] = "&#9745;" if attrs_dict[
                "uso_d"] == "true" else "&#9744;"
            attrs_dict["uso_d_1"] = attrs_dict[
                "uso_d_1"] if attrs_dict["uso_d_1"] > 0 else "-"
            attrs_dict["uso_e"] = "&#9745;" if attrs_dict[
                "uso_e"] == "true" else "&#9744;"
            attrs_dict["uso_e_1"] = attrs_dict[
                "uso_e_1"] if attrs_dict["uso_e_1"] > 0 else "-"
            attrs_dict["uso_f"] = "&#9745;" if attrs_dict[
                "uso_f"] == "true" else "&#9744;"
            attrs_dict["uso_f_1"] = attrs_dict[
                "uso_f_1"] if attrs_dict["uso_f_1"] > 0 else "-"
            attrs_dict["uso_g"] = "&#9745;" if attrs_dict[
                "uso_g"] == "true" else "&#9744;"
            attrs_dict["uso_g_1"] = attrs_dict[
                "uso_g_1"] if attrs_dict["uso_g_1"] > 0 else "-"
            attrs_dict["epoca_1"] = "&#9745;" if attrs_dict[
                "epoca_1"] == "true" else "&#9744;"
            attrs_dict["epoca_2"] = "&#9745;" if attrs_dict[
                "epoca_2"] == "true" else "&#9744;"
            attrs_dict["epoca_3"] = "&#9745;" if attrs_dict[
                "epoca_3"] == "true" else "&#9744;"
            attrs_dict["epoca_4"] = "&#9745;" if attrs_dict[
                "epoca_4"] == "true" else "&#9744;"
            attrs_dict["epoca_5"] = "&#9745;" if attrs_dict[
                "epoca_5"] == "true" else "&#9744;"
            attrs_dict["epoca_6"] = "&#9745;" if attrs_dict[
                "epoca_6"] == "true" else "&#9744;"
            attrs_dict["epoca_7"] = "&#9745;" if attrs_dict[
                "epoca_7"] == "true" else "&#9744;"
            attrs_dict["epoca_8"] = "&#9745;" if attrs_dict[
                "epoca_8"] == "true" else "&#9744;"
            attrs_dict["utilizz"] = self.utilizz_dict[attrs_dict["utilizz"]]

            html = self.unita_strutt_tmpl.substitute(attrs_dict)

        if html is not None:
            doc = QTextDocument()
            # weird & broken html subset supported by QTextDocument:
            # https://doc.qt.io/qt-5/richtext-html-subset.html
            doc.setHtml(html)
            doc.print(self.printer)