Пример #1
2
    def testRenderLineLayerDataDefined(self):
        """ test that rendering a line symbol with data defined enabled layer works"""

        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsProject.instance().addMapLayer(lines_layer)

        layer = QgsSimpleLineSymbolLayer()
        layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Name='Highway'"))
        layer.setColor(QColor(100, 150, 150))
        layer.setWidth(5)

        symbol = QgsLineSymbol()
        symbol.changeSymbolLayer(0, layer)
        lines_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(400, 400))
        ms.setOutputDpi(96)
        ms.setExtent(QgsRectangle(-133, 22, -70, 52))
        ms.setLayers([lines_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(ms)
        renderchecker.setControlPathPrefix('symbol_layer')
        renderchecker.setControlName('expected_linelayer_ddenabled')
        self.assertTrue(renderchecker.runTest('linelayer_ddenabled'))
        QgsProject.instance().removeMapLayer(lines_layer)
Пример #2
0
    def testRenderFillLayerDataDefined(self):
        """ test that rendering a fill symbol with data defined enabled layer works"""

        polys_shp = os.path.join(TEST_DATA_DIR, 'polys.shp')
        polys_layer = QgsVectorLayer(polys_shp, 'Polygons', 'ogr')
        QgsProject.instance().addMapLayer(polys_layer)

        layer = QgsSimpleFillSymbolLayer()
        layer.setDataDefinedProperty("enabled", QgsDataDefined("Name='Lake'"))
        layer.setBorderStyle(Qt.NoPen)
        layer.setColor(QColor(100, 150, 150))

        symbol = QgsFillSymbol()
        symbol.changeSymbolLayer(0, layer)
        polys_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(400, 400))
        ms.setOutputDpi(96)
        ms.setExtent(QgsRectangle(-133, 22, -70, 52))
        ms.setLayers([polys_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(ms)
        renderchecker.setControlPathPrefix('symbol_layer')
        renderchecker.setControlName('expected_filllayer_ddenabled')
        self.assertTrue(renderchecker.runTest('filllayer_ddenabled'))
        QgsProject.instance().removeMapLayer(polys_layer)
Пример #3
0
    def testRenderMetersInMapUnits(self):

        crs_wsg84 = QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326')
        rt_extent = QgsRectangle(13.37768985634235, 52.51625705830762, 13.37771931686235, 52.51628651882762)
        point_berlin_wsg84 = QgsPointXY(13.37770458660236, 52.51627178856762)
        length_wsg84_mapunits = 0.00001473026350140572
        meters_test = 2.40
        da_wsg84 = QgsDistanceArea()
        da_wsg84.setSourceCrs(crs_wsg84, QgsProject.instance().transformContext())
        if (da_wsg84.sourceCrs().isGeographic()):
            da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym())
        length_meter_mapunits = da_wsg84.measureLineProjected(point_berlin_wsg84, 1.0, (math.pi / 2))
        meters_test_mapunits = meters_test * length_wsg84_mapunits
        meters_test_pixel = meters_test * length_wsg84_mapunits
        ms = QgsMapSettings()
        ms.setDestinationCrs(crs_wsg84)
        ms.setExtent(rt_extent)
        r = QgsRenderContext.fromMapSettings(ms)
        r.setExtent(rt_extent)
        self.assertEqual(r.extent().center().toString(7), point_berlin_wsg84.toString(7))
        c = QgsMapUnitScale()
        r.setDistanceArea(da_wsg84)
        result_test_painterunits = r.convertToPainterUnits(meters_test, QgsUnitTypes.RenderMetersInMapUnits, c)
        self.assertEqual(QgsDistanceArea.formatDistance(result_test_painterunits, 7, QgsUnitTypes.DistanceUnknownUnit, True), QgsDistanceArea.formatDistance(meters_test_mapunits, 7, QgsUnitTypes.DistanceUnknownUnit, True))
        result_test_mapunits = r.convertToMapUnits(meters_test, QgsUnitTypes.RenderMetersInMapUnits, c)
        self.assertEqual(QgsDistanceArea.formatDistance(result_test_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), QgsDistanceArea.formatDistance(meters_test_mapunits, 7, QgsUnitTypes.DistanceDegrees, True))
        result_test_meters = r.convertFromMapUnits(meters_test_mapunits, QgsUnitTypes.RenderMetersInMapUnits)
        self.assertEqual(QgsDistanceArea.formatDistance(result_test_meters, 1, QgsUnitTypes.DistanceMeters, True), QgsDistanceArea.formatDistance(meters_test, 1, QgsUnitTypes.DistanceMeters, True))
Пример #4
0
    def testRenderLineLayerDisabled(self):
        """ test that rendering a line symbol with disabled layer works"""
        layer = QgsSimpleLineSymbolLayer()
        layer.setEnabled(False)

        symbol = QgsLineSymbol()
        symbol.changeSymbolLayer(0, layer)

        image = QImage(200, 200, QImage.Format_RGB32)
        painter = QPainter()
        ms = QgsMapSettings()

        geom = QgsGeometry.fromWkt('LineString (0 0,3 4,4 3)')
        f = QgsFeature()
        f.setGeometry(geom)

        extent = geom.constGet().boundingBox()
        # buffer extent by 10%
        extent = extent.buffered((extent.height() + extent.width()) / 20.0)

        ms.setExtent(extent)
        ms.setOutputSize(image.size())
        context = QgsRenderContext.fromMapSettings(ms)
        context.setPainter(painter)
        context.setScaleFactor(96 / 25.4)  # 96 DPI

        painter.begin(image)
        image.fill(QColor(255, 255, 255))

        symbol.startRender(context)
        symbol.renderFeature(f, context)
        symbol.stopRender(context)
        painter.end()

        self.assertTrue(self.imageCheck('symbol_layer', 'symbollayer_disabled', image))
Пример #5
0
    def testRenderMarkerLayerDataDefined(self):
        """ test that rendering a marker symbol with data defined enabled layer works"""

        points_shp = os.path.join(TEST_DATA_DIR, 'points.shp')
        points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(points_layer)

        layer = QgsSimpleMarkerSymbolLayer()
        layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Class='Biplane'"))
        layer.setColor(QColor(100, 150, 150))
        layer.setSize(5)
        layer.setStrokeStyle(Qt.NoPen)

        symbol = QgsMarkerSymbol()
        symbol.changeSymbolLayer(0, layer)
        points_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(400, 400))
        ms.setOutputDpi(96)
        ms.setExtent(QgsRectangle(-133, 22, -70, 52))
        ms.setLayers([points_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(ms)
        renderchecker.setControlPathPrefix('symbol_layer')
        renderchecker.setControlName('expected_markerlayer_ddenabled')
        self.assertTrue(renderchecker.runTest('markerlayer_ddenabled'))
        QgsProject.instance().removeMapLayer(points_layer)
Пример #6
0
    def testRenderMarkerLayerDisabled(self):
        """ test that rendering a marker symbol with disabled layer works"""
        layer = QgsSimpleMarkerSymbolLayer()
        layer.setEnabled(False)

        symbol = QgsMarkerSymbol()
        symbol.changeSymbolLayer(0, layer)

        image = QImage(200, 200, QImage.Format_RGB32)
        painter = QPainter()
        ms = QgsMapSettings()

        geom = QgsGeometry.fromWkt('Point (1 2)')
        f = QgsFeature()
        f.setGeometry(geom)

        extent = QgsRectangle(0, 0, 4, 4)

        ms.setExtent(extent)
        ms.setOutputSize(image.size())
        context = QgsRenderContext.fromMapSettings(ms)
        context.setPainter(painter)
        context.setScaleFactor(96 / 25.4)  # 96 DPI

        painter.begin(image)
        image.fill(QColor(255, 255, 255))

        symbol.startRender(context)
        symbol.renderFeature(f, context)
        symbol.stopRender(context)
        painter.end()

        self.assertTrue(self.imageCheck('symbol_layer', 'symbollayer_disabled', image))
Пример #7
0
    def testSimpleLineWithOffset(self):
        """ test that rendering a polygon with simple line symbol with offset results in closed line"""
        layer = QgsSimpleLineSymbolLayer()
        layer.setOffset(-1)

        symbol = QgsFillSymbol()
        symbol.changeSymbolLayer(0, layer)

        image = QImage(200, 200, QImage.Format_RGB32)
        painter = QPainter()
        ms = QgsMapSettings()

        geom = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0))')
        f = QgsFeature()
        f.setGeometry(geom)

        extent = geom.geometry().boundingBox()
        # buffer extent by 10%
        extent = extent.buffer((extent.height() + extent.width()) / 20.0)

        ms.setExtent(extent)
        ms.setOutputSize(image.size())
        context = QgsRenderContext.fromMapSettings(ms)
        context.setPainter(painter)
        context.setScaleFactor(96 / 25.4)  # 96 DPI

        painter.begin(image)
        image.fill(QColor(255, 255, 255))

        symbol.startRender(context)
        symbol.renderFeature(f, context)
        symbol.stopRender(context)
        painter.end()

        self.assertTrue(self.imageCheck('symbol_layer', 'fill_simpleline_offset', image))
    def renderGeometry(self, symbol, geom, buffer=20):
        f = QgsFeature()
        f.setGeometry(geom)

        image = QImage(200, 200, QImage.Format_RGB32)

        painter = QPainter()
        ms = QgsMapSettings()
        extent = geom.get().boundingBox()
        # buffer extent by 10%
        if extent.width() > 0:
            extent = extent.buffered((extent.height() + extent.width()) / buffer)
        else:
            extent = extent.buffered(buffer / 2)

        ms.setExtent(extent)
        ms.setOutputSize(image.size())
        context = QgsRenderContext.fromMapSettings(ms)
        context.setPainter(painter)
        context.setScaleFactor(96 / 25.4)  # 96 DPI
        context.expressionContext().setFeature(f)

        painter.begin(image)
        try:
            image.fill(QColor(0, 0, 0))
            symbol.startRender(context)
            symbol.renderFeature(f, context)
            symbol.stopRender(context)
        finally:
            painter.end()

        return image
    def testWidth(self):
        ms = QgsMapSettings()
        extent = QgsRectangle(100, 200, 100, 200)
        ms.setExtent(extent)
        ms.setOutputSize(QSize(400, 400))
        context = QgsRenderContext.fromMapSettings(ms)
        context.setScaleFactor(96 / 25.4)  # 96 DPI
        ms.setExtent(QgsRectangle(100, 150, 100, 150))
        ms.setOutputDpi(ms.outputDpi() * 2)
        context2 = QgsRenderContext.fromMapSettings(ms)
        context2.setScaleFactor(300 / 25.4)

        s = QgsFillSymbol()
        s.deleteSymbolLayer(0)

        marker_line = QgsMarkerLineSymbolLayer(True)
        marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
        marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 10)
        marker.setColor(QColor(255, 0, 0))
        marker.setStrokeStyle(Qt.NoPen)
        marker_symbol = QgsMarkerSymbol()
        marker_symbol.changeSymbolLayer(0, marker)
        marker_line.setSubSymbol(marker_symbol)

        self.assertEqual(marker_line.width(), 10)
        self.assertAlmostEqual(marker_line.width(context), 37.795275590551185, 3)
        self.assertAlmostEqual(marker_line.width(context2), 118.11023622047244, 3)

        marker_line.subSymbol().setSizeUnit(QgsUnitTypes.RenderPixels)
        self.assertAlmostEqual(marker_line.width(context), 10.0, 3)
        self.assertAlmostEqual(marker_line.width(context2), 10.0, 3)
    def testWidth(self):
        ms = QgsMapSettings()
        extent = QgsRectangle(100, 200, 100, 200)
        ms.setExtent(extent)
        ms.setOutputSize(QSize(400, 400))
        context = QgsRenderContext.fromMapSettings(ms)
        context.setScaleFactor(96 / 25.4)  # 96 DPI
        ms.setExtent(QgsRectangle(100, 150, 100, 150))
        ms.setOutputDpi(ms.outputDpi() * 2)
        context2 = QgsRenderContext.fromMapSettings(ms)
        context2.setScaleFactor(300 / 25.4)

        s = QgsFillSymbol()
        s.deleteSymbolLayer(0)

        hash_line = QgsHashedLineSymbolLayer(True)
        hash_line.setPlacement(QgsTemplatedLineSymbolLayerBase.FirstVertex)
        simple_line = QgsSimpleLineSymbolLayer()
        line_symbol = QgsLineSymbol()
        line_symbol.changeSymbolLayer(0, simple_line)
        hash_line.setSubSymbol(line_symbol)
        hash_line.setHashLength(10)

        self.assertEqual(hash_line.width(), 10)
        self.assertAlmostEqual(hash_line.width(context), 37.795275590551185, 3)
        self.assertAlmostEqual(hash_line.width(context2), 118.11023622047244, 3)

        hash_line.setHashLengthUnit(QgsUnitTypes.RenderPixels)
        self.assertAlmostEqual(hash_line.width(context), 10.0, 3)
        self.assertAlmostEqual(hash_line.width(context2), 10.0, 3)
