3. 加载层
提示
此页面上的代码片段需要以下导入:
import os # This is is needed in the pyqgis console also
from qgis.core import (
QgsVectorLayer
)
让我们打开一些包含数据的层。QGIS可以识别矢量层和栅格层。此外,自定义层类型是可用的,但我们不会在这里讨论它们。
3.1. 矢量层
要创建向量层实例并将其添加到项目中,请指定层的数据源标识符、层的名称和提供程序的名称:
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)
数据源标识符是一个字符串,它特定于每个矢量数据提供程序。层的名称在层列表小工具中使用。检查是否已成功加载层非常重要。如果不是,则返回无效的Layer实例。
对于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)
在QGIS中打开和显示矢量图层的最快方法是 addVectorLayer()
的方法。 QgisInterface
:
vlayer = iface.addVectorLayer(path_to_airports_layer, "Airports layer", "ogr")
if not vlayer:
print("Layer failed to load!")
这将在一步中创建一个新层并将其添加到当前QGIS项目中(使其显示在层列表中)。该函数返回Layer实例或 None
如果无法加载层,则。
以下列表显示了如何使用矢量数据提供程序访问各种数据源:
GDAL库(shapefile和许多其他文件格式)-数据源是文件的路径:
对于Shapefile:
vlayer = QgsVectorLayer("testdata/airports.shp", "layer_name_you_like", "ogr") QgsProject.instance().addMapLayer(vlayer)
对于DXF(请注意数据源URI中的内部选项):
uri = "testdata/sample.dxf|layername=entities|geometrytype=Polygon" vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr") QgsProject.instance().addMapLayer(vlayer)
PostGIS数据库-数据源是一个字符串,其中包含创建到PostgreSQL数据库的连接所需的所有信息。
QgsDataSourceUri
类可以为您生成此字符串。请注意,QGIS必须使用Postgres支持进行编译,否则此提供程序不可用: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")
备注
这个
False
参数传递给uri.uri(False)
防止扩展身份验证配置参数,如果您未使用任何身份验证配置,则此参数不会产生任何影响。
CSV或其他带分隔符的文本文件-要打开以分号作为分隔符、以字段“x”作为X坐标、以字段“y”作为Y坐标的文件,您可以使用如下内容:
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)
备注
提供程序字符串的结构为URL,因此路径必须以
file://
。此外,它还允许WKT(熟知文本)格式化几何作为替代x
和y
字段,并允许指定坐标参考系。例如:uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
GPX文件-“GPX”数据提供者从GPX文件中读取轨迹、路线和路点。要打开文件,需要将类型(轨迹/路线/路点)指定为url的一部分:
uri = "testdata/layers.gpx?type=track" vlayer = QgsVectorLayer(uri, "layer name you like", "gpx") QgsProject.instance().addMapLayer(vlayer)
SpatiaLite数据库-类似于PostGIS数据库,
QgsDataSourceUri
可用于生成数据源标识符: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的几何,通过GDAL-数据源是表的连接字符串:
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连接:使用URI和使用
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")
URI可以使用标准的
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))
备注
可以通过调用以下方法更改现有图层的数据源 setDataSource()
在一个 QgsVectorLayer
实例,如下例所示:
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. 栅格图层
对于栅格文件的访问,使用GDAL库。它支持多种文件格式。如果您在打开某些文件时遇到问题,请检查您的GDAL是否支持特定格式(默认情况下,并非所有格式都可用)。要从文件加载栅格,请指定其文件名和显示名称:
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!")
要从地理包加载栅格,请执行以下操作:
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!")
与矢量图层类似,可以使用的addRasterLayer函数加载栅格图层 QgisInterface
对象:
iface.addRasterLayer(path_to_tif, "layer name you like")
这将在一个步骤中创建一个新层并将其添加到当前项目(使其显示在层列表中)。
要加载PostGIS栅格,请执行以下操作:
与PostGIS矢量类似,可以使用URI字符串将PostGIS栅格添加到项目中。为数据库连接参数保留一个可重复使用的字符串字典是有效的。这使得为适用的连接编辑词典变得很容易。然后使用‘postgresraster’提供程序元数据对象将词典编码到URI中。之后,可以将栅格添加到项目中。
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")
也可以从WCS服务创建栅格图层:
layer_name = 'modis'
url = "https://demo.mapserver.org/cgi-bin/wcs?identifier={}".format(layer_name)
rlayer = QgsRasterLayer(uri, 'my wcs layer', 'wcs')
以下是WCS URI可以包含的参数的说明:
WCS URI由以下部分组成 key=value 由分隔的对 &
。它的格式与URL中的查询字符串相同,编码方式也相同。 QgsDataSourceUri
应用于构造URI,以确保对特殊字符进行正确编码。
url (必需):WCS服务器URL。请勿在URL中使用版本,因为每个版本的WCS使用不同的参数名称 GetCapabilities 版本,请参阅参数版本。
identifier (必填):覆盖范围名称
time (可选):时间位置或时间段(开始位置/结束位置 [/timeResolution] )
format (可选):支持的格式名称。默认格式是名称中带有tif的第一个支持的格式或第一个支持的格式。
crs (可选):CRS格式为AUTHORITY:ID,例如EPSG:4326。默认为EPSG:4326(如果支持)或第一个支持的CRS。
username (可选):基本身份验证的用户名。
password (可选):基本身份验证的密码。
IgnoreGetMapUrl (可选,Hack):如果指定(设置为1),则忽略GetCapables通告的GetCoverage URL。如果服务器配置不正确,则可能需要。
InvertAxisOrientation (可选,Hack):如果指定(设置为1),则切换GetCoverage请求中的轴。如果服务器使用错误的轴顺序,则可能需要对地理CRS执行此操作。
IgnoreAxisOrientation (可选,HACK):如果指定(设置为1),则不会根据地理CRS的WCS标准反转轴方向。
cache (可选):缓存加载控制,如QNetworkRequest::CacheLoadControl中所述,但如果使用Always缓存失败,则请求将作为PferCache重新发送。允许值:Alway sCache、PferCache、PferNetwork、Alway sNetwork。默认设置为Always缓存。
或者,也可以从WMS服务器加载栅格图层。然而,目前无法从API访问GetCapability响应-您必须知道您想要什么层:
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实例
如果要使用打开的层进行渲染,请不要忘记将它们添加到 QgsProject
举个例子。这个 QgsProject
实例拥有层的所有权,以后可以通过其唯一ID从应用程序的任何部分访问这些层。当从项目中删除该层时,它也会被删除。用户可以在QGIS界面中移除图层,也可以使用 removeMapLayer()
方法。
将层添加到当前项目是使用 addMapLayer()
方法:
QgsProject.instance().addMapLayer(rlayer)
要在绝对位置添加层,请执行以下操作:
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))
如果要删除该层,请使用 removeMapLayer()
方法:
# QgsProject.instance().removeMapLayer(layer_id)
QgsProject.instance().removeMapLayer(rlayer.id())
在上面的代码中,传递了层id(您可以通过调用 id()
方法),但也可以传递Layer对象本身。
有关已加载的层和层ID的列表,请使用 mapLayers()
方法:
QgsProject.instance().mapLayers()