Example #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(
                "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)
Example #2
0
    def add_data_row(self, data, title, uom, station_name = None):
        plot_item = PlotItem(size=QSizeF(self.__scene.width(), self.DEFAULT_ROW_HEIGHT),
                             render_type = POINT_RENDERER,
                             x_orientation = ORIENTATION_LEFT_TO_RIGHT,
                             y_orientation = ORIENTATION_UPWARD)

        plot_item.set_layer(data.get_layer())
        plot_item.tooltipRequested.connect(lambda txt:self.on_plot_tooltip(station_name, txt))

        legend_item = LegendItem(self.DEFAULT_ROW_HEIGHT, title, unit_of_measure=uom, is_vertical=True)
        data.data_modified.connect(lambda data=data : self._update_data_row(data))

        if self._min_x is None:
            self._min_x, self._max_x = data.get_x_min(), data.get_x_max()
            # if we have only one value, center it on a 2 minutes range
            if self._min_x == self._max_x:
                self._min_x -= 60
                self._max_x += 60
            self.add_time_scale()

        self.__data2logitems[data] = (plot_item, legend_item)
        self._add_row(plot_item, legend_item)
        self._update_data_row(data)
        self._update_row_depths()
Example #3
0
    def testHtmlAnnotationWithFeature(self):
        """ test rendering a html annotation with a feature"""
        layer = QgsVectorLayer(
            "Point?crs=EPSG:3111&field=station:string&field=suburb:string",
            'test', "memory")

        a = QgsHtmlAnnotation()
        a.fillSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0))
        a.markerSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0))
        a.setFrameSizeMm(QSizeF(400 / 3.7795275, 250 / 3.7795275))
        a.setFrameOffsetFromReferencePointMm(
            QPointF(70 / 3.7795275, 90 / 3.7795275))
        a.setMapLayer(layer)
        html = TEST_DATA_DIR + "/test_html_feature.html"
        a.setSourceFile(html)
        im = self.renderAnnotation(a, QPointF(20, 30))
        self.assertTrue(self.imageCheck('html_nofeature', 'html_nofeature',
                                        im))
        f = QgsFeature(layer.fields())
        f.setValid(True)
        f.setAttributes(['hurstbridge', 'somewhere'])
        a.setAssociatedFeature(f)
        im = self.renderAnnotation(a, QPointF(20, 30))
        self.assertTrue(self.imageCheck('html_feature', 'html_feature', im))
    def testSettingFeature(self):
        """ test that feature is set when item moves """
        a = QgsTextAnnotation()
        a.setFrameSize(QSizeF(300, 200))
        a.setFrameOffsetFromReferencePoint(QPointF(40, 50))
        a.setHasFixedMapPosition(True)
        a.setMapPosition(QgsPointXY(12, 34))
        a.setMapPositionCrs(QgsCoordinateReferenceSystem(4326))

        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)

        canvas.setExtent(QgsRectangle(10, 30, 20, 35))

        i = QgsMapCanvasAnnotationItem(a, canvas)  # NOQA

        layer = QgsVectorLayer(
            "Point?crs=EPSG:4326&field=station:string&field=suburb:string",
            'test', "memory")
        canvas.setLayers([layer])
        f = QgsFeature(layer.fields())
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(14, 31)))
        f.setValid(True)
        f.setAttributes(['hurstbridge', 'somewhere'])
        self.assertTrue(layer.dataProvider().addFeatures([f]))
        a.setMapLayer(layer)
        self.assertFalse(a.associatedFeature().isValid())

        a.setMapPosition(QgsPointXY(14, 31))
        self.assertTrue(a.associatedFeature().isValid())
        self.assertEqual(a.associatedFeature().attributes()[0], 'hurstbridge')

        a.setMapPosition(QgsPointXY(17, 31))
        self.assertFalse(a.associatedFeature().isValid())
Example #5
0
    def testPlot(self):
        plot = Qgs2DPlot()
        plot.setSize(QSizeF(600, 500))

        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_style': 'no'
        })
        plot.setChartBackgroundSymbol(sym1)

        sym2 = QgsFillSymbol.createSimple({
            'outline_color': '#0000ff',
            'style': 'no',
            'outline_style': 'solid',
            'outline_width': 1
        })
        plot.setChartBorderSymbol(sym2)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#00ffff',
            'outline_width': 1
        })
        plot.xAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff00ff',
            'outline_width': 0.5
        })
        plot.xAxis().setGridMinorSymbol(sym4)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#0066ff',
            'outline_width': 1
        })
        plot.yAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff4433',
            'outline_width': 0.5
        })
        plot.yAxis().setGridMinorSymbol(sym4)

        font = QgsFontUtils.getStandardTestFont('Bold', 16)
        x_axis_format = QgsTextFormat.fromQFont(font)
        x_axis_format.setColor(QColor(255, 0, 0))
        plot.xAxis().setTextFormat(x_axis_format)

        x_axis_number_format = QgsBasicNumericFormat()
        x_axis_number_format.setNumberDecimalPlaces(1)
        x_axis_number_format.setShowTrailingZeros(True)
        plot.xAxis().setNumericFormat(x_axis_number_format)

        font = QgsFontUtils.getStandardTestFont('Bold', 18)
        y_axis_format = QgsTextFormat.fromQFont(font)
        y_axis_format.setColor(QColor(0, 255, 0))
        plot.yAxis().setTextFormat(y_axis_format)

        y_axis_number_format = QgsBasicNumericFormat()
        y_axis_number_format.setShowPlusSign(True)
        plot.yAxis().setNumericFormat(y_axis_number_format)

        plot.setXMinimum(3)
        plot.setXMaximum(9)

        plot.setYMinimum(2)
        plot.setYMaximum(12)

        im = QImage(600, 500, QImage.Format_ARGB32)
        im.fill(Qt.white)
        im.setDotsPerMeterX(int(96 / 25.4 * 1000))
        im.setDotsPerMeterY(int(96 / 25.4 * 1000))

        painter = QPainter(im)
        rc = QgsRenderContext.fromQPainter(painter)
        plot.render(rc)
        painter.end()

        assert self.imageCheck('plot_2d_base', 'plot_2d_base', im)

        plot_rect = plot.interiorPlotArea(rc)
        self.assertAlmostEqual(plot_rect.left(), 64.8, 0)
        self.assertAlmostEqual(plot_rect.right(), 592.44, 0)
        self.assertAlmostEqual(plot_rect.top(), 7.559, 0)
        self.assertAlmostEqual(plot_rect.bottom(), 465.55, 0)
Example #6
0
    def testOptimiseIntervals(self):
        plot = Qgs2DPlot()
        plot.setSize(QSizeF(600, 500))

        font = QgsFontUtils.getStandardTestFont('Bold', 16)
        x_axis_format = QgsTextFormat.fromQFont(font)
        plot.xAxis().setTextFormat(x_axis_format)

        font = QgsFontUtils.getStandardTestFont('Bold', 18)
        y_axis_format = QgsTextFormat.fromQFont(font)
        plot.yAxis().setTextFormat(y_axis_format)

        plot.setXMinimum(3)
        plot.setXMaximum(13)
        plot.setYMinimum(2)
        plot.setYMaximum(12)

        im = QImage(600, 500, QImage.Format_ARGB32)
        im.fill(Qt.white)
        im.setDotsPerMeterX(int(96 / 25.4 * 1000))
        im.setDotsPerMeterY(int(96 / 25.4 * 1000))

        painter = QPainter(im)
        rc = QgsRenderContext.fromQPainter(painter)
        painter.end()

        plot.calculateOptimisedIntervals(rc)
        self.assertEqual(plot.xAxis().labelInterval(), 1)
        self.assertEqual(plot.yAxis().labelInterval(), 2)
        self.assertEqual(plot.xAxis().gridIntervalMinor(), 1)
        self.assertEqual(plot.yAxis().gridIntervalMinor(), 1)
        self.assertEqual(plot.xAxis().gridIntervalMajor(), 5)
        self.assertEqual(plot.yAxis().gridIntervalMajor(), 4)

        plot.setXMinimum(3)
        plot.setXMaximum(113)
        plot.setYMinimum(2)
        plot.setYMaximum(112)

        plot.calculateOptimisedIntervals(rc)
        self.assertEqual(plot.xAxis().labelInterval(), 20)
        self.assertEqual(plot.yAxis().labelInterval(), 20)
        self.assertEqual(plot.xAxis().gridIntervalMinor(), 10)
        self.assertEqual(plot.yAxis().gridIntervalMinor(), 10)
        self.assertEqual(plot.xAxis().gridIntervalMajor(), 40)
        self.assertEqual(plot.yAxis().gridIntervalMajor(), 40)

        plot.setXMinimum(0.3)
        plot.setXMaximum(0.5)
        plot.setYMinimum(1.1)
        plot.setYMaximum(2)

        plot.calculateOptimisedIntervals(rc)
        self.assertEqual(plot.xAxis().labelInterval(), 0.05)
        self.assertEqual(plot.yAxis().labelInterval(), 0.2)
        self.assertEqual(plot.xAxis().gridIntervalMinor(), 0.025)
        self.assertEqual(plot.yAxis().gridIntervalMinor(), 0.1)
        self.assertEqual(plot.xAxis().gridIntervalMajor(), 0.1)
        self.assertEqual(plot.yAxis().gridIntervalMajor(), 0.4)

        plot.setXMinimum(-10)
        plot.setXMaximum(0)
        plot.setYMinimum(-10000)
        plot.setYMaximum(-500)

        plot.calculateOptimisedIntervals(rc)
        self.assertEqual(plot.xAxis().labelInterval(), 2)
        self.assertEqual(plot.yAxis().labelInterval(), 2000)
        self.assertEqual(plot.xAxis().gridIntervalMinor(), 1)
        self.assertEqual(plot.yAxis().gridIntervalMinor(), 1000)
        self.assertEqual(plot.xAxis().gridIntervalMajor(), 4)
        self.assertEqual(plot.yAxis().gridIntervalMajor(), 4000)

        plot.setXMinimum(100000)
        plot.setXMaximum(200000)

        plot.calculateOptimisedIntervals(rc)
        self.assertEqual(plot.xAxis().labelInterval(), 100000)
        self.assertEqual(plot.xAxis().gridIntervalMinor(), 50000)
        self.assertEqual(plot.xAxis().gridIntervalMajor(), 200000)