Пример #11
0
    def checkRepaintNonLabeledLayerDoesNotInvalidateLabelCache(self, job_type):
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")
        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(cache.hasCacheImage(layer.id()))
        self.assertEqual(cache.dependentLayers('_labels_'), [])

        # trigger repaint on layer - should not invalidate label cache because layer is not labeled
        layer.triggerRepaint()
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertFalse(cache.hasCacheImage(layer.id()))
        self.assertTrue(job.takeLabelingResults())

        # second job should still use label cache
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertTrue(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())
Пример #12
0
    def testSize(self):
        # test size and setSize
        ms = QgsMapSettings()
        extent = QgsRectangle(100, 200, 100, 200)
        ms.setExtent(extent)
        ms.setOutputSize(QSize(400, 400))
        context = QgsRenderContext.fromMapSettings(ms)
        context.setScaleFactor(96 / 25.4)  # 96 DPI
        ms.setExtent(QgsRectangle(100, 150, 100, 150))
        ms.setOutputDpi(ms.outputDpi() * 2)
        context2 = QgsRenderContext.fromMapSettings(ms)
        context2.setScaleFactor(300 / 25.4)

        # create a marker symbol with a single layer
        markerSymbol = QgsMarkerSymbol()
        markerSymbol.deleteSymbolLayer(0)
        markerSymbol.appendSymbolLayer(
            QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase.Star, color=QColor(255, 0, 0),
                                       strokeColor=QColor(0, 255, 0), size=10))
        self.assertEqual(markerSymbol.size(), 10)
        self.assertAlmostEqual(markerSymbol.size(context), 37.795275590551185, 3)
        self.assertAlmostEqual(markerSymbol.size(context2), 118.11023622047244, 3)
        markerSymbol.setSize(20)
        self.assertEqual(markerSymbol.size(), 20)
        self.assertEqual(markerSymbol.symbolLayer(0).size(), 20)
        self.assertAlmostEqual(markerSymbol.size(context), 75.59055118, 3)
        self.assertAlmostEqual(markerSymbol.size(context2), 236.2204724409449, 3)

        # add additional layers
        markerSymbol.appendSymbolLayer(
            QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase.Star, color=QColor(255, 0, 0),
                                       strokeColor=QColor(0, 255, 0), size=10))
        markerSymbol.appendSymbolLayer(
            QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayerBase.Star, color=QColor(255, 0, 0),
                                       strokeColor=QColor(0, 255, 0), size=30))
        self.assertEqual(markerSymbol.size(), 30)
        self.assertAlmostEqual(markerSymbol.size(context), 113.38582677165356, 3)
        self.assertAlmostEqual(markerSymbol.size(context2), 354.33070866141736, 3)

        markerSymbol.setSize(3)
        self.assertEqual(markerSymbol.size(), 3)
        # layer sizes should maintain relative size
        self.assertEqual(markerSymbol.symbolLayer(0).size(), 2)
        self.assertEqual(markerSymbol.symbolLayer(1).size(), 1)
        self.assertEqual(markerSymbol.symbolLayer(2).size(), 3)

        # symbol layer in different size
        markerSymbol.symbolLayer(1).setSize(15)
        self.assertAlmostEqual(markerSymbol.size(context), 56.69291338582678, 3)
        self.assertAlmostEqual(markerSymbol.size(context2), 177.16535433070868, 3)
        markerSymbol.symbolLayer(1).setSizeUnit(QgsUnitTypes.RenderPixels)
        self.assertAlmostEqual(markerSymbol.size(context), 15, 3)
        self.assertAlmostEqual(markerSymbol.size(context2), 35.43307086614173, 3)
        markerSymbol.symbolLayer(1).setSize(45)
        self.assertAlmostEqual(markerSymbol.size(context), 45, 3)
        self.assertAlmostEqual(markerSymbol.size(context2), 45, 3)
Пример #13
0
 def toMapSettings(self, mapSettings=None):
   if mapSettings is None:
     if QGis.QGIS_VERSION_INT >= 20300:
       from qgis.core import QgsMapSettings
       mapSettings = QgsMapSettings()
     else:
       return None
   mapSettings.setExtent(self._unrotated_rect)
   mapSettings.setRotation(self._rotation)
   return mapSettings
Пример #14
0
    def testConvertToPainterUnits(self):

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()

        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.0, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 23.622047, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 8.33333333125, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 600.0, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 2.0, places=5)

        # minimum size greater than the calculated size, so size should be limited to minSizeMM
        c.minSizeMM = 5
        c.minSizeMMEnabled = True
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 59.0551181, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 23.622047, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 8.33333333125, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 600.0, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 2.0, places=5)
        c.minSizeMMEnabled = False

        # maximum size less than the calculated size, so size should be limited to maxSizeMM
        c.maxSizeMM = 0.1
        c.maxSizeMMEnabled = True
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.0, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 23.622047, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 8.33333333125, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 600.0, places=5)
        size = r.convertToPainterUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 2.0, places=5)
Пример #15
0
    def test_signalConnection(self):
        # remove all layers
        QgsProject.instance().removeAllMapLayers()
        # set dependencies and add back layers
        self.pointsLayer = QgsVectorLayer("dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points", "spatialite")
        assert self.pointsLayer.isValid()
        self.linesLayer = QgsVectorLayer("dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines", "spatialite")
        assert self.linesLayer.isValid()
        self.pointsLayer2 = QgsVectorLayer(
            "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2", "spatialite"
        )
        assert self.pointsLayer2.isValid()
        self.pointsLayer.setDependencies([QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies([QgsMapLayerDependency(self.pointsLayer.id())])
        # this should update connections between layers
        QgsProject.instance().addMapLayers([self.pointsLayer])
        QgsProject.instance().addMapLayers([self.linesLayer])
        QgsProject.instance().addMapLayers([self.pointsLayer2])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(
            self.pointsLayer,
            QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels),
        )
        cfg.setIndividualLayerSettings(
            self.pointsLayer2,
            QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels),
        )
        u.setConfig(cfg)
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setFeatureId(4)
        geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is ok
        m = u.snapToMap(QPoint(75, 100 - 0))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPoint(0.8, 0.0))

        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
Пример #16
0
    def testConvertSingleUnit(self):

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()
        #self.assertEqual(r.scaleFactor(),666)

        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)

        # minimum scale greater than the renderer scale, so should be limited to minScale
        c.minScale = 150000000.0
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 3.89250455, places=5)
        # only conversion from mapunits should be affected
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)
        c.minScale = 0

        # maximum scale less than the renderer scale, so should be limited to maxScale
        c.maxScale = 350000000.0
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        # only conversion from mapunits should be affected
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)
Пример #17
0
def render_layers(layer_paths):
    """

    :param layer_paths: A list of layer paths.
    :return: Buffer containing output. Note caller is responsible for closing
        the buffer with buffer.close()
    :rtype: QBuffer
    """
    layers = []
    extent = None


    crs = QgsCoordinateReferenceSystem()
    crs.createFromSrid(3857)

    for layer_path in layer_paths:
        map_layer = QgsVectorLayer(layer_path, None, 'ogr')
        QgsMapLayerRegistry.instance().addMapLayer(map_layer)
        transform = QgsCoordinateTransform(map_layer.crs(), crs)
        print map_layer.extent().toString()
        layer_extent = transform.transform(map_layer.extent())
        if extent is None:
            extent = layer_extent
        else:
            extent.combineExtentWith(layer_extent)
        print extent.toString()
        # set layer set
        layers.append(map_layer.id())  # add ID of every layer

    map_settings = QgsMapSettings()

    map_settings.setDestinationCrs(crs)
    map_settings.setCrsTransformEnabled(True)
    map_settings.setExtent(extent)
    map_settings.setOutputSize(QSize(1000, 1000))

    map_settings.setLayers(layers)

    # job = QgsMapRendererParallelJob(settings)
    job = QgsMapRendererSequentialJob(map_settings)
    job.start()
    job.waitForFinished()
    image = job.renderedImage()
    # Save teh image to a buffer
    map_buffer = QBuffer()
    map_buffer.open(QIODevice.ReadWrite)
    image.save(map_buffer, "PNG")
    image.save('/tmp/test.png', 'png')

    # clean up
    QgsMapLayerRegistry.instance().removeAllMapLayers()

    return map_buffer
Пример #18
0
    def testMapUnitsPerPixel(self):
        # test computeMapUnitsPerPixel

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(75)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()

        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 2.0, places=5)

        # add a minimum scale less than the renderer scale, so should be no change
        c.minScale = 350000000.0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 2.0, places=5)

        # minimum scale greater than the renderer scale, so should be limited to minScale
        c.minScale = 150000000.0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 1.0276160, places=5)
        c.minScale = 50000000.0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 0.3425386, places=5)
        c.minScale = 350000000.0

        # add a maximum scale greater than the renderer scale, so should be no change
        c.maxScale = 150000000.0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 2.0, places=5)

        # maximum scale less than the renderer scale, so should be limited to maxScale
        c.maxScale = 350000000.0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 2.3977706, places=5)
        c.maxScale = 500000000.0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 3.4253867, places=5)

        # test resetting to min/max
        c.minScale = 0
        c.maxScale = 0
        mup = c.computeMapUnitsPerPixel(r)
        self.assertAlmostEqual(mup, 2.0, places=5)
Пример #19
0
    def testPixelSizeScaleFactor(self):
        # test QgsSymbolLayerUtils::pixelSizeScaleFactor() using QgsMapUnitScale

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()

        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 33.48006689762, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)

        # minimum scale greater than the renderer scale, so should be limited to minScale
        c.minScale = 1 / 150000000.0
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 3.8925045, places=5)
        # only conversion from mapunits should be affected
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.811023, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 33.48006689762, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)
        c.minScale = 0

        # maximum scale less than the renderer scale, so should be limited to maxScale
        c.maxScale = 1 / 350000000.0
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        # only conversion from mapunits should be affected
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 33.48006689762, places=5)
        sf = QgsSymbolLayerUtils.pixelSizeScaleFactor(r, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)
Пример #20
0
    def cloneMapSettings(self, oms):
        """
        :param QgsMapSettings oms: Other QgsMapSettings
        :rtype: QgsMapSettings
        """
        ms = QgsMapSettings()
        ms.setBackgroundColor(oms.backgroundColor())
        ms.setOutputSize(oms.outputSize())
        ms.setOutputDpi(oms.outputDpi())
        ms.setFlags(oms.flags())
        ms.setDestinationCrs(oms.destinationCrs())
        ms.setExtent(oms.extent())
        ms.setOutputImageFormat(oms.outputImageFormat())
        ms.setLabelingEngineSettings(oms.labelingEngineSettings())

        ms.setLayers(oms.layers())
        return ms
Пример #21
0
    def cloneMapSettings(self, oms):
        """
        :param oms: QgsMapSettings
        :rtype: QgsMapSettings
        """
        ms = QgsMapSettings()
        ms.setBackgroundColor(oms.backgroundColor())
        ms.setOutputSize(oms.outputSize())
        ms.setOutputDpi(oms.outputDpi())
        ms.setFlags(oms.flags())
        ms.setDestinationCrs(oms.destinationCrs())
        ms.setCrsTransformEnabled(oms.hasCrsTransformEnabled())
        ms.setMapUnits(oms.mapUnits())
        ms.setExtent(oms.extent())

        ms.setLayers(oms.layers())
        return ms
Пример #22
0
  def test01_export_empty(self):
    """test exporting with empty export settings"""
    # map settings
    canvasSize = QSize(600, 600)
    width = 1000.
    height = width * canvasSize.height() / canvasSize.width()
    crs = QgsCoordinateReferenceSystem(3099, QgsCoordinateReferenceSystem.EpsgCrsId)  # JGD2000 / UTM zone 53N

    mapSettings = QgsMapSettings()
    mapSettings.setOutputSize(canvasSize)
    mapSettings.setExtent(QgsRectangle(0, 0, width, height))
    mapSettings.setDestinationCrs(crs)

    exporter = Exporter()
    exporter.setMapSettings(mapSettings)
    err = exporter.export(outputPath(os.path.join("empty", "empty.html")))
    assert err == Exporter.NO_ERROR, err
Пример #23
0
    def checkRemovingLabeledLayerInvalidatesLabelCache(self, job_type):
        """ removing a previously labeled layer should invalidate any previous label caches"""
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        layer2.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer2.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer, layer2])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer, layer2})

        # remove a previously labeled layer
        settings.setLayers([layer2])

        # second job should not be able to use label cache, since a labeled layer was removed
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # but results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer2})
        self.assertTrue(job.takeLabelingResults())
Пример #24
0
    def checkLabeledLayerWithBlendModesCannotBeCached(self, job_type):
        """ any labeled layer utilising blending modes cannot be cached"""
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        labelSettings = QgsPalLayerSettings()
        labelSettings.fieldName = "fldtxt"
        layer.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings))
        layer.setLabelsEnabled(True)

        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        labelSettings2 = QgsPalLayerSettings()
        labelSettings2.fieldName = "fldtxt"
        format2 = QgsTextFormat()
        format2.setBlendMode(QPainter.CompositionMode_SourceIn)
        labelSettings2.setFormat(format2)
        layer2.setLabeling(QgsVectorLayerSimpleLabeling(labelSettings2))
        layer2.setLabelsEnabled(True)

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer, layer2])

        # with cache - cache should not be populated!
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertFalse(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        # second job should also not be able to use label cache
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # and results should not have been cached
        self.assertFalse(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())
Пример #25
0
    def checkAddingNewLabeledLayerInvalidatesLabelCache(self, job_type):
        """ adding a new labeled layer should invalidate any previous label caches"""
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")

        layer.setCustomProperty("labeling", "pal")
        layer.setCustomProperty("labeling/enabled", True)
        layer.setCustomProperty("labeling/fieldName", "fldtxt")

        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())

        self.assertEqual(cache.dependentLayers('_labels_'), [layer])

        # add another labeled layer
        layer2 = QgsVectorLayer("Point?field=fldtxt:string",
                                "layer2", "memory")
        layer2.setCustomProperty("labeling", "pal")
        layer2.setCustomProperty("labeling/enabled", True)
        layer2.setCustomProperty("labeling/fieldName", "fldtxt")
        settings.setLayers([layer, layer2])

        # second job should not be able to use label cache, since a new layer was added
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        # shouldn't use cache
        self.assertFalse(job.usedCachedLabels())
        # but results should have been cached
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertEqual(set(cache.dependentLayers('_labels_')), {layer, layer2})
        self.assertTrue(job.takeLabelingResults())
