3 加载图层
此页面上的代码片段需要导入以下模块:
import os # pyqgis控制台同样需要
from qgis.core import (
QgsVectorLayer
)
让我们使用数据打开一些图层。QGIS可识别矢量和栅格图层。此外,自定义图层类型也可以使用,但我们不打算在此讨论。
3.1 矢量图层
创建一个矢量图层实例,指定图层的数据源标识、图层名称和提供者名称:
1
2
3
4
5
6
7
8
9
10
11
12 # 获取shapefile的路径,例如:/home/project/data/ports.shp
path_to_airports_layer = "testdata/airports.shp"
# 格式为:
# vlayer = QgsVectorLayer(data_source, layer_name, provider_name)
vlayer = QgsVectorLayer ( path_to_ports_layer , "Airports layer" , "ogr" )
if not vlayer . isValid ():
print ( "图层加载失败!" )
else :
QgsProject . instance () . addMapLayer ( vlayer )
数据源标识是一个字符串,它特定于每个矢量数据提供者。图层名称用于图层列表部件。检查图层是否已成功加载非常重要。如果不是,则返回无效的图层实例。
geopackage
矢量图层:
# 获取geopackage的路径,例如:/home/project/data/data.gpkg
path_to_gpkg = os . path . join ( QgsProject . instance () . homePath (), "data" , "data.gpkg" )
# 追加图层名称
gpkg_places_layer = path_to_gpkg + "|layername=places"
# 例如:gpkg_places_layer = "/home/project/data/data.gpkg|layername=places"
vlayer = QgsVectorLayer ( gpkg_places_layer , "Places layer" , "ogr" )
if not vlayer . isValid ():
print ( "图层加载失败!" )
else :
QgsProject . instance () . addMapLayer ( vlayer )
在QGIS中打开并显示矢量图层的最快方式是使用QgisInterface
类的 addVectorLayer()
方法:
vlayer = iface . addVectorLayer ( path_to_ports_layer , "Ports layer" , "ogr" )
if not vlayer :
print ( "图层加载失败!" )
这将创建一个新图层,并将其添加到当前QGIS项目中(使其显示在图层列表中)。该函数返回图层实例,如果无法加载图层则返回None
。
以下列表展示了如何使用矢量数据提供者访问各种数据源:
GDAL 库(Shapefile和许多其他文件格式)——数据源是文件的路径:
Shapefile:
vlayer = QgsVectorLayer ( "/path/to/shapefile/file.shp" , "layer_name_you_like" , "ogr" )
QgsProject . instance () . addMapLayer ( vlayer )
dxf(注意数据源uri中的内部选项):
uri = "/path/to/dxffile/file.dxf|layername=entities|geometrytype=Point"
vlayer = QgsVectorLayer ( uri , "layer_name_you_like" , "ogr" )
QgsProject . instance () . addMapLayer ( vlayer )
PostGIS 数据库——数据源是一个字符串,其中包含与PostgreSQL数据库创建连接所需的所有信息。
QgsDataSourceUri
类可以为你生成这个字符串。请注意,必须在编译QGIS时支持Postgres,否则此提供者不可用:
uri = QgsDataSourceUri ()
# 设置主机,端口,数据库名称,用户名和密码
uri . setConnection ( "localhost" , "5432" , "dbname" , "johny" , "xxx" )
# 设置数据库架构,表名,几何列和可选项(WHERE 语句)
uri . setDataSource ( "public" , "roads" , "the_geom" , "cityid = 2643" , "primary_key_field" )
vlayer = QgsVectorLayer ( uri . uri ( False ), "layer name you like" , "postgres" )
: !!! 提示
`uri.uri(False)`中的`False`参数可以防止扩展认证配置参数,如果你没有使用任何身份验证配置,则此参数不会产生任何差异。
: !!! 提示
提供者的字符串作为一个URL,因此路径必须以file://为前缀。它还允许WKT((well known text)格式的几何作为`x`和`y`的替代字段,并允许指定坐标参考系统。例如:
```python
uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
```
GPX文件——“gpx”数据提供者从gpx文件中读取轨迹,路线和路点。要打开文件,需要在url中指定类型(track / route / waypoint):
uri = "path/to/gpx/file.gpx?type=track"
vlayer = QgsVectorLayer ( uri , "layer name you like" , "gpx" )
QgsProject . instance () . addMapLayer ( vlayer )
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 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.geo-solutions.it/geoserver/ows?service=WFS&version=1.1.0&request=GetFeature&typename=geosolutions:regioni"
vlayer = QgsVectorLayer ( uri , "my wfs layer" , "WFS" )
可以使用标准库urllib
创建uri:
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 ))
: !!! 提示
可以通过调用[`QgsVectorLayer`](https://qgis.org/pyqgis/master/core/QgsVectorLayer.html#qgis.core.QgsVectorLayer)的 [`setDataSource()`](https://qgis.org/pyqgis/master/core/QgsMapLayer.html#qgis.core.QgsMapLayer.setDataSource) 方法更改现有图层的数据源,如下面例子:
```python
uri = "https://demo.geo-solutions.it/geoserver/ows?service=WFS&version=1.1.0&request=GetFeature&typename=geosolutions:regioni"
provider_options = QgsDataProvider.ProviderOptions()
# 使用项目的转换上下文
provider_options.transformContext = QgsProject.instance().transformContext()
vlayer.setDataSource(uri, "layer name you like", "WFS", provider_options)
del(vlayer)
```
3.2 栅格图层
访问栅格文件,用到了GDAL库。它支持多种文件格式。如果你在打开某些文件时遇到问题,请检查你的GDAL是否支持(默认情况下并非所有格式都可用)。从文件加载栅格,需要指定其文件名和显示名称:
# 获取tif文件的路径,例如:/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 ( "图层加载失败!" )
从geopackage
中加载栅格:
# 获取geopackage的路径,例如:/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 ( "图层加载失败!" )
与矢量图层类似,可以使用QgisInterface
对象的addRasterLayer
函数加载栅格图层:
iface . addRasterLayer ( "/path/to/raster/file.tif" , "layer name you like" )
这将创建一个新图层,并将其添加到当前项目中(使其显示在图层列表中)。
3.2.1 加载PostGIS栅格图层
PostGIS栅格图层,类似于PostGIS矢量图层,可以使用URI字符串添加到项目中。为数据库连接参数保留可复用字典是有效的。这样可以轻松编辑适用连接的字典。使用postgresraster
提供者的元数据对象将字典编码为URI。之后,可以将栅格图层添加到项目中。
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 uri_config = {
# 数据库参数
'dbname' : 'gis_db' , # 数据库名称
'host' : 'localhost' , # IP地址或者localhost
'port' : '5432' , # 端口
'sslmode' : QgsDataSourceUri . SslDisable , # SslAllow, SslPrefer, SslRequire, SslVerifyCa, SslVerifyFull
# 如果存储在authcfg或服务中,则不需要用户名和密码
'authcfg' : 'QconfigId' , # QGIS认证数据库ID包含连接信息
'service' : None , # 连接数据库的服务
'username' : None , # 用户名
'password' : None , # 密码
# 数据库表和栅格字段信息
'schema' : 'public' , # 数据库架构
'table' : 'my_rasters' , # 数据库表名称
'geometrycolumn' : 'rast' , # 栅格字段名称
'sql' : None , # WHERE查询语句,应该放在字符串末尾。
'key' : None , # 数据库表主键
'srid' : None , # 字符串,指定坐标参考系
'estimatedmetadata' : 'False' , # A boolean value telling if the metadata is estimated.
'type' : None , # WKT字符串,指定WKB类型
'selectatid' : None , # 设置为True可禁用按要素ID进行的选择。
'options' : None , # 不在此列表中的其他PostgreSQL连接选项。
'enableTime' : None ,
'temporalDefaultTime' : None ,
'temporalFieldIndex' : None ,
'mode' : '2' , # GDAL参数, 2 unions raster tiles, 1 adds tiles separately (may require user input)
}
# 删除空参数
uri_config = { key : val for key , val in uri_config . items () if val is not None }
# 获取数据提供者和配置的元数据
md = QgsProviderRegistry . instance () . providerMetadata ( 'postgresraster' )
uri = QgsDataSourceUri ( md . encodeUri ( uri_config ))
# 加载栅格图层到项目
rlayer = iface . addRasterLayer ( uri . uri ( False ), "raster layer name" , "postgresraster" )
3.2.2 加载WCS服务栅格图层:
layer_name = 'nurc:mosaic'
uri = "https://demo.geo-solutions.it/geoserver/ows?identifier= {} " . format ( layer_name )
rlayer = QgsRasterLayer ( uri , 'my wcs layer' , 'wcs' )
以下是WCS URI可以包含的参数说明:
WCS URI由 键=值 对组成,分隔符:&
。它与URL中的查询字符串格式相同,编码方式相同。QgsDataSourceUri
可以用于构造URI以确保正确编码特殊字符。
url (必填):WCS服务器URL。不要在URL中使用VERSION,因为每个版本的WCS对 GetCapabilities 版本使用不同的参数名称,请参阅param版本。
identifier (必填):覆盖范围名称
time (可选):时间位置或时间段(beginPosition / endPosition / timeResolution)
format (可选):支持的格式名称。默认是第一个支持的格式,其名称为tif或第一个支持的格式。
crs (可选):CRS格式为AUTHORITY:ID,例如,EPSG:4326。默认为EPSG:4326(如果支持)或第一个支持的CRS。
username (可选):基本身份验证的用户名。
password (可选):基本身份验证的密码。
IgnoreGetMapUrl (可选,hack):如果指定(设置为1),则忽略GetCapabilities公布的GetCoverage URL。如果未正确配置服务器,则可能需要。
InvertAxisOrientation (可选,hack):如果指定(设置为1),则在GetCoverage请求中切换轴。如果服务器使用错误的轴顺序,则可能需要地理CRS。
IgnoreAxisOrientation (可选,hack):如果指定(设置为1),则不要根据地理CRS的WCS标准反转轴方向。
cache (可选):缓存加载控制,如QNetworkRequest :: CacheLoadControl中所述,但如果使用AlwaysCache失败,请求将重新发送为PreferCache。允许的值:AlwaysCache,PreferCache,PreferNetwork,AlwaysNetwork。默认为AlwaysCache。
另外,你可以从WMS服务器加载栅格图层。但是目前无法从API访问GetCapabilities响应——你必须知道所需的图层:
urlWithParams = 'url=http://irs.gis-lab.info/?layers=landsat&styles=&format=image/jpeg&crs=EPSG:4326'
rlayer = QgsRasterLayer ( urlWithParams , 'some layer name' , 'wms' )
if not rlayer . isValid ():
print ( "图层加载失败!" )
3.3 QgsProject 实例
如果你想使用打开的图层进行渲染,请不要忘记将它们添加到QgsProject
实例中。QgsProject
实例拥有图层的所有权,可以通过其唯一ID从应用程序的任何部分访问它们。从项目中删除图层时,它也会被删除。用户可以在QGIS接口中删除图层,也可以通过Python使用removeMapLayer()
方法删除图层。
使用addMapLayer()
方法将图层添加到当前项目:
QgsProject . instance () . addMapLayer ( rlayer )
在绝对位置添加图层:
# 首先添加图层但不显示
QgsProject . instance () . addMapLayer ( rlayer , False )
# 在项目中获取图层树的根图层组
layerTree = iface . layerTreeCanvasBridge () . rootGroup ()
# 第一个参数是一个从0开始的数字,-1表示结束
layerTree . insertChildNode ( - 1 , QgsLayerTreeLayer ( rlayer ))
如果要删除图层,使用removeMapLayer()
方法:
QgsProject . instance () . removeMapLayer ( rlayer . id ())
在上面的代码中,传递了图层ID(你可以调用图层的id()
方法),但是你也可以传递图层对象本身。
获取已加载图层和图层ID的列表,使用mapLayers()
方法:
QgsProject . instance () . mapLayers ()