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)
def testRenderPage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(1122, 794) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) # valid page exporter.renderPage(painter, 0) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderpage.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderpage', 'renderpage', rendered_file_path))
def testRenderRegion(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a guide, to ensure it is not included in export g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) # get width/height, create image and render the composition to it size = QSize(560, 509) output_image = QImage(size, QImage.Format_RGB32) output_image.setDotsPerMeterX(self.dots_per_meter) output_image.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) exporter = QgsLayoutExporter(l) exporter.renderRegion(painter, QRectF(5, 10, 110, 100)) painter.end() rendered_file_path = os.path.join(self.basetestpath, 'test_renderregion.png') output_image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('renderregion', 'renderregion', rendered_file_path))
def testLayout(self, page=0, pixelDiff=0): if self.layout is None: myMessage = "Layout not valid" return False, myMessage # load expected image self.setControlName("expected_" + self.test_name) # get width/height, create image and render the composition to it outputImage = QImage(self.size, QImage.Format_RGB32) outputImage.setDotsPerMeterX(self.dots_per_meter) outputImage.setDotsPerMeterY(self.dots_per_meter) QgsMultiRenderChecker.drawBackground(outputImage) p = QPainter(outputImage) self.layout.exporter().renderPage(p, page) p.end() renderedFilePath = QDir.tempPath() + QDir.separator() + QFileInfo(self.test_name).baseName() + "_rendered.png" outputImage.save(renderedFilePath, "PNG") self.setRenderedImage(renderedFilePath) testResult = self.runTest(self.test_name, pixelDiff) return testResult, self.report()
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)
def testRenderNoCluster(self): self.layer.renderer().setTolerance(1) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_no_cluster') self.assertTrue(renderchecker.runTest('displacement_no_cluster'))
def testVectorBlending(self): """Test that blend modes work for vector layers.""" # Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) 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 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 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)
def testRenderWithin(self): layer, renderer, mapsettings = self._setUp() layer.renderer().setTolerance(10) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_cluster') res = renderchecker.runTest('expected_displacement_cluster') self.report += renderchecker.report() self.assertTrue(res) self._tearDown(layer)
def testRenderGrid(self): self.layer.renderer().setTolerance(10) self.layer.renderer().setPlacement(QgsPointDisplacementRenderer.Grid) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_grid') self.assertTrue(renderchecker.runTest('expected_displacement_grid'))
def testRender(self): # test no features are rendered renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('null_renderer') renderchecker.setControlName('expected_nullrenderer_render') result = renderchecker.runTest('nullrenderer_render') assert result
def testSelected(self): # select a feature and render self.layer.select([1, 2, 3]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlPathPrefix('null_renderer') renderchecker.setControlName('expected_nullrenderer_selected') result = renderchecker.runTest('nullrenderer_selected') assert result
def testRenderGridAdjust(self): layer, renderer, mapsettings = self._setUp() layer.renderer().setTolerance(10) layer.renderer().setCircleRadiusAddition(5) layer.renderer().setPlacement(QgsPointDisplacementRenderer.Grid) layer.renderer().setCircleColor(QColor()) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_adjust_grid') res = renderchecker.runTest('expected_displacement_adjust_grid') self.report += renderchecker.report() self.assertTrue(res) self._tearDown(layer)
def testClusterRingLabels(self): layer, renderer, mapsettings = self._setUp() layer.renderer().setTolerance(10) layer.renderer().setLabelAttributeName('Class') layer.renderer().setLabelDistanceFactor(0.35) f = QgsFontUtils.getStandardTestFont('Bold', 14) layer.renderer().setLabelFont(f) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_cluster_ring_labels') res = renderchecker.runTest('expected_displacement_cluster_ring_labels') self.report += renderchecker.report() self.assertTrue(res) self._tearDown(layer)
def testClusterConcentricLabelsDifferentSizesFarther(self): layer, renderer, mapsettings = self._setUp() renderer.setEmbeddedRenderer(self._create_categorized_renderer()) layer.renderer().setTolerance(10) layer.renderer().setLabelAttributeName('Class') layer.renderer().setLabelDistanceFactor(1) f = QgsFontUtils.getStandardTestFont('Bold', 14) layer.renderer().setLabelFont(f) layer.renderer().setPlacement(QgsPointDisplacementRenderer.ConcentricRings) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_cluster_concentric_labels_diff_size_farther') res = renderchecker.runTest('expected_displacement_cluster_concentric_labels_diff_size_farther') self.report += renderchecker.report() self.assertTrue(res) self._tearDown(layer)
def imageCheck(self, name, reference_image, image): self.report += "<h2>Render {}</h2>\n".format(name) temp_dir = QDir.tempPath() + '/' file_name = temp_dir + 'svg_' + name + ".png" output_image = QImage(image.size(), QImage.Format_RGB32) QgsMultiRenderChecker.drawBackground(output_image) painter = QPainter(output_image) painter.drawImage(0, 0, image) painter.end() output_image.save(file_name, "PNG") checker = QgsRenderChecker() checker.setControlPathPrefix("svg_cache") checker.setControlName("expected_" + reference_image) checker.setRenderedImage(file_name) checker.setColorTolerance(2) result = checker.compareImages(name, 20) self.report += checker.report() print((self.report)) return result
def test_3(self): sym = self.lines_layer.renderer().symbol() # double headed sym_layer = QgsArrowSymbolLayer.create( { "arrow_width": "7", "head_length": "6", "head_thickness": "8", "head_type": "0", "arrow_type": "1", "is_curved": "0", } ) fill_sym = QgsFillSymbol.createSimple( {"color": "#8bcfff", "outline_color": "#000000", "outline_style": "solid", "outline_width": "1"} ) sym_layer.setSubSymbol(fill_sym) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.lines_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() ms = self.mapsettings ms.setExtent(QgsRectangle(-101, 35, -99, 37)) renderchecker.setMapSettings(ms) renderchecker.setControlName("expected_arrowsymbollayer_3") self.assertTrue(renderchecker.runTest("arrowsymbollayer_3"))
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 test_marker(self): sym = self.renderer.symbol() sym_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'centroid($geometry)'}) sym_layer.setSymbolType(QgsSymbolV2.Marker) sym.changeSymbolLayer(0, sym_layer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_marker') self.assertTrue(renderchecker.runTest('geometrygenerator_marker'))
def testRenderVariables(self): """ test rendering with expression variables in marker """ layer, renderer, mapsettings = self._setUp() layer.renderer().setTolerance(10) old_marker = layer.renderer().centerSymbol().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')) layer.renderer().setCenterSymbol(new_marker) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('displacement_renderer') renderchecker.setControlName('expected_displacement_variables') result = renderchecker.runTest('expected_displacement_variables') self.report += renderchecker.report() layer.renderer().setCenterSymbol(old_marker) self.assertTrue(result) self._tearDown(layer)
def testOrderBy(self): self.renderer.setOrderBy(QgsFeatureRequest.OrderBy([QgsFeatureRequest.OrderByClause('Value', False)])) self.renderer.setOrderByEnabled(True) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_singlesymbol_orderby') self.assertTrue(renderchecker.runTest('singlesymbol_orderby')) # disable order by and retest self.renderer.setOrderByEnabled(False) self.assertTrue(renderchecker.runTest('single'))
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('color', QgsDataDefined('@cluster_color')) new_marker.symbolLayer(0).setDataDefinedProperty('size', QgsDataDefined('@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)
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 testOrderBy(self): self.renderer.setOrderBy(QgsFeatureRequest.OrderBy([QgsFeatureRequest.OrderByClause('Value', False)])) # Setup rendering check renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_singlesymbol_orderby') result = renderchecker.runTest('singlesymbol_orderby') assert result
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
def testVectorLayerTransparency(self): """Test that layer transparency 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.setLayerTransparency(50) 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 test_mixed(self): sym = self.renderer.symbol() buffer_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'buffer($geometry, "value"/15)'}) buffer_layer.setSymbolType(QgsSymbolV2.Fill) buffer_layer.subSymbol() sym.appendSymbolLayer(buffer_layer) marker_layer = QgsGeometryGeneratorSymbolLayerV2.create({'geometryModifier': 'centroid($geometry)'}) marker_layer.setSymbolType(QgsSymbolV2.Marker) sym.appendSymbolLayer(marker_layer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_mixed') self.assertTrue(renderchecker.runTest('geometrygenerator_mixed'))
def test_marker(self): sym = self.polys_layer.renderer().symbol() sym_layer = QgsGeometryGeneratorSymbolLayer.create({"geometryModifier": "centroid($geometry)"}) sym_layer.setSymbolType(QgsSymbol.Marker) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.polys_layer.id()] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName("expected_geometrygenerator_marker") self.assertTrue(renderchecker.runTest("geometrygenerator_marker"))
def test_marker(self): sym = self.polys_layer.renderer().symbol() sym_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'centroid($geometry)'}) sym_layer.setSymbolType(QgsSymbol.Marker) sym_layer.subSymbol().symbolLayer(0).setStrokeColor(QColor(0, 0, 0)) sym.changeSymbolLayer(0, sym_layer) rendered_layers = [self.polys_layer] self.mapsettings.setLayers(rendered_layers) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(self.mapsettings) renderchecker.setControlName('expected_geometrygenerator_marker') self.assertTrue(renderchecker.runTest('geometrygenerator_marker'))
def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize(), outputFormat='PNG'): if outputFormat == 'PNG': extFile = 'png' elif outputFormat == 'JPG': extFile = 'jpg' elif outputFormat == 'WEBP': extFile = 'webp' else: raise RuntimeError('Yeah, new format implemented') temp_image = os.path.join(tempfile.gettempdir(), "%s_result.%s" % (control_image, extFile)) with open(temp_image, "wb") as f: f.write(image) if outputFormat != 'PNG': return (True, "QgsRenderChecker can only be used for PNG") control = QgsMultiRenderChecker() control.setControlPathPrefix("qgis_server") control.setControlName(control_image) control.setRenderedImage(temp_image) if max_size_diff.isValid(): control.setSizeTolerance(max_size_diff.width(), max_size_diff.height()) return control.runTest(control_image, max_diff), control.report()
def testRenderMultipleRenderersAboveAndBelow(self): poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp')) self.assertTrue(poly_layer.isValid()) sym1 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#000000', 'outline_width': '1' }) renderer = QgsSingleSymbolRenderer(sym1) poly_layer.setRenderer(renderer) # add secondary renderer, for rendering below class Gen1(QgsFeatureRendererGenerator): def id(self): return 'Gen1' def level(self): return 3 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Name') cf1 = QgsCentroidFillSymbolLayer() cf1.setSubSymbol( QgsMarkerSymbol.createSimple({ 'color': '#33aa33', 'outline_style': 'no', 'size': '5' })) sym1 = QgsFillSymbol([cf1]) cf2 = QgsCentroidFillSymbolLayer() cf2.setSubSymbol( QgsMarkerSymbol.createSimple({ 'color': '#aa33aa', 'outline_style': 'no', 'size': '5' })) sym2 = QgsFillSymbol([cf2]) renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam')) renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake')) return renderer # add secondary renderer, for rendering below class Gen2(QgsFeatureRendererGenerator): def id(self): return 'Gen2' def level(self): return 2 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Value < 12') cf1 = QgsCentroidFillSymbolLayer() cf1.setSubSymbol( QgsMarkerSymbol.createSimple({ 'color': '#aa1111', 'outline_style': 'no', 'size': '8' })) sym1 = QgsFillSymbol([cf1]) cf2 = QgsCentroidFillSymbolLayer() cf2.setSubSymbol( QgsMarkerSymbol.createSimple({ 'color': '#1111dd', 'outline_style': 'no', 'size': '8' })) sym2 = QgsFillSymbol([cf2]) renderer.addCategory(QgsRendererCategory('1', sym1, '1')) renderer.addCategory(QgsRendererCategory('0', sym2, '0')) return renderer # add secondary renderer, for rendering below class Gen1b(QgsFeatureRendererGenerator): def id(self): return 'Gen1b' def level(self): return -2 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Name') sym1 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#33aa33', 'outline_width': '3' }) sym2 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#aa33aa', 'outline_width': '3' }) renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam')) renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake')) return renderer # add secondary renderer, for rendering below class Gen2b(QgsFeatureRendererGenerator): def id(self): return 'Gen2b' def level(self): return -3 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Value < 12') sym1 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#aa1111', 'outline_width': '5' }) sym2 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#1111dd', 'outline_width': '5' }) renderer.addCategory(QgsRendererCategory('1', sym1, '1')) renderer.addCategory(QgsRendererCategory('0', sym2, '0')) return renderer poly_layer.addFeatureRendererGenerator(Gen1()) poly_layer.addFeatureRendererGenerator(Gen2()) poly_layer.addFeatureRendererGenerator(Gen1b()) poly_layer.addFeatureRendererGenerator(Gen2b()) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:3857')) mapsettings.setExtent( QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5)) mapsettings.setLayers([poly_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName( 'expected_multiple_renderers_both_above_below') result = renderchecker.runTest( 'expected_multiple_renderers_both_above_below') self.report += renderchecker.report() self.assertTrue(result) # also try with symbol levels renderer.setUsingSymbolLevels(True) poly_layer.setRenderer(renderer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName( 'expected_multiple_renderers_both_above_below') result = renderchecker.runTest( 'expected_multiple_renderers_both_above_below') self.report += renderchecker.report() self.assertTrue(result)
def testRenderMultipleRenderersSelection(self): """ Test that selection colors only apply to main renderer :return: """ poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp')) self.assertTrue(poly_layer.isValid()) poly_layer.selectAll() sym1 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#000000', 'outline_style': 'no' }) renderer = QgsSingleSymbolRenderer(sym1) poly_layer.setRenderer(renderer) # add secondary renderer, for rendering below class Gen1(QgsFeatureRendererGenerator): def id(self): return 'Gen1' def level(self): return -2 def createRenderer(self): renderer = QgsCategorizedSymbolRenderer() renderer.setClassAttribute('Name') sym1 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#33aa33', 'outline_width': '3' }) sym2 = QgsFillSymbol.createSimple({ 'color': '#ffaaff', 'outline_color': '#aa33aa', 'outline_width': '3' }) renderer.addCategory(QgsRendererCategory('Dam', sym1, 'Dam')) renderer.addCategory(QgsRendererCategory('Lake', sym2, 'Lake')) return renderer poly_layer.addFeatureRendererGenerator(Gen1()) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:3857')) mapsettings.setExtent( QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5)) mapsettings.setLayers([poly_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_multiple_renderers_selection') result = renderchecker.runTest('expected_multiple_renderers_selection') self.report += renderchecker.report() self.assertTrue(result) # also try with symbol levels renderer.setUsingSymbolLevels(True) poly_layer.setRenderer(renderer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_multiple_renderers_selection') result = renderchecker.runTest('expected_multiple_renderers_selection') self.report += renderchecker.report() self.assertTrue(result)
def testRenderWithIntersectionRegions(self): poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp')) self.assertTrue(poly_layer.isValid()) sym1 = QgsFillSymbol.createSimple({ 'color': '#ff00ff', 'outline_color': '#000000', 'outline_width': '1' }) renderer = QgsSingleSymbolRenderer(sym1) poly_layer.setRenderer(renderer) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:3857')) mapsettings.setExtent( QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5)) mapsettings.setLayers([poly_layer]) region = QgsMapClippingRegion( QgsGeometry.fromWkt( 'Polygon ((-11725957 5368254, -12222900 4807501, -12246014 3834025, -12014878 3496059, -11259833 3518307, -10751333 3621153, -10574129 4516741, -10847640 5194995, -11105742 5325957, -11725957 5368254))' )) region.setFeatureClip( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) region2 = QgsMapClippingRegion( QgsGeometry.fromWkt( 'Polygon ((-11032549 5421399, -11533344 4693167, -11086481 4229112, -11167378 3742984, -10616504 3553984, -10161936 3925771, -9618766 4668482, -9472380 5620753, -10115709 5965063, -11032549 5421399))' )) region2.setFeatureClip( QgsMapClippingRegion.FeatureClippingType.ClipToIntersection) mapsettings.addClippingRegion(region) mapsettings.addClippingRegion(region2) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_intersection_region') result = renderchecker.runTest('expected_intersection_region') self.report += renderchecker.report() self.assertTrue(result) # also try with symbol levels renderer.setUsingSymbolLevels(True) poly_layer.setRenderer(renderer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_intersection_region') result = renderchecker.runTest('expected_intersection_region') self.report += renderchecker.report() self.assertTrue(result)
def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize(), outputJpg=False): extFile = 'png' if outputJpg: extFile = 'jpg' temp_image = os.path.join(tempfile.gettempdir(), "%s_result.%s" % (control_image, extFile)) with open(temp_image, "wb") as f: f.write(image) if outputJpg: return (True, "QgsRenderChecker can't be used for JPG images") control = QgsMultiRenderChecker() control.setControlPathPrefix("qgis_server") control.setControlName(control_image) control.setRenderedImage(temp_image) if max_size_diff.isValid(): control.setSizeTolerance(max_size_diff.width(), max_size_diff.height()) return control.runTest(control_image, max_diff), control.report()
def testRenderFiltered(self): layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept') self.assertTrue(layer.isValid()) categories = QgsPointCloudRendererRegistry.classificationAttributeCategories(layer) renderer = QgsPointCloudClassifiedRenderer('Classification', categories) layer.setRenderer(renderer) layer.renderer().setPointSize(2) layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters) layer.setSubsetString('NumberOfReturns > 1') mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs(layer.crs()) mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999)) mapsettings.setLayers([layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_classified_render_filtered') result = renderchecker.runTest('expected_classified_render_filtered') TestQgsPointCloudClassifiedRenderer.report += renderchecker.report() self.assertTrue(result) layer.setSubsetString('') renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('pointcloudrenderer') renderchecker.setControlName('expected_classified_render_unfiltered') result = renderchecker.runTest('expected_classified_render_unfiltered') TestQgsPointCloudClassifiedRenderer.report += renderchecker.report() self.assertTrue(result)
def imageCheck(self, name, reference_image, image, size_tolerance=0): TestQgsColorRampLegendNode.report += "<h2>Render {}</h2>\n".format( name) temp_dir = QDir.tempPath() + '/' file_name = temp_dir + name + ".png" image.save(file_name, "PNG") checker = QgsMultiRenderChecker() checker.setControlPathPrefix("color_ramp_legend_node") checker.setControlName("expected_" + reference_image) checker.setRenderedImage(file_name) checker.setColorTolerance(2) checker.setSizeTolerance(size_tolerance, size_tolerance) result = checker.runTest(name, 20) TestQgsColorRampLegendNode.report += checker.report() return result
def checkImage(self, name, reference_image, rendered_image, size_tolerance=0): checker = QgsMultiRenderChecker() checker.setControlPathPrefix("layout_exporter") checker.setControlName("expected_layoutexporter_" + reference_image) checker.setRenderedImage(rendered_image) checker.setColorTolerance(2) checker.setSizeTolerance(size_tolerance, size_tolerance) result = checker.runTest(name, 20) self.report += checker.report() print((self.report)) return result
def renderCheck(self, mismatch=0, colortol=0, imgpath='', grpprefix=''): """Check rendered map canvas or existing image against control image :mismatch: number of pixels different from control, and still valid :colortol: maximum difference for each color component including alpha :imgpath: existing image; if present, skips rendering canvas :grpprefix: compare test image/rendering against different test group """ if not grpprefix: grpprefix = self._TestGroupPrefix chk = QgsMultiRenderChecker() chk.setControlPathPrefix('expected_' + grpprefix) chk.setControlName(self._Test) if imgpath: chk.setRenderedImage(imgpath) ms = self._MapSettings # class settings if self._TestMapSettings is not None: ms = self._TestMapSettings # per test settings chk.setMapSettings(ms) chk.setColorTolerance(colortol) # noinspection PyUnusedLocal res = chk.runTest(self._Test, mismatch) if PALREPORT and not res: # don't report OK checks testname = self._TestGroup + ' . ' + self._Test PALREPORTS[testname] = chk.report() msg = '\nRender check failed for "{0}"'.format(self._Test) return res, msg
def canvasImageCheck(self, name, reference_image, canvas): self.report += "<h2>Render {}</h2>\n".format(name) temp_dir = QDir.tempPath() + '/' file_name = temp_dir + 'mapcanvas_' + name + ".png" print(file_name) canvas.saveAsImage(file_name) checker = QgsMultiRenderChecker() checker.setControlPathPrefix("mapcanvas") checker.setControlName("expected_" + reference_image) checker.setRenderedImage(file_name) checker.setColorTolerance(2) result = checker.runTest(name, 20) self.report += checker.report() print((self.report)) return result
def testRenderWithPainterClipRegionsMultiPolygon(self): poly_layer = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'polys.shp')) self.assertTrue(poly_layer.isValid()) sym1 = QgsFillSymbol.createSimple({ 'color': '#ff00ff', 'outline_color': '#000000', 'outline_width': '1' }) renderer = QgsSingleSymbolRenderer(sym1) poly_layer.setRenderer(renderer) mapsettings = QgsMapSettings() mapsettings.setOutputSize(QSize(400, 400)) mapsettings.setOutputDpi(96) mapsettings.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:3857')) mapsettings.setExtent( QgsRectangle(-13875783.2, 2266009.4, -8690110.7, 6673344.5)) mapsettings.setLayers([poly_layer]) region = QgsMapClippingRegion( QgsGeometry.fromWkt( 'MultiSurface (Polygon ((-10856627.66351187042891979 5625411.45629768911749125, -11083997.96136780828237534 4995770.63146586995571852, -10887235.20360786281526089 4357384.79517805296927691, -9684796.12840820662677288 4851477.9424419105052948, -10069576.63247209787368774 5428648.69853774644434452, -10856627.66351187042891979 5625411.45629768911749125)),Polygon ((-12045949.22152753174304962 5533588.83600971661508083, -12758667.65519132651388645 4868967.96535390708595514, -12478827.28859940730035305 4296169.71498607192188501, -11783598.87784760631620884 4077544.42858613422140479, -11223918.14466376602649689 4715930.26487395167350769, -11127723.01864779368042946 5673509.01930567622184753, -11359465.8222317285835743 5809056.69687363691627979, -12045949.22152753174304962 5533588.83600971661508083),(-11341975.79931973293423653 4790262.86224992945790291, -11722383.7976556234061718 4318032.24362606555223465, -12019714.18715953826904297 4606617.62167398259043694, -11757363.84347961470484734 4908320.51690589636564255, -11341975.79931973293423653 4790262.86224992945790291)))' )) region.setFeatureClip( QgsMapClippingRegion.FeatureClippingType.ClipPainterOnly) mapsettings.addClippingRegion(region) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_painterclip_region_multi') result = renderchecker.runTest('expected_painterclip_region_multi') self.report += renderchecker.report() self.assertTrue(result) # also try with symbol levels renderer.setUsingSymbolLevels(True) poly_layer.setRenderer(renderer) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlPathPrefix('vectorlayerrenderer') renderchecker.setControlName('expected_painterclip_region_multi') result = renderchecker.runTest('expected_painterclip_region_multi') self.report += renderchecker.report() self.assertTrue(result)