QGis C++ 開發之圖層分類顯示


開發環境:Win10 + VS2010 + Qt 4.8.6 + QGis 2.14.4

簡單介紹下如何用C++方式實現QGis中圖層分類顯示的方法。

要實現圖層的分類顯示主要會用到QgsCategorizedSymbolRendererV2類,這個類是一個簡單的符號分類渲染器,該類是從QgsFeatureRendererV2繼承而來,大家可以看下幫助文檔中的截圖:

wps5E79.tmp

QgsCategorizedSymbolRendererV2是其中一個子類,其他還有幾個類似的子類,而這些子類的渲染方式就是對應的QGis中的幾種不同的分類方式:

wps5E8A.tmp

所以如果掌握了其中一種分類方式的用法,其他幾種都是大同小異。下面要介紹的就是上圖中的第3種方式,用法簡單,但是也是平時用得最多的一種方式。

1、先說下如何簡單的根據指定圖層字段創建分類。先上一小段代碼,再來慢慢說:

  1 	QgsCategoryList cats;
  2 	QgsFeature f;
  3 	QgsFeatureIterator it = mLayer->getFeatures();
  4 	while (it.nextFeature(f))
  5 
  6 		cats << QgsRendererCategoryV2(f.attribute("編號"),
  7 		unlinkedSymbolV2(), f.attribute("編號").toString());
  8 	}
  9 
 10 	mLayer->setRendererV2( new QgsCategorizedSymbolRendererV2("編號", cats) );

說明下mLyaer是准備處理的一個有效的QgsVectorLayer對象。

先看最后一句,通過圖層的setRendererV2(QgsFeatureRendererV2*)便可以修改該圖層的渲染方式,我們的目的就達到了,不過要詳細說下傳遞的參數,要傳遞的參數就是上面提到的從QgsFeatureRendererV2繼承而來的渲染器子類,我是直接通過兩個參數來new了一個QgsCategorizedSymbolRendererV2對象:

第一個參數是圖層中已有的字段名稱,這里我使用矢量圖層中叫”編號”的字段來進行分類;

第二個參數是一個QgsCategoryList對象,它其實是一個別名,本質上是QList<QgsRendererCategoryV2>,這個列表里保存的是與字段內容相對應的對象。QgsRendererCategoryV2是用於管理每個分類對象符號的類,通過一個圖來看比較好理解,下圖中顯示了3種分類,每個分類就是一個單獨的QgsRendererCategoryV2,它所顯示的名稱、顏色、符號等等都是通過QgsRendererCategoryV2來管理的。

image

接着看上面在while循環中我通過遍歷圖層中的要素,創建QgsRendererCategoryV2對象,並保存到List中,第一個參數是設置對象的值,直接返回圖層中“編號”字段的值來填充;第三個參數是設置一個顯示的標簽,我直接就使用與第一個參數相同的值來設置;第二個參數是一個指向QgsSymbolV2的對象,該類主要用於管理符號,顯示的顏色、符號、透明度這些就是通過這個參數來設置,這里我是同過一個單獨的函數來返回這個對象,這個unlinkedSymbolV2()函數內容如下:

  1 QgsSymbolV2* unlinkedSymbolV2()
  2 {
  3 	QgsSymbolV2* mUnlinkedSymbolV2;
  4 
  5 	// 獲得缺省的符號
  6 	mUnlinkedSymbolV2 = QgsSymbolV2::defaultSymbol(mLayer->geometryType());
  7 
  8 	// 設置透明度與顏色
  9 	mUnlinkedSymbolV2->setAlpha(0.5);
 10 	mUnlinkedSymbolV2->setColor(cUnlinked);
 11 
 12 	return mLinkedSymbolV2->clone();
 13 }
 14 

這個符號類提供一個靜態defaultSymbol函數可返回一個默認的符號對象,傳入一個幾何類型以返回對應的幾何類型符號,然后通過setAlpha及setColor修改下符號的透明度及顏色,最后返回一個符號類指針的副本。

 

這是處理前的截圖:

image

 

這是處理后的截圖:

image

 

2、最后再說下已經像上面分類好了,怎么進行更新。

  1  // 獲得目前圖層的分類樣式符號渲染器
  2  QgsCategorizedSymbolRendererV2* cRenderer;
  3  cRenderer = dynamic_cast< QgsCategorizedSymbolRendererV2* >
  4  					( mLayer->rendererV2() );
  5  if (!cRenderer)
  6  {
  7  	return;
  8  }
  9  // 在渲染器中查找是否有對應的編號
 10  int index = cRenderer->categoryIndexForValue(QVariant("1"));
 11 
 12  // 更新
 13   if (-1 != index)
 14  {
 15  	cRenderer->deleteCategory(index);
 16  	cRenderer->addCategory(QgsRendererCategoryV2
 17  		(QVariant("1"), linkedSymbolV2(), "1"));
 18  }

首先獲得圖層的渲染器類,如果之前圖層沒有進行過分類,將會得到一個空指針。

之前我們在構造QgsRendererCategoryV2對象時不是用“編號”字段的內容設置了它的值嗎,現在就可以通過categoryIndexForValue函數來返回索引,找到正確的索引后先刪除原來記錄,再通過addCategory添加一個新的對象進去,這里我同樣通過調用一個linkedSymbolV2()返回符號,和unlinkedSymbolV2()不同的地方就是顏色改變了,所以就不貼代碼了。

更新完后還會有個小問題,會發現新添加的分類符號都顯示在最后,顯示順序和之前不一樣了,可以用下面這個方法按值重新排序。

  1 cRenderer->sortByValue();

 

關於圖層分類顯示基本上就這樣了,其實涉及代碼不多,應該還是好理解,其他幾種分類渲染方式都大同小異。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM