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 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 testSaveFields(self): # Create a new py layerwith no fields myPyLayer = QgsVectorLayer( ('Point?crs=epsg:4326&index=yes'), 'test', 'pythonprovider') # Add some fields to the layer myFields = [QgsField('TestInt', QVariant.Int, 'integer', 2, 0), QgsField('TestLong', QVariant.LongLong, 'long', -1, 0), QgsField('TestDbl', QVariant.Double, 'double', 8, 6), QgsField('TestString', QVariant.String, 'string', 50, 0), QgsField('TestDate', QVariant.Date, 'date'), QgsField('TestTime', QVariant.Time, 'time'), QgsField('TestDateTime', QVariant.DateTime, 'datetime')] assert myPyLayer.startEditing() for f in myFields: assert myPyLayer.addAttribute(f) assert myPyLayer.commitChanges() myPyLayer.updateFields() # Export the layer to a layer-definition-XML qlr = QgsLayerDefinition.exportLayerDefinitionLayers([myPyLayer], QgsReadWriteContext()) assert qlr is not None # Import the layer from the layer-definition-XML layers = QgsLayerDefinition.loadLayerDefinitionLayers(qlr, QgsReadWriteContext()) assert layers is not None myImportedLayer = layers[0] assert myImportedLayer is not None # Check for the presence of the fields importedFields = myImportedLayer.fields() assert importedFields is not None for f in myFields: assert f == importedFields.field(f.name())
def testDependency(self): inDoc = """ <maplayers> <maplayer> <id>layerB</id> <layerDependencies> <layer id="layerA"/> </layerDependencies> </maplayer> <maplayer> <id>layerA</id> </maplayer> </maplayers>""" doc = QDomDocument("testdoc") doc.setContent(inDoc) dep = QgsLayerDefinition.DependencySorter(doc) nodes = dep.sortedLayerNodes() nodeIds = dep.sortedLayerIds() self.assertTrue(not dep.hasCycle()) self.assertTrue(not dep.hasMissingDependency()) self.assertEqual(nodes[0].firstChildElement("id").text(), "layerA") self.assertEqual(nodes[1].firstChildElement("id").text(), "layerB") self.assertEqual(nodeIds[0], "layerA") self.assertEqual(nodeIds[1], "layerB")
def testSaveFields(self): # Create a new memory layer with no fields myMemoryLayer = QgsVectorLayer(('Point?crs=epsg:4326&index=yes'), 'test', 'memory') # Add some fields to the layer myFields = [ QgsField('TestInt', QVariant.Int, 'integer', 2, 0), QgsField('TestLong', QVariant.LongLong, 'long', -1, 0), QgsField('TestDbl', QVariant.Double, 'double', 8, 6), QgsField('TestString', QVariant.String, 'string', 50, 0), QgsField('TestDate', QVariant.Date, 'date'), QgsField('TestTime', QVariant.Time, 'time'), QgsField('TestDateTime', QVariant.DateTime, 'datetime'), QgsField("vallist", QVariant.List, subType=QVariant.Int), QgsField("stringlist", QVariant.StringList, subType=QVariant.String), QgsField("stringlist2", QVariant.List, subType=QVariant.String), QgsField("reallist", QVariant.List, subType=QVariant.Double), QgsField("longlist", QVariant.List, subType=QVariant.LongLong), QgsField("dict", QVariant.Map) ] self.assertTrue(myMemoryLayer.startEditing()) for f in myFields: assert myMemoryLayer.addAttribute(f) self.assertTrue(myMemoryLayer.commitChanges()) myMemoryLayer.updateFields() for f in myFields: self.assertEqual(f, myMemoryLayer.fields().field(f.name())) # Export the layer to a layer-definition-XML qlr = QgsLayerDefinition.exportLayerDefinitionLayers( [myMemoryLayer], QgsReadWriteContext()) self.assertIsNotNone(qlr) # Import the layer from the layer-definition-XML layers = QgsLayerDefinition.loadLayerDefinitionLayers( qlr, QgsReadWriteContext()) self.assertTrue(layers) myImportedLayer = layers[0] self.assertIsNotNone(myImportedLayer) # Check for the presence of the fields importedFields = myImportedLayer.fields() for f in myFields: self.assertEqual(f.name(), importedFields.field(f.name()).name()) if f.name() != 'stringlist2': self.assertEqual(f.type(), importedFields.field(f.name()).type()) else: # we automatically convert List with String subtype to StringList, to match other data providers self.assertEqual( importedFields.field(f.name()).type(), QVariant.StringList) self.assertEqual(f.subType(), importedFields.field(f.name()).subType()) self.assertEqual(f.precision(), importedFields.field(f.name()).precision()) self.assertEqual(f.length(), importedFields.field(f.name()).length())
def load_layers(self): root = QgsProject.instance().layerTreeRoot() crs = QgsCoordinateReferenceSystem("EPSG:3794") if access(self): self.iface.messageBar().pushMessage( self.tr("Povezava s podatkovno bazo CPA uspešna..")) else: self.iface.messageBar().pushMessage( self.tr("Nalagam brez CPA slojev..")) #To prevent folder locking of Plugin directory try: tmp = tempfile.mkdtemp() src = path('qlrs') shutil.rmtree(tmp) shutil.copytree(str(src), tmp) styles_path = Path(tmp) except: self.iface.messageBar().pushMessage( self.tr('Berem qlr iz mape vtičnika...')) #Load Arheologija layes group if access(self): if not root.findGroup(self.tr("Arheologija")): arheo_group = root.addGroup(self.tr("Arheologija")) else: arheo_group = root.findGroup(self.tr("Arheologija")) vlayer = postgis_connect(self, "public", "Katalog najdišč", "geom", "kid") QgsProject.instance().addMapLayer(vlayer, False) arheo_group.insertChildNode(0, QgsLayerTreeLayer(vlayer)) vlayer = postgis_connect(self, "public", "Evidenca arheoloških raziskav", "geom", "id") QgsProject.instance().addMapLayer(vlayer, False) arheo_group.insertChildNode(1, QgsLayerTreeLayer(vlayer)) arch_layers = [ 'Claustra Alpium Iuliarum', 'Načrti najdišč', 'Načrti najdišč_poligoni' ] for layer in arch_layers: vlayer = postgis_connect(self, "public", layer, "geom", "id") QgsProject.instance().addMapLayer(vlayer, False) arheo_group.insertChildNode(2, QgsLayerTreeLayer(vlayer)) arch_layers = ['SMAP', 'ZLS interpretacija'] for layer in arch_layers: vlayer = postgis_connect(self, "public", layer, "geom", "gid") QgsProject.instance().addMapLayer(vlayer, False) arheo_group.insertChildNode(7, QgsLayerTreeLayer(vlayer)) else: pass #Load Dediščina layes group if self.dlg.dediscina.isChecked(): if not root.findGroup(self.tr("Dediščina")): dedi_group = root.addGroup(self.tr("Dediščina")) else: dedi_group = root.findGroup(self.tr("Dediščina")) evrd = styles_path / 'eVRD.qlr' QgsLayerDefinition().loadLayerDefinition(str(evrd), QgsProject.instance(), dedi_group) rkd = styles_path / 'RKD.qlr' QgsLayerDefinition().loadLayerDefinition(str(rkd), QgsProject.instance(), dedi_group) #Load Prostorske enote layes group if self.dlg.prostorske_enote.isChecked(): self.iface.messageBar().pushMessage( self.tr("Nalagam Prostoske enote...")) if not root.findGroup(self.tr("Prostorske enote")): prostorske_group = root.addGroup(self.tr("Prostorske enote")) else: prostorske_group = root.findGroup(self.tr("Prostorske enote")) prostorske = styles_path / 'Prostorske enote.qlr' QgsLayerDefinition().loadLayerDefinition(str(prostorske), QgsProject.instance(), prostorske_group) if access(self): vlayer = postgis_connect(self, "public", "ZKN parcele", "geom", "fid") QgsProject.instance().addMapLayer(vlayer, False) prostorske_group.insertChildNode(6, QgsLayerTreeLayer(vlayer)) zkgji = styles_path / 'zkgji.qlr' QgsLayerDefinition().loadLayerDefinition(str(zkgji), QgsProject.instance(), prostorske_group) else: self.iface.messageBar().pushMessage( self.tr("Ne nalagam Prostorskih enot!"), duration=2) #Load Historične podlage layes group if self.dlg.historicnepodlage.isChecked(): self.iface.messageBar().pushMessage( self.tr("Nalagam Historične podlage...")) if not root.findGroup(self.tr("Historične podlage")): hist_group = root.addGroup(self.tr("Historične podlage")) else: hist_group = root.findGroup(self.tr("Historične podlage")) histo = styles_path / 'Historicne podlage.qlr' QgsLayerDefinition().loadLayerDefinition(str(histo), QgsProject.instance(), hist_group) hist_group.setExpanded(False) else: self.iface.messageBar().pushMessage( self.tr("Ne nalagam Historičnih podlag!"), duration=2) #Load podlage layes group if self.dlg.c_podlage.isChecked(): self.iface.messageBar().pushMessage(self.tr("Nalagam podlage..")) if not root.findGroup(self.tr("Podlage")): podlage_group = root.addGroup(self.tr("Podlage")) else: podlage_group = root.findGroup(self.tr("Podlage")) geology = styles_path / 'Geološka karta.qlr' QgsLayerDefinition().loadLayerDefinition(str(geology), QgsProject.instance(), podlage_group) if data_access(self): podlage_zls = styles_path / 'ZLS 1.qlr' QgsLayerDefinition().loadLayerDefinition( str(podlage_zls), QgsProject.instance(), podlage_group) else: pass podlage_gurs = styles_path / 'Podlage.qlr' QgsLayerDefinition().loadLayerDefinition(str(podlage_gurs), QgsProject.instance(), podlage_group) else: self.iface.messageBar().pushMessage(self.tr("Ne nalagam podlag!"), duration=2) QgsProject.instance().setCrs(crs) self.iface.messageBar().pushMessage( self.tr("Nastavljam Državni kordinatni sistem D96/TM.."), duration=5) if access(self): #Set which layers should not be expanded not_expanded = [ 'SMAP', 'ZLS interpretacija', 'Claustra Alpium Iuliarum', 'Načrti najdišč', 'Načrti najdišč_poligoni', 'Evidenca arheoloških raziskav', 'Katalog najdišč' ] for layer in not_expanded: if len(QgsProject.instance().mapLayersByName(layer)) != 0: layer = QgsProject.instance().mapLayersByName(layer)[0] myLayerNode = root.findLayer(layer.id()) myLayerNode.setExpanded(False) #toggle visibility layers = [ 'Claustra Alpium Iuliarum', 'Načrti najdišč', 'Načrti najdišč_poligoni', 'Evidenca arheoloških raziskav', 'SMAP', 'ZLS interpretacija', 'ZKN parcele' ] for layer in layers: if len(QgsProject.instance().mapLayersByName(layer)) != 0: layer = QgsProject.instance().mapLayersByName(layer)[0] root.findLayer(layer.id()).setItemVisibilityChecked(0) #toggle visibility layers = ['RKD'] for layer in layers: if len(QgsProject.instance().mapLayersByName(layer)) != 0: layer = QgsProject.instance().mapLayersByName(layer)[0] root.findLayer(layer.id()).setItemVisibilityChecked(0)
def testDependencyQgz(self): path = os.path.join(TEST_DATA_DIR, "embedded_groups", "project1.qgz") dep = QgsLayerDefinition.DependencySorter(path) ids = dep.sortedLayerIds() self.assertEqual(len(ids), 3)
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."))