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:softOSGeo4W64include 

D:softOSGeo4W64appsqgis-ltrinclude

4、设置附加库目录【lib文件的目录】

 D:softOSGeo4W64appsqgis-ltrlib

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:softOSGeo4W64appsqgis-ltrin

D:softOSGeo4W64in

②、路径2的dll

D:softOSGeo4W64appsQt5in

③、路径3的文件夹

D:softOSGeo4W64appsQt5plugins下的整个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: 
") + 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文件,并将文件存到内存里,然后依次绘制到画布中。




长风破浪会有时,直挂云帆济沧海!
可通过下方链接找到博主
https://www.cnblogs.com/judes/p/10875138.html
原文地址:https://www.cnblogs.com/judes/p/15145258.html