zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    在网络中传输数据(I)
    WinForm DataGrid 中在 DataGridBoolColumn 的列标题上加一个 CheckBox 实现全选和全不选
    datagrid 相关
    Agile Framework视频演示发布
    asp.net(含:模拟登陆,照片列表)
    会计电算化常考题目一
    jquery实例教学一
    ASP .net(照片列表详细功能CRUD演示)
    会计电算化常考题目
    ASP.NET(get和post比较)
  • 原文地址:https://www.cnblogs.com/judes/p/15145258.html
Copyright © 2011-2022 走看看