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 testRenderPageToImage(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) exporter = QgsLayoutExporter(l) size = QSize(1122, 794) # bad page numbers image = exporter.renderPageToImage(-1, size) self.assertTrue(image.isNull()) image = exporter.renderPageToImage(1, size) self.assertTrue(image.isNull()) # good page image = exporter.renderPageToImage(0, size) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimagepage.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimagepage', 'rendertoimagepage', rendered_file_path))
def testRenderFillLayerDisabled(self): """ test that rendering a fill symbol with disabled layer works""" layer = QgsSimpleFillSymbolLayer() layer.setEnabled(False) 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.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))
def testSimpleFillDefault(self): symbol = QgsSimpleFillSymbolLayer(QColor("red"), Qt.SolidPattern, QColor("green"), Qt.SolidLine, 5) symbol.setOffset(QPointF(5, 10)) dom, root = self.symbolToSld(symbol) # print ("Simple fill mm: \n" + dom.toString()) self.assertStrokeWidth(root, 2, 18) self.assertStaticDisplacement(root, 18, 36)
def testSimpleFillPixels(self): symbol = QgsSimpleFillSymbolLayer(QColor("red"), Qt.SolidPattern, QColor("green"), Qt.SolidLine, 5) symbol.setOffset(QPointF(5, 10)) symbol.setOutputUnit(QgsUnitTypes.RenderPixels) dom, root = self.symbolToSld(symbol) # print ( "Simple fill px: \n" + dom.toString()) self.assertStrokeWidth(root, 2, 5) self.assertStaticDisplacement(root, 5, 10)
def testPrint(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_file_path) printer.setOutputFormat(QPrinter.PdfFormat) self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue(self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def testExportReport(self): p = QgsProject() r = QgsReport(p) # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) report_header.initializeDefaults() item1 = QgsLayoutItemShape(report_header) 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) report_header.addItem(item1) r.setHeader(report_header) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) report_footer.initializeDefaults() item2 = QgsLayoutItemShape(report_footer) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) report_footer.addItem(item2) r.setFooter(report_footer) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 report_path = os.path.join(self.basetestpath, 'test_report') result, error = QgsLayoutExporter.exportToImage(r, report_path, 'png', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_report_0001.png') self.assertTrue(self.checkImage('report_page1', 'report_page1', page1_path)) page2_path = os.path.join(self.basetestpath, 'test_report_0002.png') self.assertTrue(self.checkImage('report_page2', 'report_page2', page2_path))
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(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Name='Lake'")) layer.setStrokeStyle(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 testExportToPdfSkipFirstPage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # page 1 is excluded from export page1 = l.pageCollection().page(0) page1.setExcludeFromExports(True) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False settings.exportMetadata = True pdf_file_path = os.path.join(self.basetestpath, 'test_exporttopdfdpi_skip_first.pdf') self.assertEqual(exporter.exportToPdf(pdf_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi_skip_first.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) self.assertTrue(self.checkImage('test_exporttopdfdpi_skip_first', 'exporttopdfdpi_page2', rendered_page_1, size_tolerance=1))
def testRenderRegionToImage(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) exporter = QgsLayoutExporter(l) size = QSize(560, 509) image = exporter.renderRegionToImage(QRectF(5, 10, 110, 100), size) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimageregionsize.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimageregionsize', 'rendertoimageregionsize', rendered_file_path)) # using layout dpi l.renderContext().setDpi(40) image = exporter.renderRegionToImage(QRectF(5, 10, 110, 100)) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimageregiondpi.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimageregiondpi', 'rendertoimageregiondpi', rendered_file_path)) # overriding dpi image = exporter.renderRegionToImage(QRectF(5, 10, 110, 100), QSize(), 80) self.assertFalse(image.isNull()) rendered_file_path = os.path.join(self.basetestpath, 'test_rendertoimageregionoverridedpi.png') image.save(rendered_file_path, "PNG") self.assertTrue(self.checkImage('rendertoimageregionoverridedpi', 'rendertoimageregionoverridedpi', rendered_file_path))
def testClone(self): """ test that base symbol layer properties are cloned with layer """ layer = QgsSimpleFillSymbolLayer() layer.setEnabled(False) layer.setLocked(True) layer.setRenderingPass(5) symbol = QgsFillSymbol() symbol.changeSymbolLayer(0, layer) cloned_symbol = symbol.clone() cloned_layer = cloned_symbol.symbolLayer(0) self.assertFalse(cloned_layer.enabled()) self.assertTrue(cloned_layer.isLocked()) self.assertEqual(cloned_layer.renderingPass(), 5)
def testSymbol(self): """ Test setting a page symbol for the collection """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() self.assertTrue(collection.pageStyleSymbol()) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeColor(Qt.red) fill.setStrokeWidth(6) collection.setPageStyleSymbol(fill_symbol) self.assertEqual(collection.pageStyleSymbol().symbolLayer(0).color().name(), '#00ff00') self.assertEqual(collection.pageStyleSymbol().symbolLayer(0).strokeColor().name(), '#ff0000')
def testSaveRestore(self): """ Test saving and restoring base symbol layer properties to xml""" layer = QgsSimpleFillSymbolLayer() layer.setEnabled(False) layer.setLocked(True) layer.setRenderingPass(5) symbol = QgsFillSymbol() symbol.changeSymbolLayer(0, layer) doc = QDomDocument("testdoc") elem = QgsSymbolLayerUtils.saveSymbol('test', symbol, doc, QgsReadWriteContext()) restored_symbol = QgsSymbolLayerUtils.loadSymbol(elem, QgsReadWriteContext()) restored_layer = restored_symbol.symbolLayer(0) self.assertFalse(restored_layer.enabled()) self.assertTrue(restored_layer.isLocked()) self.assertEqual(restored_layer.renderingPass(), 5)
def testReadWriteXml(self): p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeColor(Qt.red) fill.setStrokeWidth(6) collection.setPageStyleSymbol(fill_symbol) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') self.assertEqual(collection.pageNumber(page), -1) collection.addPage(page) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) doc = QDomDocument("testdoc") elem = doc.createElement("test") self.assertTrue(collection.writeXml(elem, doc, QgsReadWriteContext())) l2 = QgsLayout(p) collection2 = l2.pageCollection() self.assertTrue(collection2.readXml(elem.firstChildElement(), doc, QgsReadWriteContext())) self.assertEqual(collection2.pageCount(), 2) self.assertEqual(collection2.page(0).pageSize().width(), 210) self.assertEqual(collection2.page(0).pageSize().height(), 297) self.assertEqual(collection2.page(1).pageSize().width(), 148) self.assertEqual(collection2.page(1).pageSize().height(), 210) self.assertEqual(collection2.pageStyleSymbol().symbolLayer(0).color().name(), '#00ff00') self.assertEqual(collection2.pageStyleSymbol().symbolLayer(0).strokeColor().name(), '#ff0000')
def testQgsSimpleFillSymbolLayer(self): """Create a new style from a .sld file and match test. """ mTestName = "QgsSimpleFillSymbolLayer" mFilePath = QDir.toNativeSeparators("%s/symbol_layer/%s.sld" % (unitTestDataPath(), mTestName)) mDoc = QDomDocument(mTestName) mFile = QFile(mFilePath) mFile.open(QIODevice.ReadOnly) mDoc.setContent(mFile, True) mFile.close() mSymbolLayer = QgsSimpleFillSymbolLayer.createFromSld( mDoc.elementsByTagName("PolygonSymbolizer").item(0).toElement() ) mExpectedValue = type(QgsSimpleFillSymbolLayer()) mValue = type(mSymbolLayer) mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = Qt.SolidPattern mValue = mSymbolLayer.brushStyle() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = "#ffaa7f" mValue = mSymbolLayer.borderColor().name() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = Qt.DotLine mValue = mSymbolLayer.borderStyle() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage mExpectedValue = 0.26 mValue = mSymbolLayer.borderWidth() mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue) assert mExpectedValue == mValue, mMessage
def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, utmcheck): """Getting Input Data For Grid Generation""" grid_spacing = spacing geo_number_x = crossX geo_number_y = crossY fSize = fontSize fontType = font LLfontType = fontLL #Loading feature layer_bound = layer query = '"' + str(id_attr) + '"=' + str(id_value) layer_bound.selectByExpression(query, QgsVectorLayer.SelectBehavior(0)) feature_bound = layer_bound.selectedFeatures()[0] layer_bound.removeSelection() #Getting Feature Source CRS and Geometry if utmcheck: feature_geometry = feature_bound.geometry() bound_UTM = layer_bound.crs().authid() feature_bbox = feature_geometry.boundingBox() bound_UTM_bb = str(feature_bbox).replace(',', '').replace('>', '') # Transforming to Geographic transform_feature = QgsCoordinateTransform( QgsCoordinateReferenceSystem(bound_UTM), QgsCoordinateReferenceSystem('EPSG:4674'), QgsProject.instance()) feature_geometry.transform(transform_feature) bound_sourcecrs = 'EPSG:4674' feature_bbox = feature_geometry.boundingBox() feature_bbox_or = feature_geometry.orientedMinimumBoundingBox() else: feature_geometry = feature_bound.geometry() bound_sourcecrs = layer_bound.crs().authid() feature_bbox = feature_geometry.boundingBox() feature_bbox_or = feature_geometry.orientedMinimumBoundingBox() geo_bound_bb = str(feature_bbox).replace(',', '').replace('>', '') oriented_geo_bb = str(feature_bbox_or).replace(',', '').replace( '>', '').replace('((', '').replace('))', '') #Defining CRSs Transformations inom = feature_bound[index] if inom[0] == 'N': bound_UTM = 'EPSG:319' + str(72 + int(inom[3:5]) - 18) elif inom[0] == 'S': bound_UTM = 'EPSG:319' + str(78 + int(inom[3:5]) - 18) else: iface.messageBar().pushMessage("Error", "Invalid index attribute", level=Qgis.Critical) return trLLUTM = QgsCoordinateTransform( QgsCoordinateReferenceSystem(bound_sourcecrs), QgsCoordinateReferenceSystem(bound_UTM), QgsProject.instance()) trUTMLL = QgsCoordinateTransform( QgsCoordinateReferenceSystem(bound_UTM), QgsCoordinateReferenceSystem(bound_sourcecrs), QgsProject.instance()) #Defining UTM Grid Symbology Type renderer = layer.renderer() properties = {'color': 'black'} grid_symb = QgsFillSymbol.createSimple(properties) symb_out = QgsSimpleFillSymbolLayer() symb_out.setStrokeColor(QColor('black')) symb_out.setFillColor(QColor('white')) symb_out.setStrokeWidth(0.05) """ Creating UTM Grid """ if not utmcheck: geo_UTM = feature_bound.geometry() geo_UTM.transform(trLLUTM) bound_UTM_bb = str(geo_UTM.boundingBox()).replace(',', '').replace( '>', '') xmin_UTM = float(bound_UTM_bb.split()[1]) ymin_UTM = float(bound_UTM_bb.split()[2]) xmax_UTM = float(bound_UTM_bb.split()[3]) ymax_UTM = float(bound_UTM_bb.split()[4]) if grid_spacing > 0: UTM_num_x = floor(xmax_UTM / grid_spacing) - floor( xmin_UTM / grid_spacing) UTM_num_y = floor(ymax_UTM / grid_spacing) - floor( ymin_UTM / grid_spacing) #Generating Vertical Lines for x in range(1, UTM_num_x + 1): grid_symb = self.utm_symb_generator( grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, x, 0, geo_bound_bb, bound_UTM_bb, utmcheck) #Generating Horizontal Lines for y in range(1, UTM_num_y + 1): grid_symb = self.utm_symb_generator( grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, 0, y, geo_bound_bb, bound_UTM_bb, utmcheck) """ Creating Geo Grid """ grid_symb = self.geoGridcreator(grid_symb, geo_bound_bb, geo_number_x, geo_number_y, scale, utmcheck, trLLUTM) """ Rendering UTM and Geographic Grid """ #Changing UTM Grid Color grid_symb.setColor(color) grid_symb.changeSymbolLayer(0, symb_out) #Creating Rule Based Renderer (Rule For The Other Features) properties = {'color': 'white'} ext_grid_symb = QgsFillSymbol.createSimple(properties) symb_ot = QgsRuleBasedRenderer.Rule(ext_grid_symb) symb_ot.setFilterExpression('\"' + str(id_attr) + '\" <> ' + str(id_value)) symb_ot.setLabel('other') #Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule) symb_new = QgsRuleBasedRenderer.Rule(grid_symb) symb_new.setFilterExpression('\"' + str(id_attr) + '\" = ' + str(id_value)) symb_new.setLabel('layer') symb_new.appendChild(symb_ot) #Applying New Renderer render_base = QgsRuleBasedRenderer(symb_new) new_renderer = QgsInvertedPolygonRenderer.convertFromRenderer( render_base) layer_bound.setRenderer(new_renderer) """ Labeling Geo Grid """ if utmcheck: dx = [ 2 * scale * fSize / 1.5, -13.6 * scale * fSize / 1.5, 6 * scale * fSize / 1.5 ] dy = [1.7 * scale * fSize / 1.5, -3.8 * scale * fSize / 1.5] else: dx = [0.000018 * scale, -0.000120 * scale, 0.00005 * scale] dy = [0.000015 * scale, -0.000040 * scale] root_rule = self.geoGridlabelPlacer(geo_bound_bb, geo_number_x, geo_number_y, dx, dy, fSize, LLfontType, trLLUTM, trUTMLL, llcolor, utmcheck, scale) """ Labeling UTM Grid""" if utmcheck: dx = [-2.7, -9.7, -6.2, 5.4] dx = [i * scale * fSize / 1.5 for i in dx] dy = [2.5, -1.7, -0.5, -1.5] dy = [i * scale * fSize / 1.5 for i in dy] dy0 = [5.45, -4.8, -3.2, -4.2] dy0 = [i * scale * fSize / 1.5 for i in dy0] dy1 = [2.15, 1.2] dy1 = [i * scale * fSize / 1.5 for i in dy1] else: dx = [-0.00003, -0.000107, -0.000070, 0.000060] dx = [i * scale * fSize / 1.5 for i in dx] dy = [0.000027, 0.000016, -0.000041, -0.000052] dy = [i * scale * fSize / 1.5 for i in dy] dy0 = [0.0000644, 0.000053, -0.000076, -0.000087] dy0 = [i * scale * fSize / 1.5 for i in dy0] dy1 = [0.000032, 0.000020] dy1 = [i * scale * fSize / 1.5 for i in dy1] root_rule = self.utmGridlabelPlacer( root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0, dy1, fSize, fontType, scale, utmcheck, oriented_geo_bb) """ Activating Labels """ rules = QgsRuleBasedLabeling(root_rule) layer.setLabeling(rules) layer.setLabelsEnabled(True) layer.triggerRepaint() return
def append_SimpleFillSymbolLayer( symbol, # pylint: disable=too-many-branches layer: SimpleFillSymbolLayer, context: Context): """ Appends a SimpleFillSymbolLayer to a symbol """ fill_color = symbol_color_to_qcolor(layer.color) out = QgsSimpleFillSymbolLayer(fill_color) out.setEnabled(layer.enabled) out.setLocked(layer.locked) if isinstance(layer, SimpleFillSymbolLayer): if layer.outline_layer: if isinstance( layer.outline_layer, (SimpleLineSymbolLayer, CartographicLineSymbolLayer)): out.setStrokeColor( symbol_color_to_qcolor(layer.outline_layer.color)) out.setStrokeWidth( context.convert_size(layer.outline_layer.width)) out.setStrokeWidthUnit(context.units) if isinstance(layer.outline_layer, SimpleLineSymbolLayer): out.setStrokeStyle( symbol_pen_to_qpenstyle(layer.outline_layer.line_type)) if isinstance(layer.outline_layer, CartographicLineSymbolLayer): out.setPenJoinStyle( symbol_pen_to_qpenjoinstyle(layer.outline_layer.join)) # better matching of null stroke color to QGIS symbology if out.strokeColor().alpha() == 0: out.setStrokeStyle(Qt.NoPen) # TODO try: if layer.outline_layer.offset: raise NotImplementedException( 'Fill outline offset not supported') except AttributeError: pass try: if layer.outline_layer.template: raise NotImplementedException( 'Fill outline template not supported') except AttributeError: pass try: if layer.outline_layer.decoration: raise NotImplementedException( 'Fill outline decoration not supported') except AttributeError: pass symbol.appendSymbolLayer(out) elif layer.outline_symbol: # outline is a symbol itself out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out) # get all layers from outline append_SymbolLayer_to_QgsSymbolLayer(symbol, layer.outline_symbol, context) else: out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out) elif isinstance(layer, ColorSymbol): out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out)
def testExportToSvg(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.SvgExportSettings() settings.dpi = 80 settings.forceVectorOutput = False settings.exportMetadata = True svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgdpi.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) # metadata def checkMetadata(f, expected): # ideally we'd check the path too - but that's very complex given that # the output from Qt svg generator isn't valid XML, and no Python standard library # xml parser handles invalid xml... self.assertEqual('proj title' in open(f).read(), expected) self.assertEqual('proj author' in open(f).read(), expected) self.assertEqual('proj identifier' in open(f).read(), expected) self.assertEqual('2011-05-03' in open(f).read(), expected) self.assertEqual('proj abstract' in open(f).read(), expected) self.assertEqual('kw1' in open(f).read(), expected) self.assertEqual('kw2' in open(f).read(), expected) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, True) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvgdpi.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue(self.checkImage('exporttosvgdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('exporttosvgdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) # no metadata settings.exportMetadata = False self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, False) # layered settings.exportAsLayers = True settings.exportMetadata = True svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvglayered.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvglayered.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue(self.checkImage('exporttosvglayered_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('exporttosvglayered_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, True) # layered no metadata settings.exportAsLayers = True settings.exportMetadata = False self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) for f in [svg_file_path, svg_file_path_2]: checkMetadata(f, False)
def styleCreator(self, feature_geometry, layer_bound, utmSRID, id_attr, id_value, spacing, crossX, crossY, scale, fontSize, font, fontLL, llcolor, linwidth_geo, linwidth_utm, linwidth_buffer_geo, linwidth_buffer_utm, geo_grid_color, utm_grid_color, geo_grid_buffer_color, utm_grid_buffer_color, masks_check): """Getting Input Data For Grid Generation""" linwidth_buffer_utm += linwidth_utm linwidth_buffer_geo += linwidth_geo grid_spacing = spacing geo_number_x = crossX geo_number_y = crossY fSize = fontSize fontType = font LLfontType = fontLL #Defining CRSs Transformations trLLUTM = QgsCoordinateTransform( QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateReferenceSystem('EPSG:' + str(utmSRID)), QgsProject.instance()) trUTMLL = QgsCoordinateTransform( QgsCoordinateReferenceSystem('EPSG:' + str(utmSRID)), QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance()) #Transforming to Geographic and defining bounding boxes feature_bbox = feature_geometry.boundingBox() bound_UTM_bb = str(feature_bbox).replace(',', '').replace('>', '') feature_geometry.transform(trUTMLL) feature_geo_bbox = feature_geometry.boundingBox() feature_bbox_or = feature_geometry.orientedMinimumBoundingBox() geo_bound_bb = str(feature_geo_bbox).replace(',', '').replace('>', '') oriented_geo_bb = str(feature_bbox_or).replace(',', '').replace( '>', '').replace('((', '').replace('))', '') #Defining UTM Grid Symbology Type properties = {'color': 'black'} grid_symb = QgsFillSymbol.createSimple(properties) """ Creating UTM Grid """ extentsUTM = (float(bound_UTM_bb.split()[1]), float(bound_UTM_bb.split()[2]), float(bound_UTM_bb.split()[3]), float(bound_UTM_bb.split()[4])) extentsGeo = (float(geo_bound_bb.split()[1]), float(geo_bound_bb.split()[2]), float(geo_bound_bb.split()[3]), float(geo_bound_bb.split()[4])) if grid_spacing > 0: UTM_num_x = floor(extentsUTM[2] / grid_spacing) - floor( extentsUTM[0] / grid_spacing) UTM_num_y = floor(extentsUTM[3] / grid_spacing) - floor( extentsUTM[1] / grid_spacing) if linwidth_buffer_utm != linwidth_utm: #Generating Buffer Vertical Lines for x in range(1, UTM_num_x + 1): grid_symb = self.utm_Symb_Generator( utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, UTM_num_x, UTM_num_y, x, 0, extentsGeo, extentsUTM, linwidth_buffer_utm, utm_grid_buffer_color) #Generating Buffer Horizontal Lines for y in range(1, UTM_num_y + 1): grid_symb = self.utm_Symb_Generator( utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, UTM_num_x, UTM_num_y, 0, y, extentsGeo, extentsUTM, linwidth_buffer_utm, utm_grid_buffer_color) #Generating Vertical Lines for x in range(1, UTM_num_x + 1): grid_symb = self.utm_Symb_Generator( utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, UTM_num_x, UTM_num_y, x, 0, extentsGeo, extentsUTM, linwidth_utm, utm_grid_color) #Generating Horizontal Lines for y in range(1, UTM_num_y + 1): grid_symb = self.utm_Symb_Generator( utmSRID, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, UTM_num_x, UTM_num_y, 0, y, extentsGeo, extentsUTM, linwidth_utm, utm_grid_color) """ Creating Geo Grid """ px = (round(extentsGeo[2], 6) - round(extentsGeo[0], 6)) / (geo_number_x + 1) py = (round(extentsGeo[3], 6) - round(extentsGeo[1], 6)) / (geo_number_y + 1) if linwidth_buffer_geo != linwidth_geo: grid_symb = self.geoGridcreator(utmSRID, grid_symb, extentsGeo, px, py, geo_number_x, geo_number_y, scale, trLLUTM, linwidth_buffer_geo, geo_grid_buffer_color) grid_symb = self.geoGridcreator(utmSRID, grid_symb, extentsGeo, px, py, geo_number_x, geo_number_y, scale, trLLUTM, linwidth_geo, geo_grid_color) """ Rendering UTM and Geographic Grid """ #Changing UTM Grid Color grid_symb.deleteSymbolLayer(0) #Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule) symb_new = QgsRuleBasedRenderer.Rule(grid_symb) symb_new.setFilterExpression('\"' + str(id_attr) + '\" = ' + str(id_value)) symb_new.setLabel('layer') #Appending rules to symbol root rule root_symbol_rule = QgsRuleBasedRenderer.Rule(None) root_symbol_rule.setFilterExpression('') root_symbol_rule.appendChild(symb_new) #Applying New Renderer render_base = QgsRuleBasedRenderer(root_symbol_rule) layer_bound.setRenderer(render_base) """Rendering outside area""" #Duplicating original layer layers_names = [ i.name() for i in QgsProject.instance().mapLayers().values() ] if (layer_bound.name() + "_outside") not in layers_names: outside_bound_layer = QgsVectorLayer( layer_bound.source(), layer_bound.name() + "_outside", layer_bound.providerType()) if layer_bound.providerType() == 'memory': feats = [feat for feat in layer_bound.getFeatures()] outside_bound_layer_data = outside_bound_layer.dataProvider() outside_bound_layer_data.addFeatures(feats) QgsProject.instance().addMapLayer(outside_bound_layer) else: outside_bound_layer = QgsProject.instance().mapLayersByName( layer_bound.name() + "_outside")[0] #Creating Rule Based Renderer (Rule For The Other Features) properties = {'color': 'white'} ext_grid_symb = QgsFillSymbol.createSimple(properties) symb_out = QgsSimpleFillSymbolLayer() symb_out.setFillColor(QColor('white')) symb_out.setStrokeWidth(linwidth_utm) ext_grid_symb.changeSymbolLayer(0, symb_out) rule_out = QgsRuleBasedRenderer.Rule(ext_grid_symb) rule_out.setFilterExpression('\"' + str(id_attr) + '\" = ' + str(id_value)) rule_out.setLabel('outside') root_symbol_rule_out = QgsRuleBasedRenderer.Rule(None) root_symbol_rule_out.appendChild(rule_out) render_base_out = QgsRuleBasedRenderer(root_symbol_rule_out) new_renderer = QgsInvertedPolygonRenderer.convertFromRenderer( render_base_out) outside_bound_layer.setRenderer(new_renderer) """ Labeling Geo Grid """ dx = [2.0, -11.0, -8.0, -3.6] dx = [i * scale * fSize / 1.5 for i in dx] dy = [1.7, -3.8, -0.8, -0.8] dy = [i * scale * fSize / 1.5 for i in dy] root_rule = self.geoGridlabelPlacer(extentsGeo, px, py, geo_number_x, geo_number_y, dx, dy, fSize, LLfontType, trLLUTM, llcolor, scale, layer_bound, trUTMLL) """ Labeling UTM Grid""" dx = [-2.9, -2.9, -8.9, 2.0] dx = [i * scale * fSize / 1.5 for i in dx] dy = [1.4, -4.6, -0.5, -1.5] dy = [i * scale * fSize / 1.5 for i in dy] dy0 = [5.0, -7.2, -3.2, -4.2] dy0 = [i * scale * fSize / 1.5 for i in dy0] dy1 = [2.15, 1.2] dy1 = [i * scale * fSize / 1.5 for i in dy1] root_rule = self.utmGridlabelPlacer(root_rule, grid_spacing, extentsGeo, extentsUTM, px, py, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0, dy1, fSize, fontType, scale, oriented_geo_bb, layer_bound) """ Activating Labels """ rules = QgsRuleBasedLabeling(root_rule) layer_bound.setLabeling(rules) layer_bound.setLabelsEnabled(True) if masks_check: self.apply_masks(layer_bound) layer_bound.triggerRepaint() return
def testExportToImage(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(self.checkImage('exporttoimagedpi_page1', 'exporttoimagedpi_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi_2.png') self.assertTrue(self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) for f in (rendered_file_path, page2_path): d = gdal.Open(f) metadata = d.GetMetadata() self.assertEqual(metadata['Author'], 'proj author') self.assertEqual(metadata['Created'], '2011-05-03T09:04:05+10:00') self.assertIn(metadata['Keywords'], ('kw1,kw2', 'kw2,kw1')) self.assertEqual(metadata['Subject'], 'proj abstract') self.assertEqual(metadata['Title'], 'proj title') # crop to contents settings.cropToContents = True settings.cropMargins = QgsMargins(10, 20, 30, 40) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(self.checkImage('exporttoimagecropped_page1', 'exporttoimagecropped_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped_2.png') self.assertTrue(self.checkImage('exporttoimagecropped_page2', 'exporttoimagecropped_page2', page2_path)) # specific pages settings.cropToContents = False settings.pages = [1] rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagepages.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagepages_2.png') self.assertTrue(self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # image size settings.imageSize = QSize(600, 851) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesize.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesize_2.png') self.assertTrue(self.checkImage('exporttoimagesize_page2', 'exporttoimagesize_page2', page2_path))
def testExportToPdf(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False settings.exportMetadata = True pdf_file_path = os.path.join(self.basetestpath, 'test_exporttopdfdpi.pdf') self.assertEqual(exporter.exportToPdf(pdf_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue(self.checkImage('exporttopdfdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('exporttopdfdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) d = gdal.Open(pdf_file_path) metadata = d.GetMetadata() self.assertEqual(metadata['AUTHOR'], 'proj author') self.assertEqual(metadata['CREATION_DATE'], "D:20110503090405+10'0'") self.assertIn(metadata['KEYWORDS'], ('kw1,kw2', 'kw2,kw1')) self.assertEqual(metadata['SUBJECT'], 'proj abstract') self.assertEqual(metadata['TITLE'], 'proj title')
def testExportToSvg(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.SvgExportSettings() settings.dpi = 80 settings.forceVectorOutput = False svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgdpi.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvgdpi.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue( self.checkImage('exporttosvgdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('exporttosvgdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) # layered settings.exportAsLayers = True svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvglayered.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvglayered.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue( self.checkImage('exporttosvglayered_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('exporttosvglayered_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def testExportToImage(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime( QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue( self.checkImage('exporttoimagedpi_page1', 'exporttoimagedpi_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi_2.png') self.assertTrue( self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) for f in (rendered_file_path, page2_path): d = gdal.Open(f) metadata = d.GetMetadata() self.assertEqual(metadata['Author'], 'proj author') self.assertEqual(metadata['Created'], '2011-05-03T09:04:05+10:00') self.assertIn(metadata['Keywords'], ('kw1,kw2', 'kw2,kw1')) self.assertEqual(metadata['Subject'], 'proj abstract') self.assertEqual(metadata['Title'], 'proj title') # crop to contents settings.cropToContents = True settings.cropMargins = QgsMargins(10, 20, 30, 40) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue( self.checkImage('exporttoimagecropped_page1', 'exporttoimagecropped_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped_2.png') self.assertTrue( self.checkImage('exporttoimagecropped_page2', 'exporttoimagecropped_page2', page2_path)) # specific pages settings.cropToContents = False settings.pages = [1] rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagepages.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagepages_2.png') self.assertTrue( self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # image size settings.imageSize = QSize(600, 851) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesize.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesize_2.png') self.assertTrue( self.checkImage('exporttoimagesize_page2', 'exporttoimagesize_page2', page2_path))
def append_SimpleFillSymbolLayer(symbol, layer: SimpleFillSymbolLayer): """ Appends a SimpleFillSymbolLayer to a symbol """ fill_color = symbol_color_to_qcolor(layer.color) out = QgsSimpleFillSymbolLayer(fill_color) out.setEnabled(layer.enabled) out.setLocked(layer.locked) if isinstance(layer, SimpleFillSymbolLayer): if layer.outline_layer: if isinstance(layer.outline_layer, (SimpleLineSymbolLayer, CartographicLineSymbolLayer)): out.setStrokeColor(symbol_color_to_qcolor(layer.outline_layer.color)) out.setStrokeWidth(layer.outline_layer.width) out.setStrokeWidthUnit(QgsUnitTypes.RenderPoints) if isinstance(layer.outline_layer, SimpleLineSymbolLayer): out.setStrokeStyle(symbol_pen_to_qpenstyle(layer.outline_layer.line_type)) if isinstance(layer.outline_layer, CartographicLineSymbolLayer): out.setPenJoinStyle(symbol_pen_to_qpenjoinstyle(layer.outline_layer.join)) # better matching of null stroke color to QGIS symbology if out.strokeColor().alpha() == 0: out.setStrokeStyle(Qt.NoPen) # todo - change to new symbol layer if outline offset, template, etc set symbol.appendSymbolLayer(out) elif layer.outline_symbol: # outline is a symbol itself out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out) # get all layers from outline append_SymbolLayer_to_QgsSymbolLayer(symbol, layer.outline_symbol) else: out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out) elif isinstance(layer, ColorSymbol): out.setStrokeStyle(Qt.NoPen) symbol.appendSymbolLayer(out)
def testPrint(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PrintExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False pdf_file_path = os.path.join(self.basetestpath, 'test_printdpi.pdf') # make a qprinter directed to pdf printer = QPrinter() printer.setOutputFileName(pdf_file_path) printer.setOutputFormat(QPrinter.PdfFormat) self.assertEqual(exporter.print(printer, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue( self.checkImage('printdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue( self.checkImage('printdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def testGettersSetters(self): """ test base class getters/setters """ layer = QgsSimpleFillSymbolLayer() layer.setEnabled(False) self.assertFalse(layer.enabled()) layer.setEnabled(True) self.assertTrue(layer.enabled()) layer.setLocked(False) self.assertFalse(layer.isLocked()) layer.setLocked(True) self.assertTrue(layer.isLocked()) layer.setRenderingPass(5) self.assertEqual(layer.renderingPass(), 5)
def stylize_map(layer: QgsVectorLayer) -> [List[str], List[str]]: """Stylize the layer with unique colors per timezone Args: layer (QgsVectorLayer): The layer to stylize Returns: [List[str], List[str]]: A list with all timezone ids and one with the respective color """ print("Reading timezones from file") timezones = layer.uniqueValues(layer.fields().indexOf("tzid")) timezones = list(timezones) timezones.sort() categorized_renderer = QgsCategorizedSymbolRenderer() print("Stylizing map") timezone_ids = [] timezone_colors = [] features = layer.getFeatures() categories = [] currentColor = 0 for tz in timezones: # Modify the Etc timezones to match the Qt format qt_tz = tz # There are a few exceptions where the Qt timezone ids differ from the dataset ids: match = re.match(r"Etc/GMT([+-])(\d+)", tz) if match: qt_tz = f"UTC{match.group(1)}{match.group(2):0>2}:00" elif tz == "Etc/UTC": qt_tz = "UTC" elif tz == "Etc/GMT": qt_tz = "UTC+00:00" # Generate a consecutive color for each timezone currentColor += 25000 r = (currentColor >> 16) & 255 g = (currentColor >> 8 ) & 255 b = (currentColor ) & 255 # Add it to the mapping rh = hex(r)[2:] gh = hex(g)[2:] bh = hex(b)[2:] timezone_ids.append(qt_tz) timezone_colors.append(f"#{rh:0>2}{gh:0>2}{bh:0>2}") symbol = QgsSymbol.defaultSymbol(layer.geometryType()) symbol_layer = QgsSimpleFillSymbolLayer.create({"color": f"{r}, {g}, {b}"}) symbol_layer.setStrokeWidth(0.0) symbol_layer.setStrokeStyle(Qt.PenStyle.NoPen) symbol.changeSymbolLayer(0, symbol_layer) category = QgsRendererCategory(tz, symbol, tz) categories.append(category) renderer = QgsCategorizedSymbolRenderer("tzid", categories) layer.setRenderer(renderer) layer.triggerRepaint() return timezone_ids, timezone_colors
def testExportToPdf(self): md = QgsProject.instance().metadata() md.setTitle('proj title') md.setAuthor('proj author') md.setCreationDateTime(QDateTime(QDate(2011, 5, 3), QTime(9, 4, 5), QTimeZone(36000))) md.setIdentifier('proj identifier') md.setAbstract('proj abstract') md.setKeywords({'kw': ['kw1', 'kw2'], 'KWx': ['kw3', 'kw4']}) QgsProject.instance().setMetadata(md) l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.PdfExportSettings() settings.dpi = 80 settings.rasterizeWholeImage = False settings.forceVectorOutput = False settings.exportMetadata = True pdf_file_path = os.path.join(self.basetestpath, 'test_exporttopdfdpi.pdf') self.assertEqual(exporter.exportToPdf(pdf_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(pdf_file_path)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttopdfdpi.png') dpi = 80 pdfToPng(pdf_file_path, rendered_page_1, dpi=dpi, page=1) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttopdfdpi2.png') pdfToPng(pdf_file_path, rendered_page_2, dpi=dpi, page=2) self.assertTrue(self.checkImage('exporttopdfdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('exporttopdfdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) d = gdal.Open(pdf_file_path) metadata = d.GetMetadata() self.assertEqual(metadata['AUTHOR'], 'proj author') self.assertEqual(metadata['CREATION_DATE'], "D:20110503090405+10'0'") self.assertEqual(metadata['KEYWORDS'], 'KWx: kw3,kw4;kw: kw1,kw2') self.assertEqual(metadata['SUBJECT'], 'proj abstract') self.assertEqual(metadata['TITLE'], 'proj title')
def SimpleFillSymbolLayer_to_QgsSimpleFillSymbolLayer(layer): """ Converts a SimpleFillSymbolLayer to a QgsSimpleFillSymbolLayer """ fill_color = symbol_color_to_qcolor(layer.color) out = QgsSimpleFillSymbolLayer(fill_color) if layer.outline_layer: if isinstance(layer.outline_layer, (SimpleLineSymbolLayer, CartographicLineSymbolLayer)): out.setStrokeColor( symbol_color_to_qcolor(layer.outline_layer.color)) out.setStrokeWidth(points_to_mm(layer.outline_layer.width)) if isinstance(layer.outline_layer, SimpleLineSymbolLayer): out.setStrokeStyle( symbol_pen_to_qpenstyle(layer.outline_layer.line_type)) if isinstance(layer.outline_layer, CartographicLineSymbolLayer): out.setPenJoinStyle( symbol_pen_to_qpenjoinstyle(layer.outline_layer.join)) # better matching of null stroke color to QGIS symbology if out.strokeColor().alpha() == 0: out.setStrokeStyle(Qt.NoPen) # todo - change to new symbol layer if outline offset set else: # todo - outline symbol layer raise NotImplementedException('Outline symbol layer not implemented') return out
def testExportToImage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue( self.checkImage('exporttoimagedpi_page1', 'exporttoimagedpi_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi_2.png') self.assertTrue( self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # crop to contents settings.cropToContents = True settings.cropMargins = QgsMargins(10, 20, 30, 40) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue( self.checkImage('exporttoimagecropped_page1', 'exporttoimagecropped_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped_2.png') self.assertTrue( self.checkImage('exporttoimagecropped_page2', 'exporttoimagecropped_page2', page2_path)) # specific pages settings.cropToContents = False settings.pages = [1] rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagepages.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagepages_2.png') self.assertTrue( self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # image size settings.imageSize = QSize(600, 851) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesize.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesize_2.png') self.assertTrue( self.checkImage('exporttoimagesize_page2', 'exporttoimagesize_page2', page2_path))
def testCondenseFillAndOutline(self): """ Test QgsSymbolLayerUtils.condenseFillAndOutline """ self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( None, None)) # not simple fill or line self.assertFalse( QgsSymbolLayerUtils.condenseFillAndOutline( QgsShapeburstFillSymbolLayer(), QgsSimpleLineSymbolLayer())) self.assertFalse( QgsSymbolLayerUtils.condenseFillAndOutline( QgsSimpleFillSymbolLayer(), QgsMarkerLineSymbolLayer())) # simple fill/line fill = QgsSimpleFillSymbolLayer() line = QgsSimpleLineSymbolLayer() # set incompatible settings on outline line.setUseCustomDashPattern(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setDashPatternOffset(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setAlignDashPattern(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setTweakDashPatternOnCorners(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setTrimDistanceStart(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setTrimDistanceEnd(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setDrawInsidePolygon(True) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setRingFilter(QgsSimpleLineSymbolLayer.ExteriorRingOnly) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setOffset(1) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) line = QgsSimpleLineSymbolLayer() line.setDataDefinedProperty(QgsSymbolLayer.PropertyTrimEnd, QgsProperty.fromValue(4)) self.assertFalse(QgsSymbolLayerUtils.condenseFillAndOutline( fill, line)) # compatible! line = QgsSimpleLineSymbolLayer() line.setColor(QColor(255, 0, 0)) line.setWidth(1.2) line.setWidthUnit(QgsUnitTypes.RenderPoints) line.setWidthMapUnitScale(QgsMapUnitScale(1, 2)) line.setPenJoinStyle(Qt.MiterJoin) line.setPenStyle(Qt.DashDotDotLine) self.assertTrue(QgsSymbolLayerUtils.condenseFillAndOutline(fill, line)) self.assertEqual(fill.strokeColor(), QColor(255, 0, 0)) self.assertEqual(fill.strokeWidth(), 1.2) self.assertEqual(fill.strokeWidthUnit(), QgsUnitTypes.RenderPoints) self.assertEqual(fill.strokeWidthMapUnitScale(), QgsMapUnitScale(1, 2)) self.assertEqual(fill.penJoinStyle(), Qt.MiterJoin) self.assertEqual(fill.strokeStyle(), Qt.DashDotDotLine)
def testExportReport(self): p = QgsProject() r = QgsReport(p) # add a header r.setHeaderEnabled(True) report_header = QgsLayout(p) report_header.initializeDefaults() item1 = QgsLayoutItemShape(report_header) 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) report_header.addItem(item1) r.setHeader(report_header) # add a footer r.setFooterEnabled(True) report_footer = QgsLayout(p) report_footer.initializeDefaults() item2 = QgsLayoutItemShape(report_footer) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) report_footer.addItem(item2) r.setFooter(report_footer) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 report_path = os.path.join(self.basetestpath, 'test_report') result, error = QgsLayoutExporter.exportToImage( r, report_path, 'png', settings) self.assertEqual(result, QgsLayoutExporter.Success, error) page1_path = os.path.join(self.basetestpath, 'test_report_0001.png') self.assertTrue( self.checkImage('report_page1', 'report_page1', page1_path)) page2_path = os.path.join(self.basetestpath, 'test_report_0002.png') self.assertTrue( self.checkImage('report_page2', 'report_page2', page2_path))
def testDataDefinedOffset(self): """ test that rendering a fill symbol with data defined offset works""" polys_shp = os.path.join(TEST_DATA_DIR, 'polys.shp') polys_layer = QgsVectorLayer(polys_shp, 'Polygons', 'ogr') # lets render two layers, to make comparison easier layer = QgsSimpleFillSymbolLayer() layer.setStrokeStyle(Qt.NoPen) layer.setColor(QColor(200, 250, 50)) symbol = QgsFillSymbol() symbol.changeSymbolLayer(0, layer) layer = QgsSimpleFillSymbolLayer() layer.setDataDefinedProperty( QgsSymbolLayer.PropertyOffset, QgsProperty.fromExpression( "array(-(x_min($geometry)+100)/5, (y_min($geometry)-35)/5)")) layer.setStrokeStyle(Qt.NoPen) layer.setColor(QColor(100, 150, 150)) symbol.appendSymbolLayer(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]) # Test rendering renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_simplefill') renderchecker.setControlName('expected_simplefill_ddoffset') res = renderchecker.runTest('simplefill_ddoffset') TestQgsSimpleFillSymbolLayer.report += renderchecker.report() self.assertTrue(res)
def testExportToImage(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.ImageExportSettings() settings.dpi = 80 rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(self.checkImage('exporttoimagedpi_page1', 'exporttoimagedpi_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagedpi_2.png') self.assertTrue(self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # crop to contents settings.cropToContents = True settings.cropMargins = QgsMargins(10, 20, 30, 40) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(self.checkImage('exporttoimagecropped_page1', 'exporttoimagecropped_page1', rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagecropped_2.png') self.assertTrue(self.checkImage('exporttoimagecropped_page2', 'exporttoimagecropped_page2', page2_path)) # specific pages settings.cropToContents = False settings.pages = [1] rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagepages.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagepages_2.png') self.assertTrue(self.checkImage('exporttoimagedpi_page2', 'exporttoimagedpi_page2', page2_path)) # image size settings.imageSize = QSize(600, 851) rendered_file_path = os.path.join(self.basetestpath, 'test_exporttoimagesize.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) self.assertFalse(os.path.exists(rendered_file_path)) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesize_2.png') self.assertTrue(self.checkImage('exporttoimagesize_page2', 'exporttoimagesize_page2', page2_path))
def testExportToSvg(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) # add some items item1 = QgsLayoutItemShape(l) item1.attemptSetSceneRect(QRectF(10, 20, 100, 150)) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.green) fill.setStrokeStyle(Qt.NoPen) item1.setSymbol(fill_symbol) l.addItem(item1) item2 = QgsLayoutItemShape(l) item2.attemptSetSceneRect(QRectF(10, 20, 100, 150)) item2.attemptMove(QgsLayoutPoint(10, 20), page=1) fill = QgsSimpleFillSymbolLayer() fill_symbol = QgsFillSymbol() fill_symbol.changeSymbolLayer(0, fill) fill.setColor(Qt.cyan) fill.setStrokeStyle(Qt.NoPen) item2.setSymbol(fill_symbol) l.addItem(item2) exporter = QgsLayoutExporter(l) # setup settings settings = QgsLayoutExporter.SvgExportSettings() settings.dpi = 80 settings.forceVectorOutput = False svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvgdpi.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvgdpi.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvgdpi2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue(self.checkImage('exporttosvgdpi_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('exporttosvgdpi_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1)) # layered settings.exportAsLayers = True svg_file_path = os.path.join(self.basetestpath, 'test_exporttosvglayered.svg') svg_file_path_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered_2.svg') self.assertEqual(exporter.exportToSvg(svg_file_path, settings), QgsLayoutExporter.Success) self.assertTrue(os.path.exists(svg_file_path)) self.assertTrue(os.path.exists(svg_file_path_2)) rendered_page_1 = os.path.join(self.basetestpath, 'test_exporttosvglayered.png') svgToPng(svg_file_path, rendered_page_1, width=936) rendered_page_2 = os.path.join(self.basetestpath, 'test_exporttosvglayered2.png') svgToPng(svg_file_path_2, rendered_page_2, width=467) self.assertTrue(self.checkImage('exporttosvglayered_page1', 'exporttopdfdpi_page1', rendered_page_1, size_tolerance=1)) self.assertTrue(self.checkImage('exporttosvglayered_page2', 'exporttopdfdpi_page2', rendered_page_2, size_tolerance=1))
def stylePoly(self, layer, metric: str): """ Style isochrone polygon layer. :param QgsVectorLayer layer: Polygon layer to be styled. :param str metric: distance or time. """ field = layer.fields().lookupField('contour') unique_values = sorted(layer.uniqueValues(field)) colors = { "distance": { 0: QColor('#FCF0EE'), 1: QColor('#F9E1DC'), 2: QColor('#F6D2CB'), 3: QColor('#F3C3BA'), 4: QColor('#F0B3A8'), 5: QColor('#EDA396'), 6: QColor('#EA9485'), 7: QColor('#E78573'), 8: QColor('#E47662'), 9: QColor('#E16651') }, "time": { 0: QColor('#2b83ba'), 1: QColor('#64abb0'), 2: QColor('#9dd3a7'), 3: QColor('#c7e9ad'), 4: QColor('#edf8b9'), 5: QColor('#ffedaa'), 6: QColor('#fec980'), 7: QColor('#f99e59'), 8: QColor('#e85b3a'), 9: QColor('#d7191c') } } categories = [] for cid, unique_value in enumerate(unique_values): # initialize the default symbol for this geometry type symbol = QgsSymbol.defaultSymbol(layer.geometryType()) # configure a symbol layer symbol_layer = QgsSimpleFillSymbolLayer( color=colors[metric][cid], strokeColor=QColor('#000000')) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(unique_value, symbol, str(unique_value) + ' mins') # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer('contour', categories) # assign the created renderer to the layer if renderer is not None: layer.setRenderer(renderer) layer.setOpacity(0.5) layer.triggerRepaint()