QGIS二次開發-新建工程並顯示一個圖層


一、環境

開發環境為VS2019+Qt14,編譯器為MSVC【MingW在windows下的動態庫為.a文件,但是現成的QGIS動態庫是dll的,所以選擇MSVC,以免麻煩】

配置vs+qt環境,參考:https://www.cnblogs.com/judes/p/8992231.html

 

二、安裝QGIS相關【用於獲取桌面版和二次開發依賴包,也可直接下載現成的,見此節末尾】

1、安裝桌面版【只是使用Qt開發的一個工具,可以用來玩玩,只要這個工具有的功能,理論上都能通過二次開發QGIS庫開發出來】,參考:https://www.cnblogs.com/judes/p/15143756.html

大概熟悉一下,如使用OSM【OpenStreetMap,開源,很多webgis和接口gis都用這個】圖層,在線高德圖層、谷歌圖層、3D、2維....

 

 

  

 

2、安裝好桌面版之后,需要下載QGIS運行庫【后續二次開發所依賴的庫】,打開配置工具

 

 3、按照下圖依次下一步

 

 

 

  

  

 這里需要注意下,我最開始按照其他博客選擇最后一個,但是下載失敗,一直提示license有問題,選擇第二個就ok了

 然后等待下載,會比較慢,我在家里是每秒幾百k,大概等了半小時

 

3、下載完成

后面二次開發的依賴就在這里面

注意:

如果不想自己下載安裝這么多東西,也可以直接網上找現成的編譯好了的依賴庫,我就是這樣做的【下文也按照此路徑進行配置】,下載來是這樣的:

 跟上面差不多。此外也可以網上找如何對QGIS進行源碼編譯的方法,是基於CMake的,如果是跨環境估計就得用這方法了。

 

 

三、下載地圖瓦片數據

QGIS的瓦片數據類型是shp的,可在此網站下載:http://download.geofabrik.de/,下載下來里面有很多,如建築、學校、工廠等等,這里做實驗隨便留一個備用

 

四、新建工程及環境配置

1、打開vs,新建Qt gui widget工程,源文件如下:

 

2、右鍵項目,為項目添加svg和xml的Qt模塊

為啥要加這模塊呢,是因為QGis源碼里會用到。

 

3、設置附加包目錄【頭文件目錄】

D:\soft\OSGeo4W64\include 

D:\soft\OSGeo4W64\apps\qgis-ltr\include

 

4、設置附加庫目錄【lib文件的目錄】

 D:\soft\OSGeo4W64\apps\qgis-ltr\lib

 

5、設置附加依賴項【依賴的dll動態庫】

 qgis_core.lib

 qgis_app.lib 

 qgis_gui.lib

 

6、設置宏定義【編譯會出現未定義標識符“M_PI”】 

右鍵項目,C/C++,預處理器,預處理器定義,添加_USE_MATH_DEFINES

 

 

 

7、編譯程序生成exe【必須是64位和release,64位是因為要與QGis位數一致】

8、將相關動態庫放到exe同一路徑,以免運行失敗

①、路徑1的dll

D:\soft\OSGeo4W64\apps\qgis-ltr\bin

D:\soft\OSGeo4W64\bin

②、路徑2的dll

D:\soft\OSGeo4W64\apps\Qt5\bin

③、路徑3的文件夾

D:\soft\OSGeo4W64\apps\Qt5\plugins下的整個platforms文件夾

最終可執行文件夾是這樣的:

 注意都要復制,不然后面代碼寫了也不能運行,會報無dll錯誤和Qt platforms錯誤。至此二次開發環境就ok了。

 

五、代碼編寫

1、qtwidgetsapplication.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_qtwidgetsapplication.h"


#include <qmenu.h>
#include <qaction.h>
#include <qgsmapcanvas.h>

class QtWidgetsApplication : public QMainWindow
{
    Q_OBJECT

public:
    QtWidgetsApplication(QWidget *parent = Q_NULLPTR);

private:
    Ui::QtWidgetsApplicationClass ui;




    QMenu* fileMenu;
    QAction* openFileAction;
    QgsMapCanvas* mapCanvas;
    QList<QgsMapLayer*> layers;

public slots:
    void on_openFileAction_triggered();
    //

public:
    void addVectorLayer();
};

2、qtwidgetsapplication.cpp

#include "qtwidgetsapplication.h"

#include <qmenubar.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qgsvectorlayer.h>

QtWidgetsApplication::QtWidgetsApplication(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    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 QtWidgetsApplication::on_openFileAction_triggered()
{
    addVectorLayer();
}


void QtWidgetsApplication::addVectorLayer()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open shape file"), "", "*.shp");
    //QString fileName = QFileDialog::getOpenFileName(this, tr("Open shape file"), "", "*");
    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();
}

3、main.cpp

#include "qtwidgetsapplication.h"
#include <QtWidgets/QApplication>

#include <qgsapplication.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtWidgetsApplication w;
    w.show();
    return a.exec();
}

原理就是在mainwindow里,增加一個點擊action,點擊后打開shp文件,並將文件存到內存里,然后依次繪制到畫布中。

 


免責聲明!

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



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