Example #7
0
    def testPlotDataDefinedProperties(self):
        plot = Qgs2DPlot()
        plot.setSize(QSizeF(600, 500))

        sym1 = QgsFillSymbol.createSimple({
            'color': '#ffffff',
            'outline_style': 'no'
        })
        plot.setChartBackgroundSymbol(sym1)

        sym2 = QgsFillSymbol.createSimple({
            'outline_color': '#000000',
            'style': 'no',
            'outline_style': 'solid',
            'outline_width': 1
        })
        plot.setChartBorderSymbol(sym2)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#00ffff',
            'outline_width': 1,
            'capstyle': 'flat'
        })
        sym3[0].setDataDefinedProperty(
            QgsSymbolLayer.PropertyStrokeWidth,
            QgsProperty.fromExpression(
                'case when @plot_axis_value = 10 then 3 else 1 end'))
        plot.xAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff00ff',
            'outline_width': 0.5,
            'capstyle': 'flat'
        })
        sym4[0].setDataDefinedProperty(
            QgsSymbolLayer.PropertyStrokeWidth,
            QgsProperty.fromExpression(
                'case when @plot_axis_value = 6 then 3 else 0.5 end'))
        plot.xAxis().setGridMinorSymbol(sym4)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#0066ff',
            'outline_width': 1,
            'capstyle': 'flat'
        })
        sym3[0].setDataDefinedProperty(
            QgsSymbolLayer.PropertyStrokeWidth,
            QgsProperty.fromExpression(
                'case when @plot_axis_value = 5 then 3 else 0.5 end'))
        plot.yAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff4433',
            'outline_width': 0.5,
            'capstyle': 'flat'
        })
        sym4[0].setDataDefinedProperty(
            QgsSymbolLayer.PropertyStrokeWidth,
            QgsProperty.fromExpression(
                'case when @plot_axis_value = 9 then 3 else 0.5 end'))
        plot.yAxis().setGridMinorSymbol(sym4)

        font = QgsFontUtils.getStandardTestFont('Bold', 16)
        x_axis_format = QgsTextFormat.fromQFont(font)
        x_axis_format.dataDefinedProperties().setProperty(
            QgsPalLayerSettings.Color,
            QgsProperty.fromExpression(
                'case when @plot_axis_value %3 = 0 then \'#ff0000\' else \'#000000\' end'
            ))
        plot.xAxis().setTextFormat(x_axis_format)

        font = QgsFontUtils.getStandardTestFont('Bold', 18)
        y_axis_format = QgsTextFormat.fromQFont(font)
        y_axis_format.dataDefinedProperties().setProperty(
            QgsPalLayerSettings.Color,
            QgsProperty.fromExpression(
                'case when @plot_axis_value %4 = 0 then \'#0000ff\' else \'#000000\' end'
            ))
        plot.yAxis().setTextFormat(y_axis_format)

        plot.setXMinimum(3)
        plot.setXMaximum(13)

        plot.setYMinimum(2)
        plot.setYMaximum(12)

        im = QImage(600, 500, QImage.Format_ARGB32)
        im.fill(Qt.white)
        im.setDotsPerMeterX(int(96 / 25.4 * 1000))
        im.setDotsPerMeterY(int(96 / 25.4 * 1000))

        painter = QPainter(im)
        rc = QgsRenderContext.fromQPainter(painter)
        plot.render(rc)
        painter.end()

        assert self.imageCheck('plot_2d_data_defined', 'plot_2d_data_defined',
                               im)

        plot_rect = plot.interiorPlotArea(rc)
        self.assertAlmostEqual(plot_rect.left(), 44.71, 0)
        self.assertAlmostEqual(plot_rect.right(), 592.44, 0)
        self.assertAlmostEqual(plot_rect.top(), 7.559, 0)
        self.assertAlmostEqual(plot_rect.bottom(), 465.55, 0)
Example #8
0
    def testPlotIntervals(self):
        plot = Qgs2DPlot()
        plot.setSize(QSizeF(600, 500))

        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_style': 'no'
        })
        plot.setChartBackgroundSymbol(sym1)

        sym2 = QgsFillSymbol.createSimple({
            'outline_color': '#0000ff',
            'style': 'no',
            'outline_style': 'solid',
            'outline_width': 1
        })
        plot.setChartBorderSymbol(sym2)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#00ffff',
            'outline_width': 1
        })
        plot.xAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff00ff',
            'outline_width': 0.5
        })
        plot.xAxis().setGridMinorSymbol(sym4)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#0066ff',
            'outline_width': 1
        })
        plot.yAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff4433',
            'outline_width': 0.5
        })
        plot.yAxis().setGridMinorSymbol(sym4)

        font = QgsFontUtils.getStandardTestFont('Bold', 16)
        x_axis_format = QgsTextFormat.fromQFont(font)
        plot.xAxis().setTextFormat(x_axis_format)

        font = QgsFontUtils.getStandardTestFont('Bold', 18)
        y_axis_format = QgsTextFormat.fromQFont(font)
        plot.yAxis().setTextFormat(y_axis_format)

        plot.setXMinimum(1)
        plot.setXMaximum(21)

        plot.setYMinimum(27)
        plot.setYMaximum(327)

        plot.xAxis().setGridIntervalMajor(10)
        plot.xAxis().setGridIntervalMinor(2)

        plot.yAxis().setGridIntervalMajor(100)
        plot.yAxis().setGridIntervalMinor(50)

        plot.xAxis().setLabelInterval(5)
        plot.yAxis().setLabelInterval(70)

        im = QImage(600, 500, QImage.Format_ARGB32)
        im.fill(Qt.white)
        im.setDotsPerMeterX(int(96 / 25.4 * 1000))
        im.setDotsPerMeterY(int(96 / 25.4 * 1000))

        painter = QPainter(im)
        rc = QgsRenderContext.fromQPainter(painter)
        plot.render(rc)
        painter.end()

        assert self.imageCheck('plot_2d_intervals', 'plot_2d_intervals', im)
