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;对于仅控制台应用程序,设置false
 	QgsApplication 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();																	// 初始化QGis

	QtWidgetsApplication1 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_OBJECT

public:
    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、.qgs
	QgsProject::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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为 HCIP-Datacom H12-821 题库 (16)

1.需要题库的小伙伴至博客最下方添加微信公众号关注后回复题库 2.有兴趣交流IT问题的小伙伴微信公众号回复交流群&#xff0c;加入微信IT交流群 1. OSPF 邻居关系建立出现故障&#xff0c;通过 display ospf error 命令来检查&#xff0c;输出结果如图所示&#xff0c;根据图中…

OceanBase 4.x 存储引擎解析:如何让历史库场景成本降低50%+

据国际数据公司&#xff08;IDC&#xff09;的报告显示&#xff0c;预计到2025年&#xff0c;全球范围内每天将产生高达180ZB的庞大数据量&#xff0c;这一趋势预示着企业将面临着更加严峻的海量数据处理挑战。随着数据日渐庞大&#xff0c;一些存储系统会出现诸如存储空间扩展…

【Python 千题 —— 算法篇】寻找最长回文子串

Python 千题持续更新中 …… 脑图地址 &#x1f449;&#xff1a;⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 回文串是指一个字符串从左到右和从右到左读都是一样的。寻找一个字符串中的最长回文子串是许多经典算法问题之一&#xff0c;广泛应…

使用docker安装jenkins,然后使用jenkins本地发版和远程发版

使用docker安装jenkins&#xff0c;然后使用jenkins本地发版和远程发版 1、安装docker 1.安装必要的一些系统工具 sudo yum install docker-ce 2.添加软件源信息 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 3.更新…

DAY74

#ifndef WIDGET_H #define WIDGET_H#include <QWidget>#include <QPainter> //画家类 #include <QTimer> //定时器类 #include <QTime> //时间类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : …

风控——贷中管理介绍

一、概念介绍 贷中管理&#xff0c;指从贷款发放之日起&#xff0c;至贷款本息收回日期为止的贷款管理&#xff0c;贷中管理策略也集中在贷款发放后的管理和监控阶段&#xff0c;其目的是确保贷款资金的安全和有效使用&#xff0c;贷中预警和贷中调额在贷中管理中至关重要。 …

STMCuBeMX新建项目的两种匪夷所思的问题

错误一、保存地址名中有中文 错误&#xff1a;error1-haveCHinese_有中文\error1-haveCHinese_有中文.axf: error: L6002U: Could not open file error1-havechinese_???\stm32f1xx_it.o: No such file or directory 解决方法&#xff1a;重新导出&#xff0c;并且不要用中文…

Leetcode 701-二叉搜索树中的插入操作

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效的插入方式&a…

c# Avalonia 架构开发跨平台应用

Avalonia&#xff0c;读&#xff1a;阿瓦隆尼亚 由于以前的c#开发的windows平台项目想移植到信创平台&#xff08;UOS,Kylin)上&#xff0c;起初想用python重写&#xff0c;后来发现了这个Avalonia,用这个改动起来工作相对较少于是就先了解一下。 官网Avalonia Docs | Avalon…

贪心-单调递增的数字

给定一个非负整数 N&#xff0c;找出小于或等于 N 的最大的整数&#xff0c;同时这个整数需要满足其各个位数上的数字是单调递增。 &#xff08;当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。&#xff09; 示例 1: 输入: …

如何显示Dialog窗口

文章目录 1. 概念介绍2. 使用方法2.1 Overlay效果2.1 Dialog效果 3. 示例代码4. 内容总结 我们在上一章回中介绍了"使用get显示snackBar"相关的内容&#xff0c;本章回中将介绍使用get显示Dialog.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在…

又一款强大好用的Shell脚本项目,支持Bash,Sh、Dash、Ksh等,甚至可以在编辑器中直接用,程序员必备!(附源码)

作为一个程序员&#xff0c;肯定经常都要和shell脚本打交道&#xff0c;Shell脚本可以帮我们自动化各种任务&#xff0c;但也经常有格式错误、拼写错误、逻辑错误等等麻烦&#xff0c;而且它不会告诉你错在哪里&#xff01; 今天就给大家分享一个超级实用的开源项目 - ShellCh…

Vue接入高德地图并实现基本的路线规划功能

目录 一、申请密钥 二、安装依赖 三、代码实现 四、运行截图 五、官方文档 一、申请密钥 登录高德开放平台&#xff0c;点击我的应用&#xff0c;先添加新应用&#xff0c;然后再添加Key。 如图所示填写对应的信息&#xff0c;系统就会自动生成。 二、安装依赖 npm i am…

Opencv中的直方图(3)直方图比较函数compareHist()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 比较两个直方图。 函数 cv::compareHist 使用指定的方法比较两个密集或两个稀疏直方图。 该函数返回 d ( H 1 , H 2 ) d(H_1, H_2) d(H1​,H2​…

el-form之表单校验自动定位到报错位置问题,,提升用户体验

需求描述 由于需要填写的表单项太多&#xff0c;提交的时候校验不通过&#xff0c;如果没填写的表单项在最上面&#xff0c;用户看不到不知道发生了啥&#xff0c;所以需要将页面滚动定位到第一个报错的表单项位置&#xff0c;提升用户体验 实现步骤 点击保存校验 报错项class会…

echarts 水平柱图 科技风

var category [{ name: "管控", value: 2500 }, { name: "集中式", value: 8000 }, { name: "纳管", value: 3000 }, { name: "纳管", value: 3000 }, { name: "纳管", value: 3000 } ]; // 类别 var total 10000; // 数据…

基于BiLSTM-CRF的医学命名实体识别研究(下)模型构建

一.生成映射字典 接下来需要将每个汉字、边界、拼音、偏旁部首等映射成向量。所以&#xff0c;我们首先需要来构造字典&#xff0c;统计多少个不同的字、边界、拼音、偏旁部首等&#xff0c;然后再构建模型将不同的汉字、拼音等映射成不同的向量。 在prepare_data.py中自定义…

Vue 获取参数

Vue 获取参数 在Vue.js开发过程中&#xff0c;获取参数是处理用户输入和动态数据的关键环节。本文将深度解析Vue中获取参数的几种方法&#xff0c;并分享一些扩展与高级技巧&#xff0c;帮助你更高效地完成参数处理任务。 文章目录 Vue 获取参数 一、Vue获取参数包含哪些几种1.…

【无标题】nginx服务器代码信息、数据库连接信息、敏感文件的路径、服务器版本信息发起有针对性的攻击

Nginx敏感文件的路径、服务器版本信息 Nginx 403、404、500等错误时&#xff0c;返回详细错误信息。报错信息中可能会包含服务器代码信息、数据库连接信息、敏感文件的路径、服务器版本信息等&#xff0c;攻击者可以利用这些信息来寻找已知的漏洞&#xff0c;从而发起有针对性…

mybatis 查询Not Found TableInfoCache

近期在工程迁移中遇到一个mybatis查询的问题&#xff0c;检查代码没有问题&#xff0c;但是报Not Found TableInfoCache 解决过程 是不是数据库对应表错误或者实体类指定的表名错误 查看配置文件链接的数据源是否正确TableName中指定的表名然后去数据库看一下是否存在 如果…