矢量图层属性的图标显示功能,能够帮助我们以图形化的方式直观地显示数据中的信息,使得数据生动起来的同时也变得美观起来。
QgsDiagamRenderV2
首先认识一下控制图表的渲染类,QgsDiagramRenderV2。该类在QgsVectorLayer具有引用指针,通过 QgsVectorLayer 的 setDiagramRenderer() 方法,传入一个 QgsDiagramRendererV2 的实例,当前的矢量图层就会以设置的方法来渲染显示图表。但是 QgsDiagramRendererV2 是一个抽象类,并不能直接实现它的实例,而应该进一步选择实现它的子类。
其中 QgsLinearlyInterpolatedDiagramRenderer 和 QgsSingleCategoryDiagramRenderer 是具体的渲染方法类,具体算法的不同请参阅API文档。
有了渲染类到底是以饼状图还是以文本或柱状图来显示,还需要通过渲染类的setDiagram() 方法来设置。下面就来看看具体的图表类。
Diagram类
QGis中提供的图标类包括三个:QgsPieDiagram、QgsTextDiagram和QgsHistogramDiagram。它们分别对应于饼状图、文本图和柱状图,均继承于QgsDiagram类。
继承关系如下图所示:
图表类并不需要额外的参数,仅初始化就可以了。当然,它们具有一系列的参数可供配置。如果将每个类的参数都封装在类里面,不仅重复代码会增多,而且并不便于管理,况且不论是哪一种图表,它们都具有某些共通的设置参数。于是QGis把这些参数通过其他类进行统一管理。具体来说,有两个,一个是QgsDiagramSettings,用于配置针对图表的参数,另一个是 QgsDiagramLayerSettings,是更高一级的参数,将图表类作为一个图层,配置与矢量要素的显示关系。
QgsDiagramSettings
专门用于图表配置属性的类,这个类的定义是包含在 qgsdiagramrendererV2.h 这个文件中的,由于上文用到了 QgsDiagramRendererV2,想必你应该已经添加了这个头文件的 include 了。
QgsDiagramSettings 类包含的图表属性包括字体、大小、颜色等等,下图来源于 API 文档,可以比较详细的看到可配置的属性:
QgsDiagramLayerSettings
这个类控制图标作为一个图层,具有的显示方式,包括要素的显示长度,显示相对对于要素的方式等。同样,从API文档中查看它具有的属性。
调用方式
首先,要有一个QgsVectorLayer,指向当前的矢量图层。
//这句话是获取当前图层,修改成你自己获取当前图层的方式
QgsVectorLayer * layer = qobject_cast<QgsVectorLayer*>(activeLayer());
然后需要一个具体的Diagram
这里以柱状图为例:
QgsDiagram * diagram = new QgsHistogramDiagram();
接着定义QgsDiagramSettings类,并设置它的参数
QgsDiagramSettings ds;
ds.transparency = 0; //设置透明度
....
....
同样,定义 QgsDiagramLayerSettings类,并设置参数
QgsDiagramLayerSettings dls;
dls.dist = 0; //与要素相隔的距离
dls.priority = 5; //设置优先级
....
还需要选择渲染类,并设置一些它的属性,这里以 QgsLinearlyInterpolatedDiagramRenderer 类为例。
QgsLinearlyInterpolatedDiagramRenderer* dr = new QgsLinearlyInterpolatedDiagramRenderer();
dr->setLowerValue(0.0);
最后层层调用,并刷新一下显示。
dr->setDiagram(diagram);
dr->setDiagramSettings(ds);
layer->setDiagramRenderer( dr );
layer->setDiagramLayerSettings( dls );
layer->triggerRepaint();
mapCanvas->refresh();
示例代码,仅供大家参考。
void qgis_dev_layerPropDialog::setDiagramProperty()
{
// 这一句是获取当前图层,修改成你自己获取当前图层的方式
QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( activeLayer() );
QgsDiagram* diagram = 0;
QString diagramType = "Hist"; // 这一句修改成获取图表类型的代码
bool scaleAttributeValueOk = false;
QgsVectorDataProvider* provider = layer->dataProvider();
double maxVal = 0;
int fld = 2;
if ( fld != -1 )
{
bool ok = false;
double val = provider->maximumValue( fld ).toDouble( &ok ); // 获取该字段的最大值
if ( ok )
{
maxVal = val;
}
}
bool mValueLineEdit = false;
if ( diagramType == "Text" )
{
//diagram = new QgsTextDiagram();
}
else if ( diagramType == "Pie" )
{
//diagram = new QgsPieDiagram();
}
else // if ( diagramType == DIAGRAM_NAME_HISTOGRAM )
{
diagram = new QgsHistogramDiagram();
}
#pragma region 设置diagram属性
QgsDiagramSettings ds; // diagram的设置项
//ds.font = mDiagramFont; // 设置字体
ds.transparency = 0; // 设置透明度
QList<QColor> categoryColors; // 颜色
QList<QString> categoryAttributes; // 属性
QColor color = QColor( 255, 0, 0 );
color.setAlpha( 255 - ds.transparency );
categoryColors.append( color );
categoryAttributes.append( "ELEV" );
ds.categoryColors = categoryColors;
ds.categoryAttributes = categoryAttributes;
ds.size = QSizeF( 1, 1 );
ds.sizeType = static_cast<QgsDiagramSettings::SizeType>( 0 );
ds.labelPlacementMethod = static_cast<QgsDiagramSettings::LabelPlacementMethod>( 1 );
ds.scaleByArea = true;
ds.minimumSize = 0;
ds.backgroundColor = QColor( 0, 0, 0 ); // 背景色
ds.penColor = QColor( 0, 0, 0 ); // 轮廓颜色
ds.penWidth = 1; // 轮廓宽度
ds.minScaleDenominator = -1;
ds.maxScaleDenominator = -1;
// Diagram 方向 (histogram)
ds.angleOffset = 1440;
ds.diagramOrientation = static_cast<QgsDiagramSettings::DiagramOrientation>( 0 );
ds.barWidth = 5; // 宽度
#pragma endregion 设置diagram属性
QgsLinearlyInterpolatedDiagramRenderer* dr = new QgsLinearlyInterpolatedDiagramRenderer();
dr->setLowerValue( 0.0 );
dr->setLowerSize( QSizeF( 0.0, 0.0 ) );
dr->setUpperValue( 2 );
dr->setUpperSize( QSizeF( 2, 2 ) );
bool isExpression = true;
dr->setClassificationAttributeIsExpression( isExpression );
dr->setClassificationAttributeExpression( "" );
dr->setDiagram( diagram );
dr->setDiagramSettings( ds );
layer->setDiagramRenderer( dr );
QgsDiagramLayerSettings dls;
dls.dist = 0;
dls.priority = 5;
dls.xPosColumn = -1;
dls.yPosColumn = -1;
dls.placement = static_cast<QgsDiagramLayerSettings::Placement>( 0 );
dls.placementFlags = 0;
layer->setDiagramLayerSettings( dls );
layer->setTitle( "" );
QgsVectorSimplifyMethod simplifyMethod = m_layer->simplifyMethod();
simplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod::NoSimplification );
simplifyMethod.setThreshold( 1 );
simplifyMethod.setForceLocalOptimization( true );
simplifyMethod.setMaximumScale( 1 );
layer->setSimplifyMethod( simplifyMethod );
layer->triggerRepaint();
m_mapCanvas->refresh(); // 改成你自己的 map canvas
}
转自https://blog.youkuaiyun.com/shineplusplus/article/details/78362098