2. qgis c++ api 整体框架详解

整体架构

QGis库官方文档

下表是官方文档中的模块说明:

文档 说明
core The CORE library contains all basic GIS functionality 核心库
gui The GUI library is build on top of the CORE library and adds reusable GUI widgets 基于CORE库的,增加了可复用的界面组件
analysis The ANALYSIS library is built on top of CORE library and provides high level tools for carrying out spatial analysis on vector and raster data 集成了一些算法,如缓冲区的生成
3D The 3D library is build on top of the CORE library and Qt 3D framework 3D库
plugin classes Contains classes related to implementation of QGIS plugins 组件库 如data provider, 一些算法都是采用插件机制实现的
QgsQuick The QgsQuick library is built on top of the CORE library and Qt Quick/QML framework 基于CORE库,可用于QML
server The SERVER library is built on top of the CORE library and adds map server components to QGIS 服务端组件

其中3D,QgsQuick和server库需要在编译之前进行配置,配置项分别为WITH_3D WITH_QUICKWITH_SERVER,具体编译配置方法见开发环境搭建章节

编译生成的库

实际编译生成的库如下图


image.png
说明
app QGis Desktop程序库,属于应用层,并没有这个库的官方文档
native 不同平台之间特有的功能
python 用于使用python特性
test 单元测试库
core 核心库
gui 小组件库
analysis 算法库

其中core为基础库,其他库都依赖core,以下详细说明core、gui和analysis三个库

core

core库是qgis系统中的基础类,包含所有基本的GIS功能,而该库的很大一部分功能是用于处理矢量(vector)和栅格(raster)地理空间数据,并在地图中显示这些类型的数据。在讲解vector和raster之前先介绍一下地图图层概念

地图和图层

地图由多个图层组成,一个层绘制在另一个层的上层,qgis支持多种类型的图层:


image.png
  • Annotaion layer: 表示包含一组地理参考注释的地图层,例如标记、直线、多边形或文本项。在qgis desktop中可以添加对应类型的annotaion


    image.png
  • Group layer: 由一组子层组成的地图层


    image.png
  • Mesh Layer: 表示支持在结构化或非结构化网格上显示数据的网格层。多用于存储气候气象数据、水文数据、洋流数据等


    image.png
  • Plugin Layer: Base class for plugin layers. 插件实现自定义图层

  • PointCloud Layer: 点云图层

  • Vector Tile Layer: 矢量瓦片图层

  • Raster Layer: 栅格图层


    image.png
  • Vector Layer: 矢量图层


    image.png

其中矢量图层和栅格图层是最常用的,我们将重点研究这两个图层,下图是矢量图层和栅格图层叠加显示效果图


image.png

矢量图层(Vector layers)

矢量数据通常用点、线、多边形等基本几何对象描述。矢量格式的地理空间数据通常从矢量数据源(data provider)读取,常见的矢量数据源有.shp文件、数据库、内存、webservice等等,如下图QGis添加矢量图层示例

image.png

矢量层本身由QgsVectorLayer类表示。矢量层包括很多模块,如下图所示,

image.png

下面重点讲解以下模块

  • symbology: 图层要素符号
  • proj: 坐标映射
  • providers: 数据源

图层要素符号

图层要素

矢量格式具有许多要素(features),矢量图层属性表每一行都代表一个要素

jilin_city.shp为例,在QGis中添加图层后,打开属性表(Attribute Table)如下图所示

image.png

image.png
image.png

可以看到矢量属性表有9行,代表9个要素,这9个要素以符号的形式显示在地图上,使用QGis的地图工具:Identify Feature工具查看属性如下图

image.png

可以看到要素(feature)的属性包含了id,Geometry以及附件属性,QgsFeature类用于表示要素。每个要素都有以下属性:

  • id: feature id
  • Geometry: 要素的地理信息,表示要素是地图上点、线、多边形等。
  • Attributes: 要素的附加属性,例如一个城市要素可能具有total_area、population、elevation等属性。属性值可以是字符串、整数或浮点数。

要素渲染(feature renderer)

上边已经看到了jilin_city.shp中的要素(feature)渲染为一个点,在QGis中提供了多种渲染方式,如下图

image.png

QgsFeatureRenderer类是这些渲染方式的父类,见如下类图

image.png

以后的章节我们一一讲解各个渲染类

符号(symbol)

设置渲染器之后需要设置符号,以单一符号渲染器为例,可设置的符号类别如下图


image.png

