QGIS 3.xでは2.xからレイヤ管理周りが大きく変更されています。
主なところを整理しつつ、凡例、オーバービューとの関連付けを調べてみましたが自分でもよくわからなくなってきました。
レイヤツリー
QGIS 3.xではQgsMapCanvasLayer
クラスがQgsMapCanvas
クラスが使用する内部クラスに変更され、表示/非表示の管理もしなくなりました。代わりにQgsLayerTreeLayer
クラスが表示レイヤを管理しています。QgsLayerTreeLayer
オブジェクトはQgsLayerTree
オブジェクトに登録して管理されますが、このオブジェクトはQGISのアプリケーションが生成されると1つ作成されます。
具体的には、まず以下のコードでプロジェクトにレイヤを追加します。
QgsProject::instance()->addMapLayer( pLayer, true );
これを実行すると、途中イロイロあってQgsProject
が持っているメンバ変数mRootGroup
のinsertChildNodes()
が呼ばれてレイヤが追加されます。
また、これとは別に、QgsMapCanvasオブジェクトにもレイヤリストを登録する必要があります。
// centralwidgetはQgsMapCanvasオブジェクト // m_lstLayers は QList<QgsMapLayer *> 型オブジェクトで、 // レイヤを読み込んだらこれに追加する m_lstLayers.append( pLayer ); centralwidget->setLayers( m_lstLayers );
レイヤの表示/非表示
この状態でレイヤの表示/非表示を操作する場合は、一例としては以下のようにします。
QgsLayerTreeLayer *p =
QgsProject::instance()->layerTreeRoot()->findLayer( pLayer );
p->setItemVisibilityChecked( false );
プラグインなどでは、これだけで大方事足ります。
アプリケーションを作成する場合
アプリケーションを作る場合はもう一つ手間がかかります。
まず、レイヤを管理しているクラスのメンバ変数にQgsLayerTreeMapCanvasBridge
クラスの変数を用意します。
QgsLayerTreeMapCanvasBridge *mLayerTreeCanvasBridge;
次に、アプリケーションの初期化のところでキャンバスとレイヤツリーを関連付けます。
// centralwidgetはQgsMapCanvasオブジェクト mLayerTreeCanvasBridge = new QgsLayerTreeMapCanvasBridge( QgsProject::instance()->layerTreeRoot(), centralwidget, this ); connect( mLayerTreeCanvasBridge, &QgsLayerTreeMapCanvasBridge::canvasLayersChanged, centralwidget, &QgsMapCanvas::setLayers );
これをやっておかないと表示/非表示の操作ができません。
このクラスは、setCanvasLayers()
関数でQgsLayerTreeLayer
等のツリーに登録されるオブジェクトの表示/非表示のフラグを見てキャンバスに表示するレイヤを選別しています。
凡例との連携
凡例の操作でレイヤの表示/非表示を操作する、または逆にコードから表示/非表示を操作したときに凡例のチェックをOn/Offしたりするためには、レイヤツリーとの関連付けを行います。QGISの場合は凡例の専用クラスが用意されているのでそれを使います。
// 凡例オブジェクトの作成 mLayerTreeView = new QgsLayerTreeView( this ); // QgsLayerTreeModelオブジェクトを作成 QgsLayerTreeModel *model = new QgsLayerTreeModel( QgsProject::instance()->layerTreeRoot(), this ); // 表示関連を操作可能にする model->setFlag( QgsLayerTreeModel::AllowNodeChangeVisibility ); // よくわからないが、ウィジェットを埋め込めるようになるとか model->setFlag( QgsLayerTreeModel::UseEmbeddedWidgets ); // 凡例をツリーとして表示 model->setFlag( QgsLayerTreeModel::ShowLegendAsTree ); // チェックボックスを表示 model->setFlag( QgsLayerTreeModel::AllowLegendChangeState ); // 親ノードの操作を子ノードにも適用 model->setFlag( QgsLayerTreeModel::ActionHierarchical ); // 10以上のツリーは閉じた状態にする model->setAutoCollapseLegendNodes( 10 ); // モデルをセット mLayerTreeView->setModel( model );
オーバービューとの連携
オーバービューを作成して連携させる場合は、上記のQgsLayerTreeMapCanvasBridge
クラスを使います。
クラス宣言
// オーバービューキャンバス QgsMapOverviewCanvas *mOverviewCanvas; // なぜか用意されているQGISのドッキングウィジェット QgsDockWidget *mOverviewDock;
実装部
mOverviewCanvas = new QgsMapOverviewCanvas( this, centralwidget ); mOverviewDock = new QgsDockWidget( tr( "Overview" ), this ); mOverviewDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); mOverviewDock->setWidget( mOverviewCanvas ); addDockWidget( Qt::LeftDockWidgetArea, mOverviewDock ); // QgsLayerTreeMapCanvasBridgeにセット mLayerTreeCanvasBridge->setOverviewCanvas( mOverviewCanvas );