11.3 QGIS地图图表直方图应用和二次开发实现
文章目录
- 前言
- 图表示例图层
- QGIS图表通用设置
- 直方图
- 二次开发实现文字图表
- 总结
前言
- 本章介绍直方图(Histogram)在QGIS中的应用以及对应的二次开发的实现过程
- 说明:文章中的示例代码均来自开源项目qgis_cpp_api_apps
图表示例图层
- 以protected_areas.shp为例,该图层数据中包含prec_2020,prec_2021和prec_2022的降水量统计值,见下图

QGIS图表通用设置
- 在矢量图层的图层属性中,通过“Diagrams”选项卡左上角的下拉菜单可以选择图表类型,包括无图表( No diagrams)、饼图( Pie chart)、文字图表( Text diagram)直方图(Histogram)以及分段条形图(Stacked bars),如下图

- 在“Diagrams”选项卡中,选中任何一种图表后,即可出现属性(Attributes)、渲染(Rendering)、尺寸(Size)、位置(Placement)、设置(Options)和图例(Legend)六个主要选项卡。
- 在属性(Attributes)需要从“Available attributes”列表中选择需要制作图表的数据
- 在渲染(Rendering)选项卡可以设置具体图表的颜色、线条宽度等。
- 在尺寸(Size)选项卡中可以设置绝对尺寸或相对尺寸。
- 位置(Placement)选项卡用于设置图表绘制的位置。
- 设置(Options)选项卡的直方图中,通过“Bar Orientation”选项可以设置直方图的方向,包括向上(Up)、向下(Down)、向左(Left)和向右(Right)。
- 图例(Legend)选项卡设置图表图例是否显示在地图图例中,包括标题、显示方式等设置选项。
直方图
- 打开“以protected_areas.shp”数据,进入其图层属性的“Diagrams”选项卡,将其上方下拉菜单中的图表类型设置为“Histogram”。
- 在“Attributes”选项卡中,将“prec_2020”、“prec_2021”和“prec_2022”属性加入“Assigned attributes”列表中。
- 在“Size”选项卡中设置相对尺寸(Scaled size),并设置数值的最大值“Maximum value”,此处设为“300”;在“Bar length”中设置直方图的长度为“30”。

- 确定后的显示效果如下图

二次开发实现文字图表
-
图表类的基类为
QgsDiagram,类图如下

-
子类
QgsHistogramDiagram为直方图的实现 -
矢量图层类
QgsVectorLayer的成员函数void setDiagramRenderer( QgsDiagramRenderer *r SIP_TRANSFER );用于设置图层的图表渲染器。 -
图表渲染器的基类为
QgsDiagramRenderer,类图如下

-
两个子渲染器是
QgsSingleCategoryDiagramRenderer和QgsLinearlyInterpolatedDiagramRenderer -
渲染器的两个成员函数
void setDiagram( QgsDiagram *d);用于设置图表类型,void setDiagramSettings( const QgsDiagramSettings &s )用于设置图表渲染设置 -
矢量图层类
QgsVectorLayer的成员函数void setDiagramLayerSettings( const QgsDiagramLayerSettings &s );也是用于设置图标渲染属性 -
QgsDiagramLayerSettings和QgsDiagramSettings的不同点是QgsDiagramSettings存储与渲染单个图表本身相关的设置,而QgsDiagramLayerSettings存储控制如何渲染一个层内所有图表的设置。 -
以下以protected_areas.shp为例,讲解饼图的显示
- 添加protected_areas图层
QgsVectorLayer* layer = addTestShape(QStringLiteral("maps/shapefile/protected_areas.shp"));
- 设置
QgsDiagramSettings,包括是否启用图表,设置属性名称、属性颜色、属性Label
QgsDiagramSettings ds;
ds.enabled = true;
//Attributes选项卡
QColor col1 = Qt::red;
QColor col2 = Qt::yellow;
QColor col3 = Qt::blue;
ds.categoryColors = QList<QColor>() << col1 << col2 << col3;
ds.categoryAttributes = QList<QString>() << QStringLiteral( "prec_2020" ) << QStringLiteral( "prec_2021" ) << QStringLiteral( "prec_2022" );
ds.categoryLabels = QList<QString>() << QStringLiteral( "prec_2020" ) << QStringLiteral( "prec_2021" ) << QStringLiteral( "prec_2022" );
//Rendering选项卡
ds.opacity = 1.0;
//Size选项卡
ds.size = QSizeF( 15, 15 );
- 构建渲染器
QgsLinearlyInterpolatedDiagramRenderer *dr = new QgsLinearlyInterpolatedDiagramRenderer();dr->setLowerValue( 0.0 );dr->setLowerSize( QSizeF( 0.0, 0.0 ) );dr->setUpperValue( 100 );dr->setUpperSize( QSizeF( 40, 40 ) );dr->setClassificationField( QStringLiteral( "prec_2020" ) );dr->setDiagram(new QgsHistogramDiagram());dr->setDiagramSettings(ds);
- 图层图表设置
QgsDiagramLayerSettings
QgsDiagramLayerSettings dls = QgsDiagramLayerSettings();dls.setPlacement( QgsDiagramLayerSettings::OverPoint );dls.setShowAllDiagrams( true );
- 图层设置渲染器
layer->setDiagramLayerSettings(dls);layer->setDiagramRenderer( dr );
- 完整测试代码如下
void MainWindow::diagramHistogramSlot()
{//添加测试图层QString filename = QStringLiteral("maps/shapefile/protected_areas.shp");QFileInfo ff(filename);QgsVectorLayer* layer = (QgsVectorLayer*)mApp->addVectorLayer(filename,ff.baseName());zoomToFirstLayer<QgsVectorLayer*>();QgsDiagramSettings ds;ds.enabled = true;//Attributes选项卡QColor col1 = Qt::red;QColor col2 = Qt::yellow;QColor col3 = Qt::blue;ds.categoryColors = QList<QColor>() << col1 << col2 << col3;ds.categoryAttributes = QList<QString>() << QStringLiteral( "prec_2020" ) << QStringLiteral( "prec_2021" ) << QStringLiteral( "prec_2022" );ds.categoryLabels = QList<QString>() << QStringLiteral( "prec_2020" ) << QStringLiteral( "prec_2021" ) << QStringLiteral( "prec_2022" );//Rendering选项卡ds.opacity = 1.0;//Size选项卡ds.size = QSizeF( 15, 15 );QgsLinearlyInterpolatedDiagramRenderer *dr = new QgsLinearlyInterpolatedDiagramRenderer();dr->setLowerValue( 0.0 );dr->setLowerSize( QSizeF( 0.0, 0.0 ) );dr->setUpperValue( 100 );dr->setUpperSize( QSizeF( 40, 40 ) );dr->setClassificationField( QStringLiteral( "prec_2020" ) );dr->setDiagram(new QgsHistogramDiagram());dr->setDiagramSettings(ds);QgsDiagramLayerSettings dls = QgsDiagramLayerSettings();dls.setPlacement( QgsDiagramLayerSettings::OverPoint );dls.setShowAllDiagrams( true );layer->setDiagramLayerSettings(dls);layer->setDiagramRenderer( dr );}
- 效果如下图


总结
- 介绍了QGis中直方图的使用和二次开发实现方法