QgsSymbol是符号的父类,见下图的类图

image.png

QgsFillSymbol,QgsLineSymbolQgsMarkerSymbol分别对应三种几何图形面、线和点的符号

坐标映射

在GIS软件中,空间坐标依据坐标系的不同分为地理坐标和投影坐标。地理坐标是将地球比作一个类椭球体,描述一个点在球面上的位置。但是在地图制图过程中,往往需要在一个平面(无论是纸质地图还是电子地图)上展示地物,这时需要解决地球球面与地图平面之间的矛盾,因此需要对地球进行投影,经过投影后的坐标称为投影坐标,因此投影坐标是建立在地理坐标之上的。

为了解决地球椭球面和地图平面之间的矛盾,需要将地球椭球面进行投影,经过投影以后的坐标系称为投影坐标系。投影后的平面坐标系一定会出现变形,我们只能在等距、等积和等角之间进行取舍。因此,在不同应用场景下,大量的投影坐标系应运而生。

各个国家或地区建立了能够基本符合自己国家或地区的地球椭球面,或者根据精度需要及特定应用场景构建了不同的地球椭球面。根据构建的地球椭球面的参数不同,地理坐标系也层出不穷。我国的地理坐标系经历了从北京1954坐标系(BJZ54)到西安1980坐标系(XI'AN-80),再到2000国家大地坐标系(CGCS2000)的发展过程。

由于地理坐标系和投影坐标系众多,如果仅通过参数对这些坐标系进行整理与应用则过于麻烦,因此需要通过标准化组织将这些坐标系归档整理。对于石油的探查和开采来讲,坐标系的不同会显著影响开采精度,因此欧洲石油调查组织(European Petroleum Survey Group,EPSG)整合了绝大多数常用的坐标系,并为每个坐标系设置了一个编码,例如,“EPSG:4326”和“EPSG:3785”分别表示WGS 1984坐标系和WGS 1984 Web墨卡托投影坐标系。

QGis矢量图层会显示坐标系,如下图


image.png

数据源(data provider)

QgsVectorDataProvider代表Vector Layer的数据源,类图如下

image.png

数据源包含的数据在QGis中以表格形式展示,如下图


image.png

Raster layers

光栅格式的地理空间数据本质上是位图图像,其中图像中的每个像素都对应于地球表面的特定部分。
栅格数据采用某种数据类型的数值阵列存储数据,阵列中的每个数值称为一个像元(Pixel)。由于数据阵列本身不存在空间信息,因此需要元数据进行界定。
栅格数据的元数据包括空间坐标系、数据类型等。


image.png
image.png

光栅图层本身由QgsRasterLayer类表示。每个光栅图层包括:

  • symbology: 图层要素符号
  • proj: 坐标映射
  • Data provider: 数据源

图层符号

Raster Layer有多种渲染方式,QgsRasterRenderer是Raster图层渲染的父类,如下图

image.png

在QGis中设置不同渲染器


image.png
  • Multiband color
    如果光栅数据具有多个波段,则通常会将带组合以生成所需的颜色。例如,一个波段可能表示颜色的红色分量,另一个波段可以表示绿色分量,还有一个波段则可能表示蓝色分量。
  • Paletted/Unique values
    如果光栅数据只有一个波段,则像素值可以用作调色板的索引。调色板将每个像素值映射到特定的颜色。
  • Singleband gray
    如果光栅数据只有一个波段,但没有提供调色板。像素值可以直接用作灰度值;也就是说,越大的数字越亮,越小的数字越暗。或者,像素值可以通过伪彩色算法来计算要显示的颜色。
  • Singleband pseudocolor
    多波段数据可以使用调色板绘制多波段光栅数据源,或者将其绘制为灰度或伪彩色图像。
  • Hillshade
    多用于显示高程数据
  • Contours
    显示轮廓

数据源

QgsRasterDataProvider代表Raster Layer的数据源,类图如下

image.png

成员函数identify用于查看raster图层数据

QgsRasterIdentifyResult QgsRasterDataProvider::identify (   const QgsPointXY &  point,
QgsRaster::IdentifyFormat format,const QgsRectangle & boundingBox = QgsRectangle(),
int width = 0,int height = 0,int dpi = 96 )

后边章节会逐一介绍相关类和函数

坐标映射

坐标参考系(Coordinate Reference System,CRS)界定了栅格数据所处的投影坐标系或地理坐标系。

core库其他有用类

说明
QgsProject 代表当前项目,包含一系列属性如地图图层及其样式、布局、注释、画布等
Qgis Qgis类提供全局常量,供整个应用程序使用
QgsGeometry 代表几何特征,是feature的空间表示,QgsGeometry对象本质上是笛卡尔/平面几何。
QgsCurve 曲线类型的抽象基类
QgsPoint 点类型
QgsSurface 曲面类型
QgsRectangle 矩形
QgsEllipse 椭圆形
QgsDistanceArea 距离、面积测算类

gui

GUI库构建在CORE库之上,并添加了可重用的GUI小部件

QgsMapCanvas

地图视图(也称为地图画布)用于显示地图控件,QGIS主窗体的地图区域就是一个地图视图。QGIS支持多地图视图,即可以在保留地图区域的基础上,以面板的形式增加地图视图(或3D地图视图)。QGIS多个地图视图采用同一个图层控制面板控制,因此一般用于显示同一个地图主题的不同四至范围数据(或以3D形式展示数据)。

QgsMapcanvas类是一个用于在画布上显示所有GIS数据类型的类。是QGraphicsView的子类
包括以下功能:

  • 当前显示的地图图层的列表。这可以使用layers()方法访问。
  • 获取地图使用的地图单位(米、英尺、度等)。可以通过调用mapUnits())方法来获取。
  • 显示范围,即当前显示在画布中的地图区域。地图的范围将随着用户放大和缩小以及在地图上平移而改变。当前映射范围可以通过调用extent()方法来获得。
  • 当前地图工具,可以使用setMapTool()设置,使用mapTool()获取当前工具
  • 设置地图背景色,使用canvasColor()获取
  • 坐标转换,将地图坐标转换为窗口坐标