Пример #26
0
    def renderGeometry(self, geom):
        f = QgsFeature()
        f.setGeometry(geom)

        image = QImage(200, 200, QImage.Format_RGB32)

        painter = QPainter()
        ms = QgsMapSettings()
        extent = geom.get().boundingBox()
        # buffer extent by 10%
        if extent.width() > 0:
            extent = extent.buffered((extent.height() + extent.width()) / 20.0)
        else:
            extent = extent.buffered(10)

        ms.setExtent(extent)
        ms.setOutputSize(image.size())
        context = QgsRenderContext.fromMapSettings(ms)
        context.setPainter(painter)
        context.setScaleFactor(96 / 25.4)  # 96 DPI

        painter.begin(image)
        try:
            image.fill(QColor(0, 0, 0))

            if geom.type() == QgsWkbTypes.PolygonGeometry:
                self.fill_symbol.startRender(context)
                self.fill_symbol.renderFeature(f, context)
                self.fill_symbol.stopRender(context)

            elif geom.type() == QgsWkbTypes.LineGeometry:
                self.line_symbol.startRender(context)
                self.line_symbol.renderFeature(f, context)
                self.line_symbol.stopRender(context)

            elif geom.type() == QgsWkbTypes.PointGeometry:
                self.marker_symbol.startRender(context)
                self.marker_symbol.renderFeature(f, context)
                self.marker_symbol.stopRender(context)
            else:
                self.fail("Unknown type: " + geom.type())
        finally:
            painter.end()

        return image
Пример #27
0
 def getBaseMapSettings(cls):
     """
     :rtype: QgsMapSettings
     """
     ms = QgsMapSettings()
     crs = QgsCoordinateReferenceSystem()
     """:type: QgsCoordinateReferenceSystem"""
     # default for labeling test data: WGS 84 / UTM zone 13N
     crs.createFromSrid(32613)
     ms.setBackgroundColor(QColor(152, 219, 249))
     ms.setOutputSize(QSize(420, 280))
     ms.setOutputDpi(72)
     ms.setFlag(QgsMapSettings.Antialiasing, True)
     ms.setFlag(QgsMapSettings.UseAdvancedEffects, False)
     ms.setFlag(QgsMapSettings.ForceVectorOutput, False)  # no caching?
     ms.setDestinationCrs(crs)
     ms.setExtent(cls.aoiExtent())
     return ms
Пример #28
0
    def testFromMapSettings(self):
        """
        test QgsRenderContext.fromMapSettings()
        """
        ms = QgsMapSettings()
        ms.setOutputSize(QSize(1000, 1000))
        ms.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3111'))
        ms.setExtent(QgsRectangle(10000, 20000, 30000, 40000))

        ms.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysText)
        rc = QgsRenderContext.fromMapSettings(ms)
        self.assertEqual(rc.textRenderFormat(), QgsRenderContext.TextFormatAlwaysText)

        ms.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysOutlines)
        rc = QgsRenderContext.fromMapSettings(ms)
        self.assertEqual(rc.textRenderFormat(), QgsRenderContext.TextFormatAlwaysOutlines)

        self.assertEqual(rc.mapExtent(), QgsRectangle(10000, 20000, 30000, 40000))
Пример #29
0
    def testConvertFromMapUnits(self):
        # test QgsSymbolLayerUtils::convertToMapUnits() without QgsMapUnitScale

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841
        size = QgsSymbolLayerUtils.convertFromMapUnits(r, 2, QgsUnitTypes.RenderMapUnits)
        self.assertEqual(size, 2.0)
        size = QgsSymbolLayerUtils.convertFromMapUnits(r, 50, QgsUnitTypes.RenderMillimeters)
        self.assertAlmostEqual(size, 2.1166666666, places=5)
        size = QgsSymbolLayerUtils.convertFromMapUnits(r, 50, QgsUnitTypes.RenderPoints)
        self.assertAlmostEqual(size, 6.0000000015, places=5)
        size = QgsSymbolLayerUtils.convertFromMapUnits(r, 4, QgsUnitTypes.RenderPixels)
        self.assertAlmostEqual(size, 2.0, places=5)
Пример #30
0
    def testMapUnitScaleFactor(self):
        # test QgsSymbolLayerV2Utils::mapUnitScaleFactor() using QgsMapUnitScale

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        c = QgsMapUnitScale()
        sf = QgsSymbolLayerV2Utils.mapUnitScaleFactor(r, QgsSymbolV2.MapUnit, c)
        self.assertAlmostEqual(sf, 1.0, places=5)
        sf = QgsSymbolLayerV2Utils.mapUnitScaleFactor(r, QgsSymbolV2.MM, c)
        self.assertAlmostEqual(sf, 23.622047, places=5)
        sf = QgsSymbolLayerV2Utils.mapUnitScaleFactor(r, QgsSymbolV2.Pixel, c)
        self.assertAlmostEqual(sf, 2.0, places=5)
Пример #31
0
    def test_signalConnection(self):
        # remove all layers
        QgsProject.instance().removeAllMapLayers()
        # set dependencies and add back layers
        self.pointsLayer = QgsVectorLayer(
            "dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points",
            "spatialite")
        assert (self.pointsLayer.isValid())
        self.linesLayer = QgsVectorLayer(
            "dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines",
            "spatialite")
        assert (self.linesLayer.isValid())
        self.pointsLayer2 = QgsVectorLayer(
            "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2",
            "spatialite")
        assert (self.pointsLayer2.isValid())
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies(
            [QgsMapLayerDependency(self.pointsLayer.id())])
        # this should update connections between layers
        QgsProject.instance().addMapLayers([self.pointsLayer])
        QgsProject.instance().addMapLayers([self.linesLayer])
        QgsProject.instance().addMapLayers([self.pointsLayer2])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(
            self.pointsLayer,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        cfg.setIndividualLayerSettings(
            self.pointsLayer2,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(4)
        geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is OK
        m = u.snapToMap(QPoint(75, 100 - 0))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.8, 0.0))

        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
Пример #32
0
    def test_render_via_job(self):
        """
        Test rendering an annotation layer via a map render job
        """
        layer = QgsAnnotationLayer(
            'test',
            QgsAnnotationLayer.LayerOptions(
                QgsProject.instance().transformContext()))
        self.assertTrue(layer.isValid())

        item = QgsAnnotationPolygonItem(
            QgsPolygon(
                QgsLineString([
                    QgsPoint(11.5, 13),
                    QgsPoint(12, 13),
                    QgsPoint(12, 13.5),
                    QgsPoint(11.5, 13)
                ])))
        item.setSymbol(
            QgsFillSymbol.createSimple({
                'color': '200,100,100',
                'outline_color': 'black',
                'outline_width': '2'
            }))
        item.setZIndex(1)
        i1_id = layer.addItem(item)

        item = QgsAnnotationLineItem(
            QgsLineString(
                [QgsPoint(11, 13),
                 QgsPoint(12, 13),
                 QgsPoint(12, 15)]))
        item.setSymbol(
            QgsLineSymbol.createSimple({
                'color': '#ffff00',
                'line_width': '3'
            }))
        item.setZIndex(2)
        i2_id = layer.addItem(item)

        item = QgsAnnotationMarkerItem(QgsPoint(12, 13))
        item.setSymbol(
            QgsMarkerSymbol.createSimple({
                'color': '100,200,200',
                'size': '6',
                'outline_color': 'black'
            }))
        item.setZIndex(3)
        i3_id = layer.addItem(item)

        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))

        settings = QgsMapSettings()
        settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        settings.setExtent(QgsRectangle(10, 10, 18, 18))
        settings.setOutputSize(QSize(200, 200))
        settings.setLayers([layer])

        job = QgsMapRendererParallelJob(settings)
        job.start()
        job.waitForFinished()

        # check rendered item results
        item_results = job.takeRenderedItemResults()
        item_details = item_results.renderedItems()
        self.assertEqual(len(item_details), 3)
        self.assertEqual([i.layerId() for i in item_details], [layer.id()] * 3)
        self.assertCountEqual([i.itemId() for i in item_details],
                              [i1_id, i2_id, i3_id])
        self.assertCountEqual([
            i.itemId() for i in item_results.renderedAnnotationItemsInBounds(
                QgsRectangle(0, 0, 1, 1))
        ], [])
        self.assertCountEqual([
            i.itemId() for i in item_results.renderedAnnotationItemsInBounds(
                QgsRectangle(10, 10, 11, 18))
        ], [i2_id])
        self.assertCountEqual([
            i.itemId() for i in item_results.renderedAnnotationItemsInBounds(
                QgsRectangle(10, 10, 12, 18))
        ], [i1_id, i2_id, i3_id])

        # bounds should be in map crs
        self.assertEqual(
            [i.boundingBox() for i in item_details if i.itemId() == i1_id][0],
            QgsRectangle(11.5, 13, 12, 13.5))
        self.assertEqual(
            [i.boundingBox() for i in item_details if i.itemId() == i2_id][0],
            QgsRectangle(11, 13, 12, 15))
        self.assertEqual([
            i.boundingBox().toString(1) for i in item_details
            if i.itemId() == i3_id
        ][0], '11.5,12.5 : 12.5,13.5')
Пример #33
0
    def test_render_via_job_with_transform(self):
        """
        Test rendering an annotation layer via a map render job
        """
        layer = QgsAnnotationLayer(
            'test',
            QgsAnnotationLayer.LayerOptions(
                QgsProject.instance().transformContext()))
        self.assertTrue(layer.isValid())

        item = QgsAnnotationPolygonItem(
            QgsPolygon(
                QgsLineString([
                    QgsPoint(11.5, 13),
                    QgsPoint(12, 13),
                    QgsPoint(12, 13.5),
                    QgsPoint(11.5, 13)
                ])))
        item.setSymbol(
            QgsFillSymbol.createSimple({
                'color': '200,100,100',
                'outline_color': 'black',
                'outline_width': '2'
            }))
        item.setZIndex(1)
        i1_id = layer.addItem(item)

        item = QgsAnnotationLineItem(
            QgsLineString(
                [QgsPoint(11, 13),
                 QgsPoint(12, 13),
                 QgsPoint(12, 15)]))
        item.setSymbol(
            QgsLineSymbol.createSimple({
                'color': '#ffff00',
                'line_width': '3'
            }))
        item.setZIndex(2)
        i2_id = layer.addItem(item)

        item = QgsAnnotationMarkerItem(QgsPoint(12, 13))
        item.setSymbol(
            QgsMarkerSymbol.createSimple({
                'color': '100,200,200',
                'size': '6',
                'outline_color': 'black'
            }))
        item.setZIndex(3)
        i3_id = layer.addItem(item)

        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))

        settings = QgsMapSettings()
        settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        settings.setExtent(QgsRectangle(1250958, 1386945, 1420709, 1532518))
        settings.setOutputSize(QSize(200, 200))
        settings.setLayers([layer])

        job = QgsMapRendererSequentialJob(settings)
        job.start()
        job.waitForFinished()

        # check rendered item results
        item_results = job.takeRenderedItemResults()
        item_details = item_results.renderedItems()
        self.assertEqual(len(item_details), 3)
        self.assertEqual([i.layerId() for i in item_details], [layer.id()] * 3)
        self.assertCountEqual([i.itemId() for i in item_details],
                              [i1_id, i2_id, i3_id])
        # bounds should be in map crs
        self.assertEqual(
            [
                QgsGeometry.fromRect(i.boundingBox()).asWkt(0)
                for i in item_details if i.itemId() == i1_id
            ][0],
            'Polygon ((1280174 1459732, 1335834 1459732, 1335834 1516914, 1280174 1516914, 1280174 1459732))'
        )
        self.assertEqual(
            [
                QgsGeometry.fromRect(i.boundingBox()).asWkt(0)
                for i in item_details if i.itemId() == i2_id
            ][0],
            'Polygon ((1224514 1459732, 1335834 1459732, 1335834 1689200, 1224514 1689200, 1224514 1459732))'
        )
        expected = 'Polygon ((1325786 1449684, 1345882 1449684, 1345882 1469780, 1325786 1469780, 1325786 1449684))'
        result = [
            QgsGeometry.fromRect(i.boundingBox()).asWkt(0)
            for i in item_details if i.itemId() == i3_id
        ][0]
        self.assertTrue(
            compareWkt(result, expected, tol=1000),
            "mismatch Expected:\n{}\nGot:\n{}\n".format(expected, result))
