Viktigt

Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.

3. Laddning av skikt

Råd

Kodsnuttarna på den här sidan behöver följande import:

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

Låt oss öppna några lager med data. QGIS känner igen vektor- och rasterlager. Dessutom finns det anpassade lagertyper, men vi kommer inte att diskutera dem här.

3.1. Vektorskikt

Om du vill skapa och lägga till en vektorlagerinstans i projektet anger du lagrets datakällsidentifierare. Datakällans identifierare är en sträng och den är specifik för varje vektordataleverantör. Ett valfritt skiktnamn används för att identifiera skiktet i panelen Layers. Det är viktigt att kontrollera om skiktet har laddats på rätt sätt. Om så inte är fallet returneras en ogiltig lagerinstans.

För ett geopackage-vektorlager:

1# get the path to a geopackage
2path_to_gpkg = "testdata/data/data.gpkg"
3# append the layername part
4gpkg_airports_layer = path_to_gpkg + "|layername=airports"
5vlayer = QgsVectorLayer(gpkg_airports_layer, "Airports layer", "ogr")
6if not vlayer.isValid():
7    print("Layer failed to load!")
8else:
9    QgsProject.instance().addMapLayer(vlayer)

Det snabbaste sättet att öppna och visa ett vektorlager i QGIS är metoden addVectorLayer() i klassen QgisInterface:

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

Detta skapar ett nytt lager och lägger till det i det aktuella QGIS-projektet (vilket gör att det visas i lagerlistan) i ett steg. Funktionen returnerar skiktinstansen eller None om skiktet inte kunde laddas.

Följande lista visar hur du får åtkomst till olika datakällor med hjälp av vector data providers:

  • Ogr-leverantören från GDAL-biblioteket stöder en ”stor mängd olika format” <https://gdal.org/en/latest/drivers/vector/index.html>`_, även kallade drivrutiner i GDAL-språk. Exempel är ESRI Shapefile, Geopackage, Flatgeobuf, Geojson, … För format med en enda fil räcker det vanligtvis med filvägen som uri. För geopaket eller dxf kan ett pipseparerat suffix användas för att ange vilket lager som ska laddas.

    • för ESRI Shapefile:

      uri = "testdata/airports.shp"
      vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
    • för Geopackage (observera de interna alternativen i datakällans uri):

      uri = "testdata/data/data.gpkg|layername=airports"
      vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
    • för dxf (notera de interna alternativen i datakällans uri):

      uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon"
      vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
      QgsProject.instance().addMapLayer(vlayer)
      
  • PostGIS-databas - datakälla är en sträng med all information som behövs för att skapa en anslutning till PostgreSQL-databasen.

    QgsDataSourceUri kan generera denna sträng åt dig. Observera att QGIS måste kompileras med stöd för Postgres, annars är den här leverantören inte tillgänglig:

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

    Observera

    Argumentet False som skickas till uri.uri(False) förhindrar utvidgning av parametrarna för autentiseringskonfigurationen, om du inte använder någon autentiseringskonfiguration gör detta argument ingen skillnad.

  • CSV eller andra avgränsade textfiler — för att öppna en fil med semikolon som avgränsare, med fält ”x” för X-koordinat och fält ”y” för Y-koordinat använder du något liknande detta:

    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)
    

    Observera

    Providersträngen är strukturerad som en URL, så sökvägen måste inledas med file://. Den tillåter också WKT (well known text)-formaterade geometrier som ett alternativ till fälten x och y, och tillåter att koordinatreferenssystemet anges. Exempelvis

    uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
    
  • GPX-filer — Dataleverantören ”gpx” läser spår, rutter och waypoints från gpx-filer. För att öppna en fil måste typen (track/route/waypoint) anges som en del av webbadressen:

    uri = "testdata/layers.gpx?type=track"
    vlayer = QgsVectorLayer(uri, "layer name you like", "gpx")
    QgsProject.instance().addMapLayer(vlayer)
    
  • SpatiaLite-databas — På samma sätt som PostGIS-databaser kan QgsDataSourceUri användas för att generera datakällans identifierare:

     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-baserade geometrier, genom GDAL — datakälla är anslutningssträngen till tabellen:

    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-anslutning: anslutningen definieras med en URI och med hjälp av WFS-providern:

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

    URI kan skapas med hjälp av standardbiblioteket 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))
    

Observera

Du kan ändra datakällan för ett befintligt skikt genom att anropa setDataSource() på en QgsVectorLayer-instans, som i följande exempel:

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. Rasterskikt