Example #9
0
class PointRotationItem(QgsMapCanvasItem):
    """
    A map canvas item which shows an angle display and preview of marker rotation
    """
    def __init__(self, canvas):
        super().__init__(canvas)

        self.rotation = 0
        self.pixmap = QPixmap()
        self.item_size = QSizeF()

        self.marker_font = QFont()
        self.marker_font.setPointSize(12)
        self.marker_font.setBold(True)

        self.arrow_path = QPainterPath()

        im = QImage(24, 24, QImage.Format_ARGB32)
        im.fill(Qt.transparent)
        self.set_symbol(im)

    def paint(self, painter, option, widget):
        if not painter:
            return

        painter.save()
        painter.setRenderHint(QPainter.Antialiasing, True)

        # do a bit of trigonometry to find out how to transform a rotated item such
        # that the center point is at the point feature
        x = 0.0
        y = 0.0

        if self.pixmap.width() > 0 and self.pixmap.height() > 0:
            half_item_diagonal = math.sqrt(
                self.pixmap.width() * self.pixmap.width() +
                self.pixmap.height() * self.pixmap.height()) / 2
            diagonal_angle = math.acos(
                self.pixmap.width() / (half_item_diagonal * 2)) * 180 / math.pi
            x = half_item_diagonal * math.cos(
                (self.rotation - diagonal_angle) * math.pi / 180)
            y = half_item_diagonal * math.sin(
                (self.rotation - diagonal_angle) * math.pi / 180)

        painter.rotate(self.rotation)
        painter.translate(x - self.pixmap.width() / 2.0,
                          -y - self.pixmap.height() / 2.0)
        painter.drawPixmap(0, 0, self.pixmap)

        # draw arrow, using a red line over a thicker white line so that the arrow is visible
        # against a range of backgrounds
        pen = QPen()
        pen.setWidth(GuiUtils.scale_icon_size(4))
        pen.setColor(QColor(Qt.white))
        painter.setPen(pen)
        painter.drawPath(self.arrow_path)
        pen.setWidth(GuiUtils.scale_icon_size(1))
        pen.setColor(QColor(Qt.red))
        painter.setPen(pen)
        painter.drawPath(self.arrow_path)
        painter.restore()

        # draw numeric value beside the symbol
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing, True)

        buffer_pen = QPen()
        buffer_pen.setColor(Qt.white)
        buffer_pen.setWidthF(GuiUtils.scale_icon_size(4))
        fm = QFontMetricsF(self.marker_font)
        label = QPainterPath()
        label.addText(self.pixmap.width(),
                      self.pixmap.height() / 2.0 + fm.height() / 2.0,
                      self.marker_font, str(round(self.rotation, 1)))
        painter.setPen(buffer_pen)
        painter.setBrush(Qt.NoBrush)
        painter.drawPath(label)
        painter.setPen(Qt.NoPen)
        painter.setBrush(QBrush(Qt.black))
        painter.drawPath(label)

        painter.restore()

    def set_point_location(self, p):
        transformed_point = self.toCanvasCoordinates(p)
        self.setPos(transformed_point.x() - self.pixmap.width() / 2.0,
                    transformed_point.y() - self.pixmap.height() / 2.0)

    def set_symbol_rotation(self, rotation: float):
        self.rotation = rotation

    def set_symbol(self, symbol_image: QImage):
        self.pixmap = QPixmap.fromImage(symbol_image)
        fm = QFontMetricsF(self.marker_font)

        # set item size
        self.item_size.setWidth(self.pixmap.width() + fm.width("360"))

        pixmap_height = self.pixmap.height()
        font_height = fm.height()
        if pixmap_height >= font_height:
            self.item_size.setHeight(self.pixmap.height())
        else:
            self.item_size.setHeight(fm.height())

        half_item_width = self.pixmap.width() / 2.0
        self.arrow_path = QPainterPath()
        self.arrow_path.moveTo(half_item_width, pixmap_height)
        self.arrow_path.lineTo(half_item_width, 0)
        self.arrow_path.moveTo(self.pixmap.width() * 0.25,
                               pixmap_height * 0.25)
        self.arrow_path.lineTo(half_item_width, 0)
        self.arrow_path.lineTo(self.pixmap.width() * 0.75,
                               pixmap_height * 0.25)
Example #10
0
    def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        ''' draw the result '''
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = -1
        for row in rows:
            cur2 = con.cursor()
            args['result_path_id'] = row[0]
            args['result_source_id'] = row[1]
            args['result_target_id'] = row[2]
            args['result_cost'] = row[3]
            if args['result_path_id'] != cur_path_id:
                cur_path_id = args['result_path_id']
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas,
                                           Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)
            if args['result_cost'] != -1:
                query2 = """
                    SELECT ST_AsText( ST_MakeLine(
                        (SELECT the_geom FROM  %(edge_table)s_vertices_pgr WHERE id = %(result_source_id)d),
                        (SELECT the_geom FROM  %(edge_table)s_vertices_pgr WHERE id = %(result_target_id)d)
                        ))
                    """ % args
                ##Utils.logMessage(query2)
                cur2.execute(query2)
                row2 = cur2.fetchone()
                ##Utils.logMessage(str(row2[0]))
                assert row2, "Invalid result geometry. (path_id:%(result_path_id)d, saource_id:%(result_source_id)d, target_id:%(result_target_id)d)" % args

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
        resultNodesTextAnnotations = canvasItemList['annotations']
        Utils.setStartPoint(geomType, args)
        Utils.setEndPoint(geomType, args)
        for row in rows:
            cur2 = con.cursor()
            args['result_seq'] = row[0]
            args['result_source_id'] = row[1]
            args['result_target_id'] = row[2]
            args['result_cost'] = row[3]
            query2 = """
                SELECT ST_AsText(%(transform_s)s%(startpoint)s%(transform_e)s) FROM %(edge_table)s
                    WHERE %(source)s = %(result_target_id)d
                UNION
                SELECT ST_AsText(%(transform_s)s%(endpoint)s%(transform_e)s) FROM %(edge_table)s
                    WHERE %(target)s = %(result_target_id)d
            """ % args
            cur2.execute(query2)
            row2 = cur2.fetchone()
            assert row2, "Invalid result geometry. (target_id:%(result_target_id)d)" % args

            geom = QgsGeometry().fromWkt(str(row2[0]))
            pt = geom.asPoint()
            textDocument = QTextDocument(
                "%(result_target_id)d:%(result_cost)f" % args)
            textAnnotation = QgsTextAnnotation()
            textAnnotation.setMapPosition(geom.asPoint())
            textAnnotation.setFrameSize(QSizeF(textDocument.idealWidth(), 20))
            textAnnotation.setFrameOffsetFromReferencePoint(QPointF(20, -40))
            textAnnotation.setDocument(textDocument)

            QgsMapCanvasAnnotationItem(textAnnotation, mapCanvas)
            resultNodesTextAnnotations.append(textAnnotation)
Example #11
0
    def testFills(self):
        shape = QgsLegendPatchShape(
            QgsSymbol.Fill,
            QgsGeometry.fromWkt('Polygon((5 5, 1 2, 3 4, 5 5))'), False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(1,
                                                                        1))),
            [[[[1.0, 0.0], [0.0, 1.0], [0.5, 0.333], [1.0, 0.0]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(10,
                                                                        2))),
            [[[[10.0, 0.0], [0.0, 2.0], [5.0, 0.667], [10.0, 0.0]]]])

        # requesting different symbol type, should return default
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(1,
                                                                        1))),
            [[[[0.0, 0.5], [1.0, 0.5]]]])

        # rings
        shape = QgsLegendPatchShape(
            QgsSymbol.Fill,
            QgsGeometry.fromWkt(
                'Polygon((5 5, 1 2, 3 4, 5 5), (4.5 4.5, 4.4 4.4, 4.5 4.4, 4.5 4.5))'
            ), False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(1,
                                                                        1))),
            [[[[1.0, 0.0], [0.0, 1.0], [0.5, 0.333], [1.0, 0.0]],
              [[0.875, 0.167], [0.85, 0.2], [0.875, 0.2], [0.875, 0.167]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(10,
                                                                        2))),
            [[[[10.0, 0.0], [0.0, 2.0], [5.0, 0.667], [10.0, 0.0]],
              [[8.75, 0.333], [8.5, 0.4], [8.75, 0.4], [8.75, 0.333]]]])

        # circular
        shape = QgsLegendPatchShape(
            QgsSymbol.Fill,
            QgsGeometry.fromWkt(
                'CurvePolygon(CircularString(5 5, 3 4, 1 2, 3 0, 5 5))'),
            False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill,
                                                 QSizeF(1, 1)))[0][0][:5],
            [[0.746, -0.0], [0.722, 0.009], [0.698, 0.018], [0.675, 0.028],
             [0.651, 0.038]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill,
                                                 QSizeF(10, 2)))[0][0][:5],
            [[7.459, -0.0], [6.83, 0.04], [6.201, 0.09], [5.574, 0.151],
             [4.947, 0.223]])

        # multipolygon
        shape = QgsLegendPatchShape(
            QgsSymbol.Fill,
            QgsGeometry.fromWkt(
                'MultiPolygon(((5 5, 1 2, 3 4, 5 5), (4.5 4.5, 4.4 4.4, 4.5 4.4, 4.5 4.5)),((10 11, 11 11, 11 10, 10 11)))'
            ), False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(1,
                                                                        1))),
            [[[[0.4, 0.667], [0.0, 1.0], [0.2, 0.778], [0.4, 0.667]],
              [[0.35, 0.722], [0.34, 0.733], [0.35, 0.733], [0.35, 0.722]]],
             [[[0.9, 0.0], [1.0, 0.0], [1.0, 0.111], [0.9, 0.0]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(10,
                                                                        2))),
            [[[[4.0, 1.333], [0.0, 2.0], [2.0, 1.556], [4.0, 1.333]],
              [[3.5, 1.444], [3.4, 1.467], [3.5, 1.467], [3.5, 1.444]]],
             [[[9.0, 0.0], [10.0, 0.0], [10.0, 0.222], [9.0, 0.0]]]])