Пример #34
0
    def testConvertToMapUnits(self):
        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()

        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertEqual(size, 2.0)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)

        # minimum size greater than the calculated size, so size should be limited to minSizeMM
        c.minSizeMM = 5
        c.minSizeMMEnabled = True
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 118.1102362, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.minSizeMMEnabled = False

        # maximum size less than the calculated size, so size should be limited to maxSizeMM
        c.maxSizeMM = 0.05
        c.maxSizeMMEnabled = True
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.1811023622047245, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.maxSizeMMEnabled = False

        # test with minimum scale set
        c.minScale = 150000000.0
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 15.57001821, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.minScale = 0

        # test with maximum scale set
        c.maxScale = 1550000000.0
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.50677595625, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.maxScale = 0
Пример #35
0
class Exporter:
    """A convenient class to export the scenes to web programmatically
    """

    NO_ERROR = None

    def __init__(self, iface=None, settingsPath=None):
        """ Constructor.

          :param iface: If specified, mapSettings attribute is initialized with the map settings of the map canvas.
                        The iface.legendInterface() is used to export vector layers in the same order as the legend.
          :type iface: QgisInterface
          :param settingsPath: Path to an existing settings file (.qto3settings).
          :type settingsPath: unicode
        """
        self.iface = iface
        self.mapSettings = None

        # create an export settings object
        self.settings = ExportSettings()
        if settingsPath:
            self.settings.loadSettingsFromFile(settingsPath)

        if iface:
            self.setMapSettings(iface.mapCanvas().mapSettings())

    def setExtent(self, center, width, height, rotation=0):
        """ Set map extent to export settings.

        This is a convenience method to set map extent to export settings.
        Map settings should be set before this method is called.

        :param center: Center of the map extent in the map CRS.
        :type center: QgsPoint
        :param width: Width of the map extent in unit of the map CRS.
        :type width: float
        :param height: Height of the map extent in unit of the map CRS.
        :type height: float
        :param rotation: Rotation in degrees. Requires QGIS version 2.8 or later.
        :type rotation: float
        """
        if self.mapSettings is None:
            self.mapSettings = QgsMapSettings()

        if rotation:
            rect = RotatedRect(center, width, height, rotation)
            rect.toMapSettings(self.mapSettings)
        else:
            rect = QgsRectangle(center.x() - width / 2,
                                center.y() - height / 2,
                                center.x() + width / 2,
                                center.y() + height / 2)
            self.mapSettings.setExtent(rect)

        self.settings.setMapSettings(self.mapSettings)

    def setMapSettings(self, mapSettings):
        """Set map settings to export settings.

        Map settings is used to define base extent of the export and render a map canvas image.

        :param mapSettings: Map settings to be set.
        :type mapSettings: QgsMapSettings
        """
        self.mapSettings = mapSettings
        self.settings.setMapSettings(mapSettings)

    def export(self, htmlPath, openBrowser=False):
        """Do export.

        :param htmlPath: Output HTML file path.
        :type htmlPath: unicode
        :param openBrowser: If True, open the exported page using default web browser.
        :type openBrowser: bool

        :returns: Exporter.NO_ERROR if success. Otherwise returns error message.
        :rtype: None or unicode.
        """
        self.settings.setOutputFilename(htmlPath)

        # check validity of export settings
        err_msg = self.settings.checkValidity()
        if err_msg:
            return err_msg

        ret = exportToThreeJS(
            self.settings,
            self.iface.legendInterface() if self.iface else None)
        if not ret:
            return "Failed to export (Unknown error)"

        if openBrowser:
            qgis2threejstools.openHTMLFile(self.settings.htmlfilename)

        return Exporter.NO_ERROR
