【QGIS二次开发】地图显示与交互-01

 1. 系统界面设计

设计的系统界面如下,很好还原了QGIS、ArcGIS等软件的系统界面,充分利用了QT中顶部工具栏、菜单栏、底部状态栏,实现了图层管理器、鹰眼图、工具箱三个工具面板。

菜单栏、工具栏、工具箱集成了系统中实现的全部功能,并进行了功能分区,让用户能够更便捷地进行操作,底部状态栏显示了标语和QGIS工程的坐标系更方便用户的查看。

图 1 界面设计

2. 地图显示与交互

2.1 地图显示

图层显示通过在工具栏中添加按钮为用户提供了打开矢量与栅格数据的方式,打开位置如下:

图 2 地图数据显示按钮

        打开矢量数据效果如下:

图 3 打开矢量数据效果

        打开栅格数据的操作步骤和显示效果如下:

图 4 打开栅格数据界面

图 5 打开栅格数据效果

        实现数据显示的代码如下,对于矢量数据处理on_actionAddVectorData_triggered函数中用户先通过文件对话框选择一个或多个Shapefile文件,然后针对每个选择的文件,创建一个QgsVectorLayer对象并检查其有效性。如果图层有效,将其添加到地图图层列表layerList中。最后,将所有矢量图层添加到QgsProject中,并刷新地图画布map canvas。

        对于栅格数据处理on_actionAddRasterData_triggered函数:用户通过文件对话框选择一个或多个栅格文件,然后为每个选择的文件创建一个QgsRasterLayer对象并检查其有效性。如果图层有效,将其添加到地图图层列表layerList中。最后,将所有栅格图层添加到QgsProject中,并刷新地图画布。

2.2 图层管理

图层管理通过QGIS目录树形式管理地图文档中的图层,通过添加添加组、展开和折叠所有组、移除图层/组四个按键,实现了控制图层的显示与隐藏等功能,图层树的实现界面如下,打开了多个矢量文件用于展示:

图 6 图层管理功能实现

