def findGroup(root: QgsLayerTreeGroup, name: str) -> QgsLayerTreeGroup: """Recursively finds first group that matches name.""" #Search immediate children for child in root.children(): if isinstance(child, QgsLayerTreeGroup): if name == child.name(): return child #Search subchildren for child in root.children(): if isinstance(child, QgsLayerTreeGroup): result = findGroup(child, name) if result != None: return result #Found nothing return None
def findChildren(root: QgsLayerTreeGroup, matchString: str): """Return a list of groups in the root that match a regex string argument.""" result = [] matchStringParts = matchString.split('/', 1) for child in root.children(): if fnmatch.fnmatch(child.name(), matchStringParts[0]): if isinstance(child, QgsLayerTreeGroup): result.extend(findChildren(child, matchStringParts[1])) else: result.append(child) return result
def load_qlr_file(self, path): # Load qlr into a group owned by us try: group = QgsLayerTreeGroup() # On Windows this locks the parent dirs indefinitely # See http://hub.qgis.org/issues/14811 # QgsLayerDefinition.loadLayerDefinition(path, group) # Instead handle file ourselves f = QFile(path) if not f.open(QIODevice.ReadOnly): return False try: doc = QDomDocument() if not doc.setContent(f.readAll()): return False QgsLayerDefinition.loadLayerDefinition(doc, group) finally: f.close() # Get subtree of nodes nodes = group.children() # plain list of nodes nodeslist = [] for addedNode in nodes: internalid = self._random_string() nodeinfo = {'internalid': internalid} addedNode.setCustomProperty(QlrManager.customPropertyName, internalid) if isinstance(addedNode, QgsLayerTreeGroup): nodeinfo['type'] = 'group' nodeinfo['name'] = addedNode.name() elif isinstance(addedNode, QgsLayerTreeLayer): nodeinfo['type'] = 'layer' nodeinfo['name'] = addedNode.layerName() nodeinfo['layerid'] = addedNode.layerId() nodeslist.append(nodeinfo) # Remove from parent node. Otherwise we cant add it to a new parent group.takeChild(addedNode) self.fileSystemItemToLegendNode[path] = nodeslist # Insert them into the main project QgsProject.instance().layerTreeRoot().insertChildNodes(0, nodes) return True except: # For now just return silently return False
def load_qlr_file(self, path): # Load qlr into a group owned by us try: group = QgsLayerTreeGroup() # On Windows this locks the parent dirs indefinitely # See http://hub.qgis.org/issues/14811 # QgsLayerDefinition.loadLayerDefinition(path, group) # Instead handle file ourselves f = QFile(path) if not f.open(QIODevice.ReadOnly): return False try: doc = QDomDocument() if not doc.setContent( f.readAll() ): return False QgsLayerDefinition.loadLayerDefinition(doc, group) finally: f.close() # Get subtree of nodes nodes = group.children() # plain list of nodes nodeslist = [] for addedNode in nodes: internalid = self._random_string() nodeinfo = {'internalid': internalid} addedNode.setCustomProperty(QlrManager.customPropertyName, internalid) if isinstance(addedNode, QgsLayerTreeGroup): nodeinfo['type'] = 'group' nodeinfo['name'] = addedNode.name() elif isinstance(addedNode, QgsLayerTreeLayer): nodeinfo['type'] = 'layer' nodeinfo['name'] = addedNode.layerName() nodeinfo['layerid'] = addedNode.layerId() nodeslist.append(nodeinfo) # Remove from parent node. Otherwise we cant add it to a new parent group.takeChild(addedNode) self.fileSystemItemToLegendNode[path] = nodeslist # Insert them into the main project QgsProject.instance().layerTreeRoot().insertChildNodes(0, nodes) return True except: # For now just return silently return False
def __add_layer_definition_file(self, file_name, root_group): """ shamelessly copied from https://github.com/qgis/QGIS/blob/master/src/core/qgslayerdefinition.cpp """ qfile = QFile(file_name) if not qfile.open(QIODevice.ReadOnly): return None doc = QDomDocument() if not doc.setContent(qfile): return None file_info = QFileInfo(qfile) QDir.setCurrent(file_info.absoluteDir().path()) root = QgsLayerTreeGroup() ids = doc.elementsByTagName('id') for i in range(0, ids.size()): id_node = ids.at(i) id_elem = id_node.toElement() old_id = id_elem.text() layer_name = old_id[:-17] date_time = QDateTime.currentDateTime() new_id = layer_name + date_time.toString('yyyyMMddhhmmsszzz') id_elem.firstChild().setNodeValue(new_id) tree_layer_nodes = doc.elementsByTagName('layer-tree-layer') for j in range(0, tree_layer_nodes.count()): layer_node = tree_layer_nodes.at(j) layer_elem = layer_node.toElement() if old_id == layer_elem.attribute('id'): layer_node.toElement().setAttribute('id', new_id) layer_tree_elem = doc.documentElement().firstChildElement( 'layer-tree-group') load_in_legend = True if not layer_tree_elem.isNull(): root.readChildrenFromXML(layer_tree_elem) load_in_legend = False layers = QgsMapLayer.fromLayerDefinition(doc) QgsProject.instance().addMapLayers(layers, load_in_legend) nodes = root.children() for node in nodes: root.takeChild(node) del root root_group.insertChildNodes(-1, nodes) return None
def __add_layer_definition_file(self, file_name, root_group): """ shamelessly copied from https://github.com/qgis/QGIS/blob/master/src/core/qgslayerdefinition.cpp """ qfile = QFile(file_name) if not qfile.open(QIODevice.ReadOnly): return None doc = QDomDocument() if not doc.setContent(qfile): return None file_info = QFileInfo(qfile) QDir.setCurrent(file_info.absoluteDir().path()) root = QgsLayerTreeGroup() ids = doc.elementsByTagName('id') for i in xrange(0, ids.size()): id_node = ids.at(i) id_elem = id_node.toElement() old_id = id_elem.text() layer_name = old_id[:-17] date_time = QDateTime.currentDateTime() new_id = layer_name + date_time.toString('yyyyMMddhhmmsszzz') id_elem.firstChild().setNodeValue(new_id) tree_layer_nodes = doc.elementsByTagName('layer-tree-layer') for j in xrange(0, tree_layer_nodes.count()): layer_node = tree_layer_nodes.at(j) layer_elem = layer_node.toElement() if old_id == layer_elem.attribute('id'): layer_node.toElement().setAttribute('id', new_id) layer_tree_elem = doc.documentElement().firstChildElement('layer-tree-group') load_in_legend = True if not layer_tree_elem.isNull(): root.readChildrenFromXML(layer_tree_elem) load_in_legend = False layers = QgsMapLayer.fromLayerDefinition(doc) QgsMapLayerRegistry.instance().addMapLayers(layers, load_in_legend) nodes = root.children() for node in nodes: root.takeChild(node) del root root_group.insertChildNodes(-1, nodes) return None
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()