def test_draw_settings(self): r = QgsGradientColorRamp(QColor(200, 0, 0, 100), QColor(0, 200, 0, 200)) # need a layer in order to make legend nodes layer = QgsVectorLayer('dummy', 'test', 'memory') layer_tree_layer = QgsLayerTreeLayer(layer) settings = QgsColorRampLegendNodeSettings() format = QgsBasicNumericFormat() format.setShowTrailingZeros(True) format.setNumberDecimalPlaces(3) settings.setNumericFormat(format) settings.setDirection(QgsColorRampLegendNodeSettings.MaximumToMinimum) node = QgsColorRampLegendNode(layer_tree_layer, r, settings, 5, 10) ls = QgsLegendSettings() item_style = ls.style(QgsLegendStyle.SymbolLabel) item_style.setFont(QgsFontUtils.getStandardTestFont('Bold', 18)) ls.setStyle(QgsLegendStyle.SymbolLabel, item_style) item_context = QgsLayerTreeModelLegendNode.ItemContext() image = QImage(400, 250, QImage.Format_ARGB32) image.fill(QColor(255, 255, 255)) p = QPainter(image) ms = QgsMapSettings() ms.setExtent(QgsRectangle(1, 10, 1, 10)) ms.setOutputSize(image.size()) context = QgsRenderContext.fromMapSettings(ms) context.setPainter(p) context.setScaleFactor(150 / 25.4) # 150 DPI p.scale(context.scaleFactor(), context.scaleFactor()) item_context.context = context item_context.painter = p item_context.top = 1 item_context.columnLeft = 3 item_context.columnRight = 30 item_context.patchSize = QSizeF(12, 40) symbol_size = node.drawSymbol(ls, item_context, 0) node.drawSymbolText(ls, item_context, symbol_size) p.end() self.assertTrue( self.imageCheck('color_ramp_legend_node_settings_draw', 'color_ramp_legend_node_settings_draw', image))
def test_json_export(self): project = QgsProject() self.assertTrue(project.read(os.path.join(unitTestDataPath('qgis_server'), 'test_project.qgs'))) model = QgsLegendModel(project.layerTreeRoot()) ctx = QgsRenderContext() settings = QgsLegendSettings() renderer = QgsLegendRenderer(model, settings) nodes = renderer.exportLegendToJson(ctx)['nodes'].toVariant() self.assertEqual(len(nodes), 7) self.assertEqual(nodes[0]['type'], 'layer') self.assertEqual(nodes[0]['title'], 'testlayer')
def getLegendGraphic(self, params): qgsLayer = self.layerRegistry.mapLayer(params.get('layer')) boxSpace = 1 layerSpace = 2 # layerTitleSpace = 3 symbolSpace = 2 iconLabelSpace = 2 symbolWidth = 5 symbolHeight = 3 drawLegendLabel = True rootGroup = QgsLayerTreeGroup() rootGroup.addLayer(qgsLayer) # layer = QgsLayerTreeLayer(qgsLayer) # if qgsLayer.title(): # layer.setLayerName(qgsLayer.title()) legendModel = QgsLayerTreeModel(rootGroup) rootChildren = rootGroup.children() img_tmp = QImage(QSize(1, 1), QImage.Format_ARGB32_Premultiplied) dpm = 1 / 0.00028 img_tmp.setDotsPerMeterX(dpm) img_tmp.setDotsPerMeterY(dpm) dpmm = img_tmp.dotsPerMeterX() / 1000.0 del img_tmp legendSettings = QgsLegendSettings() legendSettings.setTitle('') legendSettings.setBoxSpace(boxSpace) legendSettings.rstyle(QgsComposerLegendStyle.Subgroup).setMargin(QgsComposerLegendStyle.Top, layerSpace) legendSettings.rstyle(QgsComposerLegendStyle.Symbol).setMargin(QgsComposerLegendStyle.Top, symbolSpace) legendSettings.rstyle(QgsComposerLegendStyle.SymbolLabel).setMargin(QgsComposerLegendStyle.Left, iconLabelSpace) legendSettings.setSymbolSize(QSizeF(symbolWidth, symbolHeight)) # legendSettings.rstyle(QgsComposerLegendStyle.Subgroup).setFont(layerFont) # legendSettings.rstyle(QgsComposerLegendStyle.SymbolLabel).setFont(itemFont) # // TODO: not available: layer font color # legendSettings.setFontColor( itemFontColor ); # for node in rootChildren: # if (QgsLayerTree.isLayer(node)): # QgsLegendRenderer.setNodeLegendStyle(node, QgsComposerLegendStyle.Subgroup) # # rule item titles # # if ( !mDrawLegendItemLabel ) # # for legendNode in legendModel.layerLegendNodes(nodeLayer): # # legendNode.setUserLabel(' ') # # } legendRenderer = QgsLegendRenderer(legendModel, legendSettings) minSize = legendRenderer.minimumSize() s = QSize(minSize.width() * dpmm, minSize.height() * dpmm) img = QImage(s, QImage.Format_ARGB32_Premultiplied) # fill in the background color = QColor(0, 0, 0, 0) img.fill(color) p = QPainter() p.begin(img) p.setRenderHint(QPainter.Antialiasing, True) p.scale(dpmm, dpmm) legendRenderer.drawLegend(p) map_buffer = QBuffer() map_buffer.open(QIODevice.ReadWrite) img.save(map_buffer, 'PNG') # clean up map_buffer.close() p.end() # self.layerRegistry.removeAllMapLayers() return map_buffer.data()
def renderer(self): if 'QGIS_AUTH_DB_DIR_PATH' not in os.environ: os.environ['QGIS_AUTH_DB_DIR_PATH'] = '/tmp' qgis = None while True: options, result = self.queue.get() # Don't start QGIS until first request if qgis is None: qgis = QgsApplication([], False) qgis.setPrefixPath(self.settings.get('path'), True) qgis.setDefaultSvgPaths(qgis.svgPaths() + self.settings.get('svgpaths')) qgis.setMaxThreads(1) qgis.initQgis() try: if isinstance(options, LegendOptions): style, = options layer = self._qgs_memory_layer(style) layer.setName(style.parent.display_name) QgsMapLayerRegistry.instance().addMapLayer(layer) root = QgsLayerTreeGroup() root.addLayer(layer) # 'Cannot create a QPixmap when no GUI is being used' # warning occurs here model = QgsLayerTreeModel(root) settings = QgsLegendSettings() settings.setTitle('') settings.setBoxSpace(1) settings.setSymbolSize(QSizeF(5, 3)) settings.setDpi(96) renderer = QgsLegendRenderer(model, settings) # Dots per mm dpmm = settings.dpi() / 25.4 min_size = renderer.minimumSize() size = QSize(dpmm * min_size.width(), dpmm * min_size.height()) img = QImage(size, QImage.Format_ARGB32) img.fill(QColor(0, 0, 0, 0)) painter = QPainter() painter.begin(img) painter.scale(dpmm, dpmm) renderer.drawLegend(painter) painter.end() QgsMapLayerRegistry.instance().removeAllMapLayers() ba = QByteArray() bf = QBuffer(ba) bf.open(QIODevice.WriteOnly) img.save(bf, 'PNG') bf.close() buf = StringIO() buf.write(bf.data()) buf.seek(0) result.put(buf) else: path = features = None if isinstance(options, VectorRenderOptions): style, features, render_size, \ extended, target_box = options layer = self._qgs_memory_layer(style, features=features) elif isinstance(options, RasterRenderOptions): style, path, render_size, \ extended, target_box = options layer = QgsRasterLayer(path) layer.loadNamedStyle( self.env.file_storage.filename(style.qml_fileobj)) settings = QgsMapSettings() settings.setLayers([layer.id()]) settings.setFlag(QgsMapSettings.DrawLabeling) settings.setFlag(QgsMapSettings.Antialiasing) settings.setCrsTransformEnabled(True) settings.setDestinationCrs(layer.crs()) settings.setMapUnits(layer.crs().mapUnits()) settings.setOutputSize(QSize(*render_size)) settings.setExtent(QgsRectangle(*extended)) settings.setOutputImageFormat(QImage.Format_ARGB32) bgcolor = QColor.fromRgba(qRgba(255, 255, 255, 0)) settings.setBackgroundColor(bgcolor) settings.setOutputDpi(96) QgsMapLayerRegistry.instance().addMapLayer(layer) settings.setLayers([layer.id()]) # Create QImage by hand to be able to use # QgsMapRendererCustomPainterJob. Others will not # allow to workaround a bug with overlay rendering. img = QImage(settings.outputSize(), QImage.Format_ARGB32) # These cludges are needed for rendering # on transparent background, otherwise it's a mess. img.fill(QColor.fromRgba(qRgba(255, 255, 255, 255))) img.fill(QColor.fromRgba(qRgba(255, 255, 255, 0))) # DPI should be equal to settings, otherwise an error. # In QImage the resolution is set in dots per meter # for each axis. dpm = settings.outputDpi() / 25.4 * 1000 img.setDotsPerMeterX(dpm) img.setDotsPerMeterY(dpm) painter = QPainter(img) job = QgsMapRendererCustomPainterJob(settings, painter) job.renderSynchronously() painter.end() QgsMapLayerRegistry.instance().removeAllMapLayers() img = self._qimage_to_pil(img) # Clip needed part result.put(img.crop(target_box)) # Cleanup if path is not None: gdal.Unlink(path) except Exception as exc: self.logger.error(exc.message) result.put(exc) qgis.exitQgis()