日前由於項目需求,學習了QGIS,並在QGIS上進行二次開發。在這裏記錄一下到目前爲止的——入坑過程。
下載QGIS
下載QGIS可以從官網上直接下載。首先,我也是想着編譯一下源碼,從源碼學習。當我開始下載源碼之後,並按照網上的一系列教程開始編譯時,到目前爲止,我還沒有成功過。都是在VS中編譯時報各種錯誤。所以,本文不介紹源碼編譯。當我哪天成功了,我再來補充。
下面介紹一下我所使用的環境:
- windows 10 (64位)
- VS2017 (或者VS2015)這兩個VS版本我都試過了
- qt5.9.2 (我使用的是這個地址) 其實在安裝QGIS的時候也會安裝對應的QT,但是由於我之前安裝過Qt,所以就直接使用之前的Qt了。 注意:使用自己提前下載的Qt會缺少幾個DLL(比如:Qt5WebkitWidgets.dll等),這幾個DLL在伴隨下載的Qt中。
- QGIS 3.0.2-1(利用OSGeo4W下載得到),如下所示:
啓動VS,創建Qt工程
Qt開發環境配置:啓動VS2017,如果沒有安裝Qt VS tools的在”工具–>擴展和更新”中搜索並下載安裝。然後配置QtVSTools,添加Qt安裝的路徑。該部分內容可以自行百度。
當開發環境配置好了之後,創建Qt工程(Qt Gui Application)。在選擇導入模塊的時候勾選以下幾個(其實就是比默認的多選擇XML)
將編譯環境改成release x64(release是因爲QGIS下載的都是release版本的,debug得自己編譯,x64是因爲我的機器是64位的),然後編譯、運行,看看時候能否正常執行
配置項目屬性
在“C++” >>”常規” >> “附加包含目錄”中添加以下項(具體路徑需要做適當調整):
C:\path\to\OSGeo4W64\include
C:\path\to\OSGeo4W64\apps\qgis\include
在“鏈接器” >>”常規” >> “附加庫目錄”中添加以下項(具體路徑需要做適當調整):
C:\path\to\OSGeo4W64\apps\qgis\lib;
在“鏈接器” >>”輸入” >> “附加依賴項”中添加以下項:
qgis_app.lib
qgis_core.lib
qgis_gui.lib
修改項目文件
1 修改main.cpp
如下所示
#include "ImageViewer.h"
#include <QtWidgets/QApplication>
#include <qgsapplication.h>
int main(int argc, char *argv[])
{
QgsApplication a(argc, argv, true);
QgsApplication::setPrefixPath("C:/path/to/OSGeo4W64/apps/qgis", true);
QgsApplication::initQgis(); //初始化QGIS應用
ImageViewer w; //創建一個窗體,類似於Qt
w.show();
return a.exec(); //進入QGIS應用的消息循環
}
每一個QGIS的程序開始時都必須聲明創建QgsApplication,這個和Qt必須創建QApplication一樣,所以這裏就是將QApplication替換成QgsApplication。QgsApplication::setPrefixPath
是用來設置qgis的安裝路徑的,其實它主要作用是加載plugins。
2 修改ImageViewer.cpp
如下所示
#include "ImageViewer.h"
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qgsvectorlayer.h>
ImageViewer::ImageViewer(QWidget *parent)
: QMainWindow(parent)
{
this->resize(600, 400);
// create the menus and then add the actions to them.
fileMenu = this->menuBar()->addMenu("File");
openFileAction = new QAction("Open", this);
this->connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(on_openFileAction_triggered()));
fileMenu->addAction(openFileAction);
// initialize the map canvas
mapCanvas = new QgsMapCanvas();
this->setCentralWidget(mapCanvas);
mapCanvas->setCanvasColor(QColor(255, 255, 255));
mapCanvas->setVisible(true);
mapCanvas->enableAntiAliasing(true);
}
void ImageViewer::on_openFileAction_triggered() {
addVectorLayer();
}
void ImageViewer::addVectorLayer()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open shape file"), "", "*.shp");
QStringList temp = fileName.split('/');
QString basename = temp.at(temp.size() - 1);
QgsVectorLayer* vecLayer = new QgsVectorLayer(fileName, basename, "ogr");
if (!vecLayer->isValid())
{
QMessageBox::critical(this, "error", QString("layer is invalid: \n") + fileName);
return;
}
mapCanvas->setExtent(vecLayer->extent());
layers.append(vecLayer);
mapCanvas->setLayers(layers);
mapCanvas->refresh();
}
該段代碼主要的作用就是添加菜單欄,在菜單欄中添加“File”菜單,然後在“File”菜單中增加一個“Open” Action,並設置Open的響應函數。在響應函數中加載矢量地圖文件(.shp格式),並顯示在界面中。
3 修改ImageViewer.h
如下所示
#pragma once
#include <QtWidgets/QMainWindow>
#include <qmenu.h>
#include <qaction.h>
#include <qgsmapcanvas.h>
class ImageViewer : public QMainWindow
{
Q_OBJECT
public:
ImageViewer(QWidget *parent = Q_NULLPTR);
private:
// create the menus and then add the actions to them.
QMenu *fileMenu;
QAction *openFileAction;
//map canvas
QgsMapCanvas *mapCanvas;
QList<QgsMapLayer *> layers;
public slots:
void on_openFileAction_triggered();
//
public:
void addVectorLayer();
};
再次運行程序後會遇到缺少各種DLL的錯誤,這時候有兩種方法:
- 將
C:\path\to\OSGeo4W64\bin
和C:\path\to\OSGeo4W64\app\qgis\bin
添加到環境變量Path中 - 將
C:\path\to\OSGeo4W64\bin
和C:\path\to\OSGeo4W64\app\qgis\bin
中的DLL全部拷貝到生成的exe的目錄下。
這時再次運行程序,可能還是會缺少各種DLL,如果是以Qt5開頭的,在C:\path\to\OSGeo4W64\app\Qt5
中查找;如果是其他的DLL,可以在你的系統中查找,推薦使用everything。如果還是找不到需要的DLL,請自己百度下載或者請留言,看看我有沒有。
最後得到如下的結果: