QGIS相关API用法汇总(一)
QGIS相关API用法汇总
QGIS的API参见官方文档:《QGIS API Documentation 3.22.4-Białowieża (ce8e65e95e)》。
本文仅仅记录自己在项目中用到的API,记录自己的理解和总结。
QGIS库的五个包:
qgis.core | 这样可以访问整个QGIS中使用的核心GIS功能。 |
qgis.gui | 这定义了一系列GUI小部件,您可以在自己的程序中包含这些小部件。 |
qgis.analysis | 这提供了空间分析工具来分析矢量和栅格格式数据。 |
qgis.networkanalysis | 这提供了构建和分析拓扑的工具。 |
qgis.utils | 这实现了各种功能,允许您使用Python使用QGIS应用程序。 |
前两个包(qgis.core和qgis.gui)实现了QGIS库中最重要的部分,值得花一些时间来熟悉它们定义的概念和类。现在让我们仔细看看这两个包。
qgis.core包
qgis.core包定义了整个QGIS系统中使用的基本类。该软件包的很大一部分专门用于处理矢量和栅格格式的地理空间数据,并在地图中显示这些类型的数据。我们来看看这是如何完成的。
地图和地图图层
地图由一个在另一个上面绘制的多个图层组成:
我们用的最多的三种类型的地图图层如下:
- 矢量图层:此图层绘制地理空间要素,如点,线和多边形
- 栅格图层:此图层将栅格(位图)数据绘制到地图上
- 插件层:此图层允许插件直接绘制到地图上。
所有的图层类从QgsMapLayer派生,从下图可以看到有多少个图层类及派生关系:
这些类型的地图图层中的每一个都在qgis.core库中具有相应的类。例如,矢量地图图层将由qgis.core.QgsVectorLayer类型的对象表示。
我们将很快详细介绍矢量和栅格地图图层。但是,在我们这样做之前,我们需要了解地理空间数据(矢量和栅格数据)如何
定位在地图上。
协调参考系统
由于地球是一个三维物体,地图只会将地球表面表示为一个二维平面,因此必须有一种方法将地球表面上的点转换为地图内的(x, y)坐标。这是使用坐标参考系统(CRS)完成的:
地球图片由维基媒体提供(http://commons.wikimedia.org/wiki/File:Rotating_globe.gif)
CRS有两个部分:椭圆体,它是地球表面的数学模型,以及投影,它是将球体表面上的点转换为地图上(x, y)坐标的公式。
通常,您不必担心所有这些细节。您只需选择与您正在使用的数据的CRS匹配的相应CRS即可。但是,由于多年来设计了许多不同的坐标参考系统,因此在绘制地理空间数据时使用正确的CRS至关重要。如果不这样做,您的功能将显示在错误的位置或形状错误。
目前可用的大多数地理空间数据使用EPSG 4326坐标参考系统(有时也称为WGS84)。此CRS将坐标定义为纬度和经度值。这是用于导入QGIS的新数据的默认CRS。但是,如果您的数据使用不同的坐标参照系,则需要为地图图层创建和使用不同的CRS。
qgis.core.QgsCoordinateReferenceSystem类表示CRS。创建坐标参照系后,可以在访问基础数据时告诉地图图层使用该CRS。例如:
crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId))
layer.setCrs(crs)
请注意,不同的地图图层可以使用不同的坐标参考系 在将图层的内容绘制到地图上时,每个图层都将使用其CRS。
矢量图层
矢量图层以点,线,多边形等形式将地理空间数据绘制到地图上。矢量格式地理空间数据通常从矢量数据源(例如shapefile或数据库)加载。其他矢量数据源可以将矢量数据保存在存储器中,或者通过因特网从Web服务加载数据。
矢量格式数据源具有许多功能,其中每个功能代表数据源中的单个记录。qgis.core.QgsFeature类表示数据源中的功能。每个功能都有以下原则:
- ID:这是数据源中功能的唯一标识符。
- 几何:这是底层的点,线,多边形等,它代表地图上的特征。例如,表示城市的数据源将为每个城市提供一个要素,几何图形通常是表示城市中心的点,或表示城市轮廓的多边形(或多边形)。
- 属性:这些是键/值对,提供有关该功能的其他信息。例如,城市数据源可能具有total_area,population,elevation等属性。属性值可以是字符串,整数或浮点数。
在QGIS中,数据提供程序允许矢量图层访问数据源中的要素。数据提供程序是qgis.core.QgsVectorDataProvider的一个实例,包括:
- 存储在数据源中的几何类型
- 提供有关为每个要素存储的属性的信息的字段列表
- 使用getFeatures()方法和QgsFeatureRequest类搜索数据源中的功能的能力
您可以使用qgis.core.QgsProviderRegistry类访问各种矢量(以及栅格)数据提供程序。
矢量图层本身由qgis.core.QgsVectorLayer对象表示。每个矢量图层包括:
- 数据提供者:这是与底层文件或数据库的连接,用于保存要显示的地理空间信息
- 坐标参照系:这表示地理空间数据使用的CRS
- 渲染器:选择如何显示要素
让我们仔细看看渲染器的概念以及如何在矢量地图图层中显示要素。
显示矢量数据
矢量地图图层中的要素使用渲染器和符号对象的组合显示。渲染器选择用于给定特征的符号,以及执行实际绘制的符号。
QGIS定义了三种基本类型的符号:
- 标记符号:这将点显示为实心圆
- 线符号:使用给定的线宽和颜色绘制线条
- 填充符号:这将绘制具有给定颜色的多边形的内部
这三种类型的符号实现为qgis.core.QgsSymbolV2类的子类:
- qgis.core.QgsMarkerSymbolV2
- qgis.core.QgsLineSymbolV2
- qgis.core.QgsFillSymbolV2
在内部,符号相当复杂,因为“符号层”允许多个元素彼此重叠绘制。但是,在大多数情况下,您可以使用符号的“简单”版本。这使得在不必处理符号层的内部复杂性的情况下更容易创建新符号。例如:
symbol = QgsMarkerSymbolV2.createSimple({'width': 1.0, 'color':"255,0,0"})
当符号将要素绘制到地图上时,渲染器用于选择绘制特定要素的符号。在最简单的情况下,相同的符号用于图层中的每个要素。这称为单符号渲染器,由qgis.core.QgsSingleSymbolRenderV2类表示。其他可能性包括:
- 分类符号渲染器(qgis.core.QgsCategorizedSymbolRendererV2):此渲染器根据属性值选择符号。分类符号渲染器具有从属性值到符号的映射。
- 渐变符号渲染器(qgis.core.QgsGraduatedSymbolRendererV2):此类渲染器具有一系列属性,值,并将每个范围映射到适当的符号。
使用单个符号渲染器非常简单:
symbol = ...
renderer = QgsSingleSymbolRendererV2(symbol)
layer.setRendererV2(renderer)
要使用分类符号渲染器,首先要定义qgis.core列表。QgsRendererCategoryV2对象,然后使用它来创建渲染器。
例如:
symbol_male = ...
symbol_female = ...
categories = [] categories.append(QgsRendererCategoryV2("M", symbol_male, "Male"))
categories.append(QgsRendererCategoryV2("F", symbol_female, "Female"))
renderer = QgsCategorizedSymbolRendererV2("", categories)
renderer.setClassAttribute("GENDER")
layer.setRendererV2(renderer)
请注意,QgsRendererCategoryV2构造函数有三个参数:所需的值,使用的符号以及用于描述该类别的标签。
最后,要使用渐变符号渲染器,您可以定义qgis.core.QgsRendererRangeV2对象的列表,然后使用它来创建渲染器。例如:
symbol1 = ...
symbol2 = ...
ranges = [] ranges.append(QgsRendererRangeV2(0, 10, symbol1, "Range 1"))
ranges.append(QgsRendererRange(11, 20, symbol2, "Range 2"))
renderer = QgsGraduatedSymbolRendererV2("", ranges)
renderer.setClassAttribute("FIELD")
layer.setRendererV2(renderer)
访问矢量数据
除了在地图中显示矢量图层的内容之外,您还可以直接访问基础数据。这可以使用数据提供程序的getFeatures()方法完成。例如,要迭代图层中的所有要素,您可以执行以下操作:
provider.getFeatures(QgsFeatureRequest())
中的功能的provider = layer.dataProvider():
...
如果要根据某些条件搜索要素,可以使用QgsFeatureRequest对象的setFilterExpression()方法,如下所示:
provider = layer.dataProvider()
request = QgsFeatureRequest()
request.setFilterExpression('"GENDER"="M"')
for provider.getFeatures(QgsFeatureRequest())中的功能:
...
获得这些功能后,可以轻松访问功能的几何,ID 和属性。例如:
geometry = feature.geometry()
id = feature.id()
name = feature.attribute("NAME")
由feature.geometry()调用返回的对象(将是qgis.core.QgsGeometry的实例)表示要素的几何。此对象有许多方法可用于提取基础数据并执行各种地理空间计算。
空间索引
在上一节中,我们根据属性值搜索了要素。但是,有时您可能希望根据它们在太空中的位置找到特征。例如,您可能希望查找位于给定点的特定距离内的所有要素。为此,您可以使用空间索引,该索引根据功能的位置和范围对功能进行索引。空间索引由QgsSpatialIndex类在QGIS中表示。
出于性能原因,不会为每个矢量图层自动创建空间索引。但是,在您需要时可以轻松创建一个:
provider = layer.dataProvider()
index = QgsSpatialIndex()
用于provider.getFeatures(QgsFeatureRequest())中的
功能:index.insertFeature(feature)
不要忘记您可以使用QgsFeatureRequest.SetFilterExpression()方法来限制添加到索引的功能集。
获得空间索引后,可以使用它根据要素的位置执行查询。特别是:
- 您可以使用nearestNeighbor()方法找到最接近给定点的一个或多个要素。例如:
features = index.nearestNeighbor(QgsPoint(long,lat),5)
请注意,此方法有两个参数:作为QgsPoint对象的所需点和要返回的要素数。
- 您可以使用intersects()方法找到与给定矩形区域相交的所有要素,如下所示:
features = index.intersects(QgsRectangle(左,下,右,上))
栅格图层
栅格格式的地理空间数据本质上是位图图像,其中图像中的每个像素或“单元”对应于地球表面的特定部分。栅格数据通常被组织成频带,其中每个频带代表不同的信息。波段的常见用途是将像素颜色的红色,绿色和蓝色分量存储在单独的波段中。波段也可能代表其他类型的信息,例如湿度,海拔或土壤类型。
有许多方法可以显示栅格信息。例如:
- 如果栅格数据只有一个波段,则像素值可以用作调色板的索引。调色板将每个像素值映射映射到特定颜色。
- 如果栅格数据只有一个波段但没有提供调色板。像素值可以直接用作灰度值; 也就是说,数字越大,数字越小。或者,可以通过伪彩色算法传递像素值以计算要显示的颜色。
- 如果栅格数据具有多个频带,则通常将频带组合以生成期望的颜色。例如,一个波段可能代表颜色的红色分量,另一个波段可能代表绿色分量,而另一个波段可能代表蓝色分量。
- 或者,可以通过选择用于颜色计算的特定频带,使用调色板或作为灰度或伪彩色图像来绘制多频带光栅数据源。
让我们仔细看看如何将光栅数据绘制到地图上。
显示栅格数据
与栅格波段关联的绘图样式控制栅格数据的显示方式。目前支持以下绘图样式:
绘画风格 | 描述 |
PalettedColor | 对于单波段栅格数据源,调色板将每个栅格值映射为颜色。 |
SingleBandGray | 对于单波段栅格数据源,栅格值直接用作灰度值。 |
SingleBandPseudoColor | 对于单波段栅格数据源,栅格值用于计算伪彩色。 |
PalettedSingleBandGray | 对于具有调色板的单波段栅格数据源,此绘图样式告诉QGIS忽略调色板并直接将栅格值用作灰度值。 |
PalettedSingleBandPseudoColor | 对于具有调色板的单波段栅格数据源,此绘图样式告诉QGIS忽略调色板并使用栅格值计算伪彩色。 |
MultiBandColor | 对于多波段栅格数据源,请为红色,绿色和蓝色组件中的每一个使用单独的波段。对于此绘图样式,可以使用setRedBand(),setGreenBand()和setBlueBand()方法来选择要用于每个颜色分量的波段。 |
MultiBandSingleBandGray | 对于多波段栅格数据源,请选择单个波段作为灰度颜色值。对于此绘图样式,请使用setGrayBand()方法指定要使用的波段。 |
MultiBandSingleBandPseudoColor | 对于多波段栅格数据源,选择用于计算伪彩色的单个波段。对于此绘图样式,请使用setGrayBand()方法指定要使用的波段。 |
要设置绘图样式,请使用layer.setDrawingStyle()方法,传入包含所需绘图样式名称的字符串。您还需要调用各种setXXXBand()方法(如上表所述),以告诉栅格图层哪些波段包含用于绘制每个像素的值。
请注意,当您调用前面的函数来更改栅格数据的显示方式时,QGIS不会自动更新地图。要立即显示更改,您需要执行以下操作:
- 关闭光栅图像缓存。这可以通过调用layer.setImageCache(None)来完成。
- 通过调用layer.triggerRepaint()告诉栅格图层重绘自身。
访问栅格数据
provider = layer.dataProvider()
values = provider.identify(QgsPoint(x, y), QgsRaster.IdentifyFormatValue)
if values.isValid():
for band, values in values.results().items():
...
如您所见,您需要检查栅格数据中是否存在给定坐标(使用isValid()调用)。values.results()方法返回一个将band编号映射到值的字典。
使用此技术,您可以提取与栅格图层中给定坐标关联的所有基础数据。
您还可以使用Provider.Block()方法一次性检索大量坐标的波段数据。我们将在本文后面介绍如何执行此操作。
其他有用的qgis.core类
除了处理数据源和地图图层所涉及的所有类和功能之外,qgis.core库还定义了许多您可能会觉得有用的其他类:
类 | 描述 |
QgsProject | 这代表了当前的QGIS项目。请注意,这是一个单例对象,因为一次只能打开一个项目。所述QgsProject类负责加载和存储的特性,其可以是对插件有用。 |
QGIS | 该类定义了整个QGIS系统中使用的各种常量,数据类型和函数。 |
QgsPoint | 这是一个通用类,用于存储二维平面内点的坐标。 |
QgsRectangle | 这是一个通用类,用于存储二维平面内矩形区域的坐标。 |
QgsRasterInterface | 这是用于处理栅格数据的基类。这可以用于将一组栅格数据重新投影到新的坐标系中,应用滤镜来更改栅格数据的亮度或颜色,重新采样栅格数据,以及通过渲染现有数据来生成新的栅格数据各种方式。 |
QgsDistanceArea | 此类可用于计算给定几何体的距离和面积,自动从源坐标参考系统转换为米。 |
QgsMapLayerRegistry | 此类提供对当前项目中所有已注册地图图层的访问。 |
QgsMessageLog | 此类提供QGIS程序中的常规日志记录功能。这使您可以将调试消息,警告和错误发送到QGIS“日志消息”面板。 |
qgis.gui包
qgis.gui包定义了许多可以包含在程序中的用户界面小部件。让我们从查看最重要的qgis.gui类开始,然后简要介绍一下您可能会觉得有用的其他类。
QgisInterface类
QgisInterface表示QGIS系统的用户界面。它允许以编程方式访问地图画布,菜单栏和QGIS应用程序的其他部分。在脚本或插件中运行Python代码时,或直接从QGIS Python控制台运行时,通常可以通过iface全局变量引用QgisInterface。
您可以使用QgisInterface对象执行的一些更重要的事情是:
- 通过legendInterface()方法获取当前QGIS项目中的图层列表的引用。
- 使用mapCanvas()方法获取对主应用程序窗口中显示的地图画布的引用。
- 使用activeLayer()方法检索项目中当前活动的图层,并使用setActiveLayer()方法设置当前活动图层。
- 通过调用mainWindow()方法获取对应用程序主窗口的引用。如果要创建
使用主窗口作为其父窗口的其他Qt窗口或对话框,这将非常有用。 - 通过调用messageBar()方法获取对QGIS系统消息栏的引用。这允许您直接在QGIS主窗口中向用户显示消息。
QgsMapCanvas类
地图画布负责将各种地图图层绘制到窗口中。QgsMapCanvas类表示地图画布。这堂课包括:
-
当前显示的地图图层列表。这可以使用layers()方法访问。
请注意,地图画布中可用的地图图层列表与QgisInterface.LegendInterface()方法中包含的地图图层列表之间存在细微差别。地图画布的图层列表仅包含当前可见的图层列表,而QgisInterface.LegendInterface()则返回所有地图图层,包括当前隐藏的图层。
- 此地图使用的地图单位(米,英尺,度等)。可以通过调用mapUnits()方法来检索地图的单位。
- 范围,即当前在画布中显示的地图区域。地图的范围将随着用户放大和缩小而变化,并在地图上平移。可以通过调用extent()方法获取当前地图范围。
- 一种当前地图工具,用于控制用户与地图画布内容的交互。可以使用setMapTool()方法设置当前地图工具,并且可以通过调用mapTool()方法检索当前地图工具(如果有)。
- 用于在所有地图图层后面绘制背景的背景颜色。您可以通过调用canvasColor()方法更改地图的背景颜色。
- 从地图坐标(即数据源的坐标参考系中的坐标)转换为窗口内的像素的坐标变换。您可以通过调用getCoordinateTransform()方法来检索当前坐标转换。
QgsMapCanvasItem类
地图画布项是在地图画布顶部绘制的项。地图画布项目将显示在地图图层的前面。虽然如果要在地图画布上绘制自定义项目,可以创建自己的QgsMapCanvasItem子类,但是使用现有的子类来为您完成工作会更有用。目前有三个QgsMapCanvasItem的子类,您可能会发现它们很有用:
- QgsVertexMarker:这会绘制一个以地图上给定点为中心的图标(“X”,“+”或小方框)。
- QgsRubberBand:这会在地图上绘制任意多边形或折线。当用户在地图上绘制多边形时,它旨在提供视觉反馈。
- QgsAnnotationItem:用于以连接到要素的气球形式显示有关要素的其他信息。QgsAnnotationItem类具有各种子类,允许您自定义信息的显示方式。
QgsMapTool类
地图工具允许用户与地图画布交互并操纵地图画布,捕获鼠标事件并进行适当的响应。许多QgsMapTool子类提供标准的地图交互行为,例如单击以放大,拖动以平移地图,以及单击要识别的特征。您还可以通过继承QgsMapTool并实现响应用户界面事件的各种方法(如按下鼠标按钮,拖动画布等)来创建自己的自定义地图工具。
创建地图工具后,您可以允许用户通过将地图工具与工具栏按钮相关联来激活它。或者,您可以通过调用mapCanvas.setMapTool(...)方法在Python代码中激活它。
我们将在下表中使用PyQGIS库一节中查看创建自定义地图工具的过程:
其他有用的qgis.gui类
虽然qgis.gui包定义了大量类,但您最有可能发现有用的类在下表中给出:
类 | 描述 |
QgsLegendInterface | 这样可以访问地图图例,即当前项目中的地图图层列表。请注意,地图图层可以在地图图例中进行分组,隐藏和显示。 |
QgsMapTip | 当用户将鼠标悬停在要素上时,这会在地图画布上显示提示。地图提示将显示该功能的显示字段; 你可以通过调用layer.setDisplayField("FIELD")来设置它。 |
QgsColorDialog | 这是一个允许用户选择颜色的对话框。 |
QgsDialog | 这是一个带有垂直框布局和按钮框的通用对话框,可以轻松地向对话框添加内容和标准按钮。 |
QgsMessageBar | 这是一个用户界面小部件,用于向用户显示非阻止消息。我们查看了上一篇文章中的消息栏类。 |
QgsMessageViewer | 这是一个通用类,它在模式对话框中向用户显示长消息。 |
QgsBlendModeComboBox QgsBrushStyleComboBox QgsColorRampComboBox QgsPenCapStyleComboBox QgsPenJoinStyleComboBox QgsScaleComboBox | 这些QComboBox用户界面小部件允许您提示用户使用各种绘图选项。除了允许用户选择地图比例的QgsScaleComboBox之外,所有其他QComboBox子类都允许用户选择各种Qt绘图选项。 |
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)