Example #12
0
    def convert_fill_symbol_background(
            background_symbol,  # pylint: disable=too-many-branches,too-many-statements
            context,
            reference_scale=None):
        """
        Converts a fill symbol background to QgsTextBackgroundSettings
        """
        settings = QgsTextBackgroundSettings()
        settings.setEnabled(True)
        settings.setType(QgsTextBackgroundSettings.ShapeRectangle)
        if isinstance(background_symbol, BalloonCallout):
            fill_symbol = background_symbol.fill_symbol

            if background_symbol.style == BalloonCallout.STYLE_ROUNDED_RECTANGLE:
                # TODO - confirm actual size rendering on Arc
                settings.setRadii(QSizeF(1, 1))
            elif background_symbol.style == BalloonCallout.STYLE_OVAL:
                # TODO - verify comparitive rendering
                settings.setType(QgsTextBackgroundSettings.ShapeEllipse)
        else:
            fill_symbol = background_symbol.border_symbol

        from .symbols import SymbolConverter  # pylint: disable=import-outside-toplevel

        # can't use the fill itself - we can only use the fill color and outline
        if isinstance(fill_symbol, SimpleFillSymbol):
            if not fill_symbol.color.is_null:
                fill_color = ColorConverter.color_to_qcolor(fill_symbol.color)
                settings.setFillColor(fill_color)
            else:
                settings.setFillColor(QColor())

            if isinstance(fill_symbol.outline, SimpleLineSymbol):
                if not fill_symbol.outline.color.is_null:
                    settings.setStrokeColor(
                        ColorConverter.color_to_qcolor(
                            fill_symbol.outline.color))
                    if reference_scale is None:
                        settings.setStrokeWidth(
                            context.convert_size(fill_symbol.outline.width))
                        settings.setStrokeWidthUnit(context.units)
                    else:
                        settings.setStrokeWidth(fill_symbol.outline.width *
                                                reference_scale * 0.000352778)
                        settings.setStrokeWidthUnit(
                            QgsUnitTypes.RenderMetersInMapUnits)
            else:
                stroke = SymbolConverter.Symbol_to_QgsSymbol(
                    fill_symbol, context)
                if stroke:
                    settings.setStrokeColor(stroke.color())
                    if reference_scale is None:
                        settings.setStrokeWidth(0.2)
                        settings.setStrokeWidthUnit(
                            QgsUnitTypes.RenderMillimeters)
                    else:
                        settings.setStrokeWidth(0.2 * reference_scale * 0.001)
                        settings.setStrokeWidthUnit(
                            QgsUnitTypes.RenderMetersInMapUnits)
        else:
            symbol = SymbolConverter.Symbol_to_QgsSymbol(fill_symbol, context)
            settings.setFillColor(symbol.color())

        settings.setSizeType(QgsTextBackgroundSettings.SizeBuffer)
        # TODO: margin
        x_margin = (background_symbol.margin_left +
                    background_symbol.margin_right) / 2
        y_margin = (background_symbol.margin_top +
                    background_symbol.margin_bottom) / 2

        x_delta = (background_symbol.margin_right -
                   background_symbol.margin_left) / 2
        y_delta = (background_symbol.margin_bottom -
                   background_symbol.margin_top) / 2

        if reference_scale is None:
            settings.setSize(
                QSizeF(context.convert_size(x_margin),
                       context.convert_size(y_margin)))
            settings.setSizeUnit(context.units)
        else:
            settings.setSize(
                QSizeF(x_margin * reference_scale * 0.000352778,
                       y_margin * reference_scale * 0.000352778))
            settings.setSizeUnit(QgsUnitTypes.RenderMetersInMapUnits)

        if reference_scale is None:
            settings.setOffset(
                QPointF(context.convert_size(x_delta),
                        context.convert_size(y_delta)))
            settings.setOffsetUnit(context.units)
        else:
            settings.setOffset(
                QPointF(x_delta * reference_scale * 0.000352778,
                        y_delta * reference_scale * 0.000352778))
            settings.setOffsetUnit(QgsUnitTypes.RenderMetersInMapUnits)

        return settings
