3. Carregando Camadas

Dica

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# get the path to the shapefile e.g. /home/project/data/ports.shp
 2path_to_airports_layer = "testdata/airports.shp"
 3
 4# The format is:
 5# vlayer = QgsVectorLayer(data_source, layer_name, provider_name)
 6
 7vlayer = QgsVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
 8if not vlayer.isValid():
 9    print("Layer failed to load!")
10else:
11    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# get the path to a geopackage  e.g. /usr/share/qgis/resources/data/world_map.gpkg
 2path_to_gpkg = os.path.join(QgsApplication.pkgDataPath(), "resources", "data", "world_map.gpkg")
 3# append the layername part
 4gpkg_countries_layer = path_to_gpkg + "|layername=countries"
 5# e.g. gpkg_places_layer = "/usr/share/qgis/resources/data/world_map.gpkg|layername=countries"
 6vlayer = QgsVectorLayer(gpkg_countries_layer, "Countries layer", "ogr")
 7if not vlayer.isValid():
 8    print("Layer failed to load!")
 9else:
10    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:

  • GDAL library (Shapefile and many other file formats) — data source is the path to the file:

    • 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:

    1uri = QgsDataSourceUri()
    2# set host name, port, database name, username and password
    3uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")
    4# set database schema, table name, geometry column and optionally
    5# subset (WHERE clause)
    6uri.setDataSource("public", "roads", "the_geom", "cityid = 2643", "primary_key_field")
    7
    8vlayer = 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:

     1uri = QgsDataSourceUri()
     2uri.setDatabase('/home/martin/test-2.3.sqlite')
     3schema = ''
     4table = 'Towns'
     5geom_column = 'Geometry'
     6uri.setDataSource(schema, table, geom_column)
     7
     8display_name = 'Towns'
     9vlayer = QgsVectorLayer(uri.uri(), display_name, 'spatialite')
    10QgsProject.instance().addMapLayer(vlayer)
    
  • MySQL WKB-based geometries, through GDAL — data source is the connection string to the table:

    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.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities"
    vlayer = QgsVectorLayer(uri, "my wfs layer", "WFS")
    

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

     1import urllib
     2
     3params = {
     4    'service': 'WFS',
     5    'version': '2.0.0',
     6    'request': 'GetFeature',
     7    'typename': 'ms:cities',
     8    'srsname': "EPSG:4326"
     9}
    10uri2 = 'https://demo.mapserver.org/cgi-bin/wfs?' + urllib.parse.unquote(urllib.parse.urlencode(params))
    

Nota

You can change the data source of an existing layer by calling setDataSource() on a QgsVectorLayer instance, as in the following example:

1uri = "https://demo.mapserver.org/cgi-bin/wfs?service=WFS&version=2.0.0&request=GetFeature&typename=ms:cities"
2provider_options = QgsDataProvider.ProviderOptions()
3# Use project's transform context
4provider_options.transformContext = QgsProject.instance().transformContext()
5vlayer.setDataSource(uri, "layer name you like", "WFS", provider_options)
6
7del(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# get the path to a tif file  e.g. /home/project/data/srtm.tif
2path_to_tif = "qgis-projects/python_cookbook/data/srtm.tif"
3rlayer = QgsRasterLayer(path_to_tif, "SRTM layer name")
4if not rlayer.isValid():
5    print("Layer failed to load!")

Para carregar um raster de um geopackage:

1# get the path to a geopackage  e.g. /home/project/data/data.gpkg
2path_to_gpkg = os.path.join(os.getcwd(), "testdata", "sublayers.gpkg")
3# gpkg_raster_layer = "GPKG:/home/project/data/data.gpkg:srtm"
4gpkg_raster_layer = "GPKG:" + path_to_gpkg + ":srtm"
5
6rlayer = QgsRasterLayer(gpkg_raster_layer, "layer name you like", "gdal")
7
8if not rlayer.isValid():
9    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.

Para carregar um raster PostGIS:

PostGIS rasters, similar to PostGIS vectors, can be added to a project using a URI string. It is efficient to keep a reusable dictionary of strings for the database connection parameters. This makes it easy to edit the dictionary for the applicable connection. The dictionary is then encoded into a URI using the ‘postgresraster’ provider metadata object. After that the raster can be added to the project.

 1uri_config = {
 2    # database parameters
 3    'dbname':'gis_db',      # The PostgreSQL database to connect to.
 4    'host':'localhost',     # The host IP address or localhost.
 5    'port':'5432',          # The port to connect on.
 6    'sslmode':QgsDataSourceUri.SslDisable, # SslAllow, SslPrefer, SslRequire, SslVerifyCa, SslVerifyFull
 7    # user and password are not needed if stored in the authcfg or service
 8    'authcfg':'QconfigId',  # The QGIS athentication database ID holding connection details.
 9    'service': None,         # The PostgreSQL service to be used for connection to the database.
10    'username':None,        # The PostgreSQL user name.
11    'password':None,        # The PostgreSQL password for the user.
12    # table and raster column details
13    'schema':'public',      # The database schema that the table is located in.
14    'table':'my_rasters',   # The database table to be loaded.
15    'geometrycolumn':'rast',# raster column in PostGIS table
16    'sql':None,             # An SQL WHERE clause. It should be placed at the end of the string.
17    'key':None,             # A key column from the table.
18    'srid':None,            # A string designating the SRID of the coordinate reference system.
19    'estimatedmetadata':'False', # A boolean value telling if the metadata is estimated.
20    'type':None,            # A WKT string designating the WKB Type.
21    'selectatid':None,      # Set to True to disable selection by feature ID.
22    'options':None,         # other PostgreSQL connection options not in this list.
23    'enableTime': None,
24    'temporalDefaultTime': None,
25    'temporalFieldIndex': None,
26    'mode':'2',             # GDAL 'mode' parameter, 2 unions raster tiles, 1 adds tiles separately (may require user input)
27}
28# remove any NULL parameters
29uri_config = {key:val for key, val in uri_config.items() if val is not None}
30# get the metadata for the raster provider and configure the URI
31md = QgsProviderRegistry.instance().providerMetadata('postgresraster')
32uri = QgsDataSourceUri(md.encodeUri(uri_config))
33
34# the raster can then be loaded into the project
35rlayer = iface.addRasterLayer(uri.uri(False), "raster layer name", "postgresraster")

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

layer_name = 'modis'
url = "https://demo.mapserver.org/cgi-bin/wcs?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=continents&styles&url=https://demo.mapserver.org/cgi-bin/wms"
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# first add the layer without showing it
2QgsProject.instance().addMapLayer(rlayer, False)
3# obtain the layer tree of the top-level group in the project
4layerTree = iface.layerTreeCanvasBridge().rootGroup()
5# the position is a number starting from 0, with -1 an alias for the end
6layerTree.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()