核心架构与模块设计
第三章 核心架构与模块设计
3.1 QGIS整体架构概览
3.1.1 架构设计理念
QGIS采用分层架构设计,遵循以下核心原则:
- 模块化设计:各功能模块相对独立,便于维护和扩展
- 开放标准:遵循OGC标准,支持多种数据格式
- 可扩展性:通过插件机制支持功能扩展
- 跨平台:基于Qt框架实现跨平台支持
- 脚本友好:完整的Python API支持自动化
3.1.2 架构层次图
┌─────────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ QGIS Desktop│ │ QGIS Server │ │ QField │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ GUI层 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ qgis_gui (Qt Widgets) │ │
│ └─────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 核心层 │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ qgis_core │ │qgis_analysis│ │ qgis_3d │ │
│ └────────────┘ └────────────┘ └────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 提供者层 │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ OGR │ │ GDAL │ │ PostGIS │ │ WMS │ │ WFS │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 底层库 │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Qt │ │ GDAL │ │ PROJ │ │ GEOS │ │ SQLite │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │
└─────────────────────────────────────────────────────────────┘
3.1.3 源代码结构
QGIS源代码组织在多个目录中:
qgis/
├── src/
│ ├── core/ # 核心库(不依赖GUI)
│ ├── gui/ # GUI组件
│ ├── analysis/ # 空间分析功能
│ ├── 3d/ # 3D功能
│ ├── app/ # Desktop应用程序
│ ├── server/ # QGIS Server
│ ├── providers/ # 数据提供者
│ │ ├── ogr/
│ │ ├── gdal/
│ │ ├── postgres/
│ │ ├── wms/
│ │ ├── wfs/
│ │ └── ...
│ ├── plugins/ # 核心插件
│ └── ui/ # UI定义文件
├── python/ # Python绑定
│ ├── core/
│ ├── gui/
│ ├── analysis/
│ └── plugins/ # 默认Python插件
├── tests/ # 测试代码
├── resources/ # 资源文件
└── doc/ # 文档
3.2 核心模块详解
3.2.1 qgis_core模块
qgis_core是QGIS的核心库,提供不依赖GUI的基础功能:
主要类别:
| 类别 | 主要类 | 功能 |
|---|---|---|
| 几何 | QgsGeometry, QgsPoint, QgsPolygon | 几何对象操作 |
| 要素 | QgsFeature, QgsFields, QgsAttributes | 要素和属性管理 |
| 图层 | QgsVectorLayer, QgsRasterLayer | 数据图层 |
| 项目 | QgsProject, QgsMapSettings | 项目管理 |
| 坐标系 | QgsCoordinateReferenceSystem | CRS处理 |
| 渲染 | QgsMapRenderer, QgsSymbol | 地图渲染 |
| 表达式 | QgsExpression, QgsExpressionContext | 表达式引擎 |
核心类关系图:
QgsProject (项目容器)
│
├── QgsLayerTree (图层树)
│
├── QgsMapLayer (图层基类)
│ ├── QgsVectorLayer (矢量图层)
│ │ ├── QgsFeatureIterator (要素迭代器)
│ │ ├── QgsFeature (要素)
│ │ │ ├── QgsGeometry (几何)
│ │ │ └── QgsAttributes (属性)
│ │ └── QgsRenderer (渲染器)
│ │
│ └── QgsRasterLayer (栅格图层)
│ └── QgsRasterDataProvider (数据提供者)
│
└── QgsCoordinateReferenceSystem (坐标系)
3.2.2 qgis_gui模块
qgis_gui提供图形界面组件:
主要组件:
| 组件 | 类 | 功能 |
|---|---|---|
| 地图画布 | QgsMapCanvas | 地图显示和交互 |
| 图层面板 | QgsLayerTreeView | 图层管理界面 |
| 属性表 | QgsAttributeTableView | 属性编辑 |
| 字段编辑器 | QgsFieldValidator | 字段值验证 |
| 坐标选择器 | QgsCrsSelector | CRS选择界面 |
| 颜色按钮 | QgsColorButton | 颜色选择 |
| 表达式构建器 | QgsExpressionBuilderWidget | 表达式编辑 |
地图工具类层次:
QgsMapTool (基类)
├── QgsMapToolPan (平移)
├── QgsMapToolZoom (缩放)
├── QgsMapToolIdentify (识别)
├── QgsMapToolSelect (选择)
├── QgsMapToolEmitPoint (点发射)
└── QgsMapToolEdit (编辑工具基类)
├── QgsMapToolAddFeature (添加要素)
├── QgsMapToolMoveFeature (移动要素)
└── QgsMapToolDeletePart (删除部分)
3.2.3 qgis_analysis模块
提供空间分析功能:
分析功能分类:
| 类别 | 类/命名空间 | 功能 |
|---|---|---|
| 矢量分析 | QgsGeometryAnalyzer | 缓冲、叠加、裁剪 |
| 栅格分析 | QgsRasterCalculator | 栅格计算 |
| 插值 | QgsInterpolator | 空间插值 |
| 网络分析 | QgsNetworkAnalysis | 路径分析 |
| 地形分析 | QgsRasterTerrainAnalysis | 坡度、坡向 |
3.2.4 qgis_3d模块
3D可视化功能(QGIS 3.0+):
主要类:
| 类 | 功能 |
|---|---|
| Qgs3DMapScene | 3D场景管理 |
| Qgs3DMapSettings | 3D地图设置 |
| QgsPhongMaterialSettings | 材质设置 |
| QgsTerrainGenerator | 地形生成 |
| Qgs3DSymbol | 3D符号 |
3.3 数据提供者架构
3.3.1 提供者接口
数据提供者是QGIS与数据源之间的桥梁:
QgsDataProvider (抽象基类)
├── QgsVectorDataProvider (矢量数据)
│ ├── QgsOgrProvider (OGR/Shapefile等)
│ ├── QgsPostgresProvider (PostgreSQL/PostGIS)
│ ├── QgsDelimitedTextProvider (CSV/文本)
│ ├── QgsMemoryProvider (内存图层)
│ └── QgsSpatiaLiteProvider (SpatiaLite)
│
└── QgsRasterDataProvider (栅格数据)
├── QgsGdalProvider (GDAL)
└── QgsWmsProvider (WMS服务)
3.3.2 矢量数据提供者
矢量提供者实现QgsVectorDataProvider接口:
核心方法:
class QgsVectorDataProvider : public QgsDataProvider
{
public:
// 要素访问
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request);
virtual long featureCount() const;
// 字段信息
virtual QgsFields fields() const;
// 能力查询
virtual Capabilities capabilities() const;
// 编辑操作
virtual bool addFeatures(QgsFeatureList &features);
virtual bool deleteFeatures(const QgsFeatureIds &ids);
virtual bool changeAttributeValues(const QgsChangedAttributesMap &map);
virtual bool changeGeometryValues(const QgsGeometryMap &map);
// 范围
virtual QgsRectangle extent() const;
// CRS
virtual QgsCoordinateReferenceSystem crs() const;
};
提供者能力标志:
enum Capability
{
NoCapabilities = 0,
AddFeatures = 1,
DeleteFeatures = 1 << 1,
ChangeAttributeValues = 1 << 2,
AddAttributes = 1 << 3,
DeleteAttributes = 1 << 4,
ChangeGeometries = 1 << 5,
SelectAtId = 1 << 6,
CreateSpatialIndex = 1 << 7,
SelectGeometryAtId = 1 << 8,
TransactionSupport = 1 << 9,
CircularGeometries = 1 << 10,
// ...
};
3.3.3 栅格数据提供者
class QgsRasterDataProvider : public QgsDataProvider
{
public:
// 波段信息
virtual int bandCount() const;
virtual Qgis::DataType dataType(int bandNo) const;
// 数据读取
virtual QgsRasterBlock *block(int bandNo, const QgsRectangle &extent, int width, int height);
// 统计信息
virtual QgsRasterBandStats bandStatistics(int bandNo);
// 颜色表
virtual QList<QgsColorRampShader::ColorRampItem> colorTable(int bandNo) const;
// 元数据
virtual QString metadata() const;
};
3.3.4 Web服务提供者
WMS提供者:
# 使用WMS提供者
uri = "url=https://example.com/wms&layers=layer1&format=image/png&crs=EPSG:4326"
layer = QgsRasterLayer(uri, "WMS Layer", "wms")
WFS提供者:
# 使用WFS提供者
uri = "https://example.com/wfs?typename=ns:layer&version=2.0.0"
layer = QgsVectorLayer(uri, "WFS Layer", "WFS")
3.4 插件架构
3.4.1 插件类型
QGIS支持两种插件类型:
| 类型 | 语言 | 特点 |
|---|---|---|
| Python插件 | Python | 易于开发,大多数插件 |
| C++插件 | C++ | 高性能,核心功能扩展 |
3.4.2 Python插件结构
my_plugin/
├── __init__.py # 插件入口
├── metadata.txt # 元数据
├── my_plugin.py # 主模块
├── my_plugin_dialog.py # 对话框
├── resources.qrc # Qt资源
├── resources_rc.py # 编译的资源
├── my_plugin_dialog_base.ui # UI定义
├── icon.png # 图标
├── help/ # 帮助文档
└── i18n/ # 翻译文件
metadata.txt格式:
[general]
name=My Plugin
qgisMinimumVersion=3.0
description=This is a plugin description
version=1.0.0
author=Author Name
email=author@example.com
about=Detailed plugin description
tracker=https://github.com/author/plugin/issues
repository=https://github.com/author/plugin
tags=analysis, vector
homepage=https://example.com
category=Plugins
icon=icon.png
experimental=False
deprecated=False
3.4.3 插件接口
# __init__.py
def classFactory(iface):
"""加载插件类"""
from .my_plugin import MyPlugin
return MyPlugin(iface)
# my_plugin.py
class MyPlugin:
def __init__(self, iface):
"""构造函数
:param iface: QgisInterface实例
"""
self.iface = iface
def initGui(self):
"""初始化GUI,添加菜单和工具栏"""
self.action = QAction("My Plugin", self.iface.mainWindow())
self.action.triggered.connect(self.run)
self.iface.addToolBarIcon(self.action)
self.iface.addPluginToMenu("&My Plugin", self.action)
def unload(self):
"""卸载插件"""
self.iface.removePluginMenu("&My Plugin", self.action)
self.iface.removeToolBarIcon(self.action)
def run(self):
"""执行插件功能"""
pass
3.4.4 QgisInterface
QgisInterface是插件与QGIS主程序交互的接口:
# 常用方法
iface.mapCanvas() # 获取地图画布
iface.activeLayer() # 获取当前活动图层
iface.addVectorLayer() # 添加矢量图层
iface.addRasterLayer() # 添加栅格图层
iface.messageBar() # 消息栏
iface.mainWindow() # 主窗口
iface.layerTreeView() # 图层树视图
# 菜单操作
iface.addPluginToMenu() # 添加到插件菜单
iface.addPluginToVectorMenu() # 添加到矢量菜单
iface.addPluginToRasterMenu() # 添加到栅格菜单
# 工具栏操作
iface.addToolBarIcon() # 添加工具栏图标
iface.addToolBar() # 添加工具栏
3.5 Processing框架
3.5.1 Processing架构
Processing是QGIS的地理处理框架:
Processing Framework
├── QgsProcessingRegistry (算法注册表)
│ └── QgsProcessingProvider (算法提供者)
│ └── QgsProcessingAlgorithm (算法)
│
├── QgsProcessingContext (处理上下文)
├── QgsProcessingFeedback (反馈机制)
│
└── GUI组件
├── ProcessingToolbox (工具箱面板)
├── AlgorithmDialog (算法对话框)
└── ModelDesigner (模型设计器)
3.5.2 算法提供者
内置的算法提供者:
| 提供者 | 说明 |
|---|---|
| native | QGIS原生算法 |
| qgis | QGIS Python算法 |
| gdal | GDAL/OGR工具 |
| grass7 | GRASS GIS算法 |
| saga | SAGA GIS算法 |
| script | 用户脚本 |
| model | 处理模型 |
3.5.3 自定义算法
from qgis.processing import alg
@alg(name='my_algorithm', label='My Algorithm',
group='My Tools', group_label='My Tools')
@alg.input(type=alg.SOURCE, name='INPUT', label='Input layer')
@alg.input(type=alg.DISTANCE, name='BUFFER', label='Buffer distance',
default=10.0)
@alg.input(type=alg.SINK, name='OUTPUT', label='Output layer')
def my_algorithm(instance, parameters, context, feedback, inputs):
"""
自定义处理算法
"""
source = instance.parameterAsSource(parameters, 'INPUT', context)
buffer_dist = instance.parameterAsDouble(parameters, 'BUFFER', context)
(sink, dest_id) = instance.parameterAsSink(
parameters, 'OUTPUT', context,
source.fields(),
QgsWkbTypes.Polygon,
source.sourceCrs()
)
total = source.featureCount()
for current, feature in enumerate(source.getFeatures()):
if feedback.isCanceled():
break
# 创建缓冲区
buffered_geom = feature.geometry().buffer(buffer_dist, 5)
new_feature = QgsFeature()
new_feature.setGeometry(buffered_geom)
new_feature.setAttributes(feature.attributes())
sink.addFeature(new_feature)
feedback.setProgress(int(current / total * 100))
return {'OUTPUT': dest_id}
3.5.4 算法参数类型
| 参数类型 | 常量 | 说明 |
|---|---|---|
| 矢量图层 | SOURCE | 输入矢量源 |
| 栅格图层 | RASTER | 输入栅格 |
| 要素输出 | SINK | 矢量输出 |
| 栅格输出 | RASTER_DESTINATION | 栅格输出 |
| 数值 | NUMBER | 数字输入 |
| 距离 | DISTANCE | 距离值 |
| 字符串 | STRING | 文本输入 |
| 布尔 | BOOLEAN | 是/否 |
| 枚举 | ENUM | 下拉选择 |
| 字段 | FIELD | 字段选择 |
| 表达式 | EXPRESSION | 表达式 |
| CRS | CRS | 坐标系 |
| 范围 | EXTENT | 空间范围 |
3.6 渲染系统
3.6.1 渲染架构
QgsMapCanvas
│
├── QgsMapSettings (地图设置)
│ ├── 范围、CRS、图层列表
│ └── 输出大小、DPI
│
├── QgsMapRendererJob (渲染作业)
│ ├── QgsMapRendererSequentialJob (顺序)
│ └── QgsMapRendererParallelJob (并行)
│
└── 图层渲染
├── QgsVectorLayerRenderer (矢量)
└── QgsRasterLayerRenderer (栅格)
3.6.2 矢量渲染器
矢量图层支持多种渲染器:
| 渲染器 | 类 | 说明 |
|---|---|---|
| 单一符号 | QgsSingleSymbolRenderer | 所有要素相同样式 |
| 分类 | QgsCategorizedSymbolRenderer | 按属性分类 |
| 分级 | QgsGraduatedSymbolRenderer | 按数值分级 |
| 规则 | QgsRuleBasedRenderer | 基于规则 |
| 点位移 | QgsPointDisplacementRenderer | 重叠点处理 |
| 热力图 | QgsHeatmapRenderer | 热力图 |
| 2.5D | Qgs25DRenderer | 伪3D效果 |
3.6.3 符号系统
QgsSymbol (符号基类)
├── QgsMarkerSymbol (点符号)
│ └── QgsMarkerSymbolLayer
│ ├── QgsSimpleMarkerSymbolLayer
│ ├── QgsSvgMarkerSymbolLayer
│ ├── QgsFontMarkerSymbolLayer
│ └── ...
│
├── QgsLineSymbol (线符号)
│ └── QgsLineSymbolLayer
│ ├── QgsSimpleLineSymbolLayer
│ ├── QgsMarkerLineSymbolLayer
│ └── ...
│
└── QgsFillSymbol (面符号)
└── QgsFillSymbolLayer
├── QgsSimpleFillSymbolLayer
├── QgsGradientFillSymbolLayer
├── QgsSVGFillSymbolLayer
└── ...
3.6.4 栅格渲染器
| 渲染器 | 说明 |
|---|---|
| MultiBandColor | 多波段彩色合成 |
| PalettedRaster | 调色板渲染 |
| SingleBandGray | 单波段灰度 |
| SingleBandPseudoColor | 单波段伪彩色 |
| Hillshade | 山体阴影 |
| Contour | 等值线 |
3.7 表达式引擎
3.7.1 表达式系统架构
QgsExpression (表达式解析器)
│
├── 词法分析 → 语法分析 → 语法树
│
├── QgsExpressionContext (上下文)
│ ├── QgsExpressionContextScope (作用域)
│ │ ├── 全局变量
│ │ ├── 项目变量
│ │ └── 图层变量
│ └── QgsFeature (当前要素)
│
└── 函数库
├── 数学函数
├── 字符串函数
├── 几何函数
├── 日期函数
├── 聚合函数
└── 自定义函数
3.7.2 表达式语法
-- 字段引用
"field_name"
-- 算术运算
"population" / "area"
-- 条件表达式
CASE
WHEN "type" = 'A' THEN 'Category A'
WHEN "type" = 'B' THEN 'Category B'
ELSE 'Other'
END
-- 几何函数
$area -- 当前要素面积
$length -- 当前要素长度
buffer($geometry, 100) -- 缓冲区
centroid($geometry) -- 质心
-- 聚合函数
aggregate('layer', 'sum', "value")
count("field", group_by:="category")
-- 变量引用
@project_title
@layer_name
3.7.3 自定义表达式函数
from qgis.core import qgsfunction
@qgsfunction(args='auto', group='Custom')
def my_function(value1, value2, feature, parent):
"""
自定义表达式函数
<h4>语法</h4>
<p>my_function(value1, value2)</p>
<h4>示例</h4>
<p>my_function(10, 20) → 30</p>
"""
return value1 + value2
# 注册函数
QgsExpression.registerFunction(my_function)
# 使用后注销
QgsExpression.unregisterFunction('my_function')
3.8 坐标转换系统
3.8.1 CRS架构
QgsCoordinateReferenceSystem
│
├── 创建方式
│ ├── fromEpsgId(4326)
│ ├── fromProj(proj_string)
│ ├── fromWkt(wkt_string)
│ └── fromOgcWmsCrs("EPSG:4326")
│
├── 属性
│ ├── authid() # "EPSG:4326"
│ ├── description() # "WGS 84"
│ ├── mapUnits() # 地图单位
│ └── isGeographic() # 是否地理坐标系
│
└── QgsCoordinateTransform (坐标转换)
├── transform(point)
├── transformBoundingBox(rect)
└── transformCoords(count, x, y, z)
3.8.2 坐标转换示例
from qgis.core import (
QgsCoordinateReferenceSystem,
QgsCoordinateTransform,
QgsProject,
QgsPointXY
)
# 定义源和目标CRS
source_crs = QgsCoordinateReferenceSystem("EPSG:4326") # WGS84
dest_crs = QgsCoordinateReferenceSystem("EPSG:32650") # UTM 50N
# 创建转换对象
transform = QgsCoordinateTransform(
source_crs,
dest_crs,
QgsProject.instance()
)
# 转换点坐标
point = QgsPointXY(116.0, 39.0) # 北京附近
transformed = transform.transform(point)
print(f"转换后: {transformed.x()}, {transformed.y()}")
# 反向转换
reverse_transform = QgsCoordinateTransform(
dest_crs,
source_crs,
QgsProject.instance()
)
original = reverse_transform.transform(transformed)
3.8.3 基准面转换
# 获取可用的基准面转换
transforms = QgsCoordinateTransform.datumTransformations(
source_crs, dest_crs
)
for t in transforms:
print(f"转换: {t.sourceTransformId} -> {t.destinationTransformId}")
print(f" 精度: {t.accuracy}")
# 使用特定的基准面转换
context = QgsCoordinateTransformContext()
context.addCoordinateOperation(source_crs, dest_crs, "proj_string")
3.9 消息和日志系统
3.9.1 消息系统
from qgis.core import Qgis
from qgis.utils import iface
# 消息栏消息
iface.messageBar().pushMessage(
"标题",
"消息内容",
level=Qgis.Info, # Info, Warning, Critical, Success
duration=5 # 秒,0表示不自动消失
)
# 带操作的消息
from qgis.PyQt.QtWidgets import QPushButton
def show_help():
# 显示帮助
pass
widget = iface.messageBar().createMessage("信息", "点击查看更多")
button = QPushButton("详情")
button.clicked.connect(show_help)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, Qgis.Info)
3.9.2 日志系统
from qgis.core import QgsMessageLog, Qgis
# 记录消息
QgsMessageLog.logMessage(
"这是一条日志消息",
tag="MyPlugin",
level=Qgis.Info
)
# 日志级别
# Qgis.Info - 信息
# Qgis.Warning - 警告
# Qgis.Critical - 错误
# Qgis.Success - 成功
# 监听日志消息
def log_handler(message, tag, level):
print(f"[{tag}] {level}: {message}")
QgsMessageLog.instance().messageReceived.connect(log_handler)
3.10 设置和配置
3.10.1 QgsSettings
from qgis.core import QgsSettings
settings = QgsSettings()
# 读取设置
value = settings.value("plugin/my_setting", defaultValue="default")
# 写入设置
settings.setValue("plugin/my_setting", "new_value")
# 分组操作
settings.beginGroup("plugin")
settings.setValue("setting1", "value1")
settings.setValue("setting2", "value2")
settings.endGroup()
# 删除设置
settings.remove("plugin/my_setting")
3.10.2 项目设置
from qgis.core import QgsProject
project = QgsProject.instance()
# 读取项目变量
value = project.readEntry("section", "key", "default")[0]
# 写入项目变量
project.writeEntry("section", "key", "value")
# 自定义属性
project.setCustomProperty("my_property", "value")
prop = project.customProperty("my_property")
# 项目元数据
project.setTitle("My Project")
project.setAuthor("Author Name")
3.11 小结
本章详细介绍了QGIS的核心架构和模块设计:
关键要点:
- QGIS采用分层模块化架构,核心库不依赖GUI
- 数据提供者架构支持多种数据源
- 插件系统允许功能扩展
- Processing框架提供统一的地理处理能力
- 渲染系统支持丰富的可视化选项
- 表达式引擎是数据驱动样式的核心
理解这些架构概念对于高效使用QGIS和进行二次开发至关重要。
上一章:第02章 安装与环境配置
下一章:第04章 用户界面详解

浙公网安备 33010602011771号