Example #13
0
    def run(self):
        project_id = self.settings.value("project/id")
        epsg = self.settings.value("project/epsg")

        locale = QSettings().value('locale/userLocale')[0:2]

        if not project_id:
            self.message_bar.pushCritical(
                "Error",
                _translate("VeriSO_EE_Geb_LokTest", "project_id not set",
                           None))
            return

        QApplication.setOverrideCursor(Qt.WaitCursor)
        try:
            group = _translate("VeriSO_EE_Geb_LokTest",
                               "Gebaeudeadressen - Lokalisationstest", None)
            group += " (" + str(project_id) + ")"

            # TODO: Check "tid" vs. t_ili_tid... in queries. Do not import
            # i_ili_tid?

            # define layer names here
            lokalisation = _translate("VeriSO_EE_Geb_LokTest",
                                      "Lokalisation Lokalisationstest", None)
            strassenstueck_geometrie = _translate(
                "VeriSO_EE_Geb_LokTest", "Strassenstueck (geometrie) "
                "Lokalisationstest", None)
            strassenstueck_anfangspunkt = _translate(
                "VeriSO_EE_Geb_LokTest", "Strassenstueck ("
                "anfangspunkt) "
                "Lokalisationstest", None)
            benanntesgebiet = _translate("VeriSO_EE_Geb_LokTest",
                                         "Benanntes Gebiet Lokalisationstest",
                                         None)
            gebaeudeeingang = _translate("VeriSO_EE_Geb_LokTest",
                                         "Gebaeudeeingang Lokalisationstest",
                                         None)
            shortestline = _translate("VeriSO_EE_Geb_LokTest",
                                      "Kuerzeste Linie Lokalisationstest",
                                      None)
            hausnummerpos = _translate("VeriSO_EE_Geb_LokTest",
                                       "HausnummerPos Lokalisationstest", None)
            lokalisationsname = _translate("VeriSO_EE_Geb_LokTest",
                                           "LokalisationsName", None)

            vlayer_lokalisation = self.get_vector_layer_by_name(lokalisation)
            if not vlayer_lokalisation:
                layer = {
                    "type": "postgres",
                    "title": lokalisation,
                    "featuretype": "gebaeudeadressen_lokalisation",
                    "key": "ogc_fid",
                    "sql": "ogc_fid = -1",
                    "readonly": True,
                    "group": group
                }
                vlayer_lokalisation = self.layer_loader.load(layer)

            vlayer_strassenstueck_geometrie = self.get_vector_layer_by_name(
                strassenstueck_geometrie)
            if not vlayer_strassenstueck_geometrie:
                layer = {
                    "type":
                    "postgres",
                    "title":
                    "Strassenstueck (geometrie) Lokalisationstest",
                    "featuretype":
                    "gebaeudeadressen_strassenstueck",
                    "geom":
                    "geometrie",
                    "key":
                    "ogc_fid",
                    "sql":
                    "strassenstueck_von = -1",
                    "readonly":
                    True,
                    "group":
                    group,
                    "style":
                    "global_qml/gebaeudeadressen/strassenachsen_rot"
                    ".qml"
                }
                vlayer_strassenstueck_geometrie = self.layer_loader.load(layer)

            vlayer_strassenstueck_anfangspunkt = self.get_vector_layer_by_name(
                strassenstueck_anfangspunkt)
            if not vlayer_strassenstueck_anfangspunkt:
                layer = {
                    "type": "postgres",
                    "title": "Strassenstueck (anfangspunkt) Lokalisationstest",
                    "featuretype": "gebaeudeadressen_strassenstueck",
                    "geom": "anfangspunkt",
                    "key": "ogc_fid",
                    "sql": "strassenstueck_von = -1",
                    "readonly": True,
                    "group": group,
                    "style": "global_qml/gebaeudeadressen/anfangspunkt_rot.qml"
                }
                vlayer_strassenstueck_anfangspunkt = self.layer_loader.load(
                    layer)

            vlayer_benanntesgebiet = self.get_vector_layer_by_name(
                benanntesgebiet)
            if not vlayer_benanntesgebiet:
                layer = {
                    "type":
                    "postgres",
                    "title":
                    "Benanntes Gebiet Lokalisationstest",
                    "featuretype":
                    "gebaeudeadressen_benanntesgebiet",
                    "geom":
                    "flaeche",
                    "key":
                    "ogc_fid",
                    "sql":
                    "benanntesgebiet_von = -1",
                    "readonly":
                    True,
                    "group":
                    group,
                    "style":
                    "global_qml/gebaeudeadressen/benanntesgebiet_rot"
                    ".qml"
                }
                vlayer_benanntesgebiet = self.layer_loader.load(layer)

            vlayer_gebaeudeeingang = self.get_vector_layer_by_name(
                gebaeudeeingang)
            if not vlayer_gebaeudeeingang:
                layer = {
                    "type":
                    "postgres",
                    "title":
                    "Gebaeudeeingang Lokalisationstest",
                    "featuretype":
                    "gebaeudeadressen_gebaeudeeingang",
                    "geom":
                    "lage",
                    "key":
                    "ogc_fid",
                    "sql":
                    "gebaeudeeingang_von = -1",
                    "readonly":
                    True,
                    "group":
                    group,
                    "style":
                    "global_qml/gebaeudeadressen/gebaeudeeingang_rot"
                    ".qml"
                }
                vlayer_gebaeudeeingang = self.layer_loader.load(layer)

            vlayer_shortestline = self.get_vector_layer_by_name(shortestline)
            if not vlayer_shortestline:
                layer = {
                    "type":
                    "postgres",
                    "title":
                    "Kuerzeste Linie Lokalisationstest",
                    "featuretype":
                    "t_shortestline_hausnummerpos",
                    "geom":
                    "the_geom",
                    "key":
                    "ogc_fid",
                    "sql":
                    "lok_tid = -1",
                    "readonly":
                    True,
                    "group":
                    group,
                    "style":
                    "global_qml/gebaeudeadressen/shortestline_linie_rot.qml"
                }
                vlayer_shortestline = self.layer_loader.load(layer)

            vlayer_hausnummerpos = self.get_vector_layer_by_name(hausnummerpos)
            if not vlayer_hausnummerpos:
                layer = {
                    "type": "postgres",
                    "title": "HausnummerPos Lokalisationstest",
                    "featuretype": "v_gebaeudeadressen_hausnummerpos",
                    "geom": "pos",
                    "key": "ogc_fid",
                    "sql": "lok_tid = -1",
                    "readonly": True,
                    "group": group,
                    "style":
                    "global_qml/gebaeudeadressen/hausnummerpos_rot.qml"
                }
                vlayer_hausnummerpos = self.layer_loader.load(layer)

            vlayer_lokalisationsname = self.get_vector_layer_by_name(
                lokalisationsname)
            if not vlayer_lokalisationsname:
                self.message_bar.pushMessage(
                    "Error",
                    _translate("VeriSO_EE_Geb_LokTest",
                               "Layer _LokalisationsName_ not found.", None),
                    level=QgsMessageBar.CRITICAL,
                    duration=0)
                QApplication.restoreOverrideCursor()
                return

            iterator = vlayer_lokalisationsname.getFeatures()
            ids = []

            for feature in iterator:
                ids.append(feature.id())

            if vlayer_lokalisationsname.selectedFeatureCount() < 1:
                self.message_bar.pushCritical(
                    "Error",
                    _translate("VeriSO_EE_Geb_LokTest",
                               "No _LokalisationsName_ selected.", None))
                QApplication.restoreOverrideCursor()
                return

            if vlayer_lokalisationsname.selectedFeatureCount() > 1:
                self.message_bar.pushCritical(
                    "Error",
                    _translate(
                        "VeriSO_EE_Geb_LokTest",
                        "Please select only one (1) _LokalisationsName_.",
                        None))
                QApplication.restoreOverrideCursor()
                return

            feat = QgsFeature()
            id = vlayer_lokalisationsname.selectedFeaturesIds()[0]
            feat = vlayer_lokalisationsname.selectedFeatures()[0]
            idx = ids.index(id)

            benannte_idx = vlayer_lokalisationsname.fieldNameIndex("benannte")
            text_idx = vlayer_lokalisationsname.fieldNameIndex("atext")

            if benannte_idx == -1 or text_idx == -1:
                self.message_bar.pushCritical(
                    "Error",
                    _translate("VeriSO_EE_Geb_LokTest",
                               "Field _benannte_ or _text_ not found.", None))
                QApplication.restoreOverrideCursor()
                return

            benannte = feat.attributes()[benannte_idx]
            lokalisationsname = feat.attributes()[text_idx]

            vlayer_strassenstueck_geometrie.setSubsetString(
                "(strassenstueck_von = " + str(benannte) + ")")
            vlayer_strassenstueck_anfangspunkt.setSubsetString(
                "(strassenstueck_von = " + str(benannte) + ")")
            vlayer_benanntesgebiet.setSubsetString("(benanntesgebiet_von = " +
                                                   str(benannte) + ")")
            vlayer_gebaeudeeingang.setSubsetString("(gebaeudeeingang_von = " +
                                                   str(benannte) + ")")
            vlayer_lokalisation.setSubsetString("(ogc_fid = " + str(benannte) +
                                                ")")
            vlayer_shortestline.setSubsetString("(lok_tid = " + str(benannte) +
                                                ")")
            vlayer_hausnummerpos.setSubsetString("(lok_tid = " +
                                                 str(benannte) + ")")

            if vlayer_strassenstueck_geometrie.featureCount() > 0:
                x_min = vlayer_strassenstueck_geometrie.extent().xMinimum()
                y_min = vlayer_strassenstueck_geometrie.extent().yMinimum()
                x_max = vlayer_strassenstueck_geometrie.extent().xMaximum()
                y_max = vlayer_strassenstueck_geometrie.extent().yMaximum()

            if vlayer_benanntesgebiet.featureCount() > 0:
                x_min = vlayer_benanntesgebiet.extent().xMinimum()
                y_min = vlayer_benanntesgebiet.extent().yMinimum()
                x_max = vlayer_benanntesgebiet.extent().xMaximum()
                y_max = vlayer_benanntesgebiet.extent().yMaximum()

            try:
                if vlayer_gebaeudeeingang.featureCount() > 0:
                    if vlayer_gebaeudeeingang.extent().xMinimum() < x_min:
                        x_min = vlayer_gebaeudeeingang.extent().xMinimum()
                    if vlayer_gebaeudeeingang.extent().yMinimum() < y_min:
                        y_min = vlayer_gebaeudeeingang.extent().yMinimum()
                    if vlayer_gebaeudeeingang.extent().xMaximum() > x_max:
                        x_max = vlayer_gebaeudeeingang.extent().xMaximum()
                    if vlayer_gebaeudeeingang.extent().yMaximum() > y_max:
                        y_max = vlayer_gebaeudeeingang.extent().yMaximum()

                rect = QgsRectangle(x_min, y_min, x_max, y_max)
                rect.scale(1.3)

            except UnboundLocalError:
                vlayer_gemeindegrenze = self.getVectorLayerByName(
                    "Gemeindegrenze")
                if vlayer_gemeindegrenze is None:
                    rect = self.canvas.fullExtent()
                else:
                    rect = vlayer_gemeindegrenze.extent()

            self.iface.mapCanvas().setExtent(rect)
            self.iface.mapCanvas().refresh()

            iterator = vlayer_lokalisation.getFeatures()

            # only one feature is selected
            for feature in iterator:
                prinzip_idx = vlayer_lokalisation.fieldNameIndex(
                    "nummerierungsprinzip_txt")
                attributeprovisorisch_idx = vlayer_lokalisation.fieldNameIndex(
                    "attributeprovisorisch_txt")
                offiziell_idx = vlayer_lokalisation.fieldNameIndex(
                    "istoffiziellebezeichnung_txt")
                status_idx = vlayer_lokalisation.fieldNameIndex("status_txt")
                inaenderung_idx = vlayer_lokalisation.fieldNameIndex(
                    "inaenderung_txt")
                art_idx = vlayer_lokalisation.fieldNameIndex("art_txt")

                something_missing = (prinzip_idx == -1
                                     or attributeprovisorisch_idx == -1
                                     or offiziell_idx == -1 or status_idx == -1
                                     or inaenderung_idx == -1 or art_idx == -1)
                if something_missing:
                    self.message_bar.pushMessage("Error",
                                                 _translate(
                                                     "VeriSO_EE_Geb_LokTest",
                                                     "Field not found.", None),
                                                 level=QgsMessageBar.CRITICAL,
                                                 duration=0)
                    QApplication.restoreOverrideCursor()
                    return

                prinzip = feature.attributes()[prinzip_idx]
                attributeprovisorisch = feature.attributes(
                )[attributeprovisorisch_idx]
                offiziell = feature.attributes()[offiziell_idx]
                status = feature.attributes()[status_idx]
                inaenderung = feature.attributes()[inaenderung_idx]
                art = feature.attributes()[art_idx]

                map_extent = self.canvas.extent()
                x = map_extent.xMinimum()
                y = map_extent.yMaximum()

            text_item_found = False
            items = list(self.iface.mapCanvas().scene().items())
            for i in range(len(items)):
                try:
                    name = items[i].data(0)
                    if str(name) == "LokalisationsInfo":
                        text_item = items[i]
                        text_item_found = True
                except Exception:
                    pass

            if not text_item_found:
                text_item = QgsTextAnnotationItem(self.canvas)
                text_item.setData(0, "LokalisationsInfo")

            # noinspection PyUnboundLocalVariable
            text_item.setMapPosition(
                QgsPoint(x + 10 * self.canvas.mapUnitsPerPixel(),
                         y - 10 * self.canvas.mapUnitsPerPixel()))
            text_item.setMapPositionFixed(False)
            text_item.setFrameBorderWidth(0.0)
            text_item.setFrameColor(QColor(250, 250, 250, 255))
            text_item.setFrameBackgroundColor(QColor(250, 250, 250, 123))
            text_item.setFrameSize(QSizeF(250, 150))
            text_document = QTextDocument()
            text_document.setHtml(
                "<table style='font-size:12px;'><tr><td>Lok.Name: </td><td>" +
                lokalisationsname + "</td></tr><tr><td>TID: </td><td>" +
                str(benannte) + "</td></tr> <tr><td>Num.prinzip: "
                "</td><td>" + str(prinzip) +
                "</td></tr> <tr><td>Attr. prov.: </td><td>" +
                str(attributeprovisorisch) + "</td></tr> <tr><td>ist "
                "offiziell: </td><td>" + str(offiziell) +
                "</td></tr> <tr><td>Status: "
                "</td><td>" + str(status) + "</td></tr> <tr><td>in Aenderung: "
                "</td><td>" + str(inaenderung) + "</td></tr> <tr><td>Art: "
                "</td><td>" + str(art) + "</td></tr>  </table>")
            text_item.setDocument(text_document)

            # This is a workaround: first ever position is not correct.
            text_item.setMapPosition(
                QgsPoint(x + 10 * self.canvas.mapUnitsPerPixel(),
                         y - 10 * self.canvas.mapUnitsPerPixel()))
            text_item.update()

            self.iface.mapCanvas().refresh()

            try:
                vlayer_lokalisationsname.setSelectedFeatures([ids[idx + 1]])
            except IndexError:
                self.message_bar.pushInfo(
                    "Information",
                    _translate("VeriSO_EE_Geb_LokTest", "End of table.", None))

        except Exception as e:
            QApplication.restoreOverrideCursor()
            exc_type, exc_value, exc_traceback = sys.exc_info()
            self.message_bar.pushMessage(
                "Error",
                str(traceback.format_exc(exc_traceback)),
                level=QgsMessageBar.CRITICAL,
                duration=0)
        QApplication.restoreOverrideCursor()
        QApplication.restoreOverrideCursor()
