def test_layerDefinitionRewriteId(self): tmpfile = os.path.join(tempfile.tempdir, "test.qlr") ltr = QgsProject.instance().layerTreeRoot() self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) QgsLayerDefinition.exportLayerDefinition(tmpfile, [ltr]) grp = ltr.addGroup("imported") QgsLayerDefinition.loadLayerDefinition(tmpfile, QgsProject.instance(), grp) newPointsLayer = None newLinesLayer = None for l in grp.findLayers(): if l.layerId().startswith('points'): newPointsLayer = l.layer() elif l.layerId().startswith('lines'): newLinesLayer = l.layer() self.assertIsNotNone(newPointsLayer) self.assertIsNotNone(newLinesLayer) self.assertTrue(newLinesLayer.id( ) in [dep.layerId() for dep in newPointsLayer.dependencies()]) self.pointsLayer.setDependencies([])
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 testVectorAndRaster(self): # Load a simple QLR containing a vector layer and a raster layer. QgsProject.instance().removeAllMapLayers() layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 0) (result, errMsg) = QgsLayerDefinition.loadLayerDefinition(TEST_DATA_DIR + '/vector_and_raster.qlr', QgsProject.instance(), QgsProject.instance().layerTreeRoot()) self.assertTrue(result) layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 2) QgsProject.instance().removeAllMapLayers()
def testVectorAndRaster(self): # Load a simple QLR containing a vector layer and a raster layer. QgsProject.instance().removeAllMapLayers() layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 0) (result, errMsg) = QgsLayerDefinition.loadLayerDefinition(TEST_DATA_DIR + '/vector_and_raster.qlr', QgsProject.instance(), QgsProject.instance().layerTreeRoot()) self.assertTrue(result) layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 2) QgsProject.instance().removeAllMapLayers()
def testInvalidSource(self): # Load a QLR containing a vector layer with a broken path QgsProject.instance().removeAllMapLayers() layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 0) (result, errMsg) = QgsLayerDefinition.loadLayerDefinition(TEST_DATA_DIR + '/invalid_source.qlr', QgsProject.instance(), QgsProject.instance().layerTreeRoot()) self.assertTrue(result) self.assertFalse(errMsg) layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 1) self.assertFalse(list(layers.values())[0].isValid()) QgsProject.instance().removeAllMapLayers()
def testInvalidSource(self): # Load a QLR containing a vector layer with a broken path QgsProject.instance().removeAllMapLayers() layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 0) (result, errMsg) = QgsLayerDefinition.loadLayerDefinition(TEST_DATA_DIR + '/invalid_source.qlr', QgsProject.instance(), QgsProject.instance().layerTreeRoot()) self.assertTrue(result) self.assertFalse(errMsg) layers = QgsProject.instance().mapLayers() self.assertEqual(len(layers), 1) self.assertFalse(list(layers.values())[0].isValid()) QgsProject.instance().removeAllMapLayers()
def test_layerDefinitionRewriteId(self): tmpfile = os.path.join(tempfile.tempdir, "test.qlr") ltr = QgsProject.instance().layerTreeRoot() self.pointsLayer.setDependencies([QgsMapLayerDependency(self.linesLayer.id())]) QgsLayerDefinition.exportLayerDefinition(tmpfile, [ltr]) grp = ltr.addGroup("imported") QgsLayerDefinition.loadLayerDefinition(tmpfile, grp) newPointsLayer = None newLinesLayer = None for l in grp.findLayers(): if l.layerId().startswith('points'): newPointsLayer = l.layer() elif l.layerId().startswith('lines'): newLinesLayer = l.layer() self.assertFalse(newPointsLayer is None) self.assertFalse(newLinesLayer is None) self.assertTrue(newLinesLayer.id() in [dep.layerId() for dep in newPointsLayer.dependencies()]) self.pointsLayer.setDependencies([])
def paste(self): bNoClipboardData = False clipboardText = self.clipboard.text() if not (isinstance(clipboardText, str) or isinstance(clipboardText, unicode)): self.showNoDataMessage() return xmlFilePath = clipboardText.split("@QGIS-layers-and-groups@") if len(xmlFilePath) != 2: self.showNoDataMessage() return xmlFilePath = xmlFilePath[1] # Get payload if not (os.path.isfile(xmlFilePath) and os.path.splitext(xmlFilePath)[1] == '.qlr'): self.showNoDataMessage() return QgsLayerDefinition.loadLayerDefinition( xmlFilePath, QgsProject.instance().layerTreeRoot())
def ok_clicked(self): self.close() ret = extract_zipfile('trends.earth_basemap_data.zip', verify=False) if ret: f = open(os.path.join(os.path.dirname(__file__), 'data', 'basemap.qlr'), 'rt') lyr_def_content = f.read() f.close() # The basemap data, when downloaded, is stored in the data # subfolder of the plugin directory lyr_def_content = lyr_def_content.replace('DATA_FOLDER', os.path.join(os.path.dirname(__file__), 'data')) if self.checkBox_mask.isChecked(): if not self.area_admin_1.currentText() or self.area_admin_1.currentText() == 'All regions': admin_code = self.admin_bounds_key[self.area_admin_0.currentText()]['code'] # Mask out a level 0 admin area - this is default, so don't # need to edit the brrush styles lyr_def_content = lyr_def_content.replace('MASK_SQL_ADMIN0', "|subset="ISO_A3" != '{}'".format(admin_code)) lyr_def_content = lyr_def_content.replace('MASK_SQL_ADMIN1', '') document = QtXml.QDomDocument() document.setContent(lyr_def_content) zoomer = zoom_to_admin_poly(admin_code) else: # Mask out a level 1 admin area lyr_def_content = lyr_def_content.replace('MASK_SQL_ADMIN0', '') admin_code = self.admin_bounds_key[self.area_admin_0.currentText()]['admin1'][self.area_admin_1.currentText()]['code'] lyr_def_content = lyr_def_content.replace('MASK_SQL_ADMIN1', "|subset="adm1_code" != '{}'".format(admin_code)) # Set national borders to no brush, and regional borders to # solid brush document = QtXml.QDomDocument() document.setContent(lyr_def_content) maplayers = document.elementsByTagName('maplayer') set_fill_style(maplayers, 'ne_10m_admin_0_countries', 'no') set_fill_style(maplayers, 'ne_10m_admin_1_states_provinces', 'solid') # Set the flag used in the zoom function to know this is an # admin 1 code zoomer = zoom_to_admin_poly(admin_code, True) else: # Don't mask any areas lyr_def_content = lyr_def_content.replace('MASK_SQL_ADMIN0', '') lyr_def_content = lyr_def_content.replace('MASK_SQL_ADMIN1', '') # To not use a mask, need to set the fill style to no brush document = QtXml.QDomDocument() document.setContent(lyr_def_content) maplayers = document.elementsByTagName('maplayer') set_fill_style(maplayers, 'ne_10m_admin_0_countries', 'no') zoomer = None # Always add the basemap at the top of the TOC root = QgsProject.instance().layerTreeRoot().insertGroup(0, 'Basemap') QgsLayerDefinition.loadLayerDefinition(document, QgsProject.instance(), root, QgsReadWriteContext()) if zoomer: zoomer.zoom() else: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Error downloading basemap data."))