Пример #36
0
    def testReprojectionErrorsWhileRendering(self):
        # WKT of a polygon which causes reprojection errors while rendering
        # (apologies for the ridiculously complex wkt, but I can't find a way to reproduce with simplifiction)
        wkt = 'MultiPolygon (((16.93392988400009358 42.77094147300012139, 16.88493899800005238 42.72939687700012712, ' \
              '16.80298912900011032 42.76349518400014915, 16.85816491000014139 42.78400299700011544, ' \
              '16.93392988400009358 42.77094147300012139)),((17.38200931100010393 42.79783763200002511, ' \
              '17.65894616000011297 42.74298737200008702, 17.74887129000009622 42.69456614800010641, ' \
              '17.32374108200008322 42.79083893400003547, 17.38200931100010393 42.79783763200002511)),' \
              '((16.768565300000148 42.97223541900014254, 17.03207441500009622 42.98261139500014849, ' \
              '17.13184655000009116 42.96954987200014386, 17.20020592500009116 42.92177969000012183, ' \
              '16.85141035200010151 42.90070221600008438, 16.65544681100004709 42.92625560099999404, ' \
              '16.70679772200014668 42.96954987200014386, 16.63168379000003938 42.98261139500014849, ' \
              '16.768565300000148 42.97223541900014254)),((17.05567467500011958 43.02895742400001211, ' \
              '17.24024498800011429 43.02277252800014651, 17.74146569100011561 42.83926015800001608, ' \
              '17.70736738400009358 42.88703034100014122, 17.65334906206413734 42.8909283361407887, ' \
              '17.70158573400010482 42.91950022500007833, 17.81175988700005064 42.909862570000044, ' \
              '17.85847538200005147 42.81697418200012351, 18.22413781700009849 42.62807098500009317, ' \
              '18.43735477700010961 42.55921213800017711, 18.4371480710000526 42.4934022020000981, ' \
              '18.49642988400009358 42.41632721600008438, 18.23894290500010129 42.55906810100005089, ' \
              '18.21753991000014139 42.6201032570001388, 18.07601972700010151 42.65131256700003348, ' \
              '18.0432235040000819 42.70205312700007028, 17.90162194100014403 42.75189850500014188, ' \
              '17.8928328790000819 42.79083893400003547, 17.72095787900005348 42.8262393250000315, ' \
              '17.7618921230000808 42.77871328300012976, 17.74870853000004445 42.77204010600017625, ' \
              '17.21387780000011958 42.98261139500014849, 17.04615319100011561 42.9950625670000619, ' \
              '17.00163821700004974 43.05149974200010377, 17.05567467500011958 43.02895742400001211)),' \
              '((16.19467207100007045 43.07440827000000638, 16.254893425000148 43.06854889500006323, ' \
              '16.08716881600014403 43.01146067900008063, 16.04883873800011429 43.06517161700004692, ' \
              '16.19467207100007045 43.07440827000000638)),((16.56275475400011032 43.22898997600010773, ' \
              '16.65951582100009887 43.21596914300012315, 16.72771243600001867 43.16461823100003414, ' \
              '17.19336998800014271 43.12726471600016964, 16.67017662900013875 43.12547435099999404, ' \
              '16.37159264400014536 43.19550202000006323, 16.49642988400006516 43.21808502800014651, ' \
              '16.58326256600014403 43.18866608300005794, 16.52051842500006273 43.22898997600010773, ' \
              '16.56275475400011032 43.22898997600010773)),((16.80681399800010922 43.34247467700005529, ' \
              '16.89234459700011826 43.31220123900006058, 16.84620201900008851 43.27338288000005662, ' \
              '16.62826582100012729 43.26373932500008834, 16.50074303500014139 43.28424713700003679, ' \
              '16.42188561300008587 43.31757233300011478, 16.40577233200011165 43.33270905200011214, ' \
              '16.45346113400009358 43.35317617400009738, 16.42628014400008851 43.39411041900011412, ' \
              '16.44703209700008983 43.39484284100014122, 16.80681399800010922 43.34247467700005529)),' \
              '((16.29818769600012729 43.40363190300011809, 16.30274498800008587 43.38727448100009099, ' \
              '16.39144941500012465 43.34638092700005529, 16.348643425000148 43.33869049700003018, ' \
              '16.20045006600014403 43.40704987200003018, 16.29818769600012729 43.40363190300011809)),' \
              '((16.33415774800010922 43.50153229400014254, 16.3752547540000819 43.49017975500008504, ' \
              '16.21143639400008851 43.49005768400009231, 16.26441491000014139 43.51288483300011478, ' \
              '16.33415774800010922 43.50153229400014254)),((15.67888431100004709 43.64801666900014254, ' \
              '15.74040774800010922 43.62750885600009099, 15.67204837300002396 43.63743724200010377, ' \
              '15.60377037900013875 43.67470937700007028, 15.67888431100004709 43.64801666900014254)),' \
              '((15.36736087300005238 43.79010651200015047, 15.39568118600007551 43.7724063170000619, ' \
              '15.22779381600014403 43.87445709800014981, 15.24073326900014536 43.88076406500009341, ' \
              '15.36736087300005238 43.79010651200015047)),((15.44271894600009887 43.89907461100013109, ' \
              '15.35865319100014403 43.91937897300014981, 15.26124108200011165 44.01105377800003282, ' \
              '15.38404381600008719 43.9701602230000077, 15.44271894600009887 43.89907461100013109)),' \
              '((15.22575931100010393 44.06622955900014915, 15.25440514400008851 44.01788971600014122, ' \
              '15.12183678500014139 44.09223053600005926, 15.06251061300008587 44.16193268400012073, ' \
              '15.22575931100010393 44.06622955900014915)),((14.83545983200014007 44.15102773600013109, ' \
              '14.85726972700010151 44.15204498900000374, 14.86915123800014271 44.14052969000006499, ' \
              '14.83521569100008719 44.14166901200009363, 14.81983483200014007 44.15302155199999845, ' \
              '14.82243899800005238 44.16868724200004692, 14.83545983200014007 44.15102773600013109)),' \
              '((14.98511803500011297 44.09096914300012315, 15.21680748800008587 43.91278717700008372, ' \
              '15.13331139400011693 43.92121002800003282, 15.19450931100004709 43.87262604400017096, ' \
              '15.10661868600007551 43.92544179900015422, 14.84961998800014271 44.17560455900014915, ' \
              '14.98511803500011297 44.09096914300012315)),((14.765961134000122 44.26504140800015819, ' \
              '14.74854576900014536 44.26166413000014188, 14.73959394600012729 44.28017812700015554, ' \
              '14.79167728000007287 44.27252838700003679, 14.765961134000122 44.26504140800015819)),' \
              '((14.66138756600011561 44.30866120000014519, 14.6407983730000808 44.31183502800003282, ' \
              '14.59506269600007045 44.34711334800006455, 14.643565300000148 44.32575104400011412, ' \
              '14.66138756600011561 44.30866120000014519)),((14.81120853000004445 44.35004303600000242, ' \
              '14.75619550900009358 44.36399974200004692, 14.76343834700008983 44.41535065300017493, ' \
              '14.80323326900008851 44.40550364800004957, 14.81120853000004445 44.35004303600000242)),' \
              '((14.27116946700002131 44.61253489800004957, 14.23259524800005238 44.62604401200012205, ' \
              '14.2657983730000808 44.67951080900003547, 14.28044681100007551 44.67755768400009231, ' \
              '14.27116946700002131 44.61253489800004957)),((14.84522545700008322 44.60053131700011875, ' \
              '14.93824303500014139 44.59414297100001079, 15.07553144600007045 44.48407623900006058, ' \
              '14.91114342500011958 44.54547760600014783, 15.04802493600004709 44.43943919500001982, ' \
              '15.09669030000009116 44.41518789300000947, 15.04151451900014536 44.47662995000008834, ' \
              '15.25440514400008851 44.34003327000000638, 15.165049675000148 44.36737702000006323, ' \
              '15.22022545700008322 44.3127302100001117, 15.13086998800008587 44.33258698100003414, ' \
              '15.17237389400014536 44.29913971600016964, 15.12875410200007309 44.31199778900018771, ' \
              '15.08920332100009887 44.37421295800000109, 15.11719811300014271 44.38719310099999404, ' \
              '15.04900149800010922 44.39468008000015686, 14.89747155000009116 44.49091217699999845, ' \
              '14.91863040500010129 44.50454336100013109, 14.87696373800011429 44.55975983300005794, ' \
              '14.73365319100008719 44.70319245000014519, 14.84522545700008322 44.60053131700011875)),' \
              '((14.41000410200010151 44.60097890800001608, 14.52662194100011561 44.50372955900012073, ' \
              '14.53435306100010393 44.48407623900006058, 14.42261803500008455 44.57387929900009738, ' \
              '14.36304772200014668 44.57343170800000109, 14.38257897200014668 44.60325755399999537, ' \
              '14.33578535200007309 44.71678294500010509, 14.39747155000009116 44.6856143250000315, ' \
              '14.41000410200010151 44.60097890800001608)),((14.75326582100007045 44.84585195500012844, ' \
              '14.74048912900011032 44.82050202000000638, 14.82243899800005238 44.77142975500005662, ' \
              '14.84961998800014271 44.70319245000014519, 14.65788821700004974 44.79877350500014188, ' \
              '14.7268172540000819 44.79877350500014188, 14.6858016290000819 44.8471540390000456, ' \
              '14.75326582100007045 44.84585195500012844)),((14.47103925900006516 44.95392487200003018, ' \
              '14.45191491000008455 44.79877350500014188, 14.47217858200011165 44.7079531920000619, ' \
              '14.53435306100010393 44.63426341400010244, 14.51335696700007816 44.618841864000089, ' \
              '14.42790774800005238 44.65656159100014122, 14.29420006600008719 44.9086367860001161, ' \
              '14.30152428500011297 44.94342682500014519, 14.38738040500004445 44.90900299700003018, ' \
              '14.39031009200004974 44.96039459800012139, 14.41138756600008719 44.95636627800014651, ' \
              '14.27849368600004709 45.1133487000000315, 14.29957116000014139 45.16233958499999801, ' \
              '14.35621178500014139 45.16925690300008966, 14.387705925000148 45.03904857000013351, ' \
              '14.47103925900006516 44.95392487200003018)),((14.56332441500012465 45.24974192900008063, ' \
              '14.62378991000011297 45.17548248900006058, 14.59742272200011826 45.16644928600005926, ' \
              '14.66529381600011561 45.16181061400011743, 14.66529381600011561 45.08734772300006455, ' \
              '14.74048912900011032 45.07306549700014386, 14.81495201900008851 44.97748444200009033, ' \
              '14.70639082100009887 44.9467227230000077, 14.62891686300014271 44.97817617400004053, ' \
              '14.62086022200008983 45.04559967700011214, 14.61695397200008983 45.02464427300007799, ' \
              '14.51050866000014139 45.03217194200011875, 14.43873131600014403 45.07050202000006323, ' \
              '14.4670516290000819 45.12409088700015047, 14.53012129000009622 45.13483307500014519, ' \
              '14.53435306100010393 45.23753489800002114, 14.56332441500012465 45.24974192900008063)),' \
              '((16.36947066200013978 46.54057118800012915, 16.63767134600004738 46.47447703100009164, ' \
              '16.75508020000012266 46.38187286400001597, 16.83765913900006694 46.38187286400001597, ' \
              '16.88923221800007468 46.29216257800014489, 17.05294315600005461 46.15346303300005104, ' \
              '17.20859257000006437 46.11656606000003933, 17.27587528500004055 46.01202463800002818, ' \
              '17.31680301900004793 45.99765859000002877, 17.29013798000011093 45.98463612900009423, ' \
              '17.40620324700006449 45.94365671800015605, 17.59110152100009827 45.93621531200012953, ' \
              '17.65652388500006964 45.84541982000014571, 17.80917606600013414 45.81441396100005647, ' \
              '17.85806197100004056 45.77172922800004073, 18.21121870900006456 45.78537180600012846, ' \
              '18.40438521300006869 45.74180857400001798, 18.57347049900010916 45.81668772400014689, ' \
              '18.6556360270001278 45.90758656800015558, 18.7755253500000947 45.88283355700004051, ' \
              '18.90130578600007993 45.93120269800006383, 18.87288374800004931 45.89523590100002082, ' \
              '18.90699019400011593 45.86795074500018643, 18.85531376100007606 45.85735707600009903, ' \
              '18.84497847500006174 45.8157058720000947, 18.96848514800012708 45.66873809800016204, ' \
              '18.90357954900008508 45.57308502200005762, 18.94171675700005153 45.53892689999999277, ' \
              '19.01809452300011571 45.56740061400002162, 19.10625451700005328 45.51164174500017623, ' \
              '19.00961958800010621 45.49867095900005154, 19.00300500400010151 45.45536611000007099, ' \
              '19.03742150900006891 45.42229319300010104, 18.97592655400006834 45.39495636000008005, ' \
              '19.09199182100007874 45.34999786400005917, 19.12475467900009107 45.29811472600006539, ' \
              '19.36308638500014467 45.24824696900010679, 19.40783817500010855 45.20313344400013023, ' \
              '19.39068160000005037 45.16933705700016333, 19.22593713300008744 45.16194732700016345, ' \
              '19.12186079900010327 45.195795390000157, 19.13767378700009658 45.14603098600004216, ' \
              '19.04486291500009543 45.13724599300006446, 19.08227665200013234 45.08494944300004192, ' \
              '19.0872375890000967 44.97710072800013847, 19.13167932100006396 44.95317454000003465, ' \
              '19.06667036900009293 44.90568389900012392, 18.99142948400006503 44.9149339800001286, ' \
              '19.01582076000008215 44.86563466400004074, 18.88962691200009658 44.86119049100013001, ' \
              '18.78338016700013213 44.91374542300012251, 18.79175174900009893 45.00154368100008639, ' \
              '18.73831831900008638 45.0159097290000858, 18.68405806500004473 45.08479441400000098, ' \
              '18.64871138500012648 45.06267689999999959, 18.61667199700013953 45.09766184500010411, ' \
              '18.54959598800010667 45.09476796500011631, 18.51703983500007666 45.05585561200003042, ' \
              '18.23788374800011525 45.15745147700012296, 18.15365116400005263 45.0975584930001645, ' \
              '18.00347945100011771 45.1493382780000303, 17.83573775200005684 45.0644338990000648, ' \
              '17.68473921700012852 45.1639627080000281, 17.48185754400009273 45.11440500900012296, ' \
              '17.49622359200009214 45.1416901650001563, 17.44775109900012922 45.13430043600014585, ' \
              '17.44330692500011537 45.16205068000009248, 17.38243208800008688 45.1396231090000839, ' \
              '17.26895064300006766 45.18954254200015441, 17.24548954300007608 45.15538442000017483, ' \
              '17.18709517400012032 45.14856313100001728, 17.0363033440001459 45.23047027600007652, ' \
              '17.00829471800011561 45.21615590500009318, 17.00829471800011561 45.24416453100009505, ' \
              '16.94731652900014751 45.23568959600000028, 16.9243721930001243 45.28452382500016427, ' \
              '16.81171757000004163 45.18122263700009, 16.52894413300009546 45.22225372400005483, ' \
              '16.38921106000003647 45.11683380099999852, 16.31624393700010955 45.00123362300008978, ' \
              '16.12152714000009723 45.09616322900008356, 16.02044803900011516 45.213933818000001, ' \
              '15.79234826700013627 45.18980092400012438, 15.76361617000014803 44.97555043600003444, ' \
              '15.7308533120001357 44.92723297200008403, 15.77343469200010873 44.84501576800015243, ' \
              '15.71607385200013596 44.80320953400008932, 15.72847619600008784 44.76910308800002269, ' \
              '15.80568078600006743 44.69665273000013883, 15.88877648900006534 44.72424794500012979, ' \
              '15.96897831200004703 44.63924021400013942, 16.02830285600006732 44.62471913700009907, ' \
              '16.04473596200011798 44.58937245700018082, 16.00608199000004106 44.54100331600012908, ' \
              '16.11646285000011858 44.52146962500013672, 16.15966434700004584 44.41610138000002905, ' \
              '16.13827030500004867 44.37760243800015303, 16.20286584400008678 44.35977406800010669, ' \
              '16.18756962000011868 44.28241444999999032, 16.21578495300011014 44.20815541600011045, ' \
              '16.32688928200008149 44.08237498000012522, 16.50103885900011846 43.99271637000008184, ' \
              '16.67859908100004418 43.8406843060001421, 16.71260217300007866 43.77151540100005889, ' \
              '17.03051558500007445 43.54847991900005866, 17.27050093600007585 43.46321380700000248, ' \
              '17.28993127500007176 43.3034302780000786, 17.44206669100009321 43.15243174300015028, ' \
              '17.6284119050001209 43.04657257100008394, 17.66272505700004558 42.96569895500012137, ' \
              '17.63450972400008254 42.950402731000068, 17.51563561300008587 42.95888906500012183, ' \
              '17.47087649800005238 43.01341380400010905, 17.50196373800014271 43.03099192900005221, ' \
              '17.43360436300014271 43.01740143400009231, 17.46021569100011561 43.03099192900005221, ' \
              '17.42611738400009358 43.06517161700004692, 17.4045516290000819 43.05149974200010377, ' \
              '17.31625410200012993 43.12726471600016964, 17.11394290500004445 43.21320221600008438, ' \
              '16.88062584700011826 43.40595123900006058, 16.62582441500009622 43.44904205900009231, ' \
              '16.52466881600011561 43.51080963700009363, 16.39144941500012465 43.51080963700009363, ' \
              '16.47339928500008455 43.5381533870001789, 16.43384850400013875 43.54975006700000506, ' \
              '16.11768639400008851 43.52448151200003679, 16.17237389400014536 43.4896914730000077, ' \
              '16.11312910200004467 43.47890859600009605, 15.95948326900011693 43.50397370000008834, ' \
              '15.987315300000148 43.54490794500010509, 15.92530358200011165 43.55857982000004824, ' \
              '15.91895592500009116 43.62872955900012073, 15.96631920700011165 43.64118073100003414, ' \
              '15.90479576900014536 43.64801666900014254, 15.95297285200010151 43.65086497599999404, ' \
              '15.95045006600008719 43.68854401200015047, 15.70630944100008719 43.76341380400005221, ' \
              '15.6174422540000819 43.82550690300017493, 15.66309655000009116 43.81297435099999404, ' \
              '15.67888431100004709 43.81928131700011875, 15.45508873800014271 43.92804596600014122, ' \
              '15.14454186300011429 44.19546133000015686, 15.15219160200012993 44.23529694200014717, ' \
              '15.11036217500011958 44.26434967700011214, 15.14063561300011429 44.28245677300013483, ' \
              '15.17660566500009622 44.24994538000005662, 15.20777428500008455 44.27277252800014651, ' \
              '15.19809004000012465 44.30166250200007028, 15.295258009000122 44.25067780199999845, ' \
              '15.30274498800008587 44.29913971600016964, 15.26124108200011165 44.33258698100003414, ' \
              '15.42448978000001603 44.26797109600006763, 15.52865644600009887 44.27179596600008438, ' \
              '15.30795332100009887 44.35439687700007028, 15.00733483200014007 44.56972890800012976, ' \
              '14.883799675000148 44.7236188820001388, 14.883799675000148 44.86147695500012844, 14.92164147200008983 ' \
              '44.95880768400009231, 14.85279381600011561 45.09365469000000815, 14.65788821700004974 ' \
              '45.19660065300017493, 14.57081139400008851 45.29364655200011214, 14.31153405000009116 ' \
              '45.34398021000005485, 14.23259524800005238 45.14935944200000506, 14.17937259200007816 ' \
              '45.13450755400005221, 14.19312584700008983 45.10561758000012844, 14.14389082100007045 ' \
              '45.05939362200003018, 14.151377800000148 44.97748444200009033, 14.06885826900014536 ' \
              '44.94953034100014122, 14.08383222700007309 44.9863955750000315, 14.04029381600014403 ' \
              '45.03896719000015025, 14.0756942070000548 44.98371002800003282, 14.02051842500011958 ' \
              '44.90110911700004692, 13.97266686300011429 44.90110911700004692, 13.99301191500009622 ' \
              '44.88129303600014453, 13.97266686300011429 44.82664622599999404, 14.00001061300008587 ' \
              '44.81305573100003414, 13.89014733200011165 44.83348216400010244, 13.91797936300014271 ' \
              '44.77826569200009033, 13.90316816500009622 44.77240631700014717, 13.89698326900011693 ' \
              '44.81305573100003414, 13.78711998800014271 44.87506745000008834, 13.84229576900008851 ' \
              '44.88812897300006455, 13.79460696700010658 44.89496491100008768, 13.77409915500007287 ' \
              '44.96381256700014717, 13.6232202480000808 45.07306549700014386, 13.61255944100014403 ' \
              '45.11786530199999845, 13.72624759200004974 45.13450755400005221, 13.5959578790000819 ' \
              '45.14541250200001343, 13.57545006600011561 45.26487864800007799, 13.60271243600001867 ' \
              '45.28534577000012007, 13.57545006600011561 45.30646393400006389, 13.60954837300005238 ' \
              '45.32013580900017757, 13.54127037900013875 45.34613678600005926, 13.50709069100014403 ' \
              '45.51190827000000638, 13.62901778100007277 45.45898346000016943, 13.75929406800014476 ' \
              '45.46316925100011019, 13.88900191200011136 45.42363678000005223, 13.98263960800005634 ' \
              '45.47531321200001742, 13.97189091000012695 45.5142255660000643, 14.09291711400010172 ' \
              '45.47391794800002174, 14.21869755100007637 45.49717234400004884, 14.37279667100006009 ' \
              '45.47784535800009564, 14.4689148350000778 45.52559438100014688, 14.49857710800012001 ' \
              '45.59618438800005435, 14.58094934100009255 45.66780792200010808, 14.66848921700008646 ' \
              '45.53396596300005683, 14.79716353300005949 45.46518463200006011, 14.88160282300009385 ' \
              '45.46978383400001178, 14.9226339110000481 45.51494903600017494, 15.13926151500010064 ' \
              '45.43004465799999991, 15.32519331800011742 45.45283396399999276, 15.36136682100004691 ' \
              '45.48203114900003641, 15.29666792800006192 45.52295888300012905, 15.2685559480001416 ' \
              '45.60166208900012919, 15.37376916500011248 45.64021270800010655, 15.25501672300006817 ' \
              '45.72346344000011698, 15.42906294700014769 45.77529490200011253, 15.45128381300008868 ' \
              '45.81513743100013869, 15.67607629400006886 45.84169911700014666, 15.65943648300003588 ' \
              '45.88882802400014782, 15.69798710100010908 46.0362092080000167, 15.58988000500005455 ' \
              '46.11351715100001059, 15.62284956800010605 46.19170359400006021, 16.01920780400010358 ' \
              '46.29882883700007312, 16.05961877400008575 46.33231516600015709, 16.0579651280001201 ' \
              '46.37753204400003426, 16.2756262620000598 46.37316538500006402, 16.23490523300009158 ' \
              '46.4933389280001137, 16.36947066200013978 46.54057118800012915))) '
        geom = QgsGeometry.fromWkt(wkt)
        f = QgsFeature()
        f.setGeometry(geom)

        image = QImage(200, 200, QImage.Format_RGB32)

        painter = QPainter()
        ms = QgsMapSettings()
        crs = QgsCoordinateReferenceSystem.fromProj4(
            '+proj=ortho +lat_0=36.5 +lon_0=-118.8 +x_0=0 +y_0=0 +a=6371000 +b=6371000 +units=m +no_defs'
        )
        self.assertTrue(crs.isValid())
        ms.setDestinationCrs(crs)
        ms.setExtent(QgsRectangle(1374999.8, 3912610.7, 4724462.5, 6505499.6))
        ms.setOutputSize(image.size())
        context = QgsRenderContext.fromMapSettings(ms)
        context.setPainter(painter)
        context.setScaleFactor(96 / 25.4)  # 96 DPI
        ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem('epsg:4326'),
                                    crs, QgsProject.instance())
        self.assertTrue(ct.isValid())
        context.setCoordinateTransform(ct)
        context.setExtent(
            ct.transformBoundingBox(ms.extent(),
                                    QgsCoordinateTransform.ReverseTransform))

        fill_symbol = QgsFillSymbol.createSimple({
            'color': '#ffffff',
            'outline_color': '#ffffff',
            'outline_width': '10'
        })

        painter.begin(image)
        try:
            image.fill(QColor(0, 0, 0))
            fill_symbol.startRender(context)
            fill_symbol.renderFeature(f, context)
            fill_symbol.stopRender(context)
        finally:
            painter.end()

        assert self.imageCheck('Reprojection errors polygon',
                               'reprojection_errors_polygon', image)

        #also test linestring
        linestring = QgsGeometry(geom.constGet().boundary())
        f.setGeometry(linestring)
        line_symbol = QgsLineSymbol.createSimple({
            'color': '#ffffff',
            'outline_width': '10'
        })

        image = QImage(200, 200, QImage.Format_RGB32)
        painter.begin(image)
        try:
            image.fill(QColor(0, 0, 0))
            line_symbol.startRender(context)
            line_symbol.renderFeature(f, context)
            line_symbol.stopRender(context)
        finally:
            painter.end()

        assert self.imageCheck('Reprojection errors linestring',
                               'reprojection_errors_linestring', image)