Example #14
0
    def canvasMoveEvent(self, mouseEvent):
        item = self.selectedItem()
        if not item:
            return

        annotation = item.annotation()
        if not annotation:
            return

        pixelToMmScale = 25.4 / self.canvas.logicalDpiX()
        if self.currentMoveAction == QgsMapCanvasAnnotationItem.MoveFramePosition:
            # move the entire frame
            newCanvasPos = item.pos() + (mouseEvent.pos() -
                                         self.lastMousePosition)
            if annotation.hasFixedMapPosition():
                deltaX = pixelToMmScale * (mouseEvent.pos().x() -
                                           self.lastMousePosition.x())
                deltaY = pixelToMmScale * (mouseEvent.pos().y() -
                                           self.lastMousePosition.y())
                annotation.setFrameOffsetFromReferencePointMm(
                    QPointF(
                        annotation.frameOffsetFromReferencePointMm().x() +
                        deltaX,
                        annotation.frameOffsetFromReferencePointMm().y() +
                        deltaY))
                annotation.setRelativePosition(
                    QPointF(newCanvasPos.x() / self.canvas.width(),
                            newCanvasPos.y() / self.canvas.height()))
                item.update()
                QgsProject.instance().setDirty(True)

        elif self.currentMoveAction != QgsMapCanvasAnnotationItem.NoAction:
            # handle vertical frame resize actions only
            size = annotation.frameSizeMm()
            xmin = annotation.frameOffsetFromReferencePointMm().x()
            ymin = annotation.frameOffsetFromReferencePointMm().y()
            xmax = xmin + size.width()
            ymax = ymin + size.height()
            relPosX = annotation.relativePosition().x()
            relPosY = annotation.relativePosition().y()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightUp):
                ymin += pixelToMmScale * (mouseEvent.pos().y() -
                                          self.lastMousePosition.y())
                relPosY = (relPosY * self.canvas.height() +
                           mouseEvent.pos().y() -
                           self.lastMousePosition.y()) / self.canvas.height()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameDown
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftDown
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightDown):
                ymax += pixelToMmScale * (mouseEvent.pos().y() -
                                          self.lastMousePosition.y())

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeft
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameLeftDown):
                xmin += pixelToMmScale * (mouseEvent.pos().x() -
                                          self.lastMousePosition.x())
                relPosX = (relPosX * self.canvas.width() +
                           mouseEvent.pos().x() -
                           self.lastMousePosition.x()) / self.canvas.width()

            if (self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRight
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightUp
                    or self.currentMoveAction
                    == QgsMapCanvasAnnotationItem.ResizeFrameRightDown):
                xmax += pixelToMmScale * (mouseEvent.pos().x() -
                                          self.lastMousePosition.x())

            # switch min / max if necessary
            if xmax < xmin:
                tmp = xmax
                xmax = xmin
                xmin = tmp
            if ymax < ymin:
                tmp = ymax
                ymax = ymin
                ymin = tmp
            annotation.setFrameOffsetFromReferencePointMm(QPointF(xmin, ymin))
            annotation.setFrameSizeMm(QSizeF(xmax - xmin, ymax - ymin))
            annotation.setRelativePosition(QPointF(relPosX, relPosY))
            item.update()
            QgsProject.instance().setDirty(True)

        moveAction = item.moveActionForPosition(mouseEvent.pos())
        cursor = QCursor()
        cursor.setShape(item.cursorShapeForAction(moveAction))
        self.setCursor(cursor)

        self.lastMousePosition = mouseEvent.pos()