QgsMapTool

  • 地图视图控制可以使用地图浏览工具栏


    image.png
image.png
image.png

QgsMapTool是地图工具类基类,用于和用户交互、操作地图、处理鼠标事件。类图如下

image.png

QgsLayerTreeView/QgsLayerTreeModel

QgsLayerTreeView类扩展了QTreeView,提供图层管理功能,并提供了一些附加功能。如下图

image.png

QgsMapCanvasItem

QgsMapCanvasItem是可以直接画在map canvas的item的基类,Map Canvas Item显示优先级高于图层。类图如下

image.png

  • QgsVertexMarker: 这将绘制一个图标(“X”、“+”或小方框),以地图上的给定点为中心。
  • QgsRubberBand: 这将在地图上绘制任意几何类型。它在用户绘制时提供视觉反馈。
  • QgsAnnotationItem: 在地图上添加标注的基类,其子类如下图


    image.png

其他有用的gui类

说明
QgsMapTip 鼠标悬停时显示的提示信息
QgsColorDialog 颜色选择框
QgsBlendModeComboBox
QgsBrushStyleComboBox
QgsColorRampComboBox
QgsPenCapStyleComboBox
QgsPenJoinStyleComboBox 以上QComboBox用户界面小部件提示用户输入各种绘图选项
QgsScaleComboBox 选择缩放等级

analysis

analysis库建立在CORE库之上,为对矢量和光栅数据进行空间分析提供了高级工具,QGis中算法多集中在Processing Toolbox中,如下图


image.png

QgsProcessingProvider

QgsProcessingProvider类通常提供一组相关算法,类图如下

image.png

QgsProcessingAlgorithm

QgsProcessingAlgorithm类代表一种算法,通常由QgsProcessingRegistry进行创建,之后可以运行算法,获取结果

QgsProcessingRegistry

QgsProcessingRegistry类用于注册算法处理的各个组件包括:providers, algorithms,input,output and various parameters.
以clip算法为例,使用QgsProcessingRegistry创建算法类

const QString id = "native:clip";
QVariantMap conf;
conf.insert(QStringLiteral("INPUT"),layer->id());
conf.insert(QStringLiteral("OVERLAY"),"jilin_dist.shp");
QgsProcessingOutputLayerDefinition value( "TEMPORARY_OUTPUT" );
conf.insert(QStringLiteral("OUTPUT"),value);
auto algorithm = QgsApplication::processingRegistry()->createAlgorithmById(id,conf);

QgsProcessingContext

QgsProcessingContext用于算法运行时

QgsProcessingFeedback

QgsProcessingFeedback用于接收算法运行时的反馈

QgsProcessingAlgRunnerTask

QgsProcessingAlgRunnerTask是在线程中运行算法的类,类图如下

image.png

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容