def testCombinedExtent(self): extent = QgsMapLayerUtils.combinedExtent([], QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext()) self.assertTrue(extent.isEmpty()) layer1 = QgsVectorLayer(unitTestDataPath() + '/points.shp', 'l1') self.assertTrue(layer1.isValid()) # one layer extent = QgsMapLayerUtils.combinedExtent([layer1], QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(3), '-118.889,22.800 : -83.333,46.872') extent = QgsMapLayerUtils.combinedExtent([layer1], QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(3), '-118.889,22.800 : -83.333,46.872') extent = QgsMapLayerUtils.combinedExtent([layer1], QgsCoordinateReferenceSystem('EPSG:3857'), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(0), '-13234651,2607875 : -9276624,5921203') # two layers layer2 = QgsRasterLayer(unitTestDataPath() + '/landsat-f32-b1.tif', 'l2') self.assertTrue(layer2.isValid()) extent = QgsMapLayerUtils.combinedExtent([layer1, layer2], QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(3), '-118.889,22.800 : 18.046,46.872') extent = QgsMapLayerUtils.combinedExtent([layer2, layer1], QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(3), '-118.889,22.800 : 18.046,46.872') extent = QgsMapLayerUtils.combinedExtent([layer1, layer2], QgsCoordinateReferenceSystem('EPSG:3857'), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(0), '-13234651,2607875 : 2008833,5921203') extent = QgsMapLayerUtils.combinedExtent([layer2, layer1], QgsCoordinateReferenceSystem('EPSG:3857'), QgsCoordinateTransformContext()) self.assertEqual(extent.toString(0), '-13234651,2607875 : 2008833,5921203')
def test_updateLayerSourcePath(self): """ Test QgsMapLayerUtils.updateLayerSourcePath() """ self.assertFalse(QgsMapLayerUtils.updateLayerSourcePath(None, '')) self.assertFalse(QgsMapLayerUtils.updateLayerSourcePath(None, 'aaaaa')) # shapefile layer1 = QgsVectorLayer(unitTestDataPath() + '/points.shp', 'l1') self.assertTrue(QgsMapLayerUtils.updateLayerSourcePath(layer1, unitTestDataPath() + '/points22.shp')) self.assertEqual(layer1.source(), unitTestDataPath() + '/points22.shp') # geopackage with layers layer1 = QgsVectorLayer(unitTestDataPath() + '/mixed_layers.gpkg|layername=lines', 'l1') self.assertTrue(QgsMapLayerUtils.updateLayerSourcePath(layer1, unitTestDataPath() + '/mixed_layers22.gpkg')) self.assertEqual(layer1.source(), unitTestDataPath() + '/mixed_layers22.gpkg|layername=lines') layer2 = QgsVectorLayer(unitTestDataPath() + '/mixed_layers.gpkg|layername=points', 'l1') self.assertTrue(QgsMapLayerUtils.updateLayerSourcePath(layer2, unitTestDataPath() + '/mixed_layers22.gpkg')) self.assertEqual(layer2.source(), unitTestDataPath() + '/mixed_layers22.gpkg|layername=points') # raster layer from gpkg rl = QgsRasterLayer(f'GPKG:{unitTestDataPath()}/mixed_layers.gpkg:band1') self.assertTrue(QgsMapLayerUtils.updateLayerSourcePath(rl, unitTestDataPath() + '/mixed_layers22.gpkg')) self.assertEqual(rl.source(), f'GPKG:{unitTestDataPath()}/mixed_layers22.gpkg:band1') # a layer from a provider which doesn't use file based paths layer = QgsVectorLayer("Point?field=x:string", 'my layer', "memory") old_source = layer.source() self.assertTrue(layer.isValid()) self.assertFalse(QgsMapLayerUtils.updateLayerSourcePath(layer, unitTestDataPath() + '/mixed_layers22.gpkg')) self.assertEqual(layer.source(), old_source)
def test_sort_layers_by_type(self): vl1 = QgsVectorLayer("Point?field=x:string", 'vector 1', "memory") vl2 = QgsVectorLayer("Point?field=x:string", 'vector 2', "memory") options = QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext()) al1 = QgsAnnotationLayer('annotations 1', options) al2 = QgsAnnotationLayer('annotations 2', options) rl1 = QgsRasterLayer( f'GPKG:{unitTestDataPath()}/mixed_layers.gpkg:band1', 'raster 1') options = QgsGroupLayer.LayerOptions( QgsProject.instance().transformContext()) gp1 = QgsGroupLayer('group 1', options) self.assertEqual( QgsMapLayerUtils.sortLayersByType([vl1, rl1, gp1, vl2, al2, al1], []), [vl1, rl1, gp1, vl2, al2, al1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType([vl1, rl1, gp1, vl2, al2, al1], [QgsMapLayerType.VectorLayer]), [vl1, vl2, rl1, gp1, al2, al1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType( [vl1, rl1, gp1, vl2, al2, al1], [QgsMapLayerType.RasterLayer, QgsMapLayerType.VectorLayer]), [rl1, vl1, vl2, gp1, al2, al1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType( [vl1, rl1, gp1, vl2, al2, al1], [QgsMapLayerType.GroupLayer, QgsMapLayerType.VectorLayer]), [gp1, vl1, vl2, rl1, al2, al1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType([vl1, rl1, gp1, vl2, al2, al1], [ QgsMapLayerType.GroupLayer, QgsMapLayerType.VectorLayer, QgsMapLayerType.AnnotationLayer ]), [gp1, vl1, vl2, al2, al1, rl1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType([vl1, rl1, gp1, vl2, al2, al1], [ QgsMapLayerType.GroupLayer, QgsMapLayerType.VectorLayer, QgsMapLayerType.RasterLayer, QgsMapLayerType.AnnotationLayer ]), [gp1, vl1, vl2, rl1, al2, al1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType([vl1, rl1, gp1, vl2], [ QgsMapLayerType.GroupLayer, QgsMapLayerType.VectorLayer, QgsMapLayerType.RasterLayer ]), [gp1, vl1, vl2, rl1]) self.assertEqual( QgsMapLayerUtils.sortLayersByType( [vl1, rl1, gp1, vl2], [QgsMapLayerType.AnnotationLayer]), [vl1, rl1, gp1, vl2])
def testCreateSqlVectorLayer(self): """Test vector layer creation from SQL query""" md = QgsProviderRegistry.instance().providerMetadata(self.providerKey) conn = md.createConnection(self.uri, {}) if not conn.capabilities() & QgsAbstractDatabaseProviderConnection.SqlLayers: print(f"FIXME: {self.providerKey} data provider does not support query layers!") return schema = getattr(self, 'sqlVectorLayerSchema', None) if schema is None: print(f"FIXME: {self.providerKey} data provider test case does not define self.sqlVectorLayerSchema for query layers test!") return table = getattr(self, 'sqlVectorLayerTable', None) if table is None: print(f"FIXME: {self.providerKey} data provider test case does not define self.sqlVectorLayerTable for query layers test!") return sql_layer_capabilities = conn.sqlLayerDefinitionCapabilities() # Try a simple select first table_info = conn.table(schema, table) options = QgsAbstractDatabaseProviderConnection.SqlVectorLayerOptions() options.layerName = 'My SQL Layer' # Some providers do not support schema if schema != '': options.sql = f'SELECT * FROM "{table_info.schema()}"."{table_info.tableName()}"' else: options.sql = f'SELECT * FROM "{table_info.tableName()}"' options.geometryColumn = table_info.geometryColumn() options.primaryKeyColumns = table_info.primaryKeyColumns() vl = conn.createSqlVectorLayer(options) self.assertTrue(vl.isSqlQuery()) self.assertTrue(vl.isValid()) self.assertTrue(vl.isSpatial()) self.assertEqual(vl.name(), options.layerName) # Test that a database connection can be retrieved from an existing layer vlconn = QgsMapLayerUtils.databaseConnection(vl) self.assertIsNotNone(vlconn) self.assertEqual(vlconn.uri(), conn.uri()) # Some providers can also create SQL layer without an explicit PK if sql_layer_capabilities & Qgis.SqlLayerDefinitionCapability.PrimaryKeys: options.primaryKeyColumns = [] vl = conn.createSqlVectorLayer(options) self.assertTrue(vl.isSqlQuery()) self.assertTrue(vl.isValid()) self.assertTrue(vl.isSpatial()) # Some providers can also create SQL layer without an explicit geometry column if sql_layer_capabilities & Qgis.SqlLayerDefinitionCapability.GeometryColumn: options.primaryKeyColumns = table_info.primaryKeyColumns() options.geometryColumn = '' vl = conn.createSqlVectorLayer(options) self.assertTrue(vl.isValid()) self.assertTrue(vl.isSqlQuery()) # This may fail for OGR where the provider is smart enough to guess the geometry column if self.providerKey != 'ogr': self.assertFalse(vl.isSpatial()) # Some providers can also create SQL layer with filters if sql_layer_capabilities & Qgis.SqlLayerDefinitionCapability.SubsetStringFilter: options.primaryKeyColumns = table_info.primaryKeyColumns() options.geometryColumn = table_info.geometryColumn() options.filter = f'"{options.primaryKeyColumns[0]}" > 0' vl = conn.createSqlVectorLayer(options) self.assertTrue(vl.isValid()) self.assertTrue(vl.isSqlQuery()) self.assertTrue(vl.isSpatial())
def test_layerSourceMatchesPath(self): """ Test QgsMapLayerUtils.layerSourceMatchesPath() """ self.assertFalse(QgsMapLayerUtils.layerSourceMatchesPath(None, '')) self.assertFalse(QgsMapLayerUtils.layerSourceMatchesPath( None, 'aaaaa')) # shapefile layer1 = QgsVectorLayer(unitTestDataPath() + '/points.shp', 'l1') self.assertFalse(QgsMapLayerUtils.layerSourceMatchesPath(layer1, '')) self.assertFalse( QgsMapLayerUtils.layerSourceMatchesPath(layer1, 'aaaaa')) self.assertTrue( QgsMapLayerUtils.layerSourceMatchesPath( layer1, unitTestDataPath() + '/points.shp')) # geopackage with layers layer1 = QgsVectorLayer( unitTestDataPath() + '/mixed_layers.gpkg|layername=lines', 'l1') self.assertFalse(QgsMapLayerUtils.layerSourceMatchesPath(layer1, '')) self.assertFalse( QgsMapLayerUtils.layerSourceMatchesPath(layer1, 'aaaaa')) self.assertTrue( QgsMapLayerUtils.layerSourceMatchesPath( layer1, unitTestDataPath() + '/mixed_layers.gpkg')) layer2 = QgsVectorLayer( unitTestDataPath() + '/mixed_layers.gpkg|layername=points', 'l1') self.assertTrue( QgsMapLayerUtils.layerSourceMatchesPath( layer2, unitTestDataPath() + '/mixed_layers.gpkg')) # raster layer from gpkg rl = QgsRasterLayer( f'GPKG:{unitTestDataPath()}/mixed_layers.gpkg:band1') self.assertFalse(QgsMapLayerUtils.layerSourceMatchesPath(rl, '')) self.assertFalse(QgsMapLayerUtils.layerSourceMatchesPath(rl, 'aaaaa')) self.assertTrue( QgsMapLayerUtils.layerSourceMatchesPath( rl, unitTestDataPath() + '/mixed_layers.gpkg'))
def test_launder_layer_name(self): self.assertEqual(QgsMapLayerUtils.launderLayerName('abc Def4_a.h%'), 'abc_def4_ah')