Пример #37
0
class TestQgsPointClusterRenderer(unittest.TestCase):
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(self.layer)

        self.renderer = QgsPointClusterRenderer()
        sym1 = QgsMarkerSymbol.createSimple({
            'color': '#ff00ff',
            'size': '3',
            'outline_style': 'no'
        })
        renderer = QgsSingleSymbolRenderer(sym1)
        self.renderer.setEmbeddedRenderer(renderer)
        self.renderer.setClusterSymbol(
            QgsMarkerSymbol.createSimple({
                'color': '#ffff00',
                'size': '3',
                'outline_style': 'no'
            }))
        self.layer.setRenderer(self.renderer)

        rendered_layers = [self.layer]
        self.mapsettings = QgsMapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52))
        self.mapsettings.setLayers(rendered_layers)

    def tearDown(self):
        QgsProject.instance().removeAllMapLayers()

    def _setProperties(self, r):
        """ set properties for a renderer for testing with _checkProperties"""
        r.setTolerance(5)
        r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
        r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
        m = QgsMarkerSymbol()
        m.setColor(QColor(0, 255, 0))
        r.setClusterSymbol(m)
        sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
        renderer = QgsSingleSymbolRenderer(sym1)
        r.setEmbeddedRenderer(renderer)

    def _checkProperties(self, r):
        """ test properties of renderer against expected"""
        self.assertEqual(r.tolerance(), 5)
        self.assertEqual(r.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
        self.assertEqual(r.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
        self.assertEqual(r.clusterSymbol().color(), QColor(0, 255, 0))
        self.assertEqual(r.embeddedRenderer().symbol().color().name(),
                         '#fdbf6f')

    def testGettersSetters(self):
        """ test getters and setters """
        r = QgsPointClusterRenderer()
        self._setProperties(r)
        self._checkProperties(r)

    def testClone(self):
        """ test cloning renderer """
        r = QgsPointClusterRenderer()
        self._setProperties(r)
        c = r.clone()
        self._checkProperties(c)

    def testSaveCreate(self):
        """ test saving and recreating from XML """
        r = QgsPointClusterRenderer()
        self._setProperties(r)
        doc = QDomDocument("testdoc")
        elem = r.save(doc, QgsReadWriteContext())
        c = QgsPointClusterRenderer.create(elem, QgsReadWriteContext())
        self._checkProperties(c)

    def testConvert(self):
        """ test renderer conversion """

        # same type, should clone
        r = QgsPointClusterRenderer()
        self._setProperties(r)
        c = QgsPointClusterRenderer.convertFromRenderer(r)
        self._checkProperties(c)

        # test conversion from displacement renderer
        r = QgsPointDisplacementRenderer()
        r.setTolerance(5)
        r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
        r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
        m = QgsMarkerSymbol()
        m.setColor(QColor(0, 255, 0))
        r.setCenterSymbol(m)
        sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
        renderer = QgsSingleSymbolRenderer(sym1)
        r.setEmbeddedRenderer(renderer)

        # want to keep as many settings as possible when converting between cluster and displacement renderer
        d = QgsPointClusterRenderer.convertFromRenderer(r)
        self.assertEqual(d.tolerance(), 5)
        self.assertEqual(d.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
        self.assertEqual(d.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
        self.assertEqual(d.clusterSymbol().color(), QColor(0, 255, 0))
        self.assertEqual(d.embeddedRenderer().symbol().color().name(),
                         '#fdbf6f')

    def testRenderNoCluster(self):
        self.layer.renderer().setTolerance(1)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('cluster_renderer')
        renderchecker.setControlName('expected_cluster_no_cluster')
        self.assertTrue(renderchecker.runTest('cluster_no_cluster'))

    def testRenderWithin(self):
        self.layer.renderer().setTolerance(10)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('cluster_renderer')
        renderchecker.setControlName('expected_cluster_cluster')
        self.assertTrue(renderchecker.runTest('expected_cluster_cluster'))

    def testRenderVariables(self):
        """ test rendering with expression variables in marker """
        self.layer.renderer().setTolerance(10)

        old_marker = self.layer.renderer().clusterSymbol().clone()

        new_marker = QgsMarkerSymbol.createSimple({
            'color': '#ffff00',
            'size': '3',
            'outline_style': 'no'
        })
        new_marker.symbolLayer(0).setDataDefinedProperty(
            QgsSymbolLayer.PropertyFillColor,
            QgsProperty.fromExpression('@cluster_color'))
        new_marker.symbolLayer(0).setDataDefinedProperty(
            QgsSymbolLayer.PropertySize,
            QgsProperty.fromExpression('@cluster_size*2'))
        self.layer.renderer().setClusterSymbol(new_marker)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('cluster_renderer')
        renderchecker.setControlName('expected_cluster_variables')
        result = renderchecker.runTest('expected_cluster_variables')
        self.layer.renderer().setClusterSymbol(old_marker)
        self.assertTrue(result)
Пример #38
0
    def testPaletted(self):
        """ test paletted raster renderer with raster with color table"""
        path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, [
            QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'),
            QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')
        ])

        self.assertEqual(renderer.nColors(), 2)
        self.assertEqual(renderer.usesBands(), [1])

        # test labels
        self.assertEqual(renderer.label(1), 'class 2')
        self.assertEqual(renderer.label(3), 'class 1')
        self.assertFalse(renderer.label(101))

        # test legend symbology - should be sorted by value
        legend = renderer.legendSymbologyItems()
        self.assertEqual(legend[0][0], 'class 2')
        self.assertEqual(legend[1][0], 'class 1')
        self.assertEqual(legend[0][1].name(), '#00ff00')
        self.assertEqual(legend[1][1].name(), '#ff0000')

        # test retrieving classes
        classes = renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'class 1')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')

        # test set label
        # bad index
        renderer.setLabel(1212, 'bad')
        renderer.setLabel(3, 'new class')
        self.assertEqual(renderer.label(3), 'new class')

        # color ramp
        r = QgsLimitedRandomColorRamp(5)
        renderer.setSourceColorRamp(r)
        self.assertEqual(renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(renderer.sourceColorRamp().count(), 5)

        # clone
        new_renderer = renderer.clone()
        classes = new_renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(new_renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(new_renderer.sourceColorRamp().count(), 5)

        # write to xml and read
        doc = QDomDocument('testdoc')
        elem = doc.createElement('qgis')
        renderer.writeXml(doc, elem)
        restored = QgsPalettedRasterRenderer.create(
            elem.firstChild().toElement(), layer.dataProvider())
        self.assertTrue(restored)
        self.assertEqual(restored.usesBands(), [1])
        classes = restored.classes()
        self.assertTrue(classes)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(restored.sourceColorRamp().type(), 'random')
        self.assertEqual(restored.sourceColorRamp().count(), 5)

        # render test
        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer"),
                        "Paletted rendering test failed")
Пример #39
0
class TileSet():

    """
    A set of tiles
    """

    def __init__(self, map_theme, layer, extent, tile_size, mupp, output,
                 map_settings):
        """

        :param map_theme:
        :param extent:
        :param layer:
        :param tile_size:
        :param mupp:
        :param output:
        :param map_settings: Map canvas map settings used for some fallback
        values and CRS
        """

        self.extent = extent
        self.mupp = mupp
        self.tile_size = tile_size

        driver = self.getDriverForFile(output)

        if not driver:
            raise QgsProcessingException(
                u'Could not load GDAL driver for file {}'.format(output))

        crs = map_settings.destinationCrs()

        self.x_tile_count = math.ceil(extent.width() / mupp / tile_size)
        self.y_tile_count = math.ceil(extent.height() / mupp / tile_size)

        xsize = self.x_tile_count * tile_size
        ysize = self.y_tile_count * tile_size

        self.dataset = driver.Create(output, xsize, ysize, 3)  # 3 bands
        self.dataset.SetProjection(str(crs.toWkt()))
        self.dataset.SetGeoTransform(
            [extent.xMinimum(), mupp, 0, extent.yMaximum(), 0, -mupp])

        self.image = QImage(QSize(tile_size, tile_size), QImage.Format_ARGB32)

        self.settings = QgsMapSettings()
        self.settings.setOutputDpi(self.image.logicalDpiX())
        self.settings.setOutputImageFormat(QImage.Format_ARGB32)
        self.settings.setDestinationCrs(crs)
        self.settings.setOutputSize(self.image.size())
        self.settings.setFlag(QgsMapSettings.Antialiasing, True)
        self.settings.setFlag(QgsMapSettings.RenderMapTile, True)

        if QgsProject.instance().mapThemeCollection().hasMapTheme(map_theme):
            self.settings.setLayers(
                QgsProject.instance().mapThemeCollection(

                ).mapThemeVisibleLayers(
                    map_theme))
            self.settings.setLayerStyleOverrides(
                QgsProject.instance().mapThemeCollection(

                ).mapThemeStyleOverrides(
                    map_theme))
        elif layer:
            self.settings.setLayers([layer])
        else:
            self.settings.setLayers(map_settings.layers())

    def render(self, feedback):
        for x in range(self.x_tile_count):
            for y in range(self.y_tile_count):
                if feedback.isCanceled():
                    return
                cur_tile = x * self.y_tile_count + y
                num_tiles = self.x_tile_count * self.y_tile_count
                self.renderTile(x, y, feedback)

                feedback.setProgress(int((cur_tile / num_tiles) * 100))

    def renderTile(self, x, y, feedback):
        """
        Render one tile

        :param x: The x index of the current tile
        :param y: The y index of the current tile
        """
        painter = QPainter(self.image)

        self.settings.setExtent(QgsRectangle(
            self.extent.xMinimum() + x * self.mupp * self.tile_size,
            self.extent.yMaximum() - (y + 1) * self.mupp * self.tile_size,
            self.extent.xMinimum() + (x + 1) * self.mupp * self.tile_size,
            self.extent.yMaximum() - y * self.mupp * self.tile_size))

        job = QgsMapRendererCustomPainterJob(self.settings, painter)
        job.renderSynchronously()
        painter.end()

        # Needs not to be deleted or Windows will kill it too early...
        tmpfile = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
        try:
            self.image.save(tmpfile.name)

            src_ds = osgeo.gdal.Open(tmpfile.name)

            self.dataset.WriteRaster(x * self.tile_size, y * self.tile_size,
                                     self.tile_size, self.tile_size,
                                     src_ds.ReadRaster(0, 0, self.tile_size,
                                                       self.tile_size))
        except Exception as e:
            feedback.reportError(str(e))
        finally:
            del src_ds
            tmpfile.close()
            os.unlink(tmpfile.name)

    def getDriverForFile(self, filename):
        """
        Get the GDAL driver for a filename, based on its extension. (.gpkg,
        .mbtiles...)
        """
        _, extension = os.path.splitext(filename)

        # If no extension is set, use .tif as default
        if extension == '':
            extension = '.tif'

        driver_name = QgsRasterFileWriter.driverForExtension(extension[1:])
        return osgeo.gdal.GetDriverByName(driver_name)
Пример #40
0
    def test_resetSnappingIndex(self):
        self.pointsLayer.setDependencies([])
        self.linesLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(
            self.pointsLayer,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)

        m = u.snapToMap(QPoint(95, 100))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPoint(1, 0))

        f = QgsFeature(self.linesLayer.fields())
        f.setId(1)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0,1 1)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()

        l1 = len([f for f in self.pointsLayer.getFeatures()])
        self.assertEqual(l1, 4)
        m = u.snapToMap(QPoint(95, 0))
        # snapping not updated
        self.pointsLayer.setDependencies([])
        self.assertEqual(m.isValid(), False)

        # set layer dependencies
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(2)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0,0.5 0.5)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the snapped point is ok
        m = u.snapToMap(QPoint(45, 50))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPoint(0.5, 0.5))
        self.pointsLayer.setDependencies([])

        # test chained layer dependencies A -> B -> C
        cfg.setIndividualLayerSettings(
            self.pointsLayer2,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies(
            [QgsMapLayerDependency(self.pointsLayer.id())])
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(3)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0.2,0.5 0.8)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is ok
        m = u.snapToMap(QPoint(75, 100 - 80))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPoint(0.7, 0.8))
        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
