Exemple #1
0
    def testClippingBackgroundFrame(self):
        """
        Make sure frame/background are also clipped
        """
        vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl",
                            "memory")

        props = {
            "color": "127,255,127",
            'outline_style': 'solid',
            'outline_width': '1',
            'outline_color': '0,0,255'
        }
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        vl.setRenderer(renderer)

        f = QgsFeature(vl.fields(), 1)
        for x in range(0, 15, 3):
            for y in range(0, 15, 3):
                f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3))
                vl.dataProvider().addFeature(f)

        p = QgsProject()

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(True)
        map.setFrameStrokeWidth(
            QgsLayoutMeasurement(2, QgsUnitTypes.LayoutMillimeters))
        map.setBackgroundEnabled(True)
        map.setBackgroundColor(QColor(200, 255, 200))
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        shape = QgsLayoutItemShape(layout)
        layout.addLayoutItem(shape)
        shape.setShapeType(QgsLayoutItemShape.Ellipse)
        shape.attemptSetSceneRect(QRectF(10, 10, 180, 180))

        map.itemClippingSettings().setEnabled(True)
        map.itemClippingSettings().setSourceItem(shape)
        map.itemClippingSettings().setFeatureClippingType(
            QgsMapClippingRegion.FeatureClippingType.ClipPainterOnly)

        checker = QgsLayoutChecker('composermap_itemclip_background', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        TestQgsLayoutMap.report += checker.report()
        self.assertTrue(result, message)
    def testClippedMapExtent(self):
        p = QgsProject()
        l = QgsPrintLayout(p)
        map = QgsLayoutItemMap(l)
        shape = QgsLayoutItemShape(l)
        l.addLayoutItem(map)
        map.attemptSetSceneRect(QRectF(10, 20, 100, 80))
        map.zoomToExtent(QgsRectangle(100, 200, 50, 40))
        l.addLayoutItem(shape)
        shape.setShapeType(QgsLayoutItemShape.Triangle)
        shape.attemptSetSceneRect(QRectF(20, 30, 70, 50))

        settings = map.itemClippingSettings()
        settings.setEnabled(True)
        settings.setSourceItem(shape)

        geom = settings.clippedMapExtent()
        self.assertEqual(geom.asWkt(),
                         'Polygon ((-5 80, 135 80, 65 180, -5 80))')
Exemple #3
0
    def testBoundingRectForStrokeSizeOnRestore(self):
        """
        Test that item bounding rect correctly accounts for stroke size on item restore
        """
        pr = QgsProject()
        l = QgsLayout(pr)
        shape = QgsLayoutItemShape(l)

        shape.setShapeType(QgsLayoutItemShape.Rectangle)
        shape.attemptSetSceneRect(QRectF(30, 10, 100, 200))
        self.assertEqual(shape.boundingRect(),
                         QRectF(-0.15, -0.15, 100.3, 200.3))

        # set a symbol with very wide stroke
        s = QgsFillSymbol.createSimple({
            'outline_color': '#ff0000',
            'outline_width': '40',
            'color': '#ff5588'
        })
        shape.setSymbol(s)
        # bounding rect for item should include stroke
        self.assertEqual(shape.boundingRect(),
                         QRectF(-20.0, -20.0, 140.0, 240.0))

        # save the shape and restore
        doc = QDomDocument("testdoc")
        parent_elem = doc.createElement("test")
        doc.appendChild(parent_elem)
        self.assertTrue(shape.writeXml(parent_elem, doc,
                                       QgsReadWriteContext()))

        item_elem = parent_elem.firstChildElement("LayoutItem")
        self.assertFalse(item_elem.isNull())

        # restore
        shape2 = QgsLayoutItemShape(l)

        self.assertTrue(shape2.readXml(item_elem, doc, QgsReadWriteContext()))

        # bounding rect for item should include stroke
        self.assertEqual(shape2.boundingRect(),
                         QRectF(-20.0, -20.0, 140.0, 240.0))
Exemple #4
0
    def testClipPath(self):
        pr = QgsProject()
        l = QgsLayout(pr)
        shape = QgsLayoutItemShape(l)

        shape.setShapeType(QgsLayoutItemShape.Rectangle)
        shape.attemptSetSceneRect(QRectF(30, 10, 100, 200))

        # must be a closed polygon, in scene coordinates!
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((30 10, 130 10, 130 210, 30 210, 30 10))')
        self.assertTrue(
            int(shape.itemFlags() & QgsLayoutItem.FlagProvidesClipPath))

        spy = QSignalSpy(shape.clipPathChanged)
        shape.setCornerRadius(
            QgsLayoutMeasurement(10, QgsUnitTypes.LayoutMillimeters))
        self.assertTrue(shape.clipPath().asWkt(0).startswith(
            'Polygon ((30 20, 30 20, 30 19, 30 19, 30 19, 30 19'))
        self.assertEqual(len(spy), 1)

        shape.setShapeType(QgsLayoutItemShape.Ellipse)
        self.assertEqual(len(spy), 2)
        self.assertTrue(shape.clipPath().asWkt(0).startswith(
            'Polygon ((130 110, 130 111, 130 113, 130 114'))

        shape.setShapeType(QgsLayoutItemShape.Triangle)
        self.assertEqual(len(spy), 3)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((30 210, 130 210, 80 10, 30 210))')

        shape.attemptSetSceneRect(QRectF(50, 20, 80, 120))
        self.assertEqual(len(spy), 4)
        self.assertEqual(shape.clipPath().asWkt(),
                         'Polygon ((50 140, 130 140, 90 20, 50 140))')
    def testToMapClippingRegion(self):
        p = QgsProject()
        l = QgsPrintLayout(p)
        p.layoutManager().addLayout(l)
        map = QgsLayoutItemMap(l)
        shape = QgsLayoutItemShape(l)
        l.addLayoutItem(map)
        map.attemptSetSceneRect(QRectF(10, 20, 100, 80))
        map.zoomToExtent(QgsRectangle(100, 200, 50, 40))
        l.addLayoutItem(shape)
        shape.setShapeType(QgsLayoutItemShape.Triangle)
        shape.attemptSetSceneRect(QRectF(20, 30, 70, 50))

        settings = map.itemClippingSettings()
        settings.setEnabled(True)
        settings.setFeatureClippingType(
            QgsMapClippingRegion.FeatureClippingType.NoClipping)
        settings.setSourceItem(shape)

        region = settings.toMapClippingRegion()
        self.assertEqual(region.geometry().asWkt(),
                         'Polygon ((-5 80, 135 80, 65 180, -5 80))')
        self.assertEqual(region.featureClip(),
                         QgsMapClippingRegion.FeatureClippingType.NoClipping)
Exemple #6
0
    def testClippingHideClipSource(self):
        """
        When an item is set to be the clip source, it shouldn't render anything itself
        """
        format = QgsTextFormat()
        format.setFont(QgsFontUtils.getStandardTestFont("Bold"))
        format.setSize(30)
        format.setNamedStyle("Bold")
        format.setColor(QColor(0, 0, 0))
        settings = QgsPalLayerSettings()
        settings.setFormat(format)
        settings.fieldName = "'XXXX'"
        settings.isExpression = True
        settings.placement = QgsPalLayerSettings.OverPoint

        vl = QgsVectorLayer("Polygon?crs=epsg:4326&field=id:integer", "vl",
                            "memory")

        props = {
            "color": "127,255,127",
            'outline_style': 'solid',
            'outline_width': '1',
            'outline_color': '0,0,255'
        }
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        vl.setRenderer(renderer)

        f = QgsFeature(vl.fields(), 1)
        for x in range(0, 15, 3):
            for y in range(0, 15, 3):
                f.setGeometry(QgsGeometry(QgsPoint(x, y)).buffer(1, 3))
                vl.dataProvider().addFeature(f)

        vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
        vl.setLabelsEnabled(True)

        p = QgsProject()

        p.addMapLayer(vl)
        layout = QgsLayout(p)
        layout.initializeDefaults()
        p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(10, 10, 180, 180))
        map.setFrameEnabled(False)
        map.zoomToExtent(vl.extent())
        map.setLayers([vl])
        layout.addLayoutItem(map)

        shape = QgsLayoutItemShape(layout)
        layout.addLayoutItem(shape)
        shape.setShapeType(QgsLayoutItemShape.Ellipse)
        shape.attemptSetSceneRect(QRectF(10, 10, 180, 180))

        map.itemClippingSettings().setEnabled(True)
        map.itemClippingSettings().setSourceItem(shape)
        map.itemClippingSettings().setForceLabelsInsideClipPath(False)
        map.itemClippingSettings().setFeatureClippingType(
            QgsMapClippingRegion.FeatureClippingType.ClipToIntersection)

        checker = QgsLayoutChecker('composermap_itemclip_nodrawsource', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        TestQgsLayoutMap.report += checker.report()
        self.assertTrue(result, message)