前言
- 地图图表功能可以为地图矢量图层添加与要素关联的饼图(Pie chart)、文字图表(Text diagram)和直方图(Histogram)。
- 本章介绍饼图(Pie chart)在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)选项卡设置图表图例是否显示在地图图例中,包括标题、显示方式等设置选项。
饼图
- 在“Attributes”选项卡中,将“prec_2020”、“prec_2021”和“prec_2022”属性加入“Assigned attributes”列表中。
- 在“Attributes”选项卡的“Assigned attributes”列表中设置color,如下图

- 确定之后可见图层显示饼图,如下图

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

- 其子类
QgsPieDiagram即为饼图 - 矢量图层类
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 );
- 构建渲染器,这里两个渲染器都可用
#if 1
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" ) );
#else
QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer();
#endif
dr->setDiagram(new QgsPieDiagram());
dr->setDiagramSettings(ds);
- 图层图表设置
QgsDiagramLayerSettings
QgsDiagramLayerSettings dls = QgsDiagramLayerSettings();
dls.setPlacement( QgsDiagramLayerSettings::OverPoint );
dls.setShowAllDiagrams( true );
layer->setDiagramLayerSettings(dls);
- 图层设置渲染器
layer->setDiagramRenderer( dr );
- 完整测试代码如下
void MainWindow::diagramPieSlot()
{
//添加一个图层
QgsVectorLayer* layer = addTestShape(QStringLiteral("maps/shapefile/protected_areas.shp"));
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 );
#if 1
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" ) );
#else
QgsSingleCategoryDiagramRenderer *dr = new QgsSingleCategoryDiagramRenderer();
#endif
dr->setDiagram(new QgsPieDiagram());
dr->setDiagramSettings(ds);
QgsDiagramLayerSettings dls = QgsDiagramLayerSettings();
dls.setPlacement( QgsDiagramLayerSettings::OverPoint );
dls.setShowAllDiagrams( true );
layer->setDiagramLayerSettings(dls);
layer->setDiagramRenderer( dr );
}
- 效果如下图


总结
- 分别介绍了QGIS中显示饼图和二次开发实现饼图
6053

被折叠的 条评论
为什么被折叠?