class TestQgsRulebasedRenderer(unittest.TestCase):
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })
        sym2 = QgsFillSymbol.createSimple({
            'color': '#71bd6c',
            'outline_color': 'black'
        })
        sym3 = QgsFillSymbol.createSimple({
            'color': '#1f78b4',
            'outline_color': 'black'
        })

        self.r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.r1)
        rootrule.appendChild(self.r2)
        rootrule.appendChild(self.r3)

        layer.setRenderer(QgsRuleBasedRenderer(rootrule))
        self.mapsettings = QgsMapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer]
        self.mapsettings.setLayers(rendered_layers)

    def testElse(self):
        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_rulebased_else')
        result = renderchecker.runTest('rulebased_else')

        assert result

    def testDisabledElse(self):
        # Disable a rule and assert that it's hidden not rendered with else
        self.r2.setActive(False)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_rulebased_disabled_else')
        result = renderchecker.runTest('rulebased_disabled_else')

        assert result

    def testWillRenderFeature(self):
        vl = self.mapsettings.layers()[0]
        ft = vl.getFeature(0)  # 'id' = 1
        renderer = vl.renderer()

        ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
        ctx.expressionContext().setFeature(ft)

        renderer.rootRule().children()[0].setActive(False)
        renderer.rootRule().children()[1].setActive(True)
        renderer.rootRule().children()[2].setActive(True)

        renderer.startRender(ctx, vl.fields())  # build mActiveChlidren
        rendered = renderer.willRenderFeature(ft, ctx)
        renderer.stopRender(ctx)
        renderer.rootRule().children()[0].setActive(True)
        assert rendered == False

        renderer.startRender(ctx, vl.fields())  # build mActiveChlidren
        rendered = renderer.willRenderFeature(ft, ctx)
        renderer.stopRender(ctx)
        assert rendered == True

    def testWillRenderFeatureNestedElse(self):
        vl = self.mapsettings.layers()[0]
        ft = vl.getFeature(0)  # 'id' = 1

        ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
        ctx.expressionContext().setFeature(ft)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })
        sym2 = QgsFillSymbol.createSimple({
            'color': '#71bd6c',
            'outline_color': 'black'
        })
        sym3 = QgsFillSymbol.createSimple({
            'color': '#1f78b4',
            'outline_color': 'black'
        })

        self.rx1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.rx2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.rx3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        self.rx3.appendChild(self.rx1)

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.rx2)
        rootrule.appendChild(self.rx3)

        vl.setRenderer(QgsRuleBasedRenderer(rootrule))
        renderer = vl.renderer()

        # Reunder with else rule and all activated
        renderer.startRender(ctx, vl.fields())
        self.assertTrue(renderer.willRenderFeature(ft, ctx))
        renderer.stopRender(ctx)

        # Reunder with else rule where else is deactivated
        renderer.rootRule().children()[1].setActive(False)
        renderer.startRender(ctx, vl.fields())
        self.assertFalse(renderer.willRenderFeature(ft, ctx))
        renderer.stopRender(ctx)

    def testFeatureCount(self):
        vl = self.mapsettings.layers()[0]
        ft = vl.getFeature(2)  # 'id' = 3 => ELSE
        renderer = vl.renderer()

        ctx = QgsRenderContext.fromMapSettings(self.mapsettings)
        ctx.expressionContext().setFeature(ft)

        counter = vl.countSymbolFeatures()
        counter.waitForFinished()

        renderer.startRender(ctx, vl.fields())

        elseRule = None
        for rule in renderer.rootRule().children():
            if rule.filterExpression() == 'ELSE':
                elseRule = rule

        assert elseRule != None

        cnt = counter.featureCount(elseRule.ruleKey())
        assert cnt == 1

    def testRefineWithCategories(self):
        # Test refining rule with categories (refs #10815)

        # First, try with a field based category (id)
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "id 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "id 2"))
        c = QgsCategorizedSymbolRenderer("id", cats)

        QgsRuleBasedRenderer.refineRuleCategories(self.r2, c)
        assert self.r2.children()[0].filterExpression() == '"id" = 1'
        assert self.r2.children()[1].filterExpression() == '"id" = 2'

        # Next try with an expression based category
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer("id + 1", cats)

        QgsRuleBasedRenderer.refineRuleCategories(self.r1, c)
        assert self.r1.children()[0].filterExpression() == 'id + 1 = 1'
        assert self.r1.children()[1].filterExpression() == 'id + 1 = 2'

        # Last try with an expression which is just a quoted field name
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer('"id"', cats)

        QgsRuleBasedRenderer.refineRuleCategories(self.r3, c)
        assert self.r3.children()[0].filterExpression() == '"id" = 1'
        assert self.r3.children()[1].filterExpression() == '"id" = 2'

    def testRefineWithRanges(self):
        # Test refining rule with ranges (refs #10815)

        # First, try with a field based category (id)
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id", ranges)

        QgsRuleBasedRenderer.refineRuleRanges(self.r2, g)
        assert self.r2.children()[0].filterExpression(
        ) == '"id" >= 0.0000 AND "id" <= 1.0000'
        assert self.r2.children()[1].filterExpression(
        ) == '"id" > 1.0000 AND "id" <= 2.0000'

        # Next try with an expression based range
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id / 2", ranges)

        QgsRuleBasedRenderer.refineRuleRanges(self.r1, g)
        assert self.r1.children()[0].filterExpression(
        ) == '(id / 2) >= 0.0000 AND (id / 2) <= 1.0000'
        assert self.r1.children()[1].filterExpression(
        ) == '(id / 2) > 1.0000 AND (id / 2) <= 2.0000'

        # Last try with an expression which is just a quoted field name
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer('"id"', ranges)

        QgsRuleBasedRenderer.refineRuleRanges(self.r3, g)
        assert self.r3.children()[0].filterExpression(
        ) == '"id" >= 0.0000 AND "id" <= 1.0000'
        assert self.r3.children()[1].filterExpression(
        ) == '"id" > 1.0000 AND "id" <= 2.0000'

    def testConvertFromCategorisedRenderer(self):
        # Test converting categorised renderer to rule based

        # First, try with a field based category (id)
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "id 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "id 2"))
        cats.append(QgsRendererCategory('a\'b', QgsMarkerSymbol(), "id a'b"))
        cats.append(QgsRendererCategory('a\nb', QgsMarkerSymbol(), "id a\\nb"))
        cats.append(QgsRendererCategory('a\\b', QgsMarkerSymbol(),
                                        "id a\\\\b"))
        cats.append(QgsRendererCategory('a\tb', QgsMarkerSymbol(), "id a\\tb"))
        c = QgsCategorizedSymbolRenderer("id", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" = 2')
        self.assertEqual(r.rootRule().children()[2].filterExpression(),
                         '"id" = \'a\'\'b\'')
        self.assertEqual(r.rootRule().children()[3].filterExpression(),
                         '"id" = \'a\\nb\'')
        self.assertEqual(r.rootRule().children()[4].filterExpression(),
                         '"id" = \'a\\\\b\'')
        self.assertEqual(r.rootRule().children()[5].filterExpression(),
                         '"id" = \'a\\tb\'')

        # Next try with an expression based category
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer("id + 1", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         'id + 1 = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         'id + 1 = 2')

        # Last try with an expression which is just a quoted field name
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer('"id"', cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" = 2')

    def testConvertFromGraduatedRenderer(self):
        # Test converting graduated renderer to rule based

        # First, try with a field based category (id)
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id", ranges)

        r = QgsRuleBasedRenderer.convertFromRenderer(g)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" >= 0.000000 AND "id" <= 1.000000')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" > 1.000000 AND "id" <= 2.000000')

        # Next try with an expression based range
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id / 2", ranges)

        r = QgsRuleBasedRenderer.convertFromRenderer(g)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '(id / 2) >= 0.000000 AND (id / 2) <= 1.000000')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '(id / 2) > 1.000000 AND (id / 2) <= 2.000000')

        # Last try with an expression which is just a quoted field name
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer('"id"', ranges)

        r = QgsRuleBasedRenderer.convertFromRenderer(g)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" >= 0.000000 AND "id" <= 1.000000')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" > 1.000000 AND "id" <= 2.000000')
Пример #42
0
    def testTransparency(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1)
        myRasterLayer.setRenderer(renderer)
        myRasterLayer.setContrastEnhancement(
            QgsContrastEnhancement.StretchToMinimumMaximum,
            QgsRaster.ContrastEnhancementMinMax)

        myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement()
        # print ("myContrastEnhancement.minimumValue = %.17g" %
        #       myContrastEnhancement.minimumValue())
        # print ("myContrastEnhancement.maximumValue = %.17g" %
        #        myContrastEnhancement.maximumValue())

        # Unfortunately the minimum/maximum values calculated in C++ and Python
        # are slightly different (e.g. 3.3999999521443642e+38 x
        # 3.3999999521444001e+38)
        # It is not clear where the precision is lost.
        # We set the same values as C++.
        myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38)
        myContrastEnhancement.setMaximumValue(3.3999999521443642e+38)
        #myType = myRasterLayer.dataProvider().dataType(1);
        #myEnhancement = QgsContrastEnhancement(myType);

        myTransparentSingleValuePixelList = []
        rasterTransparency = QgsRasterTransparency()

        myTransparentPixel1 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel1.min = -2.5840000772112106e+38
        myTransparentPixel1.max = -1.0879999684602689e+38
        myTransparentPixel1.percentTransparent = 50
        myTransparentSingleValuePixelList.append(myTransparentPixel1)

        myTransparentPixel2 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel2.min = 1.359999960575336e+37
        myTransparentPixel2.max = 9.520000231087593e+37
        myTransparentPixel2.percentTransparent = 70
        myTransparentSingleValuePixelList.append(myTransparentPixel2)

        rasterTransparency.setTransparentSingleValuePixelList(
            myTransparentSingleValuePixelList)

        rasterRenderer = myRasterLayer.renderer()
        assert rasterRenderer

        rasterRenderer.setRasterTransparency(rasterTransparency)

        QgsMapLayerRegistry.instance().addMapLayers([
            myRasterLayer,
        ])

        myMapSettings = QgsMapSettings()
        myMapSettings.setLayers([myRasterLayer.id()])
        myMapSettings.setExtent(myRasterLayer.extent())

        myChecker = QgsRenderChecker()
        myChecker.setControlName("expected_raster_transparency")
        myChecker.setMapSettings(myMapSettings)

        myResultFlag = myChecker.runTest("raster_transparency_python")
        assert myResultFlag, "Raster transparency rendering test failed"
Пример #43
0
    def testRenderLayerWithReferenceScale(self):
        layer = QgsAnnotationLayer(
            'test',
            QgsAnnotationLayer.LayerOptions(
                QgsProject.instance().transformContext()))
        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertTrue(layer.isValid())

        item = QgsAnnotationPolygonItem(
            QgsPolygon(
                QgsLineString([
                    QgsPoint(12, 13),
                    QgsPoint(14, 13),
                    QgsPoint(14, 15),
                    QgsPoint(12, 13)
                ])))
        item.setSymbol(
            QgsFillSymbol.createSimple({
                'color': '200,100,100',
                'outline_color': 'black',
                'outline_width': '2'
            }))
        item.setZIndex(3)
        i1_id = layer.addItem(item)

        item = QgsAnnotationLineItem(
            QgsLineString(
                [QgsPoint(11, 13),
                 QgsPoint(12, 13),
                 QgsPoint(12, 15)]))
        item.setSymbol(
            QgsLineSymbol.createSimple({
                'color': '#ffff00',
                'line_width': '3'
            }))
        item.setZIndex(2)
        i2_id = layer.addItem(item)

        item = QgsAnnotationMarkerItem(QgsPoint(12, 13))
        item.setSymbol(
            QgsMarkerSymbol.createSimple({
                'color': '100,200,200',
                'size': '6',
                'outline_color': 'black'
            }))
        item.setZIndex(1)
        i3_id = layer.addItem(item)

        settings = QgsMapSettings()
        settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        settings.setExtent(QgsRectangle(10, 10, 18, 18))
        settings.setOutputSize(QSize(300, 300))

        settings.setFlag(QgsMapSettings.Antialiasing, False)

        rc = QgsRenderContext.fromMapSettings(settings)

        layer.item(i1_id).setUseSymbologyReferenceScale(True)
        layer.item(i1_id).setSymbologyReferenceScale(rc.rendererScale() * 2)
        # note item 3 has use symbology reference scale set to false, so should be ignored
        layer.item(i2_id).setUseSymbologyReferenceScale(False)
        layer.item(i2_id).setSymbologyReferenceScale(rc.rendererScale() * 2)
        layer.item(i3_id).setUseSymbologyReferenceScale(True)
        layer.item(i3_id).setSymbologyReferenceScale(rc.rendererScale() * 2)

        image = QImage(200, 200, QImage.Format_ARGB32)
        image.setDotsPerMeterX(int(96 / 25.4 * 1000))
        image.setDotsPerMeterY(int(96 / 25.4 * 1000))
        image.fill(QColor(255, 255, 255))
        painter = QPainter(image)
        rc.setPainter(painter)

        try:
            renderer = layer.createMapRenderer(rc)
            renderer.render()
        finally:
            painter.end()

        self.assertTrue(
            self.imageCheck('layer_render_reference_scale',
                            'layer_render_reference_scale', image))

        # also check details of rendered items
        item_details = renderer.takeRenderedItemDetails()
        self.assertEqual([i.layerId() for i in item_details], [layer.id()] * 3)
        self.assertCountEqual([i.itemId() for i in item_details],
                              [i1_id, i2_id, i3_id])
        self.assertEqual(
            [i.boundingBox() for i in item_details if i.itemId() == i1_id][0],
            QgsRectangle(12, 13, 14, 15))
        self.assertEqual(
            [i.boundingBox() for i in item_details if i.itemId() == i2_id][0],
            QgsRectangle(11, 13, 12, 15))
        self.assertEqual([
            i.boundingBox().toString(1) for i in item_details
            if i.itemId() == i3_id
        ][0], '11.4,12.4 : 12.6,13.6')
