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 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'], '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.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.assertEqual(metadata['Keywords'], 'KWx: kw3,kw4;kw: kw1,kw2') 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)) # image size with incorrect aspect ratio # this can happen as a result of data defined page sizes settings.imageSize = QSize(851, 600) rendered_file_path = os.path.join( self.basetestpath, 'test_exporttoimagesizebadaspect.png') self.assertEqual(exporter.exportToImage(rendered_file_path, settings), QgsLayoutExporter.Success) page2_path = os.path.join(self.basetestpath, 'test_exporttoimagesizebadaspect_2.png') im = QImage(page2_path) self.assertTrue( self.checkImage('exporttoimagesize_badaspect', 'exporttoimagedpi_page2', page2_path), '{}x{}'.format(im.width(), im.height()))
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 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 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 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 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): 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 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 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 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()