QGis二次开发 —— 3、程序加载栅格tif与矢量shp文件可进行切换控制,可进行导出/导入工程(附源码)

效果

在这里插入图片描述

功能说明

     软件可同时加载.tif栅格图片与.shp矢量图片、加载图片后可进行自由切换查看图层、可对加载的图片进行关闭 关闭后清空图层、可对加载的图片进行导出.qgs的QGIS工程、可对.qgs的QGis工程导入并导入后可进行自由切换查看图层。

源码

     注意: 在加载tif栅格文件后会在该文件同级目录下自动创建.html文件。
     注意: .shp文件目录下应该要有对应同名的.shx矢量字体文件,这样才能加载成功。

     main.cpp

#include "QtWidgetsApplication1.h"
#include <QtWidgets/QApplication>#include <qgsapplication.h>int main(int argc, char *argv[])
{// 参数三: 如果需要GUI应用程序,则设置为true;对于仅控制台应用程序,设置falseQgsApplication a(argc, argv, true);QgsApplication::setPrefixPath("D:/Software/QGis-OSGeo4W/install/apps/qgis-ltr", true);		// 设置qgis路径QgsApplication::setPluginPath("D:/Software/QGis-OSGeo4W/install/apps/qgis-ltr/plugins");	// 设置插件路径QgsApplication::initQgis();																	// 初始化QGisQtWidgetsApplication1 w;w.show();return a.exec();
}


     QtWidgetsApplication1.h

#pragma once#include <QtWidgets/QMainWindow>
#include "ui_QtWidgetsApplication1.h"#include <QtMath>
#include <qgsmapcanvas.h>class QtWidgetsApplication1 : public QMainWindow
{Q_OBJECTpublic:QtWidgetsApplication1(QWidget *parent = nullptr);~QtWidgetsApplication1();protected:// 将画布放在ui的Widget上,供显示void initQgsMapCanvas();// 加载本地.tif、.shp文件bool loadLocalFile(const QString &RasterFileName, const QString &VectorFileName);// 删除画布上所有图层并更新画布void removeMapLayers();protected slots:// 通过按钮驱动进行加载本地文件void on_btn_qgsLoadFile_clicked();// 保存QGIS工程项目void on_btn_SaveQgisProject_clicked();// 导入QGIS工程项目void on_btn_LoadQgisProject_clicked();// 关闭QGIS工程项目void on_btn_CloseQgisProject_clicked();// 切换显示画布上的矢量、栅格图层void sltQgsShowFile(int);private:Ui::QtWidgetsApplication1Class ui;// 画布QgsMapCanvas *qMapCanvas = nullptr;// 图层列表: qMapLayerList为真实使用,qVirtualMapLayerList为虚拟使用。真实使用时会增删、虚拟使用则仅在函数内增加后则不再增删。QList<QgsMapLayer*> qMapLayerList, qVirtualMapLayerList;
};


     QtWidgetsApplication1.cpp

