3. Lagen laden¶
De codesnippers op deze pagina hebben de volgende import nodig:
import os # This is is needed in the pyqgis console also
from qgis.core import (
QgsVectorLayer
)
Laten we enkele lagen met gegevens openen. QGIS herkent vector- en rasterlagen. Aanvullend zijn aangepaste typen lagen beschikbaar, maar die zullen we hier niet bespreken.
3.1. Vectorlagen¶
Specificeer de identificatie van de gegevensbron van de laag, de naam voor de laag en de naam van de provider om een instance voor een vectorlaag voor het project te maken of toe te voegen:
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)
|
De identificatie van de gegevensbron van de laag is een string en is specifiek voor elke vector gegevensprovider. De naam van de laag wordt gebruikt in de widget Lagenlijst. Het is belangrijk om te controleren of de laag met succes is geladen. Als dat niet zo was wordt een ongeldige instance van de laag teruggegeven.
Voor een laag van 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)
|
De snelste manier om een vectorlaag te openen en weer te geven in QGIS is de addVectorLayer()
van QgisInterface
:
vlayer = iface.addVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
if not vlayer:
print("Layer failed to load!")
Dit maakt een nieuwe laag en voegt die toe aan het huidige project van QGIS (waardoor het verschijnt in de lagenlijst). De functie geeft de instance van de laag terug of None
als de laag niet kon worden geladen.
De volgende lijst geeft weer hoe toegang wordt verkregen tot verscheidene gegevensbronnen met behulp van vector gegevensproviders:
bibliotheek OGR (Shapefiles en vele andere bestandsindelingen) — gegevensbron is het pad naar het bestand:
vpor Shapefile:
vlayer = QgsVectorLayer("testdata/airports.shp", "layer_name_you_like", "ogr") QgsProject.instance().addMapLayer(vlayer)
voor DXF (let op de interne opties in de URI van de gegevensbron):
uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon" vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr") QgsProject.instance().addMapLayer(vlayer)
database PostGIS - gegevensbron is een tekenreeks met alle benodigde informatie om een verbinding naar een database van PostgreSQL te maken.
De klasse
QgsDataSourceUri
kan deze string voor u maken. Onthoud dat QGIS moet worden gecompileerd met ondersteuning voor Postgres, anders is deze provider niet beschikbaar: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")
Notitie
Het argument
False
, doorgegeven aanuri.uri(False)
, voorkomt het uitbreiden van de parameters voor de configuratie voor authenticatie, indien u geen configuratie voor authenticatie gebruikt maakt dit argument geen enkel verschil.
CSV of andere gescheiden tekstbestanden — om een bestand te openen met een punt-komma als scheidingsteken, met veld “x” voor de X-coördinaat en veld “y” voor de Y-coördinaat zou u zoiets als dit gebruiken:
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)
Notitie
De string voor de provider is gestructureerd als een URL, dus moet het pad worden voorafgegaan door file://. Ook staat het als WKT (well known text) opgemaakte geometrieën toe als een alternatief voor velden “X” en “Y”, en staat het toe dat het coördinaten referentiesysteem wordt gespecificeerd. Bijvoorbeeld
uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
GPX-bestanden — de “GPX”-gegevensprovider leest tracks, routes en waypoints uit GPX-bestanden. Het type (track/route/waypoint) moet worden gespecificeerd als deel van de URL om een bestand te openen:
uri = "testdata/layers.gpx?type=track" vlayer = QgsVectorLayer(uri, "layer name you like", "gpx") QgsProject.instance().addMapLayer(vlayer)
database SpatiaLite — Soortgelijk aan databases van PostGIS,
QgsDataSourceUri
kan worden gebruikt voor het maken van de identificatie van de gegevensbron: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)
MySQL op WKB gebaseerde geometrieën, via OGR — gegevensbron is de string voor de verbinding naar de tabel:
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-verbinding: de verbinding wordt gedefinieerd met een URI en het gebruiken van de provider
WFS
: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)
De URI kan worden gemaakt met behulp van de standaard bibliotheek
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))
Notitie
U kunt de gegevensbron van een bestaande laag wijzigen door setDataSource()
op een instance van QgsVectorLayer
aan te roepen, zoals in het volgende voorbeeld:
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. Rasterlagen¶
Voor toegang tot rasterbestanden wordt de bibliotheek GDAL gebruikt. Het ondersteunt een breed scala aan bestandsindelingen. In het geval u problemen hebt met het openen van enkele bestanden, controleer dan of uw GDAL ondersteuning heeft voor die bepaalde indeling (niet alle indelingen zijn standaard beschikbaar). Specificeer zijn bestandsnaam en weergavenaam om een raster uit een bestand te laden:
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!")
|
Raster laden vanuit een 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!")
|
Soortgelijk aan vectorlagen kunnen rasterlagen worden geladen met de functie addRasterLayer van het object QgisInterface
:
iface.addRasterLayer(path_to_tif, "layer name you like")
Dit maakt een nieuwe laag en voegt die in één stap toe aan het huidige project (waardoor het verschijnt in de lagenlijst).
Een raster van PostGIS laden:
Rasters van PostGIS kunnen, soortgelijk aan vectors van PostGIS, aan een project worden toegevoegd met een tekenreeks URI. Het is efficiënt om een woordenboek van tekenreeksen te maken voor de parameters van de verbinding voor de database. Het woordenboek wordt dan geladen in een lege URI, vóór het toevoegen van het raster. Onthoud dat None zou moeten worden gebruikt als het gewenst is de parameter leeg te laten:
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")
|
Rasterlagen kunnen ook worden gemaakt vanuit een service voor WCS:
layer_name = 'nurc:mosaic'
uri = "https://demo.geo-solutions.it/geoserver/ows?identifier={}".format(layer_name)
rlayer = QgsRasterLayer(uri, 'my wcs layer', 'wcs')
Hier is een beschrijving van de parameters die de URI voor WCS mag bevatten:
De URI voor WCS is samengesteld uit paren sleutel=waarde, gescheiden door &
. Het is dezelfde indeling als een tekenreeks voor een query in een URL, op dezelfde manier gecodeerd. QgsDataSourceUri
zou moeten worden gebruikt om de URI te construeren om er voor te zorgen dat speciale tekens op de juiste manier worden gecodeerd.
url (vereist) : WCS Server URL. Gebruik geen VERSION in URL, omdat elke versie van WCS een andere naam voor de parameter voor de versie GetCapabilities gebruikt, zie param versie.
identifier (vereist) : Bedekkingsnaam
time (optioneel) : tijdspositie of tijdsperiode (beginPosition/endPosition[/timeResolution])
format (optioneel) : Ondersteunde naam voor indeling. Standaard is de eerste ondersteunde indeling met tif in de naam of de eerste ondersteunde indeling.
crs (optioneel) : CRS in de vorm AUTHORITY:ID, bijv. EPSG:4326. Standaard is EPSG:4326 indien ondersteund of het eerste ondersteunde CRS.
username (optioneel) : Gebruikersnaam voor basisauthenticatie.
password (optioneel) : Wachtwoord voor basisauthenticatie.
IgnoreGetMapUrl (optioneel, hack) : Indien gespecificeerd (ingesteld op 1), negeer GetCoverage URL aangeboden door GetCapabilities. Kan nodig zijn als een server niet juist is geconfigureerd.
InvertAxisOrientation (optioneel, hack) : Indien gespecificeerd (ingesteld op 1), schakel de as in het verzoek GetCoverage. Kan nodig zijn voor geografisch CRS als een server de verkeerde volgorde voor assen gebruikt.
IgnoreAxisOrientation (optioneel, hack) : Indien gespecificeerd (ingesteld op 1), as-oriëntatie niet omdraaien overeenkomstig de standaard van WCS voor geografisch CRS.
cache (optioneel) : cache laadbeheer, zoals beschreven in QNetworkRequest::CacheLoadControl, maar verzoek wordt opnieuw verzonden als PreferCache indien mislukt met AlwaysCache. Toegestane waarden: AlwaysCache, PreferCache, PreferNetwork, AlwaysNetwork. Standaard is AlwaysCache.
Als alternatief kunt u een rasterlaag laden vanaf een server voor WMS. Momenteel is het echter niet mogelijk om toegang te krijgen tot het antwoord van GetCapabilities van de API — u moet weten welke lagen u wilt:
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. Instance QgsProject¶
Als u de geopende lagen wilt gebruiken voor renderen, vergeet dan niet om ze toe te voegen aan de instance QgsProject
. De instance QgsProject
wordt eigenaar van de lagen en er kan later toegang toe worden verkregen vanuit elk deel van de toepassing door hun unieke ID. Als de laag wordt verwijderd uit het project, wordt hij ook verwijderd. Lagen kunnen door de gebruiker worden verwijderd in de interface van QGIS interface, of via Python met de methode removeMapLayer()
.
Toevoegen van een laag aan het huidige project wordt gedaan met de methode addMapLayer()
:
QgsProject.instance().addMapLayer(rlayer)
Een laag op een absolute positie toevoegen:
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))
|
Als u de laag wilt verwijderen, gebruik dan de methode removeMapLayer()
:
# QgsProject.instance().removeMapLayer(layer_id)
QgsProject.instance().removeMapLayer(rlayer.id())
In de bovenstaande code wordt de laag-ID doorgegeven (die kunt u zien door het aanroepen van de methode id()
van de laag), maar u kunt ook het object laag zelf doorgeven.
Voor een lijst met geladen lagen en laag-ID’s, gebruik de methode mapLayers()
:
QgsProject.instance().mapLayers()