QGis(五)矢量圖層根據指定字段分級渲染顯示

已知shp圖層所有字段的名稱及值,根據指定的字段名和顏色、類別來對圖層進行分級渲染顯示。設置界面:


可能要用到的頭文件:

#include <qgsgraduatedsymbolrendererv2.h>
#include <qgsgraduatedsymbolrenderer.h>
#include <QgsVectorLayer.h>
#include <qgssymbol.h>
#include <qgsfield.h>
#include <qgsvectordataprovider.h>
#include <QgsSymbolLayerV2Utils.h>

(1)獲取shp圖層所有的字段名。將字段名插入下拉列表

先定義幾個變量:

QgsVectorLayer *mLayer = new QgsVectorLayer(myLayerPath, myLayerBasename,"ogr");
QgsGraduatedSymbolRenderer *mRenderer = new QgsGraduatedSymbolRenderer(mLayer->geometryType(),QgsGraduatedSymbolRenderer::EqualInterval);
QString mFieldName = "Id"; 
int mClasses = 5;

void InitField()
{
	//設置字段名下拉列表
	ui.cboGraduatedColumn->clear();
	const QgsFieldMap &fields = mLayer->pendingFields();//從圖層得到字段信息
	QgsField field;
	for(int i = 0; i < fields.count(); ++i)
	{
		field = fields[i];
		//只添加數值型字段
		if (field.type() == QVariant::Double || field.type() == QVariant::Int || field.type() == QVariant::LongLong &&
			(field.name() != "Id"))
		{
			ui.cboGraduatedColumn->addItem( field.name() );
		}

	}
	mFieldName = ui.cboGraduatedColumn->currentText();
	mRenderer->setClassificationField(mLayer->fieldNameIndex(mFieldName));
	
}
(2)按照分類的類別數和指定的顏色來生成漸變的顏色

//從 startcolor到endcolor的漸變,分成steps種顏色
QList<QColor> generateColorRamp( QColor startcolor, QColor endcolor, int steps )
{
	QList<QColor> colors;
	int r = endcolor.red() - startcolor.red();
	int g= endcolor.green() - startcolor.green();
	int b = endcolor.blue() - startcolor.blue();

	float rStep = r / (float)steps ;
	float gStep = g / (float)steps;
	float bStep = b / (float)steps;

	float fr = startcolor.red();
	float fg = startcolor.green();
	float fb = startcolor.blue();
	colors.push_back(startcolor);

	for ( int i = 0; i < steps - 2; ++i)
	{
		fr += rStep;
		fg += gStep;
		fb += bStep;
		QColor color((int)fr + 0.5, (int)(fg + 0.5), (int)(fb + 0.5));
		colors.push_back(color);
	}
	colors.push_back(endcolor);
	return colors;
}
(3)將指定字段的值按等間隔分成mClasses份,並賦予對應的顏色。mClasses等於上面顏色的steps
void ClassifyGraduated()
{
	...
	//計算要分類的字段的等間距值
	double min = 0, max = 0;
	double offset = 0;
	findMinMax(mFieldName, min, max);
	if (mClasses != 0)
	{
		offset = ( max - min  ) / mClasses;
	}
	QColor startColor, endColor;
	startColor.setRgb(255,255,255);
	endColor.setRgb(0, 255, 0);
	QList<QColor> mColors = generateColorRamp( startColor, endColor, mClasses );
	for (int i = 0; i < mClasses; ++i)
	{
		QgsSymbol* pSym = new QgsSymbol( QGis::Polygon );
		pSym->setFillColor( mColors.at(i) ); //顏色的控制
		pSym->setFillStyle( Qt::SolidPattern );
		pSym->setLowerValue( QString::number( min + i * offset, 'f', 5) );
		pSym->setUpperValue( QString::number( min + ( i + 1 ) * offset , 'f', 5) );
		mRenderer->addSymbol(pSym);//將symbol添加到渲染器中
		QString list = QString::number( min + i * offset, 'f', 5) + " - " + QString::number( min + ( i + 1 ) * offset , 'f', 5);
		
		QIcon icon =  QIcon( QPixmap::fromImage( pSym->getPolygonSymbolAsImage() ) ) ;
		QStandardItem* item = new QStandardItem( icon, "" );
		item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
		
		mShowModel->setItem(i, 0, item);
		mShowModel->setItem(i, 1, new QStandardItem( list));	
	}

}
(4)最後還要將渲染器設置給圖層

mLayer->setRenderer(mRenderer);

當然這裏的顏色和類別數可以通過界面來改變,而且可以實現自己雙擊上圖中列表裏的每一行來自定義顏色。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章