Example #15
0
    def convert_diagrams(
            renderer: AnnotateLayerPropertiesCollection,  # pylint: disable=too-many-branches,too-many-statements
            dest_layer: QgsVectorLayer,
            context):
        """
        Converts a diagram renderer to QGIS diagrams
        """
        if not isinstance(renderer, ChartRenderer):
            return

        layer_settings = QgsDiagramLayerSettings()
        # todo - geometry type dependent
        layer_settings.placement = QgsDiagramLayerSettings.OverPoint

        if not renderer.prevent_overlap:
            layer_settings.setShowAllDiagrams(True)

        settings = QgsDiagramSettings()
        settings.categoryLabels = renderer.labels
        settings.categoryAttributes = renderer.attributes
        settings.categoryColors = [
            SymbolConverter.symbol_to_color(c.symbol, context)
            for c in renderer.class_legend.classes
        ]

        if isinstance(renderer.symbol, BarChartSymbol):
            if renderer.symbol.display_in_3d and context.unsupported_object_callback:
                if context.layer_name:
                    context.unsupported_object_callback(
                        '{}: 3D bar chart was converted to 2d (QGIS does not support 3D bar charts)'
                        .format(context.layer_name),
                        level=Context.WARNING)
                elif context.symbol_name:
                    context.unsupported_object_callback(
                        '{}: 3D bar chart was converted to 2d (QGIS does not support 3D bar charts)'
                        .format(context.symbol_name),
                        level=Context.WARNING)
                else:
                    context.unsupported_object_callback(
                        '3D bar chart was converted to 2d (QGIS does not support 3D bar charts)',
                        level=Context.WARNING)

            if renderer.class_legend.classes:
                first_symbol = renderer.class_legend.classes[0].symbol
                settings.penColor = SymbolConverter.symbol_to_line_color(
                    first_symbol, context)
                settings.penWidth = SymbolConverter.symbol_to_line_width(
                    first_symbol, context)
                settings.lineSizeUnit = context.units

            try:
                axis_symbol = SymbolConverter.Symbol_to_QgsSymbol(
                    renderer.symbol.axis_symbol, context)
                settings.setShowAxis(renderer.symbol.show_axis)
                settings.setAxisLineSymbol(axis_symbol)
            except AttributeError:
                if context.unsupported_object_callback:
                    if context.layer_name:
                        context.unsupported_object_callback(
                            '{}: Bar chart axis symbols require QGIS 3.12 or later'
                            .format(context.layer_name),
                            level=Context.WARNING)
                    elif context.symbol_name:
                        context.unsupported_object_callback(
                            '{}: Bar chart axis symbols require QGIS 3.12 or later'
                            .format(context.symbol_name),
                            level=Context.WARNING)
                    else:
                        context.unsupported_object_callback(
                            'Bar chart axis symbols require QGIS 3.12 or later',
                            level=Context.WARNING)

            settings.barWidth = renderer.symbol.bar_width * 0.352778

            if renderer.symbol.spacing:
                try:
                    settings.setSpacing(
                        context.convert_size(renderer.symbol.spacing))
                    settings.setSpacingUnit(context.units)
                except AttributeError:
                    if context.unsupported_object_callback:
                        if context.layer_name:
                            context.unsupported_object_callback(
                                '{}: Bar chart spacing requires QGIS 3.12 or later'
                                .format(context.layer_name),
                                level=Context.WARNING)
                    elif context.symbol_name:
                        context.unsupported_object_callback(
                            '{}: Bar chart spacing requires QGIS 3.12 or later'
                            .format(context.symbol_name),
                            level=Context.WARNING)
                    else:
                        context.unsupported_object_callback(
                            'Bar chart spacing requires QGIS 3.12 or later',
                            level=Context.WARNING)

            if not renderer.symbol.orientation_vertical:
                settings.diagramOrientation = QgsDiagramSettings.Right

            diagram_renderer = QgsLinearlyInterpolatedDiagramRenderer()
            diagram_renderer.setDiagram(QgsHistogramDiagram())
            diagram_renderer.setUpperValue(renderer.symbol.max_value)
            diagram_renderer.setUpperSize(
                QSizeF(renderer.symbol.max_length * 0.352778,
                       renderer.symbol.max_length * 0.352778))
            diagram_renderer.setDiagramSettings(settings)

            dest_layer.setDiagramRenderer(diagram_renderer)
            dest_layer.setDiagramLayerSettings(layer_settings)
        elif isinstance(renderer.symbol, PieChartSymbol):
            if renderer.symbol.display_in_3d and context.unsupported_object_callback:
                if context.layer_name:
                    context.unsupported_object_callback(
                        '{}: 3D pie chart was converted to 2d (QGIS does not support 3D pie charts)'
                        .format(context.layer_name),
                        level=Context.WARNING)
                elif context.symbol_name:
                    context.unsupported_object_callback(
                        '{}: 3D pie chart was converted to 2d (QGIS does not support 3D pie charts)'
                        .format(context.symbol_name),
                        level=Context.WARNING)
                else:
                    context.unsupported_object_callback(
                        '3D pie chart was converted to 2d (QGIS does not support 3D pie charts)',
                        level=Context.WARNING)

            outline = SymbolConverter.Symbol_to_QgsSymbol(
                renderer.symbol.outline, context)
            settings.penWidth = outline.width() * 0.352778
            settings.penColor = outline.color()

            # ArcMap only shows pie charts for features with some non-zero attributes
            exp = ' or '.join(settings.categoryAttributes)
            layer_settings.dataDefinedProperties().setProperty(
                QgsDiagramLayerSettings.Show, QgsProperty.fromExpression(exp))

            if not renderer.vary_size_by_attribute:
                diagram_renderer = QgsSingleCategoryDiagramRenderer()
            else:
                diagram_renderer = QgsLinearlyInterpolatedDiagramRenderer()
                diagram_renderer.setClassificationField(
                    renderer.vary_size_by_attribute)
                diagram_renderer.setLowerValue(renderer.min_value)
                diagram_renderer.setLowerSize(
                    QSizeF(renderer.min_size * 0.352778 * 0.5,
                           renderer.min_size * 0.352778 * 0.5))
                diagram_renderer.setUpperValue(renderer.min_value * 2)
                diagram_renderer.setUpperSize(
                    QSizeF(renderer.min_size * 0.352778 * 2 * 0.5,
                           renderer.min_size * 0.352778 * 2 * 0.5))
                settings.scaleByArea = False
            diagram_renderer.setDiagram(QgsPieDiagram())
            settings.size = QSizeF(context.convert_size(renderer.symbol.size),
                                   context.convert_size(renderer.symbol.size))
            settings.sizeType = context.units

            if renderer.symbol.clockwise:
                try:
                    settings.setDirection(QgsDiagramSettings.Clockwise)
                except AttributeError:
                    if context.unsupported_object_callback:
                        if context.layer_name:
                            context.unsupported_object_callback(
                                '{}: Clockwise pie charts require QGIS 3.12 or later'
                                .format(context.layer_name),
                                level=Context.WARNING)
                    elif context.symbol_name:
                        context.unsupported_object_callback(
                            '{}: Clockwise pie charts require QGIS 3.12 or later'
                            .format(context.symbol_name),
                            level=Context.WARNING)
                    else:
                        context.unsupported_object_callback(
                            'Clockwise pie charts require QGIS 3.12 or later',
                            level=Context.WARNING)

            try:
                outline_symbol = SymbolConverter.Symbol_to_QgsSymbol(
                    renderer.class_legend.classes[0].symbol.outline,
                    context).color()
                if outline_symbol:
                    settings.penColor = outline_symbol.color()
                    settings.penWidth = outline_symbol.width() * 0.352778

            except AttributeError:
                pass

            if not renderer.symbol.clockwise:
                settings.rotationOffset = renderer.symbol.starting_angle
            else:
                settings.rotationOffset = 360.0 - renderer.symbol.starting_angle

            diagram_renderer.setDiagramSettings(settings)

            dest_layer.setDiagramRenderer(diagram_renderer)
            dest_layer.setDiagramLayerSettings(layer_settings)

        else:
            raise NotImplementedException(
                'Converting {} diagrams is not yet supported'.format(
                    renderer.symbol.__class__.__name__))
Example #16
0
    def test_read_write(self):
        plot = Qgs2DPlot()
        plot.setSize(QSizeF(600, 500))

        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_style': 'no'
        })
        plot.setChartBackgroundSymbol(sym1)

        sym2 = QgsFillSymbol.createSimple({
            'outline_color': '#0000ff',
            'style': 'no',
            'outline_style': 'solid',
            'outline_width': 1
        })
        plot.setChartBorderSymbol(sym2)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#00ffff',
            'outline_width': 1
        })
        plot.xAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff00ff',
            'outline_width': 0.5
        })
        plot.xAxis().setGridMinorSymbol(sym4)

        sym3 = QgsLineSymbol.createSimple({
            'outline_color': '#0066ff',
            'outline_width': 1
        })
        plot.yAxis().setGridMajorSymbol(sym3)

        sym4 = QgsLineSymbol.createSimple({
            'outline_color': '#ff4433',
            'outline_width': 0.5
        })
        plot.yAxis().setGridMinorSymbol(sym4)

        font = QgsFontUtils.getStandardTestFont('Bold', 16)
        x_axis_format = QgsTextFormat.fromQFont(font)
        x_axis_format.setColor(QColor(255, 0, 0))
        plot.xAxis().setTextFormat(x_axis_format)

        x_axis_number_format = QgsBasicNumericFormat()
        x_axis_number_format.setNumberDecimalPlaces(1)
        x_axis_number_format.setShowTrailingZeros(True)
        plot.xAxis().setNumericFormat(x_axis_number_format)

        font = QgsFontUtils.getStandardTestFont('Bold', 18)
        y_axis_format = QgsTextFormat.fromQFont(font)
        y_axis_format.setColor(QColor(0, 255, 0))
        plot.yAxis().setTextFormat(y_axis_format)

        y_axis_number_format = QgsBasicNumericFormat()
        y_axis_number_format.setShowPlusSign(True)
        plot.yAxis().setNumericFormat(y_axis_number_format)

        plot.setXMinimum(3)
        plot.setXMaximum(9)

        plot.setYMinimum(2)
        plot.setYMaximum(12)

        plot.xAxis().setGridIntervalMinor(0.5)
        plot.xAxis().setGridIntervalMajor(1.5)
        plot.yAxis().setGridIntervalMinor(0.3)
        plot.yAxis().setGridIntervalMajor(1.3)

        plot.xAxis().setLabelInterval(32)
        plot.yAxis().setLabelInterval(23)

        doc = QDomDocument()
        elem = doc.createElement('test')
        plot.writeXml(elem, doc, QgsReadWriteContext())

        res = Qgs2DPlot()
        self.assertTrue(res.readXml(elem, QgsReadWriteContext()))

        self.assertEqual(res.xMinimum(), 3)
        self.assertEqual(res.xMaximum(), 9)
        self.assertEqual(res.yMinimum(), 2)
        self.assertEqual(res.yMaximum(), 12)

        self.assertEqual(res.xAxis().gridIntervalMinor(), 0.5)
        self.assertEqual(res.xAxis().gridIntervalMajor(), 1.5)
        self.assertEqual(res.yAxis().gridIntervalMinor(), 0.3)
        self.assertEqual(res.yAxis().gridIntervalMajor(), 1.3)

        self.assertEqual(res.xAxis().labelInterval(), 32)
        self.assertEqual(res.yAxis().labelInterval(), 23)

        self.assertEqual(res.xAxis().numericFormat().numberDecimalPlaces(), 1)
        self.assertTrue(res.yAxis().numericFormat().showPlusSign())

        self.assertEqual(res.xAxis().textFormat().color().name(), '#ff0000')
        self.assertEqual(res.yAxis().textFormat().color().name(), '#00ff00')

        self.assertEqual(res.chartBackgroundSymbol().color().name(), '#fdbf6f')
        self.assertEqual(res.chartBorderSymbol().color().name(), '#0000ff')

        self.assertEqual(res.xAxis().gridMinorSymbol().color().name(),
                         '#ff00ff')
        self.assertEqual(res.xAxis().gridMajorSymbol().color().name(),
                         '#00ffff')
        self.assertEqual(res.yAxis().gridMinorSymbol().color().name(),
                         '#ff4433')
        self.assertEqual(res.yAxis().gridMajorSymbol().color().name(),
                         '#0066ff')
