3. Cargar capas

Consejo

Los fragmentos de código en esta página necesitan las siguientes importaciones:

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

Vamos a abrir algunas capas con datos. QGIS reconoce capas vectoriales y ráster. Además, están disponibles tipos de capas personalizadas, pero no se va a discutir de ellas aquí.

3.1. Capas Vectoriales

Para crear y agregar una instancia de capa vectorial al proyecto, especifique el identificador de origen de datos de la capa, el nombre de la capa y el nombre del proveedor:

 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)

El identificador de la fuente de datos es una cadena y se especifica a cada proveedor de datos vectoriales. El nombre de la capa se utiliza en el widget de la lista de capa. Es importante validar si la capa se ha cargado satisfactoriamente. Si no fue así, se devuelve una instancia de capa no válida.

Para una capa vectorial creada mediante un 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)

La forma más rápida para abrir y visualizar una capa vectorial en QGIS es usar el método addVectorLayer() perteneciente a QgisInterface:

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

Esto crea una nueva capa y la añade al actual proyecto QGIS (haciéndola aparecer en el listado de capas) en un solo paso. La función retorna la instancia de capa o None` si es que no puede cargarla.

La siguiente lista muestra cómo acceder a varias fuentes de datos utilizando los proveedores de datos vectoriales:

  • Librería OGR ( Shapefile y muchos otros formatos) — la fuente de datos es la ruta hacia el archivo:

    • Para Shapefile:

      vlayer = QgsVectorLayer("testdata/airports.shp", "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
    • Para dxf (tenga en cuenta las opciones internas en la fuente de datos uri):

      uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon"
      vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
  • Base de datos PostGIS - la fuente de datos es una cadena de texto con toda la información necesaria para crear una conexión con la base de datos PostgreSQL.

    La clase QgsDataSourceUri puede generar esta cadena de texto para usted. Tenga en cuenta que QGIS debe compilarse con el soporte de Postgres, o de lo contrario, este proveedor no estará disponible:

    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

    El argumento False pasado a uri.uri(False) previene la expansión de los parámetros de configuración de la autenticación. En caso de que no esté utilizando ninguna configuración para autenticación, este argumento no hará ninguna diferencia.

  • CSV u otros archivos de texto delimitados — para abrir un archivo con un punto y coma como delimitador, con el campo «x» para la coordenada X y el campo «y» para la coordenada Y, usaría algo como esto:

    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

    La cadena de proveedor está estructurada como una dirección URL, por lo que la ruta de acceso debe ir precedida de file://. También permite geometrías en formato WKT (texto bien conocido) como alternativa a los campos “”x”” y “”y””, y permite especificar el sistema de referencia de coordenadas. Por ejemplo:

    uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
    
  • Los archivos GPX — el proveedor de datos «gpx» lee los caminos, rutas y puntos de interés desde archivos GPX. Para abrir un archivo, el tipo (caminos/ruta/punto de interés) se debe especificar como parte de la url:

    uri = "testdata/layers.gpx?type=track"
    vlayer = QgsVectorLayer(uri, "layer name you like", "gpx")
    QgsProject.instance().addMapLayer(vlayer)
    
  • La base de datos SpatiaLite — De forma similar a las bases de datos PostGIS, :class:”QgsDataSourceUri <qgis.core.QgsDataSourceUri>” puede ser utilizado para la generación de identificador de origen de datos:

     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)
    
  • Las geometrias basadas en WKB de MySQL, a través de OGR — la fuente de datos es la cadena de conexión a la tabla:

    uri = "MySQL:dbname,host=localhost,port=3306,user=root,password=xxx|layername=my_table"
    vlayer = QgsVectorLayer( uri, "my table", "ogr" )
    QgsProject.instance().addMapLayer(vlayer)
    
  • Conexión WFS: La conexión se define con un URL y usando el proveedor `` WFS “”:

    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")
    

    La uri se puede crear utilizando la librería estándar 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

Puede cambiar la fuente de datos de una capa existente llamando a setDataSource() en una instancia de QgsVectorLayer, como se muestra a continuación ejemplo:

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. Capas ráster

Para acceder a un archivo raster, se utiliza la librería GDAL. Esta soporta un amplio rango de formatos de archivo. En caso de que tenga problemas al abrir algún archivo, compruebe si es que su GDAL tiene soporte para el formato en particular (no todos los formatos están disponibles de forma predeterminada). Para cargar un raster desde un archivo, especifique el nombre del archivo y su nombre de visualización:

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 cargar una capa raster desde un 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!")

De manera similar a las capas vectoriales, las capas raster pueden ser cargadas utilizando la función addRasterLayer de un objeto perteneciente a QgisInterface

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

Esto crea una nueva capa y la añade al proyecto actual (haciendo que aparezca en la lista) en un solo paso.

Para cargar un ráster PostGIS:

Los rásteres PostGIS, similares a los vectores PostGIS, se pueden agregar a un proyecto mediante una cadena URI. Es eficaz mantener un diccionario de cadenas reutilizable para los parámetros de conexión de la base de datos. Esto facilita la edición del diccionario para la conexión correspondiente. Luego, el diccionario se codifica en un URI utilizando el objeto de metadatos del proveedor “postgresraster”. Después de eso, el ráster se puede agregar al proyecto.

 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")

Las capas ráster también se pueden crear desde el servicio WCS:

layer_name = 'modis'
url = "https://demo.mapserver.org/cgi-bin/wcs?identifier={}".format(layer_name)
rlayer = QgsRasterLayer(uri, 'my wcs layer', 'wcs')

Aquí está una descripción de los parámetros que el WCS URI puede contener:

El WCS URI se compone de pares calve=valor separadas por &. Es el mismo formato que la cadena de consulta en la URL, codificada de la misma manera. QgsDataSourceUri debe utilizarse para construir el URI para garantizar que los caracteres especiales se codifican correctamente.

  • url (requerido) : URL del servidor WCS. No utilice la VERSION en el URL, porque cada versión del WCS está usando nombre de parámetro diferente para la versión de GetCapabilities vea la versión del parámetro.

  • identifier (requerido) : Nombre de la Cobertura

  • time (opcional) : posición de tiempo o período de tiempo (beginPosition/endPosition[/timeResolution])

  • format (opcional) : Nombre de formato admitido. El valor predeterminado es el primer formato compatible con el nombre en tif o el primer formato compatible.

  • crs (opcional): CRS en el formato AUTORIDAD:IDENTIFICADOR, p. ej. EPSG:4326. El valor predeterminado es EPSG:4326, si es que es compatible, o si no el primer CRS compatible.

  • nombre de usuario (opcional): Nombre de usuario para la autenticación básica.

  • contraseña (opcional): Contraseña para la autenticación básica.

  • IgnoreGetMapUrl (opcional, hack): si se especifica (establecido en 1), ignore la dirección URL de GetCoverage anunciada por GetCapabilities. Puede ser necesario si un servidor no está configurado correctamente.

  • InvertAxisOrientation (opcional, hack): si se especifica (establecido en 1), cambie el eje en la solicitud GetCoverage. Puede ser necesario para un CRS geográfico si un servidor está utilizando un orden de eje incorrecto.

  • IgnoreAxisOrientation (opcional, hack): Si se especifica (establecido en 1), no invierta la orientación del eje de acuerdo con el estándar WCS para un CRS geográfico.

  • cache (opcional): control de carga de caché, como se describe en QNetworkRequest::CacheLoadControl, pero la solicitud se reenvía como PreferCache si falló con AlwaysCache. Valores permitidos: AlwaysCache, PreferCache, PreferNetwork, AlwaysNetwork. El valor predeterminado es AlwaysCache.

Como alternativa se puede cargar una capa ráster desde un servidor WMS. Sin embargo actualmente no es posible acceder a las respuestas de GetCapabilities desde el API — se debe saber que capas desea:

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. Instancia QgsProject

Si desea utilizar las capas abiertas para la representación, no olvide agregarlas a la instancia de QgsProject. La instancia QgsProject toma la posesión de las capas y más adelante, se puede acceder desde cualquier parte de la aplicación mediante su identificador único . Cuando la capa se elimina del proyecto, también se elimina. Las capas pueden ser eliminadas por el usuario en la interfaz QGIS, o a través de Python usando el método removeMapLayer().

Añadir una capa al proyecto actual, se puede realizar, utilizando el método addMapLayer() :

QgsProject.instance().addMapLayer(rlayer)

Para agregar una capa en una posición 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))

Si quiere remover una capa utilice el método removeMapLayer() :

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

En el código anterior, el identificador de la capa es pasado (puede obtenerlo llamando el método id() que pertenece a la capa), pero también puede hacerlo pasando el objeto capa en si mismo.

Para una lista de capas cargadas y sus identificadores, use el método mapLayers() :

QgsProject.instance().mapLayers()