前言
前幾篇文章分別介紹了qgis二次開發(fā)的
在顯示GIS數(shù)據(jù)之前,需要首先介紹一下map canvas风宁,畢竟在將顏料(GIS地圖等數(shù)據(jù))畫在畫布(map canvas)之前铅搓,首先要創(chuàng)建畫布(map canvas)潭流。
- 說明:文章中的示例代碼均來自開源項目qgis_cpp_api_apps
Map canvas
QGis軟件中的Map canvas
- 官方文檔training_manual 有一節(jié)Navigating the Map Canvas專門講述了Map Canvas
-
下圖空白區(qū)域左側(cè)為圖層樹(Layer tree),右側(cè)為Map Canvas
代碼添加Map canvas
Map canvas is a class for displaying all GIS data types on a canvas.
QgsMapCanvas
是Map canvas霞掺,類的詳細內(nèi)容見文檔-
QgsMapCanvas
本質(zhì)是一個QGraphicsView
,QGraphicsView
是Qt Graphics View Framework框架的一個類,Graphics View Framework
是Qt提供的一個用于管理大量2D圖形項目并與之交互的框架辅鲸。
-
QGraphicsView
提供了視圖,相當(dāng)于畫布 -
QGraphicsItem
圖形類的基類抄腔,可以顯示在canvas的組件瓢湃,QgsMapCanvasItem
是該類的子類 -
QGraphicsScene
用于管理item
-
Map Canvas創(chuàng)建和顯示
- Map Canvas創(chuàng)建代碼如下
void ll_qgis_base_lib::initialize(QMainWindow *mainWindow)
{
mMainWindow = mainWindow;
mMapCanvas = new QgsMapCanvas;
mMapCanvas->enableAntiAliasing(true);
mMapCanvas->setCachingEnabled(true);
mMapCanvas->setCanvasColor(QColor(255,255,255));
mMapCanvas->setVisible(true);
initLayerTreeView();
initMaptools();
}
-
ll_qgis_base_lib
類是qgis_cpp_api_apps項目的一個庫,由于Map canvas和Layer tree很通用赫蛇,所以將這兩個放在庫中 - 將
mMapCanvas
添加到父Widget即可顯示Map canvas
void MainWindow::initStackwidgetPageCanvas()
{
auto gridLayout = new QGridLayout;
gridLayout->addWidget((QWidget*)mApp->mapCanvas());
ui->page_canvas->setLayout(gridLayout);
addDockWidget(Qt::LeftDockWidgetArea,mApp->layerTreeDock());
}
QGis中的QGraphicsItem
- Measure功能使用了
QgsRubberBand
類绵患,上圖中的三角形就是用QgsRubberBand
類繪制的
二次開發(fā)中的Item
類
QgsMapCanvasItem
是一個抽象類,用于放置在地圖畫布上的項目悟耘。-
類
QgsRubberband
類是一個用于在地圖上繪制臨時特征(例如數(shù)字化線條)的類落蝙。類圖如下
如下代碼實現(xiàn)在圖層上畫三角形
void MainWindow::rubberBandPolygonSlot()
{
//添加shapefile
QString filename = QStringLiteral("maps/shapefile/protected_areas.shp");
QFileInfo ff(filename);
mApp->addVectorLayer(filename,ff.baseName());
zoomToFirstLayer<QgsVectorLayer*>();
//定義三個點
QgsPointXY point1(20.34013,-33.90453);
QgsPointXY point2(20.49744,-33.91126);
QgsPointXY point3(20.41396,-33.93079);
//新建PolygonGeometry類型的RubberBand
mRubberBandPolygon = new QgsRubberBand(mApp->mapCanvas(),QgsWkbTypes::PolygonGeometry);
//添加三個點
mRubberBandPolygon->addPoint(point1);
mRubberBandPolygon->addPoint(point2);
mRubberBandPolygon->addPoint(point3);
//設(shè)置線寬顏色等屬性
mRubberBandPolygon->setWidth(4);
mRubberBandPolygon->setColor(QColor(222,155,67));
mRubberBandPoint = new QgsRubberBand(mApp->mapCanvas(),QgsWkbTypes::PointGeometry);
mRubberBandPoint->addPoint(point1);
mRubberBandPoint->addPoint(point2);
mRubberBandPoint->addPoint(point3);
mRubberBandPoint->setWidth(6);
mRubberBandPoint->setColor(QColor(222,155,67));
mRubberBandPolygon->show();
mRubberBandPoint->show();
}
- 以下代碼實現(xiàn)刪除
QgsGraphicsItem
if(mVertexMarker)
mApp->mapCanvas()->scene()->removeItem(mVertexMarker);
Layer Tree
QGis軟件中的Layer Tree
- Layer Tree用于管理圖層
- Layer Tree和Map canvas建立連接,可以對圖層進行操作
代碼實現(xiàn)layer tree
- 代碼如下
void ll_qgis_base_lib::initLayerTreeView()
{
//添加DockWidget作為圖層樹的容器
mLayerTreeDock = new QgsDockWidget(tr("Layer Tree"));
mLayerTreeDock->setObjectName( QStringLiteral( "Layers" ) );
mLayerTreeDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
//創(chuàng)建Model
QgsLayerTreeModel* model = new QgsLayerTreeModel(QgsProject::instance()->layerTreeRoot(),this);
model->setFlag( QgsLayerTreeModel::AllowNodeReorder );
model->setFlag( QgsLayerTreeModel::AllowNodeRename );
model->setFlag( QgsLayerTreeModel::AllowNodeChangeVisibility );
model->setFlag( QgsLayerTreeModel::ShowLegendAsTree );
model->setFlag( QgsLayerTreeModel::UseEmbeddedWidgets );
model->setFlag( QgsLayerTreeModel::UseTextFormatting );
model->setAutoCollapseLegendNodes( 10 );
//創(chuàng)建View暂幼,mLayerTreeView會在庫外使用筏勒,所以需要添加getter方法,
mLayerTreeView = new QgsLayerTreeView();
mLayerTreeView->setModel(model);
//Map Canvas和Layer Tree View建立聯(lián)系旺嬉,這樣通過QgsProject::instance()->addMapLayer添加圖層后管行,會自動添加在圖層樹以及會在canvas渲染圖層
mLayerTreeMapCanvasBridge = new QgsLayerTreeMapCanvasBridge(QgsProject::instance()->layerTreeRoot(),mMapCanvas,this);
connect( mLayerTreeMapCanvasBridge, &QgsLayerTreeMapCanvasBridge::canvasLayersChanged, mMapCanvas, &QgsMapCanvas::setLayers );
//Layer Tree View右鍵菜單實現(xiàn)
mLayerTreeView->setMenuProvider(new ll_qgis_base_layertreeview_menu(mMainWindow,mLayerTreeView,mMapCanvas));
connect(QgsProject::instance()->layerTreeRegistryBridge(),SIGNAL(addedLayersToLayerTree(QList<QgsMapLayer*>)),
this,SLOT(slot_autoSelectAddedLayer(QList<QgsMapLayer*>)));
}
- 主要涉及了以下類
QgsDockWidget
,QgsLayerTreeModel
,QgsLayerTreeView
,QgsLayerTreeMapCanvasBridge
-
QgsDockWidget
是一個Qt Dock Widget,用于顯示圖層樹 -
QgsLayerTreeView
和QgsLayerTreeModel
實現(xiàn)了樹的功能 -
QgsLayerTreeMapCanvasBridge
類負責(zé)從圖層樹中更新QgsMapCanvas
的圖層
QgsProject(項目管理)
QGis的項目可以保存為項目文檔邪媳,后綴名為“qgz”或“qgs”捐顷。在QGIS 3以前,只能通過“qgs”文件保存項目雨效⊙镐蹋“qgs”文件的本質(zhì)是存儲圖層的信息等的XML文件。在QGIS 3以后徽龟,“qgz”格式采用ZIP壓縮方法叮姑,不僅包含“qgs”文件,還包括附屬數(shù)據(jù)庫(Auxiliary Storage)文件(后綴名為“qgd”)据悔。自QGIS 3.2以來传透,“qgz”文件成為QGIS項目的默認存儲格式耘沼,本書也使用“qgz”文件存儲QGIS項目。
QGis軟件中的項目管理
-
新建項目朱盐,在Project菜單中可以新建一個空工程
-
保存項目 可以選擇項目名稱和位置
代碼實現(xiàn)
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
QgsProject is available both as a singleton (QgsProject::instance()) and for use as standalone objects. The QGIS project singleton always gives access to the canonical project reference open within the main QGIS application.
- 類
QgsProject
代表QGis中的一個項目耕拷,包含項目管理、圖層管理以及其他功能托享,QgsProject
的詳細內(nèi)容見官方文檔骚烧。 -
QgsProject
是一個單例類,通過方法QgsProject::instance()
即可調(diào)用其方法闰围,以下是QgsProject
的一些常用函數(shù) -
QgsProject
的最常用的功能是添加圖層赃绊,調(diào)用QgsProject::instance()->addMapLayer(vecLayer);
后會在Map Canvas顯示,也會添加到Layer tree中羡榴,如下代碼添加一個shape文件
void MainWindow::addShpSlot()
{
QString filename = QStringLiteral("maps/shapefile/protected_areas.shp");
QFileInfo ff(filename);
//創(chuàng)建圖層
QgsVectorLayer* vecLayer = new QgsVectorLayer(filename,ff.baseName(),"ogr");
if(!vecLayer->isValid())
{
QMessageBox::critical(this,tr("error"),tr("invalid layer"));
return;
}
QgsProject::instance()->addMapLayer(vecLayer);
zoomToFirstLayer<QgsVectorLayer*>();
}
- 以下是
QgsProject
的常用函數(shù)
//讀取項目文件
bool read (const QString &filename, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
bool read (Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
//保存項目文件
bool write ()
bool write (const QString &filename)
//添加單個圖層
QgsMapLayer * addMapLayer (QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
//添加多個圖層
QList< QgsMapLayer * > addMapLayers (const QList< QgsMapLayer * > &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Q_INVOKABLE QgsMapLayer *mapLayer (const QString &layerId) const
template<class T >
T mapLayer (const QString &layerId) const
QMap< QString, QgsMapLayer * > mapLayers (const bool validOnly=false) const
QList< QgsMapLayer * > mapLayersByShortName (const QString &shortName) const
template<typename T >
QVector< T > mapLayersByShortName (const QString &shortName) const
void removeAllMapLayers ()
void removeMapLayer (const QString &layerId)
void removeMapLayer (QgsMapLayer *layer)
void removeMapLayers (const QList< QgsMapLayer * > &layers)
void removeMapLayers (const QStringList &layerIds)
總結(jié)
-
QgsMapCanvas
作為視圖類提供了繪制的畫布 -
QgsMapCanvasItem
可以繪制在畫布上的Item -
QgsProject
圖層管理碧查,尤其在添加圖層時常用 - 了解了這幾個類,就可以學(xué)習(xí)如何顯示GIS數(shù)據(jù)了