def testCustomLayerOrderUpdatedFromProject(self): """ test that setting project layer order is reflected in custom layer order panel """ prj = QgsProject.instance() prj.clear() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) custom_order_widget = QgsCustomLayerOrderWidget(bridge) #custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2]) app.processEvents() self.assertEqual([l for l in prj.layerTreeRoot().customLayerOrder()], [layer3, layer, layer2]) # no custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(False) app.processEvents() self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer, layer2, layer3]) # mess around with the project layer order prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2]) app.processEvents() self.assertEqual(prj.layerTreeRoot().layerOrder(), [layer, layer2, layer3]) # try reordering through bridge prj.layerTreeRoot().setHasCustomLayerOrder(False) app.processEvents() self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer, layer2, layer3]) root = prj.layerTreeRoot() layer_node = root.findLayer(layer2) cloned_node = layer_node.clone() parent = layer_node.parent() parent.insertChildNode(0, cloned_node) parent.removeChildNode(layer_node) app.processEvents() # make sure project respects this self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer2, layer, layer3]) self.assertFalse(prj.layerTreeRoot().hasCustomLayerOrder())
def testLayerOrderUpdatedThroughBridge(self): """ test that project layer order is updated when layer tree changes """ prj = QgsProject.instance() prj.clear() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) #custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2]) app.processEvents() self.assertEqual([l for l in prj.layerTreeRoot().customLayerOrder()], [layer3, layer, layer2]) self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer3, layer, layer2]) # no custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(False) app.processEvents() self.assertEqual([l for l in prj.layerTreeRoot().customLayerOrder()], [layer3, layer, layer2]) self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer, layer2, layer3]) # mess around with the layer tree order root = prj.layerTreeRoot() layer_node = root.findLayer(layer2) cloned_node = layer_node.clone() parent = layer_node.parent() parent.insertChildNode(0, cloned_node) parent.removeChildNode(layer_node) app.processEvents() # make sure project respects this self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer2, layer, layer3]) # make sure project order includes ALL layers, not just visible ones layer_node = root.findLayer(layer) layer_node.setItemVisibilityChecked(False) app.processEvents() self.assertEqual([l for l in prj.layerTreeRoot().layerOrder()], [layer2, layer, layer3])
def make_pdf(xmin, ymin, xmax, ymax, filter_expression): canvas = QgsMapCanvas() # Load our project QgsProject.instance().read(QFileInfo(project_path)) # Set canvas extent canvas.setExtent(QgsRectangle(xmin, ymin, xmax, ymax)) # Load layers here if they are not already in the project for layer in QgsMapLayerRegistry.instance().mapLayers().values(): if layer.name() == 'data': lyr = layer break lyr.setSubsetString(filter_expression) # bridge used in standalone script: http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/loadproject.html bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), canvas) bridge.setCanvasLayers() # Check data providers load ok print('Provider List') print(QgsProviderRegistry.instance().providerList()) # Print layer validity - I've had some trouble with some wms layers for layer in QgsMapLayerRegistry.instance().mapLayers().values(): print(layer.name()) print(layer.isValid()) template_file = file(template_path) template_content = template_file.read() template_file.close() document = QDomDocument() document.setContent(template_content) composition = QgsComposition(canvas.mapSettings()) # You can use this to replace any string like this [key] # in the template with a new value. e.g. to replace # [date] pass a map like this {'date': '1 Jan 2012'} substitution_map = {'title': 'the title of my map'} composition.loadFromTemplate(document, substitution_map) # You must set the id in the template map_item = composition.getComposerItemById('Main Map') map_item.setMapCanvas(canvas) map_item.zoomToExtent(canvas.extent()) # You must set the id in the template legend_item = composition.getComposerItemById('Legend') legend_item.updateLegend() composition.refreshItems() composition.exportAsPDF('export.pdf') QgsProject.instance().clear()
def __init__(self, parent=None): super(MapWidget, self).__init__(parent) self.setupUi(self) self.canvas.setCanvasColor(Qt.white) self.canvas.enableAntiAliasing(True) self.canvas.setWheelAction(QgsMapCanvas.WheelZoomToMouseCursor) self.canvas.mapRenderer().setLabelingEngine(QgsPalLabeling()) self.style = QgsStyleV2.defaultStyle() self.styledlg = None self.bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), self.canvas) self.bridge.setAutoSetupOnFirstLayer(False) QgsProject.instance().writeProject.connect(self.bridge.writeProject) QgsProject.instance().readProject.connect(self.bridge.readProject) self.applyStyleButton.pressed.connect(self.apply_style)
def init_layerTree(self): self.layer_tree_view = QgsLayerTreeView(self) layout = QVBoxLayout(self.layerTreeWidget) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.layer_tree_view) model = QgsLayerTreeModel(QgsProject.instance().layerTreeRoot(), self) model.setFlag(QgsLayerTreeModel.AllowNodeRename) model.setFlag(QgsLayerTreeModel.AllowNodeReorder) model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility) model.setFlag(QgsLayerTreeModel.ShowLegendAsTree) model.setAutoCollapseLegendNodes(10) self.layer_tree_view.setModel(model) provider = MenuProvider(self.layer_tree_view, self.mapCanvas, self.project.instance()) self.layer_tree_view.setMenuProvider(provider) # 注意self.layer_tree_bridge必须有 self.layer_tree_bridge = QgsLayerTreeMapCanvasBridge( self.project.instance().layerTreeRoot(), self.mapCanvas)
def from_file(cls, filename, canvas, relative_base=None): """ Load a project file from a path. :param filename: The path to the project file. :param canvas: (optional) Passing a canvas will auto add layers to the canvas when the load is loaded. :param relative_base_path: (optional) Relative base path for the project file to load layers from :return: A Project object which wraps QgsProject.instance() """ QgsProject.instance().clear() bridge = None if canvas: bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), canvas) if relative_base is None: relative_base = os.path.dirname(filename) QDir.setCurrent(relative_base) QgsProject.instance().read(QFileInfo(filename)) if bridge: bridge.setCanvasLayers() return cls(bridge)
def testNonSpatialLayer(self): """ test that non spatial layers are not passed to canvas """ prj = QgsProject.instance() prj.clear() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") non_spatial = QgsVectorLayer("None?field=fldtxt:string", "non_spatial", "memory") prj.addMapLayers([layer, layer2, layer3, non_spatial]) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) #custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2]) app.processEvents() self.assertEqual(canvas.mapSettings().layers(), [layer3, layer, layer2]) # with non-spatial (should not be possible through ui, but is through api) prj.layerTreeRoot().setCustomLayerOrder( [layer3, layer, layer2, non_spatial]) app.processEvents() #self.assertEqual(canvas.mapSettings().layers(),[layer3,layer,layer2]) # no custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(False) app.processEvents() self.assertEqual(canvas.mapSettings().layers(), [layer, layer2, layer3])
def make_pdf(): canvas = QgsMapCanvas() # Load our project QgsProject.instance().read(QFileInfo(project_path)) bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), canvas) bridge.setCanvasLayers() if canvas.layerCount() < 1: print 'No layers loaded from this project, exiting.' return print canvas.mapSettings().extent().toString() template_file = file(template_path) template_content = template_file.read() template_file.close() document = QDomDocument() document.setContent(template_content) composition = QgsComposition(canvas.mapSettings()) # You can use this to replace any string like this [key] # in the template with a new value. e.g. to replace # [date] pass a map like this {'date': '1 Jan 2012'} substitution_map = { 'DATE_TIME_START': TIME_START, 'DATE_TIME_END': TIME_STOP } composition.loadFromTemplate(document, substitution_map) # You must set the id in the template map_item = composition.getComposerItemById('map') map_item.setMapCanvas(canvas) map_item.zoomToExtent(canvas.extent()) # You must set the id in the template legend_item = composition.getComposerItemById('legend') legend_item.updateLegend() composition.refreshItems() composition.exportAsPDF('/home/web/reports/pdf/%s/%s.pdf' % (TIME_SLICE, LABEL)) QgsProject.instance().clear()
def __init__(self, canvas): """Constructor :param canvas: """ QObject.__init__(self) self.canvas = canvas self.legend = QgisLegend(canvas) self.message_bar = QgsMessageBar(None) # Set up slots so we can mimic the behaviour of QGIS when layers # are added. LOGGER.debug('Initialising canvas...') # noinspection PyArgumentList QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayers) # noinspection PyArgumentList QgsMapLayerRegistry.instance().layerWasAdded.connect(self.addLayer) # noinspection PyArgumentList QgsMapLayerRegistry.instance().removeAll.connect(self.removeAllLayers) # For processing module self.destCrs = None # For keeping track of which layer is active in the legend. self.active_layer = None # In the next section of code, we are going to do some monkey patching # to make the QGIS processing framework think that this mock QGIS IFACE # instance is the actual one. It will also ensure that the processing # algorithms are nicely loaded and available for use. # Since QGIS > 2.0, the module is moved from QGisLayers to dataobjects # pylint: disable=F0401, E0611 if QGis.QGIS_VERSION_INT > 20001: # noinspection PyUnresolvedReferences from processing.tools import dataobjects else: # noinspection PyUnresolvedReferences from processing.core import QGisLayers as dataobjects # noinspection PyUnresolvedReferences import processing # noinspection PyUnresolvedReferences from processing.core.Processing import Processing # pylint: enable=F0401, E0611 processing.classFactory(self) # We create our own getAlgorithm function below which will will monkey # patch in to the Processing class in QGIS in order to ensure that the # Processing.initialize() call is made before asking for an alg. @staticmethod def mock_getAlgorithm(name): """ Modified version of the original getAlgorithm function. :param name: Name of the algorithm to load. :type name: str :return: An algorithm concrete class. :rtype: QgsAlgorithm ? """ Processing.initialize() for provider in Processing.algs.values(): if name in provider: return provider[name] return None # Now we let the monkey loose! Processing.getAlgorithm = mock_getAlgorithm # We also need to make dataobjects think that this iface is 'the one' # Note. the placement here (after the getAlgorithm monkey patch above) # is significant, so don't move it! dataobjects.iface = self # set up a layer tree bridge so that new added layers appear in legend self.layer_tree_root = QgsProject.instance().layerTreeRoot() self.bridge = QgsLayerTreeMapCanvasBridge(self.layer_tree_root, self.canvas) self.bridge.setCanvasLayers()
def __init__(self): super(MainWindow, self).__init__() self.setupUi(self) self.first_flag = True self.setWindowTitle('PyQGIS') # 调整窗口大小 self.resize(800, 600) # 初始化图层树 vl = QVBoxLayout(self.dockWidgetContents) self.layerTreeView = QgsLayerTreeView(self) vl.addWidget(self.layerTreeView) # 初始化地图画布 self.mapCanvas = QgsMapCanvas(self) hl = QHBoxLayout(self.frame) hl.setContentsMargins(0, 0, 0, 0) hl.addWidget(self.mapCanvas) # 建立桥梁 self.model = QgsLayerTreeModel(PROJECT.layerTreeRoot(), self) self.model.setFlag(QgsLayerTreeModel.AllowNodeRename) self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder) self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility) self.model.setFlag(QgsLayerTreeModel.ShowLegendAsTree) self.model.setAutoCollapseLegendNodes(10) self.layerTreeView.setModel(self.model) self.layerTreeBridge = QgsLayerTreeMapCanvasBridge( PROJECT.layerTreeRoot(), self.mapCanvas, self) # 显示经纬度 self.mapCanvas.xyCoordinates.connect(self.showLngLat) # 打开工程 self.actionOpen.triggered.connect(self.actionOpenTriggered) # 退出程序 self.actionQuit.triggered.connect(self.close) # 地图工具 # TODO:放大、缩小没有图标 self.actionPanTriggered() self.actionPan.triggered.connect(self.actionPanTriggered) self.actionZoomin.triggered.connect(self.actionZoomInTriggered) self.actionZoomout.triggered.connect(self.actionZoomOutTriggered) self.actionIdentity.triggered.connect(self.actionIdentifyTriggered) # 图层 self.actionShapefile.triggered.connect(self.actionShapefileTriggered) self.actionCsv.triggered.connect(self.actionCsvTriggered) self.actionPostGIS.triggered.connect(self.actionPostGISTriggered) self.actionWFS.triggered.connect(self.actionWFSTriggered) self.actionGeotiff.triggered.connect(self.actionGeotiffTriggered) self.actionXYZ.triggered.connect(self.actionXYZTriggered) # 绘图工具 self.actionPoint.triggered.connect(self.actionPointTriggered) self.actionLine.triggered.connect(self.actionLineTriggered) self.actionRectangle.triggered.connect(self.actionRectangleTriggered) self.actionPolygon.triggered.connect(self.actionPolygonTriggered) # 关于Qt self.actionAboutQt.triggered.connect( lambda: QMessageBox.aboutQt(self, '关于Qt')) self.actionAbout.triggered.connect( lambda: QMessageBox.about(self, '关于', 'PyQGIS二次开发')) # self.actionPan.triggered.connect(self.actionPanTriggered) # self.actionIdentify.triggered.connect(self.actionIdentifyTriggered) # 图层右键菜单 self.customMenuProvider = CustomMenuProvider(self.layerTreeView, self.mapCanvas) self.layerTreeView.setMenuProvider(self.customMenuProvider)
def print_atlas(project, layout_name, feature_filter, scales=None, scale=None): """Generate an atlas. :param project: The project to render as atlas. :type project: QgsProject :param layout_name: Name of the layout. :type layout_name: basestring :param feature_filter: QGIS Expression to use to select the feature. It can return many features, a multiple pages PDF will be returned. :type feature_filter: basestring :param scale: A scale to force in the atlas context. Default to None. :type scale: int :param scales: A list of predefined list of scales to force in the atlas context. Default to None. :type scales: list :return: Path to the PDF. :rtype: basestring """ canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas) bridge.setCanvasLayers() manager = project.layoutManager() master_layout = manager.layoutByName(layout_name) if not master_layout: raise AtlasPrintException('Layout not found') if master_layout.layoutType() != QgsMasterLayoutInterface.PrintLayout: raise AtlasPrintException('The layout is not a print layout') for l in manager.printLayouts(): if l.name() == layout_name: layout = l break else: raise AtlasPrintException('The layout is not found') atlas = layout.atlas() if not atlas.enabled(): raise AtlasPrintException('The layout is not enabled for an atlas') settings = QgsLayoutExporter.PdfExportSettings() if scale: layout.referenceMap().setAtlasScalingMode(QgsLayoutItemMap.Fixed) layout.referenceMap().setScale(scale) if scales: layout.referenceMap().setAtlasScalingMode(QgsLayoutItemMap.Predefined) if Qgis.QGIS_VERSION_INT >= 30900: settings.predefinedMapScales = scales else: layout.reportContext().setPredefinedScales(scales) layer = atlas.coverageLayer() feature_filter = optimize_expression(layer, feature_filter) expression = QgsExpression(feature_filter) if expression.hasParserError(): raise AtlasPrintException( 'Expression is invalid, parser error: {}'.format( expression.parserErrorString())) context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(project)) context.appendScope(QgsExpressionContextUtils.layoutScope(layout)) context.appendScope(QgsExpressionContextUtils.atlasScope(atlas)) context.appendScope(QgsExpressionContextUtils.layerScope(layer)) expression.prepare(context) if expression.hasEvalError(): raise AtlasPrintException( 'Expression is invalid, eval error: {}'.format( expression.evalErrorString())) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) if not scales and layout.referenceMap().atlasScalingMode( ) == QgsLayoutItemMap.Predefined: if Qgis.QGIS_VERSION_INT >= 30900: use_project = project.useProjectScales() map_scales = project.mapScales() else: map_scales = project_scales(project) use_project = len(map_scales) == 0 if not use_project or len(map_scales) == 0: QgsMessageLog.logMessage( 'Map scales not found in project, fetching predefined map scales in global config', 'atlasprint', Qgis.Info) map_scales = global_scales() if Qgis.QGIS_VERSION_INT >= 30900: settings.predefinedMapScales = map_scales else: layout.reportContext().setPredefinedScales(map_scales) export_path = os.path.join(tempfile.gettempdir(), '{}_{}.pdf'.format(layout_name, uuid4())) exporter = QgsLayoutExporter(layout) result = exporter.exportToPdf(atlas, export_path, settings) if result[0] != QgsLayoutExporter.Success and not os.path.isfile( export_path): raise Exception('export not generated {}'.format(export_path)) return export_path
) gui_flag = True app = QgsApplication(sys.argv, True) QgsApplication.setPrefixPath("/usr", True) QgsApplication.initQgis() project_path = 'report_maps.qgs' template_path = 'owner_occupancy.qpt' canvas = QgsMapCanvas() canvas.resize(QSize(1450, 850)) #start = time.time() QgsProject.instance().read(QFileInfo(project_path)) #end = time.time() root = QgsProject.instance().layerTreeRoot() bridge = QgsLayerTreeMapCanvasBridge(root, canvas) bridge.setCanvasLayers() registry = QgsMapLayerRegistry.instance() template_file = file(template_path) template_content = template_file.read() template_file.close() document = QDomDocument() document.setContent(template_content) map_settings = canvas.mapSettings() composition = QgsComposition(map_settings) #start = time.time() composition.loadFromTemplate(document) #end = time.time() #create list of all layers currently in the map
def print_atlas(project_path, composer_name, predefined_scales, feature_filter, page_name_expression=None): if not feature_filter: QgsMessageLog.logMessage("atlasprint: NO feature_filter provided !", 'atlasprint', Qgis.Critical) return None # Get composer from project # in QGIS 2, we can't get composers without iface # so we reading project xml and extract composer # TODO Since QGIS 3.0, we should be able to use project layoutManager() # noinspection PyPep8Naming from xml.etree import ElementTree as ET composer_xml = None with open(project_path, 'r') as f: tree = ET.parse(f) for elem in tree.findall('.//Composer[@title="%s"]' % composer_name): composer_xml = ET.tostring( elem, encoding='utf8', method='xml' ) if not composer_xml: for elem in tree.findall('.//Layout[@name="%s"]' % composer_name): composer_xml = ET.tostring( elem, encoding='utf8', method='xml' ) if not composer_xml: QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !", 'atlasprint', Qgis.Critical) return None document = QDomDocument() document.setContent(composer_xml) # Get canvas, map setting & instantiate composition canvas = QgsMapCanvas() project = QgsProject() project.read(project_path) bridge = QgsLayerTreeMapCanvasBridge( project.layerTreeRoot(), canvas ) bridge.setCanvasLayers() layout = QgsPrintLayout(project) # Load content from XML layout.loadFromTemplate( document, QgsReadWriteContext(), ) atlas = layout.atlas() atlas.setEnabled(True) atlas_map = layout.referenceMap() atlas_map.setAtlasDriven(True) atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Predefined) layout.reportContext().setPredefinedScales(predefined_scales) if page_name_expression: atlas.setPageNameExpression(page_name_expression) # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas) coverage_layer = atlas.coverageLayer() # Filter by FID as QGIS cannot compile expressions with $id or other $ vars # which leads to bad performance for big dataset use_fid = None if '$id' in feature_filter: import re ids = list(map(int, re.findall(r'\d+', feature_filter))) if len(ids) > 0: use_fid = ids[0] if use_fid: qReq = QgsFeatureRequest().setFilterFid(use_fid) else: qReq = QgsFeatureRequest().setFilterExpression(feature_filter) # Change feature_filter in order to improve performance pks = coverage_layer.dataProvider().pkAttributeIndexes() if use_fid and len(pks) == 1: pk = coverage_layer.dataProvider().fields()[pks[0]].name() feature_filter = '"%s" IN (%s)' % (pk, use_fid) QgsMessageLog.logMessage("atlasprint: feature_filter changed into: %s" % feature_filter, 'atlasprint', Qgis.Info) qReq = QgsFeatureRequest().setFilterExpression(feature_filter) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) uid = uuid4() i = 0 # We use a single page for now. atlas.beginRender() atlas.seekTo(i) # setup settings settings = QgsLayoutExporter.PdfExportSettings() export_path = os.path.join( tempfile.gettempdir(), '%s_%s.pdf' % (atlas.nameForPage(i), uid) ) exporter = QgsLayoutExporter(layout) result = exporter.exportToPdf(export_path, settings) atlas.endRender() if result != QgsLayoutExporter.Success: QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical) return None if not os.path.isfile(export_path): QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical) return None QgsMessageLog.logMessage("atlasprint: path generated %s" % export_path, 'atlasprint', Qgis.Success) return export_path
def setBridge(self, canvas): ltg = self.model.rootGroup() self.bridge = QgsLayerTreeMapCanvasBridge( ltg, canvas) # Need wait populate ltg
if "-D" in sys.argv: target_dir = sys.argv[sys.argv.index("-D") + 1] if "-O" in sys.argv: output_log = sys.argv[sys.argv.index("-O") + 1] # Instantiate QGIS QgsApplication.setPrefixPath(qgisPrefixPath, True) qgs = QgsApplication([], True) QgsApplication.initQgis() # Open the project p = QgsProject() p.read(project_path) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge( p.layerTreeRoot(), canvas ) bridge.setCanvasLayers() # Get the layers in the project layerList = p.mapLayersByName(parcelle_layer) if not layerList: layers = p.mapLayers() for lname, layer in layers.items(): print(lname + ' ' + layer.name() + ' ' + parcelle_layer) layerList = [layer for lname, layer in layers.items() if layer.name() == parcelle_layer] layer = layerList[0] # Get Feature req = QgsFeatureRequest() req.setFilterExpression(' "geo_parcelle" = \'%s\' ' % parcelle_id)
def __init__(self, parent=None): super(MapWidget, self).__init__(parent) self.setupUi(self) self.snapping = True icon = roam_style.iconsize() self.projecttoolbar.setIconSize(QSize(icon, icon)) self.defaultextent = None self.current_form = None self.last_form = None self.layerbuttons = [] self.editfeaturestack = [] self.lastgpsposition = None self.project = None self.gps = None self.gpslogging = None self.selectionbands = defaultdict(partial(QgsRubberBand, self.canvas)) self.bridge = QgsLayerTreeMapCanvasBridge( QgsProject.instance().layerTreeRoot(), self.canvas) self.bridge.setAutoSetupOnFirstLayer(False) self.canvas.setCanvasColor(Qt.white) self.canvas.enableAntiAliasing(True) self.snappingutils = SnappingUtils(self.canvas, self) self.canvas.setSnappingUtils(self.snappingutils) threadcount = QThread.idealThreadCount() threadcount = 2 if threadcount > 2 else 1 QgsApplication.setMaxThreads(threadcount) self.canvas.setParallelRenderingEnabled(True) self.canvas.setFrameStyle(QFrame.NoFrame) self.editgroup = QActionGroup(self) self.editgroup.setExclusive(True) self.editgroup.addAction(self.actionPan) self.editgroup.addAction(self.actionZoom_In) self.editgroup.addAction(self.actionZoom_Out) self.editgroup.addAction(self.actionInfo) self.actionGPS = GPSAction(self.canvas, self) self.projecttoolbar.addAction(self.actionGPS) if roam.config.settings.get('north_arrow', False): self.northarrow = NorthArrow(":/icons/north", self.canvas) self.northarrow.setPos(10, 10) self.canvas.scene().addItem(self.northarrow) smallmode = roam.config.settings.get("smallmode", False) self.projecttoolbar.setSmallMode(smallmode) self.projecttoolbar.setContextMenuPolicy(Qt.CustomContextMenu) gpsspacewidget = QWidget() gpsspacewidget.setMinimumWidth(30) gpsspacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.topspaceraction = self.projecttoolbar.insertWidget( self.actionGPS, gpsspacewidget) self.dataentryselection = QAction(self.projecttoolbar) self.dataentryaction = self.projecttoolbar.insertAction( self.topspaceraction, self.dataentryselection) self.dataentryselection.triggered.connect(self.select_data_entry) self.gpsMarker = GPSMarker(self.canvas) self.gpsMarker.hide() self.currentfeatureband = CurrentSelection(self.canvas) self.currentfeatureband.setIconSize(30) self.currentfeatureband.setWidth(10) self.currentfeatureband.setColor(QColor(88, 64, 173, 50)) self.currentfeatureband.setOutlineColour(QColor(88, 64, 173)) self.gpsband = QgsRubberBand(self.canvas) self.gpsband.setColor(QColor(165, 111, 212, 75)) self.gpsband.setWidth(5) RoamEvents.refresh_map.connect(self.refresh_map) RoamEvents.editgeometry.connect(self.queue_feature_for_edit) RoamEvents.selectioncleared.connect(self.clear_selection) RoamEvents.selectionchanged.connect(self.highlight_selection) RoamEvents.openfeatureform.connect(self.feature_form_loaded) RoamEvents.sync_complete.connect(self.refresh_map) RoamEvents.snappingChanged.connect(self.snapping_changed) self.snappingbutton = QToolButton() self.snappingbutton.setText("Snapping: On") self.snappingbutton.setAutoRaise(True) self.snappingbutton.pressed.connect(self.toggle_snapping) spacer = QWidget() spacer2 = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.scalewidget = QgsScaleComboBox() self.scalebutton = QToolButton() self.scalebutton.setAutoRaise(True) self.scalebutton.setMaximumHeight(self.statusbar.height()) self.scalebutton.pressed.connect(self.selectscale) self.scalebutton.setText("Scale") self.scalelist = BigList(parent=self.canvas, centeronparent=True, showsave=False) self.scalelist.hide() self.scalelist.setlabel("Map Scale") self.scalelist.setmodel(self.scalewidget.model()) self.scalelist.closewidget.connect(self.scalelist.close) self.scalelist.itemselected.connect(self.update_scale_from_item) self.scalelist.itemselected.connect(self.scalelist.close) self.positionlabel = QLabel('') self.gpslabel = QLabel("GPS: Not active") self.gpslabelposition = QLabel("") self.statusbar.addWidget(self.snappingbutton) self.statusbar.addWidget(spacer2) self.statusbar.addWidget(self.gpslabel) self.statusbar.addWidget(self.gpslabelposition) self.statusbar.addPermanentWidget(self.scalebutton) self.canvas.extentsChanged.connect(self.update_status_label) self.canvas.scaleChanged.connect(self.update_status_label) self.connectButtons() scalebar_enabled = roam.config.settings.get('scale_bar', False) self.scalebar_enabled = False if scalebar_enabled: roam.utils.warning( "Unsupported feature: Scale bar support not ported to QGIS 3 API yet." ) RoamEvents.raisemessage( "Unsupported feature", "Scale bar support not ported to QGIS 3 API yet", level=RoamEvents.CRITICAL) self.scalebar_enabled = False
def print_atlas(self, project_path, composer_name, predefined_scales, feature_filter=None, page_name_expression=None): if not feature_filter: QgsMessageLog.logMessage( "atlasprint: NO feature_filter provided !") return None # Get composer from project # in QGIS 2, canno get composers without iface # so we reading project xml and extract composer # in QGIS 3.0, we will use project layoutManager() from xml.etree import ElementTree as ET composer_xml = None with open(project_path, 'r') as f: tree = ET.parse(f) for elem in tree.findall('.//Composer[@title="%s"]' % composer_name): composer_xml = ET.tostring(elem, encoding='utf8', method='xml') if not composer_xml: QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !") return None document = QDomDocument() document.setContent(composer_xml) # Get canvas, map setting & instantiate composition canvas = QgsMapCanvas() QgsProject.instance().read(QFileInfo(project_path)) bridge = QgsLayerTreeMapCanvasBridge( QgsProject.instance().layerTreeRoot(), canvas) bridge.setCanvasLayers() ms = canvas.mapSettings() composition = QgsComposition(ms) # Load content from XML substitution_map = {} composition.loadFromTemplate(document, substitution_map) # Get atlas for this composition atlas = composition.atlasComposition() atlas.setEnabled(True) atlas_map = composition.getComposerMapById(0) atlas_map.setAtlasScalingMode(QgsComposerMap.Predefined) # get project scales atlas.setPredefinedScales(predefined_scales) atlas_map.setAtlasDriven(True) #atlas.setComposerMap(atlas_map) if page_name_expression: atlas.setPageNameExpression(page_name_expression) # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas) coverageLayer = atlas.coverageLayer() # Filter by FID as QGIS cannot compile expressions with $id or other $ vars # which leads to bad perfs for big datasets useFid = None if '$id' in feature_filter: import re ids = map(int, re.findall(r'\d+', feature_filter)) if len(ids) > 0: useFid = ids[0] if useFid: qReq = QgsFeatureRequest().setFilterFid(useFid) else: qReq = QgsFeatureRequest().setFilterExpression(feature_filter) # Change feature_filter in order to improve perfs pks = coverageLayer.dataProvider().pkAttributeIndexes() if useFid and len(pks) == 1: pk = coverageLayer.dataProvider().fields()[pks[0]].name() feature_filter = '"%s" IN (%s)' % (pk, useFid) QgsMessageLog.logMessage( "atlasprint: feature_filter changed into: %s" % feature_filter) qReq = QgsFeatureRequest().setFilterExpression(feature_filter) atlas.setFilterFeatures(True) atlas.setFeatureFilter(feature_filter) uid = uuid4() i = 0 # Set Atlas mode composition.setAtlasMode(QgsComposition.ExportAtlas) atlas.beginRender() for feat in coverageLayer.getFeatures(qReq): atlas.prepareForFeature(feat) export_path = os.path.join( tempfile.gettempdir(), '%s_%s.pdf' % (atlas.nameForPage(i), uid)) exported = composition.exportAsPDF(export_path) if not exported or not os.path.isfile(export_path): QgsMessageLog.logMessage( "atlasprint: An error occured while exporting the atlas !") return None break atlas.endRender() if os.path.isfile(export_path): QgsMessageLog.logMessage("atlasprint: path generated %s" % export_path) return export_path
def print_atlas(self, project_path, composer_name, predefined_scales, feature_filter=None, page_name_expression=None): # Get composer from project # in QGIS 2, canno get composers without iface # so we reading project xml and extract composer # in QGIS 3.0, we will use project layoutManager() from xml.etree import ElementTree as ET composer_xml = None with open(project_path, 'r') as f: tree = ET.parse(f) for elem in tree.findall('.//Composer[@title="%s"]' % composer_name): composer_xml = ET.tostring(elem, encoding='utf8', method='xml') if not composer_xml: return document = QDomDocument() document.setContent(composer_xml) # Get canvas, map setting & instantiate composition canvas = QgsMapCanvas() QgsProject.instance().read(QFileInfo(project_path)) bridge = QgsLayerTreeMapCanvasBridge( QgsProject.instance().layerTreeRoot(), canvas) bridge.setCanvasLayers() ms = canvas.mapSettings() composition = QgsComposition(ms) # Load content from XML substitution_map = {} composition.loadFromTemplate(document, substitution_map) # Get atlas for this composition atlas = composition.atlasComposition() atlas.setEnabled(True) atlas_map = composition.getComposerMapById(0) atlas_map.setAtlasScalingMode(QgsComposerMap.Predefined) # get project scales atlas.setPredefinedScales(predefined_scales) atlas.setComposerMap(atlas_map) #on definit le filtre if feature_filter: atlas.setFilterFeatures(True) atlas.setFeatureFilter(feature_filter) if page_name_expression: atlas.setPageNameExpression(page_name_expression) # Set atlas mode composition.setAtlasMode(QgsComposition.ExportAtlas) # Generate atlas atlas.beginRender() uid = uuid4() for i in range(0, atlas.numFeatures()): atlas.prepareForFeature(i) export_path = os.path.join( tempfile.gettempdir(), '%s_%s.pdf' % (atlas.nameForPage(i), uid)) exported = composition.exportAsPDF(export_path) if not exported or not os.path.isfile(export_path): return None break atlas.endRender() return export_path
#!/usr/bin/python2 from qgis.core import QgsProject from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge from qgis.core.contextmanagers import qgisapp from PyQt4.QtCore import QFileInfo with qgisapp(): # note that this must be an absolute path project_path = '/home/davefm/Documents/Teaching/Postgrad/BSG Windsor/Python_for_Managing_Your_Data/examples/QGIS_examples/TEST.qgs' canvas = QgsMapCanvas(None) # will reparent it to widget via layout # load the project bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), canvas) QgsProject.instance().read(QFileInfo(project_path)) # and show the canvas canvas.show()
def print_layout(project, layout_name, feature_filter: str = None, scales=None, scale=None, **kwargs): """Generate a PDF for an atlas or a report. :param project: The QGIS project. :type project: QgsProject :param layout_name: Name of the layout of the atlas or report. :type layout_name: basestring :param feature_filter: QGIS Expression to use to select the feature. It can return many features, a multiple pages PDF will be returned. This is required to print atlas, not report :type feature_filter: basestring :param scale: A scale to force in the atlas context. Default to None. :type scale: int :param scales: A list of predefined list of scales to force in the atlas context. Default to None. :type scales: list :return: Path to the PDF. :rtype: basestring """ canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas) bridge.setCanvasLayers() manager = project.layoutManager() master_layout = manager.layoutByName(layout_name) settings = QgsLayoutExporter.PdfExportSettings() atlas = None atlas_layout = None report_layout = None logger = Logger() if not master_layout: raise AtlasPrintException('Layout `{}` not found'.format(layout_name)) if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout: for _print_layout in manager.printLayouts(): if _print_layout.name() == layout_name: atlas_layout = _print_layout break atlas = atlas_layout.atlas() if not atlas.enabled(): raise AtlasPrintException('The layout is not enabled for an atlas') layer = atlas.coverageLayer() if feature_filter is None: raise AtlasPrintException( 'EXP_FILTER is mandatory to print an atlas layout') feature_filter = optimize_expression(layer, feature_filter) expression = QgsExpression(feature_filter) if expression.hasParserError(): raise AtlasPrintException( 'Expression is invalid, parser error: {}'.format( expression.parserErrorString())) context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(project)) context.appendScope( QgsExpressionContextUtils.layoutScope(atlas_layout)) context.appendScope(QgsExpressionContextUtils.atlasScope(atlas)) context.appendScope(QgsExpressionContextUtils.layerScope(layer)) expression.prepare(context) if expression.hasEvalError(): raise AtlasPrintException( 'Expression is invalid, eval error: {}'.format( expression.evalErrorString())) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) if scale: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Fixed) atlas_layout.referenceMap().setScale(scale) if scales: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Predefined) if Qgis.QGIS_VERSION_INT >= 30900: settings.predefinedMapScales = scales else: atlas_layout.reportContext().setPredefinedScales(scales) if not scales and atlas_layout.referenceMap().atlasScalingMode( ) == QgsLayoutItemMap.Predefined: if Qgis.QGIS_VERSION_INT >= 30900: use_project = project.useProjectScales() map_scales = project.mapScales() else: map_scales = project_scales(project) use_project = len(map_scales) == 0 if not use_project or len(map_scales) == 0: logger.info( 'Map scales not found in project, fetching predefined map scales in global config' ) map_scales = global_scales() if Qgis.QGIS_VERSION_INT >= 30900: settings.predefinedMapScales = map_scales else: atlas_layout.reportContext().setPredefinedScales(map_scales) elif master_layout.layoutType() == QgsMasterLayoutInterface.Report: report_layout = master_layout else: raise AtlasPrintException('The layout is not supported by the plugin') for key, value in kwargs.items(): found = False if atlas_layout: item = atlas_layout.itemById(key.lower()) if isinstance(item, QgsLayoutItemLabel): item.setText(value) found = True logger.info( 'Additional parameters: {} found in layout {}, value {}'.format( key, found, value)) export_path = os.path.join(tempfile.gettempdir(), '{}_{}.pdf'.format(layout_name, uuid4())) result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout, export_path, settings) if result != QgsLayoutExporter.Success and not os.path.isfile(export_path): raise Exception('export not generated {} ({})'.format( export_path, error)) return export_path
def print_layout( project: QgsProject, layout_name: str, output_format: OutputFormat, feature_filter: str = None, scales: list = None, scale: int = None, **kwargs, ): """Generate a PDF for an atlas or a report. :param project: The QGIS project. :type project: QgsProject :param layout_name: Name of the layout of the atlas or report. :type layout_name: basestring :param feature_filter: QGIS Expression to use to select the feature. It can return many features, a multiple pages PDF will be returned. This is required to print atlas, not report :type feature_filter: basestring :param scale: A scale to force in the atlas context. Default to None. :type scale: int :param scales: A list of predefined list of scales to force in the atlas context. Default to None. :type scales: list :param output_format: The output format, default to PDF if not provided. :return: Path to the PDF. :rtype: basestring """ canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas) bridge.setCanvasLayers() manager = project.layoutManager() master_layout = manager.layoutByName(layout_name) if output_format == OutputFormat.Svg: settings = QgsLayoutExporter.SvgExportSettings() elif output_format in (OutputFormat.Png, OutputFormat.Jpeg): settings = QgsLayoutExporter.ImageExportSettings() else: # PDF by default settings = QgsLayoutExporter.PdfExportSettings() atlas = None atlas_layout = None report_layout = None logger = Logger() if not master_layout: raise AtlasPrintException("Layout `{}` not found".format(layout_name)) if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout: for _print_layout in manager.printLayouts(): if _print_layout.name() == layout_name: atlas_layout = _print_layout break atlas = atlas_layout.atlas() if not atlas.enabled(): raise AtlasPrintException("The layout is not enabled for an atlas") layer = atlas.coverageLayer() if feature_filter is None: raise AtlasPrintException( "EXP_FILTER is mandatory to print an atlas layout") feature_filter = optimize_expression(layer, feature_filter) expression = QgsExpression(feature_filter) if expression.hasParserError(): raise AtlasPrintException( "Expression is invalid, parser error: {}".format( expression.parserErrorString())) context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(project)) context.appendScope( QgsExpressionContextUtils.layoutScope(atlas_layout)) context.appendScope(QgsExpressionContextUtils.atlasScope(atlas)) context.appendScope(QgsExpressionContextUtils.layerScope(layer)) expression.prepare(context) if expression.hasEvalError(): raise AtlasPrintException( "Expression is invalid, eval error: {}".format( expression.evalErrorString())) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) atlas.updateFeatures() if scale: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Fixed) atlas_layout.referenceMap().setScale(scale) if scales: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Predefined) settings.predefinedMapScales = scales if (not scales and atlas_layout.referenceMap().atlasScalingMode() == QgsLayoutItemMap.Predefined): use_project = project.useProjectScales() map_scales = project.mapScales() if not use_project or len(map_scales) == 0: logger.info( "Map scales not found in project, fetching predefined map scales in global config" ) map_scales = global_scales() settings.predefinedMapScales = map_scales elif master_layout.layoutType() == QgsMasterLayoutInterface.Report: report_layout = master_layout else: raise AtlasPrintException("The layout is not supported by the plugin") for key, value in kwargs.items(): found = False if atlas_layout: item = atlas_layout.itemById(key.lower()) if isinstance(item, QgsLayoutItemLabel): item.setText(value) found = True logger.info( 'Additional parameters "{key}" {found} in layout, value "{value}"'. format(key=key, found="found" if found else "not found", value=value)) file_name = "{}_{}.{}".format(clean_string(layout_name), uuid4(), output_format.name.lower()) export_path = Path(tempfile.gettempdir()).joinpath(file_name) Logger().info("Exporting the request in {} using {}".format( export_path, output_format.value)) if output_format in (OutputFormat.Png, OutputFormat.Jpeg): exporter = QgsLayoutExporter(atlas_layout or report_layout) result = exporter.exportToImage(str(export_path), settings) error = result_message(result) elif output_format in (OutputFormat.Svg, ): exporter = QgsLayoutExporter(atlas_layout or report_layout) result = exporter.exportToSvg(str(export_path), settings) error = result_message(result) else: # Default to PDF result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout, str(export_path), settings) # Let's override error message _ = error error = result_message(result) if result != QgsLayoutExporter.Success: raise Exception("Export not generated in QGIS exporter {} : {}".format( export_path, error)) if not export_path.is_file(): logger.warning( "No error from QGIS Exporter, but the file does not exist.\n" "Message from QGIS exporter : {}\n" "File path : {}\n".format(error, export_path)) raise Exception( "Export OK from QGIS, but file not found on the file system : {}". format(export_path)) return export_path
def testMasterLayerOrder(self): """ test master layer order""" prj = QgsProject.instance() prj.clear() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer2, layer]) prj.layerTreeRoot().setCustomLayerOrder([layer, layer2, layer3]) # make some themes... theme1 = QgsMapThemeCollection.MapThemeRecord() theme1.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3), QgsMapThemeCollection.MapThemeLayerRecord(layer)]) theme2 = QgsMapThemeCollection.MapThemeRecord() theme2.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer3), QgsMapThemeCollection.MapThemeLayerRecord(layer2), QgsMapThemeCollection.MapThemeLayerRecord(layer)]) theme3 = QgsMapThemeCollection.MapThemeRecord() theme3.setLayerRecords([QgsMapThemeCollection.MapThemeLayerRecord(layer2), QgsMapThemeCollection.MapThemeLayerRecord(layer)]) prj.mapThemeCollection().insert('theme1', theme1) prj.mapThemeCollection().insert('theme2', theme2) prj.mapThemeCollection().insert('theme3', theme3) #order of layers in theme should respect master order self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2]) # also check ids! self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer.id(), layer2.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()]) # reset master order prj.layerTreeRoot().setCustomLayerOrder([layer2, layer3, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer3, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer2, layer3, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer2, layer]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer3.id(), layer.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer2.id(), layer3.id(), layer.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer2.id(), layer.id()]) # check that layers include those hidden in the layer tree canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) root = prj.layerTreeRoot() layer_node = root.findLayer(layer2.id()) layer_node.setItemVisibilityChecked(False) app.processEvents() prj.layerTreeRoot().setHasCustomLayerOrder(False) self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer, layer2, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer.id(), layer2.id(), layer3.id()]) self.assertEqual(prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()])
def initGui(self): icon = QIcon() icon.addPixmap( QPixmap( "C:/Roberto/Visual_Studio_Code/GisBike/programa/IMG/Qgis.png"), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.setWindowModality(Qt.WindowModal) self.setWindowFlags(Qt.Window | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) self.resize(1200, 600) self.verticalLayout_2 = QVBoxLayout(self) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Horizontal) self.actionZoomIn = QPushButton("Zoom in", self.splitter) self.actionZoomOut = QPushButton("Zoom out", self.splitter) self.actionPan = QPushButton("Pan", self.splitter) self.actionFile = QPushButton("File", self.splitter) self.project = QgsProject.instance() self.project.read('C:/Users/Fcc/Desktop/QGis/pruebas2.qgz') self.root = QgsProject.instance().layerTreeRoot() self.bridge = QgsLayerTreeMapCanvasBridge(self.root, self.canvas) self.bridge.setCanvasLayers() self.bridge.setAutoSetupOnFirstLayer(True) #https://gis.stackexchange.com/questions/141516/adding-legend-to-canvas-in-standalone-pyqgis-application self.model = QgsLayerTreeModel(self.root) self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder) self.model.setFlag(QgsLayerTreeModel.AllowNodeRename) self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility) self.model.setFlag(QgsLayerTreeModel.ShowLegend) self.view = QgsLayerTreeView(self.splitter) self.view.setModel(self.model) self.view.setFixedWidth(150) #self.view.resize(150,600) self.widget = QWidget(self.splitter) self.verticalLayout = QVBoxLayout(self.widget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.addWidget(self.actionZoomIn) self.horizontalLayout.addWidget(self.actionZoomOut) self.horizontalLayout.addWidget(self.actionPan) self.horizontalLayout.addWidget(self.actionFile) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addWidget(self.canvas) self.verticalLayout_2.addWidget(self.splitter) self.actionZoomIn.clicked.connect(self.zoomIn) self.actionZoomOut.clicked.connect(self.zoomOut) self.actionPan.clicked.connect(self.pan) self.actionFile.clicked.connect(self.file) # create the map tools self.toolPan = QgsMapToolPan(self.canvas) self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out