För åtkomst till rasterfiler används GDAL-biblioteket. Det stöder ett brett utbud av filformat. Om du har problem med att öppna vissa filer, kontrollera om din GDAL har stöd för det specifika formatet (alla format är inte tillgängliga som standard). För att ladda ett raster från en fil, ange dess filnamn och visningsnamn:

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

För att ladda ett raster från ett geopaket:

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

På samma sätt som vektorlager kan rasterlager laddas med hjälp av funktionen addRasterLayer i objektet QgisInterface:

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

Detta skapar ett nytt lager och lägger till det i det aktuella projektet (vilket gör att det visas i lagerlistan) i ett steg.

För att ladda ett PostGIS-raster:

PostGIS-raster kan, på samma sätt som PostGIS-vektorer, läggas till i ett projekt med hjälp av en URI-sträng. Det är effektivt att ha en återanvändbar ordbok med strängar för databasanslutningsparametrarna. Detta gör det enkelt att redigera ordlistan för den aktuella anslutningen. Ordlistan kodas sedan till en URI med hjälp av provider-metadataobjektet ”postgresraster”. Efter det kan rastret läggas till i projektet.

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

Rasterlager kan också skapas från en WCS-tjänst:

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

Här följer en beskrivning av de parametrar som WCS-URI:n kan innehålla:

WCS URI består av nyckel=värde-par separerade med &. Det är samma format som frågesträngen i URL, kodad på samma sätt. QgsDataSourceUri bör användas för att konstruera URI:n för att säkerställa att specialtecken kodas korrekt.

  • url (krävs) : URL till WCS-servern. Använd inte VERSION i URL, eftersom varje version av WCS använder olika parameternamn för GetCapabilities-versionen, se param version.

  • identifierare (krävs) : Namn på täckning

  • time (valfritt) : tidsposition eller tidsperiod (beginPosition/endPosition[/timeResolution])

  • format (valfritt) : Namn på format som stöds. Standard är det första stödda formatet med tif i namnet eller det första stödda formatet.

  • crs (valfritt) : CRS i form av AUTHORITY:ID, t.ex. EPSG:4326. Standard är EPSG:4326 om det stöds eller det första datoriserade bokningssystemet som stöds.

  • användarnamn (valfritt) : Användarnamn för grundläggande autentisering.

  • lösenord (valfritt) : Lösenord för grundläggande autentisering.

  • IgnoreGetMapUrl (valfritt, hack) : Om angivet (satt till 1), ignorera GetCoverage URL som annonseras av GetCapabilities. Kan vara nödvändigt om en server inte är korrekt konfigurerad.

  • InvertAxisOrientation (valfritt, hack) : Om specificerat (satt till 1), byt axel i GetCoverage-begäran. Kan vara nödvändigt för geografiska CRS om en server använder fel axelordning.

  • IgnoreAxisOrientation (valfri, hack) : Om specificerat (satt till 1), invertera inte axelorienteringen enligt WCS-standarden för geografiska CRS.

  • cache (valfritt) : kontroll av cache-laddning, enligt beskrivningen i QNetworkRequest::CacheLoadControl, men begäran skickas på nytt som PreferCache om den misslyckades med AlwaysCache. Tillåtna värden: AlwaysCache, PreferCache, PreferNetwork, AlwaysNetwork. Standardvärdet är AlwaysCache.

Alternativt kan du ladda ett rasterlager från WMS-servern. Men för närvarande är det inte möjligt att komma åt GetCapabilities-svar från API — du måste veta vilka lager du vill ha:

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

Om du vill använda de öppnade lagren för rendering, glöm inte att lägga till dem i QgsProject-instansen. Instansen QgsProject tar över ägandet av lagren och de kan senare nås från vilken del av applikationen som helst med hjälp av sitt unika ID. När lagret tas bort från projektet raderas det också. Lager kan tas bort av användaren i QGIS-gränssnittet, eller via Python med hjälp av metoden removeMapLayer().

Att lägga till ett lager i det aktuella projektet görs med metoden addMapLayer():

QgsProject.instance().addMapLayer(rlayer)

För att lägga till ett lager i en absolut position:

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

Om du vill ta bort lagret använder du metoden removeMapLayer():

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

I koden ovan skickas skiktets id (du kan få det genom att anropa id()-metoden för skiktet), men du kan också skicka själva skiktobjektet.

För en lista över laddade lager och lager-id:n, använd metoden mapLayers():

QgsProject.instance().mapLayers()