Example #17
0
    def testDefault(self):
        self.assertEqual(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Hybrid, QSizeF(1, 1)), [])
        self.assertEqual(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Hybrid, QSizeF(10, 10)), [])

        # markers
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Marker, QSizeF(1, 1))), [[[[0.0, 0.0]]]])
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Marker, QSizeF(2, 2))),
                         [[[[1.0, 1.0]]]])
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Marker, QSizeF(10, 2))), [[[[5.0, 1.0]]]])

        # lines
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Line, QSizeF(1, 1))), [[[[0.0, 0.5], [1.0, 0.5]]]])
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Line, QSizeF(10, 2))), [[[[0.0, 1.0], [10.0, 1.0]]]])
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Line, QSizeF(9, 3))), [[[[0.0, 1.5], [9.0, 1.5]]]])

        # fills
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Fill, QSizeF(1, 1))), [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]]])
        self.assertEqual(self.polys_to_list(QgsStyle.defaultStyle().defaultPatchAsQPolygonF(QgsSymbol.Fill, QSizeF(10, 2))), [[[[0.0, 0.0], [10.0, 0.0], [10.0, 2.0], [0.0, 2.0], [0.0, 0.0]]]])
Example #18
0
    def __init__(self,
                 size=QSizeF(400, 200),
                 render_type=POINT_RENDERER,
                 x_orientation=ORIENTATION_LEFT_TO_RIGHT,
                 y_orientation=ORIENTATION_UPWARD,
                 allow_mouse_translation=False,
                 allow_wheel_zoom=False,
                 symbology=None,
                 parent=None):

        """
        Parameters
        ----------
        size: QSize
          Size of the item
        render_type: Literal[POINT_RENDERER, LINE_RENDERER, POLYGON_RENDERER]
          Type of renderer
        x_orientation: Literal[ORIENTATION_LEFT_TO_RIGHT, ORIENTATION_RIGHT_TO_LEFT]
        y_orientation: Literal[ORIENTATION_UPWARD, ORIENTATION_DOWNWARD]
        allow_mouse_translation: bool
          Allow the user to translate the item with the mouse (??)
        allow_wheel_zoom: bool
          Allow the user to zoom with the mouse wheel
        symbology: QDomDocument
          QGIS symbology to use for the renderer
        parent: QObject
        """
        LogItem.__init__(self, parent)

        self.__item_size = size
        self.__data_rect = None
        self.__data = None
        self.__delta = None
        self.__x_orientation = x_orientation
        self.__y_orientation = y_orientation

        # origin point of the graph translation, if any
        self.__translation_orig = None

        self.__render_type = render_type # type: Literal[POINT_RENDERER, LINE_RENDERER, POLYGON_RENDERER]

        self.__allow_mouse_translation = allow_mouse_translation
        self.__allow_wheel_zoom = allow_wheel_zoom

        self.__layer = None

        self.__default_renderers = [QgsFeatureRenderer.defaultRenderer(POINT_RENDERER),
                            QgsFeatureRenderer.defaultRenderer(LINE_RENDERER),
                            QgsFeatureRenderer.defaultRenderer(POLYGON_RENDERER)]
        symbol = self.__default_renderers[1].symbol()
        symbol.setWidth(1.0)
        symbol = self.__default_renderers[0].symbol()
        symbol.setSize(5.0)
        symbol = self.__default_renderers[2].symbol()
        symbol.symbolLayers()[0].setStrokeWidth(1.0)

        if not symbology:
            self.__renderer = self.__default_renderers[self.__render_type]
        else:
            self.__renderer = QgsFeatureRenderer.load(symbology.documentElement(), QgsReadWriteContext())

        # index of the current point to label
        self.__old_point_to_label = None
        self.__point_to_label = None
Example #19
0
    def testLines(self):
        shape = QgsLegendPatchShape(
            QgsSymbol.Line, QgsGeometry.fromWkt('LineString(5 5, 1 2)'), False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(1,
                                                                        1))),
            [[[[1.0, 0.0], [0.0, 1.0]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(10,
                                                                        2))),
            [[[[10.0, 0.0], [0.0, 2.0]]]])

        shape = QgsLegendPatchShape(
            QgsSymbol.Line, QgsGeometry.fromWkt('LineString(1 5, 6 5)'), False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(1,
                                                                        1))),
            [[[[0.0, 0.5], [1.0, 0.5]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(10,
                                                                        2))),
            [[[[0.0, 1], [10.0, 1.0]]]])

        shape = QgsLegendPatchShape(
            QgsSymbol.Line, QgsGeometry.fromWkt('LineString(1 5, 1 10)'),
            False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(1,
                                                                        1))),
            [[[[0.5, 0.0], [0.5, 1.0]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(10,
                                                                        2))),
            [[[[5, 0.0], [5, 2.0]]]])

        # requesting different symbol type, should return default
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Fill, QSizeF(1,
                                                                        1))),
            [[[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]]])

        # circularstring
        shape = QgsLegendPatchShape(
            QgsSymbol.Line,
            QgsGeometry.fromWkt('CircularString(5 5, 1 2, 3 4)'), False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line,
                                                 QSizeF(1, 1)))[0][0][:5],
            [[0.342, 0.026], [0.35, 0.023], [0.359, 0.02], [0.367, 0.018],
             [0.375, 0.016]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line,
                                                 QSizeF(10, 2)))[0][0][:5],
            [[3.419, 0.051], [3.647, 0.042], [3.875, 0.036], [4.104, 0.034],
             [4.332, 0.036]])

        # multilinestring
        shape = QgsLegendPatchShape(
            QgsSymbol.Line,
            QgsGeometry.fromWkt('MultiLineString((5 5, 1 2),(3 6, 4 2))'),
            False)
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(1,
                                                                        1))),
            [[[[1.0, 0.25], [0.0, 1.0]]], [[[0.5, 0.0], [0.75, 1.0]]]])
        self.assertEqual(
            self.polys_to_list(shape.toQPolygonF(QgsSymbol.Line, QSizeF(10,
                                                                        2))),
            [[[[10.0, 0.5], [0.0, 2.0]]], [[[5.0, 0.0], [7.5, 2.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
Example #21
0
    def drawCostPaths(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = -1
        for row in rows:
            cur2 = con.cursor()
            args['result_path_id'] = row[0]
            args['result_source_id'] = sql.Literal(row[1])
            args['result_target_id'] = sql.Literal(row[2])
            args['result_cost'] = row[3]
            if args['result_path_id'] != cur_path_id:
                cur_path_id = args['result_path_id']
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas, Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)
            if args['result_cost'] != -1:
                query2 = sql.SQL("""
                    SELECT ST_AsText( ST_MakeLine(
                        (SELECT {geometry_vt} FROM  {vertex_schema}.{vertex_table} WHERE id = {result_source_id}),
                        (SELECT {geometry_vt} FROM  {vertex_schema}.{vertex_table} WHERE id = {result_target_id})
                        ))
                    """).format(**args)
                # Utils.logMessage(query2)
                cur2.execute(query2)
                row2 = cur2.fetchone()
                # Utils.logMessage(str(row2[0]))

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        # TODO label the edge instead of labeling the target points
        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
        resultNodesTextAnnotations = canvasItemList['annotations']
        for row in rows:
            cur2 = con.cursor()
            args['result_seq'] = row[0]
            args['result_source_id'] = sql.Literal(row[1])
            result_target_id = row[2]
            args['result_target_id'] = sql.Literal(result_target_id)
            result_cost = row[3]
            query2 = sql.SQL("""
                SELECT ST_AsText( ST_startPoint({geometry}) ) FROM {edge_schema}.{edge_table}
                    WHERE {source} = {result_target_id}
                UNION
                SELECT ST_AsText( ST_endPoint( {geometry} ) ) FROM {edge_schema}.{edge_table}
                    WHERE {target} = {result_target_id}
                """).format(**args)
            cur2.execute(query2)
            row2 = cur2.fetchone()

            geom = QgsGeometry().fromWkt(str(row2[0]))
            pt = geom.asPoint()
            textDocument = QTextDocument("{0!s}:{1}".format(result_target_id, result_cost))
            textAnnotation = QgsTextAnnotation()
            textAnnotation.setMapPosition(geom.asPoint())
            textAnnotation.setFrameSize(QSizeF(textDocument.idealWidth(), 20))
            textAnnotation.setFrameOffsetFromReferencePoint(QPointF(20, -40))
            textAnnotation.setDocument(textDocument)

            QgsMapCanvasAnnotationItem(textAnnotation, mapCanvas)
            resultNodesTextAnnotations.append(textAnnotation)