前言

  使用QGis的目的是进行二次开发,或者说是融入我们的应用(无人车、无人船、无人机),本片描述搭建QGis二次基础开发环境,由于实在是太长了,进行了分篇:

  • 上半部分:主要是安装好后,使用QtCreator可以使用QGIs的apps下的Qt使用对应的编译器编译不带qgis的空工程。
  • 下半部分:在上半部分基础上添加qgis的依赖,并实现一个qgis的完全独立模模块化的应用,让没有安装qgis库的使用工程模板可以开始二次开发编译。
 

Demo

  空demo
  

  运行qgis的demo
  

 

给Demo引入QGIS库

步骤一:添加qgis代码

  新建QWidget的子类TestWidget,使用常规initControl添加布局嵌套窗口方式,来实现在QApplication消息循环里面的窗口类里面添加单独的qgis窗口。
  

void TestWidget::testEnv(QString filePath)
{
QHBoxLayout *pHBoxLayout = dynamic_cast<QHBoxLayout *>(this->layout());
if(!pHBoxLayout)
{
pHBoxLayout = new QHBoxLayout(this);
LOG;
} QgsMapCanvas *pMapCanvas = new QgsMapCanvas(); // 本地影像路径
QgsRasterLayer *pLayer = new QgsRasterLayer(filePath);
pMapCanvas->setLayers({pLayer});
pMapCanvas->setExtent(pLayer->extent());
pMapCanvas->refresh(); QgsMapToolPan *pMapToolPan = new QgsMapToolPan(pMapCanvas);
pMapCanvas->setMapTool(pMapToolPan); pHBoxLayout->addWidget(pMapCanvas, 1); pMapCanvas->show(); setLayout(pHBoxLayout);
}

步骤二:新建模块,并引入基本的qgis库

  

  

  然后开始编译。

步骤三:新增支持c++17配置

  编译出错如下:
  

   支持c++17
  

步骤四:支持数学宏定义

  

  未定义M_Pi添加
  

  最终,添加了win32下自动copy的脚本
  

步骤五:运行奔溃寻找依赖库

  编译通过,但是运行崩溃,这里不好直接把bin全部copy过来,所以用打包的方式确定少了那些库,补充一个打包环境:
  

  

  这个打包之后,像Qt5Xml.dll也没有包含进去,但是实际apps/qt5/bin下是有的,这个只能说单独弄sdk不是 很完善,目前靠个人完善。
  完善之后发现:
  

  基本就是OSGeo4W/bin下大部分库和OSGeo4W/apps/Qt5/bin下大部分库了:
  

  没有添加Qgis代码,添加之后还少qgis_gui.dll,apps下qgis-lts中bin的dll(就qgis的直接库),所以后来干脆直接三个bin目录下下的dll都拷贝了,需要精简再反向减少即可。
  

 

关键代码

qgis3.34.7env.pri

INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD # 需要QDomDocument
QT += xml # 需要支持c++17
CONFIG += c++17 # 未定义M_PI、M_PI_2添加
DEFINES += _USE_MATH_DEFINES win32{
# copy ffmpeg
src_file = $$PWD/qgis-ltr/bin/*
dst_file = $$OUT_PWD
# target_file = $$DESTDIR
src_file ~= s,/,\\,g
dst_file ~= s,/,\\,g
# target_file ~= s,/,\\,g
system(xcopy $$src_file $$dst_file /y /s/q/e)
# system(xcopy $$src_file $$target_file /y /s/q/e)
} INCLUDEPATH += $$PWD/qgis-ltr/include
LIBS += -L$$PWD/qgis-ltr/lib \
-lqgis_3d \
-lqgis_analysis \
-lqgis_app \
-lqgis_core \
-lqgis_gui \
-lqgis_native \
-lqgis_server HEADERS += \
$$PWD/qgis3.34.7.h

qgis3.34.7.h

#ifndef QGIS3_34_7_H
#define QGIS3_34_7_H #include <qgsapplication.h>
#include <qgsmapcanvas.h>
#include <qgsmaptoolpan.h>
#include <qgsrasterlayer.h>
#include <QtMath> #endif // QGIS3_34_7_H
TestWidget.cpp
#include "TestWidget.h"
#include "ui_TestWidget.h" #include <QHBoxLayout>
#include <QBoxLayout>
#include <QPushButton> #include "qgis3.34.7.h" // QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置
#define MSVC
#ifdef MSVC
#define QSTRING(s) QString::fromLocal8Bit(s)
#else
#define QSTRING(s) QString(s)
#endif #include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")

TestWidget.h

#ifndef TESTWIDGET_H
#define TESTWIDGET_H #include <QWidget> namespace Ui {
class TestWidget;
} class TestWidget : public QWidget
{
Q_OBJECT public:
explicit TestWidget(QWidget *parent = 0);
~TestWidget(); public:
void testEnv(QString filePath); protected:
void initControl(); private:
Ui::TestWidget *ui;
}; #endif // TESTWIDGET_H

TestWidget.cpp

TestWidget::TestWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::TestWidget)
{
ui->setupUi(this); QString version = "v1.0.0";
setWindowTitle(QSTRING("QGisDemo %1(作者:长沙创微智科信息技术有限公司 QQ:21497936 WX:15173255813 www.chuangweizhike.com)").arg(version)); initControl(); } TestWidget::~TestWidget()
{
delete ui;
} void TestWidget::initControl()
{
} void TestWidget::testEnv(QString filePath)
{
QHBoxLayout *pHBoxLayout = dynamic_cast<QHBoxLayout *>(this->layout());
if(!pHBoxLayout)
{
pHBoxLayout = new QHBoxLayout(this);
LOG;
} QgsMapCanvas *pMapCanvas = new QgsMapCanvas(); // 本地影像路径
QgsRasterLayer *pLayer = new QgsRasterLayer(filePath);
pMapCanvas->setLayers({pLayer});
pMapCanvas->setExtent(pLayer->extent());
pMapCanvas->refresh(); QgsMapToolPan *pMapToolPan = new QgsMapToolPan(pMapCanvas);
pMapCanvas->setMapTool(pMapToolPan); pHBoxLayout->addWidget(pMapCanvas, 1); pMapCanvas->show(); setLayout(pHBoxLayout);
}
 

模块化

  

 

工程模板v1.0.0

  

 

入坑

入坑一:无法加载tif图像

问题

  

过程

  开始以为是无法直接在QWidget加载,可以在QMainWindow里面加载,后来经过判断是因为变量的问题,在main函数里面是因为是全局的,所以exec()之后是存在的,而放到Qt窗口构造里面,则是new出来的就可以,简单来说就是保持对象存在。

解决

  局部改成new即可:
  

QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥感图的Demo的更多相关文章

  1. PHP全栈开发(三):CentOS 7 中 PHP 环境搭建及检测

    简单回顾一下我们在(一).(二)中所做的工作. 首先我们在(一)中设置了CentOS 7的网络. 其实这些工作在CentOS 6中都是很容易的,因为有鸟哥的Linux私房菜这样好的指导. 但是这些操作 ...

  2. Django开发笔记三

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.基于类的方式重写登录:views.py: from ...

  3. Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的 ...

  4. 【python】python彻底卸载的方法【windows安装版卸载的示例】

    要想彻底干净的卸载python,如果是使用的安装版的话,其实很简单.[windows安装版] 就是点击安装包. 例如,当前你安装的版本是3.6.5,你想要把它卸载掉. 查看python版本的命令: 只 ...

  5. MySql5.7.11 for Windows 安装(二)

    原文:MySql5.7.11 for Windows 安装(二) 安装之后,首先创建data文件夹(旧版本本来就有),管理员打开cmd,cd到bin文件夹,输入 mysqld –initialize- ...

  6. Modbus库开发笔记之十一:关于Modbus协议栈开发的说明(转)

    源: Modbus库开发笔记之十一:关于Modbus协议栈开发的说明

  7. Redash 二开 - 后端环境搭建

    Redash 二开 - 后端环境搭建 一.操作系统选择 官方文档有一句话:Windows users: while it should be possible to run Redash on a W ...

  8. 【转】Sqlite 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该...

    开发环境: vs2010+.net framework 4.0+ System.Data.SQLite.DLL (2.0)今天在做Sqlite数据库测试,一运行程序在一处方法调用时报出了一个异常 混合 ...

  9. 总结Selenium自动化测试方法(二)测试环境搭建

    (接上期内容) 二.测试环境搭建 1.安装python 现在python3.0比python2.0多了一些改进的功能(详见http://zhidao.baidu.com/link?url=3sT1g7 ...

  10. <VS2010>混合模式程序集是针对“v2.0”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集

    在把以前写的代码生成工具从原来的.NET3.5升级到.NET4.0时,将程序集都更新后,一运行程序在一处方法调用时报出了一个异常: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有 ...

随机推荐

  1. 面试官:实战中用过CountDownLatch吗?详细说一说,我:啊这

    写在开头 在很多的面经中都看到过提问 CountDownLatch 的问题,正好我们最近也在梳理学习AQS(抽象队列同步器),而CountDownLatch又是其中典型的代表,我们今天就继续来学一下这 ...

  2. 深度优先搜索-overview

    深度优先搜索的实现一般有2种方式 递归 //todo 非递归-借助stack 因为栈后进先出的特点,使其很容易实现树/图的深度优先遍历.如果是BFS,那非递归经常借助queue. 整个过程可以被描述为 ...

  3. CTFshow命令执行29-123

    命令执行 WEB29 eval是php中执行以PHP脚本执行的命令 PHP命令可以执行脚本命令 本题使用方法是先 system(cp f*.php 1.txt) 然后访问1.txt WEB30 在PH ...

  4. 力扣394(java)-字符串解码(中等)

    题目: 给定一个经过编码的字符串,返回它解码后的字符串. 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次.注意 k 保证为正整数 ...

  5. Dubbo-go 服务代理模型

    ​简介:HSF 是阿里集团 RPC/服务治理 领域的标杆,Go 语言又因为其高并发,云原生的特性,拥有广阔的发展前景和实践场景,服务代理模型只是一种落地场景,除此之外,还有更多的应用场景值得我们在研发 ...

  6. Serverless 可观测性的过去、现在与未来

    简介: 函数计算可观测性经历了 1.0 -> 2.0 的发展,从闭门造车的可观测发展成开源的可观测,从平台的可观测发展为开发者的可观测,从FaaS Only 的可观测演进成了云原生的可观测. 作 ...

  7. 什么是 ELF 文件(文件格式)

    ELF 是一种用于二进制文件.可执行文件.目标代码.共享库和核心转储格式文件. 是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI) ...

  8. Pod入门知识(4)

    一.Pod是什么? 官方文档:https://kubernetes.io/docs/concepts/workloads/pods/ Pod 是 Kubernetes 中的最小调度单元,k8s 是通过 ...

  9. Docker 之 Dockerfile

    Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明. 一.官方镜像 学习docker镜像的制作之前,先去看看官方的镜像是怎么制作的,查看官方dockerf ...

  10. JavaWeb 中 “转发”与 “重定向”的区别

    JavaWeb 中 "转发"与 "重定向"的区别 每博一文案 人生的常态,就是有聚有散,有得有失,就像山峰一样,总有高低,起伏不断. 曾经,我们是鲜衣怒马的少年 ...