class TestQgsRulebasedRenderer(unittest.TestCase):
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })
        sym2 = QgsFillSymbol.createSimple({
            'color': '#71bd6c',
            'outline_color': 'black'
        })
        sym3 = QgsFillSymbol.createSimple({
            'color': '#1f78b4',
            'outline_color': 'black'
        })

        self.r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.r1)
        rootrule.appendChild(self.r2)
        rootrule.appendChild(self.r3)

        layer.setRenderer(QgsRuleBasedRenderer(rootrule))
        self.mapsettings = QgsMapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer]
        self.mapsettings.setLayers(rendered_layers)

    def testElse(self):
        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_rulebased_else')
        result = renderchecker.runTest('rulebased_else')

        assert result

    def testDisabledElse(self):
        # Disable a rule and assert that it's hidden not rendered with else
        self.r2.setActive(False)

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_rulebased_disabled_else')
        result = renderchecker.runTest('rulebased_disabled_else')

        assert result

    def testRefineWithCategories(self):
        # Test refining rule with categories (refs #10815)

        # First, try with a field based category (id)
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "id 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "id 2"))
        c = QgsCategorizedSymbolRenderer("id", cats)

        QgsRuleBasedRenderer.refineRuleCategories(self.r2, c)
        assert self.r2.children()[0].filterExpression() == '"id" = 1'
        assert self.r2.children()[1].filterExpression() == '"id" = 2'

        # Next try with an expression based category
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer("id + 1", cats)

        QgsRuleBasedRenderer.refineRuleCategories(self.r1, c)
        assert self.r1.children()[0].filterExpression() == 'id + 1 = 1'
        assert self.r1.children()[1].filterExpression() == 'id + 1 = 2'

        # Last try with an expression which is just a quoted field name
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer('"id"', cats)

        QgsRuleBasedRenderer.refineRuleCategories(self.r3, c)
        assert self.r3.children()[0].filterExpression() == '"id" = 1'
        assert self.r3.children()[1].filterExpression() == '"id" = 2'

    def testRefineWithRanges(self):
        # Test refining rule with ranges (refs #10815)

        # First, try with a field based category (id)
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id", ranges)

        QgsRuleBasedRenderer.refineRuleRanges(self.r2, g)
        assert self.r2.children()[0].filterExpression(
        ) == '"id" >= 0.0000 AND "id" <= 1.0000'
        assert self.r2.children()[1].filterExpression(
        ) == '"id" > 1.0000 AND "id" <= 2.0000'

        # Next try with an expression based range
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id / 2", ranges)

        QgsRuleBasedRenderer.refineRuleRanges(self.r1, g)
        assert self.r1.children()[0].filterExpression(
        ) == '(id / 2) >= 0.0000 AND (id / 2) <= 1.0000'
        assert self.r1.children()[1].filterExpression(
        ) == '(id / 2) > 1.0000 AND (id / 2) <= 2.0000'

        # Last try with an expression which is just a quoted field name
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer('"id"', ranges)

        QgsRuleBasedRenderer.refineRuleRanges(self.r3, g)
        assert self.r3.children()[0].filterExpression(
        ) == '"id" >= 0.0000 AND "id" <= 1.0000'
        assert self.r3.children()[1].filterExpression(
        ) == '"id" > 1.0000 AND "id" <= 2.0000'

    def testConvertFromCategorisedRenderer(self):
        # Test converting categorised renderer to rule based

        # First, try with a field based category (id)
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "id 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "id 2"))
        cats.append(QgsRendererCategory('a\'b', QgsMarkerSymbol(), "id a'b"))
        cats.append(QgsRendererCategory('a\nb', QgsMarkerSymbol(), "id a\\nb"))
        cats.append(QgsRendererCategory('a\\b', QgsMarkerSymbol(),
                                        "id a\\\\b"))
        cats.append(QgsRendererCategory('a\tb', QgsMarkerSymbol(), "id a\\tb"))
        c = QgsCategorizedSymbolRenderer("id", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" = 2')
        self.assertEqual(r.rootRule().children()[2].filterExpression(),
                         '"id" = \'a\'\'b\'')
        self.assertEqual(r.rootRule().children()[3].filterExpression(),
                         '"id" = \'a\\nb\'')
        self.assertEqual(r.rootRule().children()[4].filterExpression(),
                         '"id" = \'a\\\\b\'')
        self.assertEqual(r.rootRule().children()[5].filterExpression(),
                         '"id" = \'a\\tb\'')

        # Next try with an expression based category
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer("id + 1", cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         'id + 1 = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         'id + 1 = 2')

        # Last try with an expression which is just a quoted field name
        cats = []
        cats.append(QgsRendererCategory(1, QgsMarkerSymbol(), "result 1"))
        cats.append(QgsRendererCategory(2, QgsMarkerSymbol(), "result 2"))
        c = QgsCategorizedSymbolRenderer('"id"', cats)

        r = QgsRuleBasedRenderer.convertFromRenderer(c)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" = 1')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" = 2')

    def testConvertFromGraduatedRenderer(self):
        # Test converting graduated renderer to rule based

        # First, try with a field based category (id)
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id", ranges)

        r = QgsRuleBasedRenderer.convertFromRenderer(g)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" >= 0.000000 AND "id" <= 1.000000')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" > 1.000000 AND "id" <= 2.000000')

        # Next try with an expression based range
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer("id / 2", ranges)

        r = QgsRuleBasedRenderer.convertFromRenderer(g)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '(id / 2) >= 0.000000 AND (id / 2) <= 1.000000')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '(id / 2) > 1.000000 AND (id / 2) <= 2.000000')

        # Last try with an expression which is just a quoted field name
        ranges = []
        ranges.append(QgsRendererRange(0, 1, QgsMarkerSymbol(), "0-1"))
        ranges.append(QgsRendererRange(1, 2, QgsMarkerSymbol(), "1-2"))
        g = QgsGraduatedSymbolRenderer('"id"', ranges)

        r = QgsRuleBasedRenderer.convertFromRenderer(g)
        self.assertEqual(r.rootRule().children()[0].filterExpression(),
                         '"id" >= 0.000000 AND "id" <= 1.000000')
        self.assertEqual(r.rootRule().children()[1].filterExpression(),
                         '"id" > 1.000000 AND "id" <= 2.000000')
Пример #45
0
    def testConvertSingleUnit(self):
        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()
        # self.assertEqual(r.scaleFactor(),666)

        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)

        # minimum scale greater than the renderer scale, so should be limited to minScale
        c.minScale = 150000000.0
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 3.89250455, places=5)
        # only conversion from mapunits should be affected
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)
        c.minScale = 0

        # maximum scale less than the renderer scale, so should be limited to maxScale
        c.maxScale = 350000000.0
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        # only conversion from mapunits should be affected
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)

        # with symbologyReferenceScale set
        c = QgsMapUnitScale()
        r.setSymbologyReferenceScale(1000)
        r.setRendererScale(1000)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0, places=5)

        r.setRendererScale(2000)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5 / 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236 / 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625 / 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0 / 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0 / 2, places=5)

        r.setRendererScale(500)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(sf, 0.5 * 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(sf, 11.8110236 * 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(sf, 4.166666665625 * 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(sf, 300.0 * 2, places=5)
        sf = r.convertToPainterUnits(1, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(sf, 1.0 * 2, places=5)
Пример #46
0
    def testConvertToPainterUnits(self):
        # test QgsSymbolLayerUtils::convertToPainterUnits() using QgsMapUnitScale

        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()

        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.0, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 23.622047, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 66.9601332, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 2.0, places=5)

        # minimum size greater than the calculated size, so size should be limited to minSizeMM
        c.minSizeMM = 5
        c.minSizeMMEnabled = True
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 59.0551181, places=5)
        # only conversion from mapunits should be affected
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 23.622047, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 66.9601332, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 2.0, places=5)
        c.minSizeMMEnabled = False

        # maximum size less than the calculated size, so size should be limited to maxSizeMM
        c.maxSizeMM = 0.1
        c.maxSizeMMEnabled = True
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.0, places=5)
        # only conversion from mapunits should be affected
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 23.622047, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 66.9601332, places=5)
        size = QgsSymbolLayerUtils.convertToPainterUnits(
            r, 2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 2.0, places=5)
Пример #47
0
    def testRenderWithTransform(self):
        layer = QgsAnnotationLayer(
            'test',
            QgsAnnotationLayer.LayerOptions(
                QgsProject.instance().transformContext()))
        self.assertTrue(layer.isValid())

        item = QgsAnnotationPolygonItem(
            QgsPolygon(
                QgsLineString([
                    QgsPoint(11.5, 13),
                    QgsPoint(12, 13),
                    QgsPoint(12, 13.5),
                    QgsPoint(11.5, 13)
                ])))
        item.setSymbol(
            QgsFillSymbol.createSimple({
                'color': '200,100,100',
                'outline_color': 'black',
                'outline_width': '2'
            }))
        item.setZIndex(1)
        i1_id = layer.addItem(item)

        item = QgsAnnotationLineItem(
            QgsLineString(
                [QgsPoint(11, 13),
                 QgsPoint(12, 13),
                 QgsPoint(12, 15)]))
        item.setSymbol(
            QgsLineSymbol.createSimple({
                'color': '#ffff00',
                'line_width': '3'
            }))
        item.setZIndex(2)
        i2_id = layer.addItem(item)

        item = QgsAnnotationMarkerItem(QgsPoint(12, 13))
        item.setSymbol(
            QgsMarkerSymbol.createSimple({
                'color': '100,200,200',
                'size': '6',
                'outline_color': 'black'
            }))
        item.setZIndex(3)
        i3_id = layer.addItem(item)

        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))

        settings = QgsMapSettings()
        settings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        settings.setExtent(QgsRectangle(1250958, 1386945, 1420709, 1532518))
        settings.setOutputSize(QSize(300, 300))

        settings.setFlag(QgsMapSettings.Antialiasing, False)

        rc = QgsRenderContext.fromMapSettings(settings)
        rc.setCoordinateTransform(
            QgsCoordinateTransform(layer.crs(), settings.destinationCrs(),
                                   QgsProject.instance()))
        rc.setExtent(rc.coordinateTransform().transformBoundingBox(
            settings.extent(), QgsCoordinateTransform.ReverseTransform))
        image = QImage(200, 200, QImage.Format_ARGB32)
        image.setDotsPerMeterX(int(96 / 25.4 * 1000))
        image.setDotsPerMeterY(int(96 / 25.4 * 1000))
        image.fill(QColor(255, 255, 255))
        painter = QPainter(image)
        rc.setPainter(painter)

        try:
            renderer = layer.createMapRenderer(rc)
            renderer.render()
        finally:
            painter.end()

        self.assertTrue(
            self.imageCheck('layer_render_transform', 'layer_render_transform',
                            image))

        # also check details of rendered items
        item_details = renderer.takeRenderedItemDetails()
        self.assertEqual([i.layerId() for i in item_details], [layer.id()] * 3)
        self.assertCountEqual([i.itemId() for i in item_details],
                              [i1_id, i2_id, i3_id])
        self.assertEqual(
            [i.boundingBox() for i in item_details if i.itemId() == i1_id][0],
            QgsRectangle(11.5, 13, 12, 13.5))
        self.assertEqual(
            [i.boundingBox() for i in item_details if i.itemId() == i2_id][0],
            QgsRectangle(11, 13, 12, 15))
        self.assertEqual([
            i.boundingBox().toString(2) for i in item_details
            if i.itemId() == i3_id
        ][0], '11.94,12.94 : 12.06,13.06')
Пример #48
0
class TestQgsBlendModes(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        self.iface = get_iface()

        # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
        self.mMapRegistry = QgsProject.instance()

        # create point layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPointLayer)

        self.mSimplifyMethod = QgsVectorSimplifyMethod()
        self.mSimplifyMethod.setSimplifyHints(
            QgsVectorSimplifyMethod.NoSimplification)

        # create polygon layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
        self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod)
        self.mMapRegistry.addMapLayer(self.mPolygonLayer)

        # create line layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr')
        self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod)
        self.mMapRegistry.addMapLayer(self.mLineLayer)

        # create two raster layers
        myRasterFile = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1")
        self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2")
        myMultiBandRenderer1 = QgsMultiBandColorRenderer(
            self.mRasterLayer1.dataProvider(), 1, 2, 3)
        self.mRasterLayer1.setRenderer(myMultiBandRenderer1)
        self.mMapRegistry.addMapLayer(self.mRasterLayer1)
        myMultiBandRenderer2 = QgsMultiBandColorRenderer(
            self.mRasterLayer2.dataProvider(), 1, 2, 3)
        self.mRasterLayer2.setRenderer(myMultiBandRenderer2)
        self.mMapRegistry.addMapLayer(self.mRasterLayer2)

        # to match blend modes test comparisons background
        self.mapSettings = QgsMapSettings()
        self.mapSettings.setLayers([self.mRasterLayer1, self.mRasterLayer2])
        self.mapSettings.setBackgroundColor(QColor(152, 219, 249))
        self.mapSettings.setOutputSize(QSize(400, 400))
        self.mapSettings.setOutputDpi(96)

        self.extent = QgsRectangle(-118.8888888888887720, 22.8002070393376783,
                                   -83.3333333333331581, 46.8719806763287536)

    def testVectorBlending(self):
        """Test that blend modes work for vector layers."""

        # Add vector layers to map
        myLayers = [self.mLineLayer, self.mPolygonLayer]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.extent)

        # Set blending modes for both layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_blendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_blendmodes", 20)
        myMessage = ('vector blending failed')
        assert myResult, myMessage

        # Reset layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver)

    def testVectorFeatureBlending(self):
        """Test that feature blend modes work for vector layers."""

        # Add vector layers to map
        myLayers = [self.mLineLayer, self.mPolygonLayer]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.extent)

        # Set feature blending for line layer
        self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_featureblendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_featureblendmodes", 20)
        myMessage = ('vector feature blending failed')
        assert myResult, myMessage

        # Reset layers
        self.mLineLayer.setFeatureBlendMode(
            QPainter.CompositionMode_SourceOver)

    def testVectorLayerOpacity(self):
        """Test that layer opacity works for vector layers."""

        # Add vector layers to map
        myLayers = [self.mLineLayer, self.mPolygonLayer]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.extent)

        # Set feature blending for line layer
        self.mLineLayer.setOpacity(0.5)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_layertransparency")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_layertransparency", 20)
        myMessage = ('vector layer transparency failed')
        assert myResult, myMessage

    def testRasterBlending(self):
        """Test that blend modes work for raster layers."""
        # Add raster layers to map
        myLayers = [self.mRasterLayer1, self.mRasterLayer2]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.mRasterLayer1.extent())

        # Set blending mode for top layer
        self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Difference)
        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_raster_blendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)
        checker.setColorTolerance(1)

        myResult = checker.runTest("raster_blendmodes", 20)
        myMessage = ('raster blending failed')
        assert myResult, myMessage