#include "QtWidgetsApplication1.h"#include <QMessageBox>
#include <QComboBox>
#include <QGridLayout>#include <qgsrasterlayer.h>
#include <qgsvectorlayer.h>
#include <qgsproject.h>const QString QGisProjectFileName = "qgs_project.qgs";QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QMainWindow(parent)
{ui.setupUi(this);initQgsMapCanvas();
}QtWidgetsApplication1::~QtWidgetsApplication1()
{removeMapLayers();QLayout *GridLayout = ui.qgsMapCanvasWidget->layout();if (GridLayout) {GridLayout->removeWidget(qMapCanvas);delete GridLayout; }GridLayout = nullptr;if (qMapCanvas) { delete qMapCanvas; }qMapCanvas = nullptr;
}void QtWidgetsApplication1::initQgsMapCanvas()
{// 创建地图画布对象qMapCanvas = new QgsMapCanvas(this);QGridLayout *GridLayout = new QGridLayout;GridLayout->addWidget(qMapCanvas);ui.qgsMapCanvasWidget->setLayout(GridLayout);
}bool QtWidgetsApplication1::loadLocalFile(const QString &RasterFileName, const QString &VectorFileName)
{// 创建矢量图层对象并加入本地文件QgsVectorLayer *qVectorLayer = new QgsVectorLayer(VectorFileName, "shp");if (!qVectorLayer->isValid()) { return false; }qMapLayerList << qVectorLayer;qVirtualMapLayerList << qVectorLayer;ui.cb_qgsShowFile->addItem("shp", 0);	// 1为qVectorLayer所在qMapLayerList的序号// 创建光栅图层对象加入本地文件QgsRasterLayer *qRasterLayer = new QgsRasterLayer(RasterFileName, "tif");if (!qRasterLayer->isValid()) { return false; }// 设置对比度增强(主要用于栅格图像;矢量图像不需要)。参数1算法:线性直方图、参数2界限范围:实际最小最大值qRasterLayer->setContrastEnhancement(QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax);qMapLayerList << qRasterLayer;qVirtualMapLayerList << qRasterLayer;ui.cb_qgsShowFile->addItem("tif",1);	// 0为qRasterLayer所在qMapLayerList的序号// 画布设置qMapCanvas->setLayers(qMapLayerList);							// 设置应在画布中显示的图层列表qMapCanvas->setDestinationCrs(qMapLayerList[0]->crs());			// 设置目标坐标参照系为输入光栅图层的坐标系qMapCanvas->setExtent(qMapLayerList[0]->extent());				// 设置画布范围为输入光栅图层的范围qMapCanvas->setCurrentLayer(qMapLayerList[0]);					// 设置画布当前图层为输入光栅图层qMapCanvas->refresh();											// 刷新画布// 将图层列表添加到已加载图层的映射中QgsProject::instance()->addMapLayers(qMapLayerList);return true;
}void QtWidgetsApplication1::removeMapLayers()
{if (!qMapLayerList.isEmpty()) {qMapLayerList.clear(); qVirtualMapLayerList.clear();}qMapCanvas->setLayers(QList<QgsMapLayer*>());qMapCanvas->refresh();
}void QtWidgetsApplication1::on_btn_qgsLoadFile_clicked()
{loadLocalFile("./world.tif", "./china.shp");ui.cb_qgsShowFile->setEnabled(true);ui.btn_qgsLoadFile->setEnabled(false);connect(ui.cb_qgsShowFile, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QtWidgetsApplication1::sltQgsShowFile);
}void QtWidgetsApplication1::on_btn_SaveQgisProject_clicked()
{// 工程文件扩展名为: .qgz、.qgsQgsProject::instance()->setFileName(QGisProjectFileName);QgsProject::instance()->write();
}void QtWidgetsApplication1::on_btn_LoadQgisProject_clicked()
{/*****************************************************************/int aaa = QgsProject::instance()->count();int aaa1 = qMapCanvas->layerCount();// 加载前先将之前的画布、画布上的图层清空removeMapLayers();int ccc = QgsProject::instance()->count();int ccc2 = qMapCanvas->layerCount();/* 重要: 以上测试说明当qMapLayerList删除,那么对应画布的layer与工程实例的mapLayer也会自动清空! *//*****************************************************************/if (!QgsProject::instance()->read(QGisProjectFileName)){QMessageBox::critical(this, "ERROR", "load QGIS Project fail!", QMessageBox::Yes);return;}qMapLayerList = qVirtualMapLayerList = QgsProject::instance()->mapLayers().values();qMapCanvas->setLayers(qMapLayerList);						// 设置画布当前图层为输入光栅图层qMapCanvas->setDestinationCrs(qMapLayerList[0]->crs());		// 设置目标坐标参照系为输入光栅图层的坐标系qMapCanvas->setExtent(qMapLayerList[0]->extent());			// 设置画布范围为输入光栅图层的范围qMapCanvas->setCurrentLayer(qMapLayerList[0]);				// 设置画布当前图层为输入光栅图层qMapCanvas->refresh();										// 刷新画布ui.cb_qgsShowFile->addItem("shp", 0);	// 1为qVectorLayer所在qMapLayerList的序号ui.cb_qgsShowFile->addItem("tif", 1);	// 0为qRasterLayer所在qMapLayerList的序号ui.cb_qgsShowFile->setEnabled(true);ui.btn_qgsLoadFile->setEnabled(false);connect(ui.cb_qgsShowFile, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QtWidgetsApplication1::sltQgsShowFile);qDebug() << "AA:" << QgsProject::instance()->count() << "  " << QgsProject::instance()->mapLayers().count() << " " << qMapCanvas->layerCount() << "    " << qMapLayerList.size() << " " << qVirtualMapLayerList.size();
}void QtWidgetsApplication1::on_btn_CloseQgisProject_clicked()
{// 加载前先将之前的画布、画布上的图层清空removeMapLayers();disconnect(ui.cb_qgsShowFile, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QtWidgetsApplication1::sltQgsShowFile);ui.cb_qgsShowFile->setEnabled(false);ui.btn_qgsLoadFile->setEnabled(true);ui.cb_qgsShowFile->clear();QgsProject::instance()->clear(); 
}void QtWidgetsApplication1::sltQgsShowFile(int index)
{/* 重要: 以下操作说明qMapLayerList变化,那么对应画布的layer与工程实例的mapLayer也会自动变化! */if (qVirtualMapLayerList.size() > index){qMapLayerList.clear();qMapLayerList << qVirtualMapLayerList[index];qMapCanvas->setLayers(qMapLayerList);						// 设置画布当前图层为输入光栅图层qMapCanvas->setDestinationCrs(qMapLayerList[0]->crs());		// 设置目标坐标参照系为输入光栅图层的坐标系qMapCanvas->setExtent(qMapLayerList[0]->extent());			// 设置画布范围为输入光栅图层的范围qMapCanvas->refresh();										// 刷新画布}
}


     QtWidgetsApplication1.ui
在这里插入图片描述

关注

笔者 - jxd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/54086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-table 如何实现行列转置?

在某些需求里需要用到 行列转置 的表格&#xff0c;但 el-table 提供的基本表格是不支持行列转置的&#xff0c;这样就需要对这个表格进行二次开发。下面来看具体实现的效果&#xff1a; 具体实现方式 基本原理就是对原有的可渲染的数据结构进行处理&#xff0c;表头与表格数…

计算机的错误计算(九十三)

摘要 探讨 log(y,x) 即以 x 为底 y 的对数的计算精度问题。 Log(y,x)运算是指 x 为底 y 的对数。 例1. 计算 log(123667.888, 0.999999999999999) . 不妨在Python中计算&#xff0c;则有&#xff1a; 若在 Excel 单元格中计算&#xff0c;则有几乎同样的输出&#xff1a; 然…

模型部署基础

神经网络的模型部署是将训练好的神经网络模型应用到实际系统中&#xff0c;以实现预测、分类、推荐等任务的过程。下图展示了模型从训练到部署的整个流程&#xff1a; 1.模型部署的平台 在线服务器端部署 在线服务器端部署适用于处理大模型、需要精度优先的应用场景&#xff…

CSCC2024数据库内核赛道Profile记录

同学参加CSCC2024数据库系统赛道比赛&#xff0c;我和他一起研究了一些优化的case&#xff0c;最后成功拿到全国2/325。在这里记录一下我们讨论优化过的问题&#xff08;建议把源码下下来边读边搜代码&#xff0c;否则会晕&#xff09; 行锁占用内存过大 Q&#xff1a;TPCC测…

OpenCV运动分析和目标跟踪(1)累积操作函数accumulate()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将一个图像添加到累积图像中。 该函数将 src 或其部分元素添加到 dst 中&#xff1a; dst ( x , y ) ← dst ( x , y ) src ( x , y ) if mask…

网络基础,协议,OSI分层,TCP/IP模型

网络的产生是数据交流的必然趋势&#xff0c;计算机之间的独立的个体&#xff0c;想要进行数据交互&#xff0c;一开始是使用磁盘进行数据拷贝&#xff0c;可是这样的数据拷贝效率很低&#xff0c;于是网络交互便出现了&#xff1b; 1.网络是什么 网络&#xff0c;顾名思义是…

串口接收不到数据之电阻虚焊bug分析思路

单片机和EC移远通信模块进行通信&#xff0c;相同的代码运行在相同的硬件上&#xff0c;但是一个能联网&#xff0c;一个因为没有EC的应答连不上网。 开始分析&#xff0c;排除软件问题&#xff0c;给EC模块发为什么没应答&#xff1f; 1.发送失败 2.接收失败 排除情况2&#x…

汽车租赁系统1.0版本

汽车租赁系统1.0版本比较简陋&#xff0c;以后还会有2.0、3.0……就像《我爱发明》里面的一代机器二代机器&#xff0c;三代机器一样&#xff0c;是一个迭代更新的过程&#xff08;最近比较忙&#xff0c;可能会很久&#xff09;&#xff0c;这个1.0版本很简陋&#xff0c;也请…

Python+Pytest框架,“api_key.py文件怎么编写“?

1、在"api_keyword"文件夹下新增"api_key.py" import allure import requests import json import jsonpath from deepdiff import DeepDifffrom config import *allure.title("测试用例执行") class ApiKey:allure.step(">>>:开…

跨平台开发新视角:利用Android WebView实现Web内容的原生体验

在移动应用开发领域&#xff0c;跨平台解决方案一直是一个热门话题。开发者们不断寻求能够同时在iOS和Android平台上提供一致用户体验的方法。而Android的WebView组件&#xff0c;作为一个强大的工具&#xff0c;允许开发者在Android应用中嵌入Web内容&#xff0c;为用户提供接…

Maven从入门到精通(三)

一、Settings 配置 settings.xml 用来配置 maven 项目中的各种参数文件&#xff0c;包括本地仓库、远程仓库、私服、认证等信息。 全局 settings、用户 setting、pom 的区别&#xff1a; 全局 settings.xml 是 maven 的全局配置文件&#xff0c;一般位于 ${maven.home}/conf…

安全工具 | 使用Burp Suite的10个小tips

Burp Suite 应用程序中有用功能的集合 img Burp Suite 是一款出色的分析工具&#xff0c;用于测试 Web 应用程序和系统的安全漏洞。它有很多很棒的功能可以在渗透测试中使用。您使用它的次数越多&#xff0c;您就越发现它的便利功能。 本文内容是我在测试期间学到并经常的主要…

音视频入门基础:AAC专题(4)——ADTS格式的AAC裸流实例分析

一、ADTS格式的AAC裸流实例分析 在《音视频入门基础&#xff1a;AAC专题&#xff08;3&#xff09;——AAC的ADTS格式简介》中对AAC的ADTS格式进行了简介。下面用一个具体的例子来对ADTS格式的AAC裸流进行分析。 通过《音视频入门基础&#xff1a;AAC专题&#xff08;2&#x…

SpringBoot:Web开发(基于SpringBoot使用MyBatis-Plus+JSP开发)

目录 前期准备 构建项目&#xff08;IDEA2023.1.2&#xff0c;JDK21&#xff0c;SpringBoot3.3.3&#xff09; 添加启动器 Model准备 这里我们利用MybatisX插件生成我们所需要的实体类、数据访问层以及服务层 注意选择MyBatis-Plus3以及Lombok 然后再在service接口中定义…

【算法】-单调队列

目录 什么是单调队列 区域内最大值 区域内最小值 什么是单调队列 说到单调队列&#xff0c;其实就是一个双端队列&#xff0c; 顾名思义&#xff0c;单调队列的重点分为「单调」和「队列」。「单调」指的是元素的「规律」——递增&#xff08;或递减&#xff09;。「队列」指…

电脑提示丢失mfc140u.dll的详细解决方案,mfc140u.dll文件是什么

遇到电脑显示“缺少 mfc140u.dll 文件”的错误其实是比较常见的。这种提示通常表示某个应用程序在尝试运行时未能找到它所需的关键 DLL 文件&#xff0c;导致无法正常启动。不过&#xff0c;别担心&#xff0c;本文将一步步引导你通过几种不同的方法来解决这个问题&#xff0c;…

树模式数据表设计学习

引子&#xff1a; 场景&#xff1a;某读书网站&#xff0c;支持读者评论文章&#xff0c;并且对评论支持回复功能。设计的表如下&#xff1a; 问题点&#xff1a;你想获取一个评论下所有的评论信息&#xff1f; 将所有评论一次性取出、轮巡遍历&#xff0c;获取到所有数据。 …

多人开发小程序设置体验版的痛点

抛出痛点 在分配任务时,我们将需求分为三个分支任务,分别由前端A、B、C负责: 前端A: HCC-111-实现登录功能前端B: HCC-112-实现用户注册前端C: HCC-113-实现用户删除 相应地,我们创建三个功能分支: feature_HCC-111-实现登录功能feature_HCC-112-实现用户注册feature_HCC-1…

从C语言过渡到C++

&#x1f4d4;个人主页&#x1f4da;&#xff1a;秋邱-CSDN博客☀️专属专栏✨&#xff1a;C &#x1f3c5;往期回顾&#x1f3c6;&#xff1a;单链表实现&#xff1a;从理论到代码-CSDN博客&#x1f31f;其他专栏&#x1f31f;&#xff1a;C语言_秋邱的博客-CSDN博客 目录 ​…

Golang | Leetcode Golang题解之第395题至少有K个重复字符的最长子串

题目&#xff1a; 题解&#xff1a; func longestSubstring(s string, k int) (ans int) {for t : 1; t < 26; t {cnt : [26]int{}total : 0lessK : 0l : 0for r, ch : range s {ch - aif cnt[ch] 0 {totallessK}cnt[ch]if cnt[ch] k {lessK--}for total > t {ch : s[…