void DataViewer::on_actionAddVectorData_triggered()    
{    QStringList layerPathList = QFileDialog::getOpenFileNames(this, "选择矢量数据", "", "shapefile (*.shp)");    QList<QgsMapLayer*> layerList;    for each (QString layerPath in layerPathList)    {    QFileInfo fi(layerPath);    if (!fi.exists()) { return; }    QString layerBaseName = fi.baseName(); // 图层名称    QgsVectorLayer* vecLayer = new QgsVectorLayer(layerPath, layerBaseName);    if (!vecLayer) { return; }    if (!vecLayer->isValid())    {    QMessageBox::information(0, "", "layer is invalid");    return;    }    layerList << vecLayer;    }    QgsProject::instance()->addMapLayers(layerList);    m_mapCanvas->refresh();    
}    void DataViewer::on_actionAddRasterData_triggered()    
{    QStringList layerPathList = QFileDialog::getOpenFileNames(this, "选择栅格数据", "", "Image (*.img *.tif *.tiff)");    QList<QgsMapLayer*> layerList;    for each (QString layerPath in layerPathList)    {    QFileInfo fi(layerPath);    if (!fi.exists()) { return; }    QString layerBaseName = fi.baseName(); // 图层名称    QgsRasterLayer* rasterLayer = new QgsRasterLayer(layerPath, layerBaseName);    if (!rasterLayer) { return; }    if (!rasterLayer->isValid())    {    QMessageBox::information(0, "", "layer is invalid");    return;    }    layerList << rasterLayer;    }    QgsProject::instance()->addMapLayers(layerList);    m_mapCanvas->refresh();    
}    

通过在dataviewer类中实现成员函数initLayerTreeView用于初始化地图图层树视图。通过创建图层树模型,并与当前QGIS项目的图层树根节点相关联,实现了对图层的显示和管理。代码中设置了图层树模型的各项属性,包括节点的重新排序、重命名、可见性控制等。同时,通过建立图层树与地图画布之间的桥梁,保持了它们之间的同步。为了提供更多的操作功能,代码还添加了自定义的图层树操作,如添加组、展开和折叠所有组、移除图层/组等。这些操作被整合到一个工具栏中,通过设置工具栏的图标大小和连接相应的信号槽,提供了用户友好的操作界面。整体而言,这段代码实现了一个功能完备的地理信息系统图层树控制界面,为用户提供了方便的图层管理和操作功能。

2.3 图层透明度设置

任务要求:支持用户选择一个图层,设置该图层的透明度。

        完成的逻辑是在QgsLayerTreeViewMenuProvider的实例类中添加一个editOpacity方法,实现修改透明度功能。

        代码逻辑如下:

  1. 首先获取当前选中的图层。如果没有选中的图层,就直接返回。
  2. 创建一个新的对话框,并设置其标题为"修改透明度"。
  3. 创建一个水平布局,并将其设置到对话框中。
  4. 创建一个滑动条和一个输入框,并将它们添加到布局中。滑动条的范围设置为0到100,初始值设置为100。输入框的初始值设置为1.0。
  5. 连接滑动条的valueChanged信号到一个槽函数。在这个槽函数中,首先将滑动条的值转换为0.0到1.0的透明度值,然后调用updateOpacity方法更新输入框的值,最后更新图层的透明度。
  6. 连接输入框的textChanged信号到一个槽函数。在这个槽函数中,首先将输入框的值转换为0到100的整数值,然后调用updateOpacity方法更新滑动条的值,最后更新图层的透明度。
  7. 显示对话框,并等待用户的操作。
  8. updateOpacity方法用于更新图层的透明度。首先检查图层的类型,如果图层是栅格图层,就获取图层的渲染器,然后设置渲染器的透明度,并触发图层的重绘。如果图层是矢量图层,就获取图层的渲染器,然后获取渲染器的所有符号,对每个符号设置透明度,并触发图层的重绘。

实现的效果是,在图层管理器中图层的右键菜单中添加修改透明度选项,点击修改透明度选项打开对话框,对话框内包含了一个滑块条和输入框,滑动滑块或修改输入框内的数字即可修改图层透明度。同时滑动滑块或修改输入框内的数字时另一项也随之改变。可以修改矢量图层和栅格图层的透明度。

核心代码如下:

void MenuProvider::editOpacity() {  QgsMapLayer* mapLayer = mView->currentLayer();  if (!mapLayer)  return;  // 创建一个新的对话框  QDialog dialog;  dialog.setWindowTitle("修改透明度");  // 创建一个水平布局  QHBoxLayout layout(&dialog);  // 创建一个滑动条  QSlider slider(Qt::Horizontal);  slider.setRange(0, 100);  layout.addWidget(&slider);  // 创建一个输入框  QLineEdit lineEdit;  layout.addWidget(&lineEdit);  slider.setValue(100);  lineEdit.setText(QString::number(1.0));  layout.addWidget(&slider, 3);  // 设置滑动条的拉伸因子为3  layout.addWidget(&lineEdit, 1);  // 设置输入框的拉伸因子为1  dialog.resize(300, 50);  // 连接滑动条的valueChanged信号到一个槽函数  QObject::connect(&slider, &QSlider::valueChanged, [&](int value) {  // 将滑动条的值转换为0.0到1.0的透明度值  double opacity = value / 100.0;  // 更新输入框的值  lineEdit.setText(QString::number(opacity));  // 更新图层的透明度  updateOpacity(mapLayer, opacity);  });  // 连接输入框的textChanged信号到一个槽函数  QObject::connect(&lineEdit, &QLineEdit::textChanged, [&](const QString& text) {  // 将输入框的值转换为0到100的整数值  int value = text.toDouble() * 100;  // 更新滑动条的值  slider.setValue(value);  // 更新图层的透明度  updateOpacity(mapLayer, text.toDouble());  });  // 显示对话框  dialog.exec();  
}  void MenuProvider::updateOpacity(QgsMapLayer* mapLayer, double opacity) {  // 检查图层类型  QgsRasterLayer* rasterLayer = qobject_cast<QgsRasterLayer*>(mapLayer);  QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>(mapLayer);  // 调整栅格图层透明度  if (rasterLayer) {  QgsRasterRenderer* renderer = rasterLayer->renderer();  if (renderer) {  renderer->setOpacity(opacity);  rasterLayer->triggerRepaint();  }  }  // 调整矢量图层透明度  else if (vectorLayer) {  QgsFeatureRenderer* renderer = vectorLayer->renderer();  if (renderer) {  QgsRenderContext renderContext;  QgsSymbolList symbols = renderer->symbols(renderContext);  for (QgsSymbol* symbol : symbols) {  symbol->setOpacity(opacity);  }  vectorLayer->triggerRepaint();  }  }  
}  

实现的效果如下:

图 7 右键-透明度按键

图 8 设置透明度

        

        其余内容见下篇!!

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

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

相关文章

第40天:安全开发-JavaEE应用SpringBoot框架JWT身份鉴权打包部署JARWAR

时间轴&#xff1a; 演示案例&#xff1a; SpringBoot-身份鉴权-JWT 技术 SpringBoot-打包部署-JAR&WAR SpringBoot-身份鉴权-JWT 技术 SpringBoot- 身份鉴权 -JWT 技术 JWT(JSON Web Token) 是由服务端用加密算法对信息签名来保证其完整性和不可伪 造&#xff1b; …

计算机毕业设计SpringBoot+Vue.js医院挂号就诊系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Linux之命令记录【一】

文章目录 前言几个重要的热键1.[Tab]按键2.[Ctrl]-c 按键3.[Ctrl]-d 按键4.[shift]{[PageUP]|[Page Down]}按键 线上求助&#xff08;查看帮助信息&#xff09;1. --help2.man page3.info page 用户身份1.su 基础指令1.date2.cal3.bc 系统字符集相关1.locale 文本编辑器1.nano …

Ollama存在安全风险的情况通报及解决方案

据清华大学网络空间测绘联合研究中心分析&#xff0c;开源跨平台大模型工具Ollama默认配置存在未授权访问与模型窃取等安全隐患。鉴于目前DeepSeek等大模型的研究部署和应用非常广泛&#xff0c;多数用户使用Ollama私有化部署且未修改默认配置&#xff0c;存在数据泄露、算力盗…

Sourcetrail 代码分析工具

Sourcetrail 概述 Sourcetrail 是一个代码分析工具&#xff0c;它旨在帮助开发人员理解和导航复杂的代码库。它可以创建代码库的可视化图形&#xff0c;显示代码中的类、函数、变量、依赖关系等信息&#xff0c;从而帮助开发人员更好地理解代码结构和关系&#xff0c;降低维护…

【手撕算法】支持向量机(SVM)从入门到实战:数学推导与核技巧揭秘

摘要 支持向量机&#xff08;SVM&#xff09;是机器学习中的经典算法&#xff01;本文将深入解析最大间隔分类原理&#xff0c;手撕对偶问题推导过程&#xff0c;并实战实现非线性分类与图像识别。文中附《统计学习公式手册》及SVM调参指南&#xff0c;助力你掌握这一核心算法…

《OpenCV》——dlib(人脸应用实例)

文章目录 dlib库dlib库——人脸应用实例——表情识别dlib库——人脸应用实例——疲劳检测 dlib库 dlib库的基础用法介绍可以参考这篇文章&#xff1a;https://blog.csdn.net/lou0720/article/details/145968062?spm1011.2415.3001.5331&#xff0c;故此这篇文章只介绍dlib的人…

ArcGIS操作:07 绘制矢量shp面

1、点击目录 2、右侧显示目录 3、选择要存储的文件夹&#xff0c;新建shp 4、定义名称、要素类型、坐标系 5、点击开始编辑 6、点击创建要素 7、右侧选择图层、创建面 8、开始绘制&#xff0c;双击任意位置结束绘制

用Python+Flask打造可视化武侠人物关系图生成器:从零到一的实战全记录

用PythonFlask打造可视化武侠人物关系图生成器&#xff1a;从零到一的实战全记录 一、缘起&#xff1a;一个程序小白的奇妙探索之旅 作为一个接触Python仅13天的编程萌新&#xff0c;我曾以为开发一个完整的应用是遥不可及的事情。但在DeepSeek的帮助下&#xff0c;我竟用短短…

2025年渗透测试面试题总结- 阿某云安全实习(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 阿里云安全实习 一、代码审计经验与思路 二、越权漏洞原理与审计要点 三、SSRF漏洞解析与防御 四、教…

el-select的下拉选择框插入el-checkbox

el-check注意这里要使用model-value绑定数据 <el-selectv-model"selectDevice"multiplecollapse-tags:multiple-limit"5"style"width: 200px"popper-class"select-popover-class" ><el-optionv-for"item in deviceList…

20250304在Ubuntu20.04的GUI下格式化exFAT格式的TF卡为ext4格式

20250304在Ubuntu20.04的GUI下格式化exFAT格式的TF卡为ext4格式 2025/3/4 16:47 缘起&#xff1a;128GB的TF卡&#xff0c;只能格式化为NTFS/exFAT/ext4。 在飞凌的OK3588-C下&#xff0c;NTFS格式只读。 exFAT需要改内核来支持。 现在只剩下ext4了。 linux R4默认不支持exFAT…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)示例1:基础表格

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(未成功版)

【Linux】【网络】UDP打洞–>不同子网下的客户端和服务器通信&#xff08;未成功版&#xff09; 上次说基于UDP的打洞程序改了五版一直没有成功&#xff0c;要写一下问题所在&#xff0c;但是我后续又查询了一些资料&#xff0c;成功实现了&#xff0c;这次先写一下未成功的…

C# Unity 唐老狮 No.4 模拟面试题

本文章不作任何商业用途 仅作学习与交流 安利唐老狮与其他老师合作的网站,内有大量免费资源和优质付费资源,我入门就是看唐老师的课程 打好坚实的基础非常非常重要: 全部 - 游习堂 - 唐老狮创立的游戏开发在线学习平台 - Powered By EduSoho 如果你发现了文章内特殊的字体格式,…

数据结构——队列

1. 概念与结构 队列&#xff08;Queue&#xff09;是一种先进先出&#xff08;FIFO, First In First Out&#xff09;的数据结构&#xff0c;即最先被插入队列的数据会最先被删除。队列广泛应用于计算机科学中&#xff0c;特别是在任务调度、缓冲区管理、网络数据传输等领域。…

大语言模型技术发展

摘要 海外闭源模型领域竞争激烈&#xff0c;OpenAI 保持领先地位&#xff0c;而开源模型如 Meta 的 Llama 系列也逐渐崛起。LLM 技术呈现出大型模型和小型模型并行发展的趋势&#xff0c;同时&#xff0c;多模态功能和长上下文能力成为顶级模型的标准配置。MoE 架构的出现推动…

数据结构入门篇——什么是数据结构。

一、引入 工具是一种什么东西呢&#xff1f;是一种转化媒介&#xff0c;我们需要熟食&#xff0c;我们要通过用火来将生肉烤熟。在这个过程中。我们要输入一个东西——生肉&#xff0c;通过工具——火的加工&#xff0c;从而得到我们的目的产物——熟肉。 将上面的例子和红字部…

DeepSeek掘金——DeepSeek R1驱动的PDF机器人

DeepSeek掘金——DeepSeek R1驱动的PDF机器人 本指南将引导你使用DeepSeek R1 + RAG构建一个功能性的PDF聊天机器人。逐步学习如何增强AI检索能力,并创建一个能够高效处理和响应文档查询的智能聊天机器人。 本指南将引导你使用DeepSeek R1 + RAG构建一个功能性的PDF聊天机器人…

sqli-labs靶场通关

一.less-16 1.寻找注入点 发现url无法回显 构造闭合无论 还是 "都没有任何反应 最后发现闭合符号为")时成功登录 没有回显使用盲注 2.爆数据库 12") or (length(database()))8# 爆出数据库长度 获取数据库名&#xff0c;第一个字母的ascii码值 12") …