1. 程式人生 > >QGIS二次開發入坑指南

QGIS二次開發入坑指南

日前由於專案需求,學習了QGIS,並在QGIS上進行二次開發。在這裡記錄一下到目前為止的——入坑過程。

下載QGIS

下載QGIS可以從官網上直接下載。首先,我也是想著編譯一下原始碼,從原始碼學習。當我開始下載原始碼之後,並按照網上的一系列教程開始編譯時,到目前為止,我還沒有成功過。都是在VS中編譯時報各種錯誤。所以,本文不介紹原始碼編譯。當我哪天成功了,我再來補充。

下面介紹一下我所使用的環境:

  1. windows 10 (64位)
  2. VS2017 (或者VS2015)這兩個VS版本我都試過了
  3. qt5.9.2 (我使用的是這個地址) 其實在安裝QGIS的時候也會安裝對應的QT,但是由於我之前安裝過Qt,所以就直接使用之前的Qt了。 注意:使用自己提前下載的Qt會缺少幾個DLL(比如:Qt5WebkitWidgets.dll等),這幾個DLL在伴隨下載的Qt中
  4. 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的錯誤,這時候有兩種方法:

  1. C:\path\to\OSGeo4W64\binC:\path\to\OSGeo4W64\app\qgis\bin新增到環境變數Path中
  2. C:\path\to\OSGeo4W64\binC:\path\to\OSGeo4W64\app\qgis\bin中的DLL全部拷貝到生成的exe的目錄下。

這時再次執行程式,可能還是會缺少各種DLL,如果是以Qt5開頭的,在C:\path\to\OSGeo4W64\app\Qt5中查詢;如果是其他的DLL,可以在你的系統中查詢,推薦使用everything。如果還是找不到需要的DLL,請自己百度下載或者請留言,看看我有沒有。

最後得到如下的結果:
這裡寫圖片描述