3. Carregando Camadas

Os trechos de código nesta página precisam das seguintes importações:

import os # This is is needed in the pyqgis console also
from qgis.core import (
    QgsVectorLayer
)

Vamos abrir algumas camadas com dados. QGIS reconhece camadas vetoriais e matriciais. Adicionalmente, camadas personalizadas estão disponíveis, mas não discutiremos este tipo de camadas aqui.

3.1. Camadas Vetoriais

Para criar e adicionar uma instância de camada vetorial ao projeto, especifique o identificador da fonte de dados da camada, o nome da camada e o nome do provedor:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# get the path to the shapefile e.g. /home/project/data/ports.shp
path_to_airports_layer = "testdata/airports.shp"

# The format is:
# vlayer = QgsVectorLayer(data_source, layer_name, provider_name)

vlayer = QgsVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
if not vlayer.isValid():
    print("Layer failed to load!")
else:
    QgsProject.instance().addMapLayer(vlayer)

O identificador da fonte de dados é uma string e é especifico para cada provedor de dados vetoriais. O nome da camada é usado no painel de lista de camadas. É importante verificar se a camada foi carregada com sucesso. Se não for, uma instância de camada inválida é retornada.

Para uma camada vetorial geopackage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# get the path to a geopackage  e.g. /usr/share/qgis/resources/data/world_map.gpkg
path_to_gpkg = os.path.join(QgsApplication.pkgDataPath(), "resources", "data", "world_map.gpkg")
# append the layername part
gpkg_countries_layer = path_to_gpkg + "|layername=countries"
# e.g. gpkg_places_layer = "/usr/share/qgis/resources/data/world_map.gpkg|layername=countries"
vlayer = QgsVectorLayer(gpkg_countries_layer, "Countries layer", "ogr")
if not vlayer.isValid():
    print("Layer failed to load!")
else:
    QgsProject.instance().addMapLayer(vlayer)

A maneira mais rápida de abrir e exibir uma camada vetorial no QGIS é o método addVectorLayer() de QgisInterface:

vlayer = iface.addVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
if not vlayer:
  print("Layer failed to load!")

Isso cria uma nova camada e a adiciona ao projeto QGIS atual (fazendo com que apareça na lista de camadas) em uma etapa. A função retorna a instância da camada ou Nenhuma se a camada não puder ser carregada.

A lista a seguir mostra como acessar várias fontes de dados usando provedores de dados vetoriais:

  • Biblioteca OGR (Shapefile e muitos outros formatos de arquivo) — fonte de dados é o caminho para o arquivo:

    • para Shapefile:

      vlayer = QgsVectorLayer("testdata/airports.shp", "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
    • para dxf (observe as opções internas no uri da fonte de dados):

      uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon"
      vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
  • Banco de dados PostGIS - fonte de dados é uma string com todas as informações necessárias para criar uma conexão com o banco de dados PostgreSQL.

    classe QgsDataSourceUri pode gerar essa string para você. Observe que o QGIS deve ser compilado com o suporte ao Postgres, caso contrário, esse provedor não estará disponível:

    1
    2
    3
    4
    5
    6
    7
    8
    uri = QgsDataSourceUri()
    # set host name, port, database name, username and password
    uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")
    # set database schema, table name, geometry column and optionally
    # subset (WHERE clause)
    uri.setDataSource("public", "roads", "the_geom", "cityid = 2643", "primary_key_field")
    
    vlayer = QgsVectorLayer(uri.uri(False), "layer name you like", "postgres")
    

    Nota

    O argumento Falso transmitido para uri.uri(False) impede a expansão dos parâmetros de configuração de autenticação, se você não estiver usando nenhuma configuração de autenticação, esse argumento não fará diferença.

  • CSV ou outros arquivos de texto delimitados — para abrir um arquivo com ponto-e-vírgula como delimitador, com o campo “x” para a coordenada X e o campo “y” para a coordenada Y, você usaria algo como isto:

    uri = "file://{}/testdata/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(os.getcwd(), ";", "x", "y")
    vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext")
    QgsProject.instance().addMapLayer(vlayer)
    

    Nota

    A string do provedor é estruturada como uma URL, portanto, o caminho deve ser prefixado com file://. Também permite geometrias no formato WKT (texto conhecido) como uma alternativa aos campos x e y, e permite que o sistema de referência de coordenadas seja especificado. Por exemplo:

    uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
    
  • Arquivos GPX — o provedor de dados “gpx” lê trilhas, rotas e waypoints dos arquivos gpx. Para abrir um arquivo, o tipo (trilha/rota/waypoint) precisa ser especificado como parte do URL:

    uri = "testdata/layers.gpx?type=track"
    vlayer = QgsVectorLayer(uri, "layer name you like", "gpx")
    QgsProject.instance().addMapLayer(vlayer)
    
  • Banco de dados SpatiaLite — Da mesma forma que os bancos de dados PostGIS, QgsDataSourceUri pode ser usado para geração do identificador da fonte de dados:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    uri = QgsDataSourceUri()
    uri.setDatabase('/home/martin/test-2.3.sqlite')
    schema = ''
    table = 'Towns'
    geom_column = 'Geometry'
    uri.setDataSource(schema, table, geom_column)
    
    display_name = 'Towns'
    vlayer = QgsVectorLayer(uri.uri(), display_name, 'spatialite')
    QgsProject.instance().addMapLayer(vlayer)
    
  • Geometrias baseadas em MySQL WKB, através de OGR — fonte de dados são a string de conexão com a tabela:

    uri = "MySQL:dbname,host=localhost,port=3306,user=root,password=xxx|layername=my_table"
    vlayer = QgsVectorLayer( uri, "my table", "ogr" )
    QgsProject.instance().addMapLayer(vlayer)
    
  • WFS connection: the connection is defined with a URI and using the WFS provider:

    uri = "https://demo.geo-solutions.it/geoserver/ows?service=WFS&version=1.1.0&request=GetFeature&typename=geosolutions:regioni"
    vlayer = QgsVectorLayer(uri, "my wfs layer", "WFS")
    QgsProject.instance().addMapLayer(vlayer)
    

    O uri pode ser criado usando a biblioteca padrão urllib:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    import urllib
    
    params = {
        'service': 'WFS',
        'version': '1.1.0',
        'request': 'GetFeature',
        'typename': 'geosolutions:regioni',
        'srsname': "EPSG:4326"
    }
    uri2 = 'https://demo.geo-solutions.it/geoserver/ows?' + urllib.parse.unquote(urllib.parse.urlencode(params))
    

Nota

Você pode alterar a fonte de dados de uma camada existente chamando setDataSource() em uma instância QgsVectorLayer, como o exemplo a seguir:

1
2
3
4
5
6
uri = "https://demo.geo-solutions.it/geoserver/ows?service=WFS&version=1.1.0&request=GetFeature&typename=geosolutions:regioni"
provider_options = QgsDataProvider.ProviderOptions()
# Use project's transform context
provider_options.transformContext = QgsProject.instance().transformContext()
vlayer.setDataSource(uri, "layer name you like", "WFS", provider_options)
QgsProject.instance().addMapLayer(vlayer)

3.2. Camadas Matriciais

Para acessar arquivos raster, a biblioteca GDAL é usada. Ele suporta uma ampla variedade de formatos de arquivo. Caso você tenha problemas para abrir alguns arquivos, verifique se o seu GDAL tem suporte para o formato específico (nem todos os formatos estão disponíveis por padrão). Para carregar um raster de um arquivo, especifique seu nome de arquivo e nome para exibição:

1
2
3
4
5
# get the path to a tif file  e.g. /home/project/data/srtm.tif
path_to_tif = "qgis-projects/python_cookbook/data/srtm.tif"
rlayer = QgsRasterLayer(path_to_tif, "SRTM layer name")
if not rlayer.isValid():
    print("Layer failed to load!")

Para carregar um raster de um geopackage:

1
2
3
4
5
6
7
8
9
# get the path to a geopackage  e.g. /home/project/data/data.gpkg
path_to_gpkg = os.path.join(os.getcwd(), "testdata", "sublayers.gpkg")
# gpkg_raster_layer = "GPKG:/home/project/data/data.gpkg:srtm"
gpkg_raster_layer = "GPKG:" + path_to_gpkg + ":srtm"

rlayer = QgsRasterLayer(gpkg_raster_layer, "layer name you like", "gdal")

if not rlayer.isValid():
    print("Layer failed to load!")

Da mesma forma que as camadas vetoriais, as camadas raster podem ser carregadas usando a função addRasterLayer do objeto QgisInterface:

iface.addRasterLayer(path_to_tif, "layer name you like")

Isso cria uma nova camada e a adiciona ao projeto atual (fazendo com que apareça na lista de camadas) em uma etapa.

To load a PostGIS raster:

PostGIS rasters, similar to PostGIS vectors, can be added to a project using a URI string. It is efficient to create a dictionary of strings for the database connection parameters. The dictionary is then loaded into an empty URI, before adding the raster. Note that None should be used when it is desired to leave the parameter blank:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
uri_config = {#
# a dictionary of database parameters
'dbname':'gis_db', # The PostgreSQL database to connect to.
'host':'localhost',     # The host IP address or localhost.
'port':'5432',          # The port to connect on.
'sslmode':'disable',    # The SSL/TLS mode. Options: allow, disable, prefer, require, verify-ca, verify-full
# user and password are not needed if stored in the authcfg or service
'user':None,            # The PostgreSQL user name, also accepts the new WFS provider naming.
'password':None,        # The PostgreSQL password for the user.
'service':None,         # The PostgreSQL service to be used for connection to the database.
'authcfg':'QconfigId',  # The QGIS athentication database ID holding connection details.
# table and raster column details
'schema':'public',      # The database schema that the table is located in.
'table':'my_rasters',   # The database table to be loaded.
'column':'rast',        # raster column in PostGIS table
'mode':'2',             # GDAL 'mode' parameter, 2 union raster tiles, 1 separate tiles (may require user input)
'sql':None,             # An SQL WHERE clause.
'key':None,             # A key column from the table.
'srid':None,            # A string designating the SRID of the coordinate reference system.
'estimatedmetadata':'False', # A boolean value telling if the metadata is estimated.
'type':None,            # A WKT string designating the WKB Type.
'selectatid':None,      # Set to True to disable selection by feature ID.
'options':None,         # other PostgreSQL connection options not in this list.
'connect_timeout':None,
'hostaddr':None,
'driver':None,
'tty':None,
'requiressl':None,
'krbsrvname':None,
'gsslib':None,
}
# configure the URI string with the dictionary
uri = QgsDataSourceUri()
for param in uri_config:
    if (uri_config[param] != None):
        uri.setParam(param, uri_config[param]) # add parameters to the URI

# the raster can now be loaded into the project using the URI string and GDAL data provider
rlayer = iface.addRasterLayer('PG: ' + uri.uri(False), "raster layer name", "gdal")

As camadas raster também podem ser criadas a partir de um serviço WCS:

layer_name = 'nurc:mosaic'
uri = "https://demo.geo-solutions.it/geoserver/ows?identifier={}".format(layer_name)
rlayer = QgsRasterLayer(uri, 'my wcs layer', 'wcs')

Está aqui uma descrição dos parâmetros que o URI do WCS pode conter:

O WCS URI é composto por pares chave=valor separados por &. É o mesmo formato, como a string de consulta no URL, codificada da mesma maneira. QgsDataSourceUri deve ser usado para construir o URI para garantir que os caracteres especiais sejam codificados corretamente.

  • url (obrigatório): URL do servidor WCS. Não use VERSION no URL, porque cada versão do WCS está usando um nome de parâmetro diferente para a versão GetCapabilities, consulte a versão param.

  • identifier (obrigatório): Nome da cobertura

  • tempo (opcional): posição ou período de tempo (beginPosition/endPosition[/timeResolution])

  • format (opcional): nome do formato suportado. O padrão é o primeiro formato suportado com tif no nome ou o primeiro formato suportado.

  • crs (opcional): SRC no formato AUTHORITY:ID, p. EPSG: 4326. O padrão é EPSG:4326 se suportado ou o primeiro SRC suportado.

  • username (opcional): nome de usuário para autenticação básica.

  • password (opcional) : Senha para autenticação básica.

  • IgnoreGetMapUrl (opcional, hack): se especificado (definido como 1), ignore o URL GetCoverage anunciado por GetCapabilities. Pode ser necessário se um servidor não estiver configurado corretamente.

  • InvertAxisOrientation (opcional, hack): se especificado (definido como 1), alterne o eixo na solicitação GetCoverage. Pode ser necessário para o SRC geográfico se um servidor estiver usando a ordem do eixo incorreta.

  • IgnoreAxisOrientation (opcional, hack): Se especificado (definido como 1), não inverta a orientação do eixo de acordo com o padrão WCS para SRC geográfico.

  • cache (opcional): controle de carregamento de cache, conforme descrito em QNetworkRequest::CacheLoadControl, mas a solicitação é reenviada como PreferCache se houver falha no AlwaysCache. Valores permitidos: AlwaysCache, PreferCache, PreferNetwork, AlwaysNetwork. O padrão é AlwaysCache.

Como alternativa, você pode carregar uma camada raster do servidor WMS. No entanto, atualmente não é possível acessar a resposta GetCapabilities da API - você precisa saber quais camadas deseja:

urlWithParams = "crs=EPSG:4326&format=image/png&layers=tasmania&styles&url=https://demo.geo-solutions.it/geoserver/ows"
rlayer = QgsRasterLayer(urlWithParams, 'some layer name', 'wms')
if not rlayer.isValid():
  print("Layer failed to load!")

3.3. Instância QgsProject

Se você deseja usar as camadas abertas para renderização, não se esqueça de adicioná-las à instância QgsProject. A instância QgsProject assume a propriedade das camadas e elas podem ser acessadas posteriormente de qualquer parte do aplicativo por seu ID exclusivo. Quando a camada é removida do projeto, ela também é excluída. As camadas podem ser removidas pelo usuário na interface QGIS ou via Python usando o método removeMapLayer().

A adição de uma camada ao projeto atual é feita usando o método addMapLayer():

QgsProject.instance().addMapLayer(rlayer)

Para adicionar uma camada em uma posição absoluta:

1
2
3
4
5
6
# first add the layer without showing it
QgsProject.instance().addMapLayer(rlayer, False)
# obtain the layer tree of the top-level group in the project
layerTree = iface.layerTreeCanvasBridge().rootGroup()
# the position is a number starting from 0, with -1 an alias for the end
layerTree.insertChildNode(-1, QgsLayerTreeLayer(rlayer))

Se você deseja excluir a camada, use o método removeMapLayer():

# QgsProject.instance().removeMapLayer(layer_id)
QgsProject.instance().removeMapLayer(rlayer.id())

No código acima, o ID da camada é passado (você pode obtê-lo chamando o método id() da camada), mas você também pode passar o próprio objeto da camada.

Para obter uma lista de camadas carregadas e IDs de camada, use o método :meth: mapLayers() <qgis.core.QgsProject.mapLayers>:

QgsProject.instance().mapLayers()