目录
3 加载图层
3.1 矢量图层
3.2 栅格图层
3.3 QgsProject 实例
此页面上的代码片段需要导入以下模块:
import os # pyqgis控制台同样需要
from qgis.core import (
QgsVectorLayer
)
让我们用数据打开一些图层。QGIS可识别矢量和栅格图层。此外,自定义图层类型也可以使用,但我们不打算在此讨论它们。
创建一个矢量图层实例,指定图层的数据源标识符、图层名称和提供者名称:
# 获取shapefile的路径,例如:/home/project/data/ports.shp
path_to_ports_layer = os.path.join(QgsProject.instance().homePath(), "data", "ports", "ports.shp")
# 格式为:
# vlayer = QgsVectorLayer(data_source, layer_name, provider_name)
vlayer = QgsVectorLayer(path_to_ports_layer, "Ports layer", "ogr")
if not vlayer.isValid():
print("图层加载失败!")
数据源标识符是一个字符串,它特定于每个矢量数据提供者。图层名称用于图层列表组件。检查图层是否已成功加载非常重要。如果不是,则返回无效的图层实例。
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("图层加载失败!")
在QGIS中打开并显示的矢量图层的最快方式是QgisInterface类
的 addVectorLayer()
方法:
vlayer = iface.addVectorLayer(path_to_ports_layer, "Ports layer", "ogr")
if not vlayer:
print("图层加载失败!")
这将创建一个新图层,并将其添加到当前QGIS项目中(使其显示在图层列表中)。该函数返回图层实例,如果无法加载图层则返回None
。
以下列表展示了如何使用矢量数据提供者访问各种数据源:
Shapefile:
vlayer = QgsVectorLayer("/path/to/shapefile/file.shp", "layer_name_you_like", "ogr")
dxf(注意数据源uri中的内部选项):
uri = "/path/to/dxffile/file.dxf|layername=entities|geometrytype=Point"
vlayer = QgsVectorLayer(uri, "layer_name_you_like", "ogr")
QgsDataSourceUri
类可以为你生成这个字符串。请注意,必须在编译QGIS时支持Postgres,否则此提供者不可用:uri = QgsDataSourceUri()
# 设置host,端口,数据库名,用户名和密码
uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")
# 设置数据库schema,表名,几何列和可选项(WHERE 语句)
uri.setDataSource("public", "roads", "the_geom", "cityid = 2643")
vlayer = QgsVectorLayer(uri.uri(False), "layer name you like", "postgres")
小贴士:uri.uri(False)中的False参数可以防止扩展认证配置参数,如果你没有使用任何身份验证配置,则此参数不会产生任何差异。
uri = "/some/path/file.csv?delimiter={}&xField={}&yField={}".format(";", "x","y")
vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext")
小贴士:提供者的字符串作为URL,因此路径必须以file://为前缀。它还允许WKT((well known text)格式的几何作为`x`和`y`字段的替代,并允许指定坐标参考系统。例如:
uri = "file:///some/path/file.csv?delimiter={}&crs=epsg:4723&wktField={}".format(";", "shape")
uri = "path/to/gpx/file.gpx?type=track"
vlayer = QgsVectorLayer(uri, "layer name you like", "gpx")
QgsDataSourceUri
可用于生成数据源标识符: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')
uri = "MySQL:dbname,host=localhost,port=3306,user=root,password=xxx|layername=my_table"
vlayer = QgsVectorLayer( uri, "my table", "ogr" )
WFS
提供者:uri = "http://localhost:8080/geoserver/wfs?srsname=EPSG:23030&typename=union&version=1.0.0&request=GetFeature&service=WFS",
vlayer = QgsVectorLayer(uri, "my wfs layer", "WFS")
可以使用标准库`urllib`创建uri :
params = {
'service': 'WFS',
'version': '1.0.0',
'request': 'GetFeature',
'typename': 'union',
'srsname': "EPSG:23030"
}
uri = 'http://localhost:8080/geoserver/wfs?' + urllib.unquote(urllib.urlencode(params))
小贴士:可以通过调用QgsVectorLayer
的 setDataSource()
方法更改现有图层的数据源,如下面的例子:
# vlayer是一个矢量图层,uri是一个QgsDataSourceUri实例
vlayer.setDataSource(uri.uri(), "layer name you like", "postgres")
访问栅格文件,用到了GDAL库。它支持多种文件格式。如果你在打开某些文件时遇到问题,请检查你的GDAL是否支持(默认情况下并非所有格式都可用)。从文件加载栅格,需要指定其文件名和显示名称:
# 获取tif文件的路径,例如:/home/project/data/srtm.tif
path_to_tif = os.path.join(QgsProject.instance().homePath(), "data", "srtm.tif")
rlayer = QgsRasterLayer(path_to_tif, "SRTM layer name")
if not rlayer.isValid():
print("图层加载失败!")
从geopackage中加载栅格:
# 获取地理数据包的路径,例如:/home/project/data/data.gpkg
path_to_gpkg = os.path.join(QgsProject.instance().homePath(), "data", "data.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")
这将创建一个新图层,并将其添加到当前项目中(使其显示在图层列表中)。
也可以从WCS服务创建栅格图层:
layer_name = 'modis'
uri = QgsDataSourceUri()
uri.setParam('url', 'http://demo.mapserver.org/cgi-bin/wcs')
uri.setParam("identifier", layer_name)
rlayer = QgsRasterLayer(str(uri.encodedUri()), '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("图层加载失败!")
如果您想使用打开的图层进行渲染,请不要忘记将它们添加到QgsProject
实例中。该QgsProject
实例获取图层的所有权,可以通过其唯一ID从应用程序的任何部分访问它们。从项目中删除图层时,它也会被删除。用户可以在QGIS界面中删除图层,也可以使用removeMapLayer()
方法通过Python删除图层。
使用addMapLayer()
方法将图层添加到当前项目:
QgsProject.instance().addMapLayer(rlayer)
在绝对位置添加图层:
# 首先添加图层但不显示
QgsProject.instance().addMapLayer(rlayer, False)
# 在项目中获取图层树的根图层组合
layerTree = iface.layerTreeCanvasBridge().rootGroup()
# position是一个从0开始的数字,-1表示结束
layerTree.insertChildNode(-1, QgsLayerTreeLayer(rlayer))
如果要删除图层,使用removeMapLayer()
方法:
QgsProject.instance().removeMapLayer(rlayer.id())
在上面的代码中,传递了图层ID(您可以调用图层的id()
方法),但您也可以传递图层对象本身。
获取已加载图层和图层ID的列表,使用mapLayers()
方法:
QgsProject.instance().mapLayers()
写在最后:文中难免有翻译错误,欢迎您的指正。完整版翻译请移步PyQGIS开发者手册-完整版