【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.mzph.cn/pingmian/71402.shtml

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

相关文章

Skynet入门(一)

概念 skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分&#xff0c;所以尽可以把它用于其它领域。 设计初衷 如何充分利用它们并行运作数千个相互独立的业务。 模块设计建议 在 skynet 中&#xff0c;用服务 (service) 这…

threejs:用着色器给模型添加光带扫描效果

第一步&#xff1a;给模型添加光带 首先创建一个立方体&#xff0c;不进行任何缩放平移操作&#xff0c;也不要set position。 基础代码如下&#xff1a; 在顶点着色器代码里varying vec3 vPosition;vPosition position;获得threejs自动计算的顶点坐标插值&#xff08;也就…

【时序预测】在线学习:算法选择(从线性模型到深度学习解析)

——如何为动态时序预测匹配最佳增量学习策略&#xff1f; 引言&#xff1a;在线学习的核心价值与挑战 在动态时序预测场景中&#xff08;如实时交通预测、能源消耗监控&#xff09;&#xff0c;数据以流式&#xff08;Streaming&#xff09;形式持续生成&#xff0c;且潜在的…

Spring Boot如何利用Twilio Verify 发送验证码短信?

Twilio提供了一个名为 Twilio Verify 的服务&#xff0c;专门用于处理验证码的发送和验证。这是一个更为简化和安全的解决方案&#xff0c;适合需要用户身份验证的应用。 使用Twilio Verify服务的步骤 以下是如何在Spring Boot中集成Twilio Verify服务的步骤&#xff1a; 1.…

【Linux操作系统】VM17虚拟机安装Ubuntu22.04,图文详细记录

1.双击桌面的 VMware Workstation17 Player&#xff0c;点击“创建新虚拟机”&#xff0c;如下图所示。 2.选择“稍后安装操作系统”&#xff0c;点击“下一步”。如下图所示。 3.客户机操作系统选择“Linux”&#xff0c;版本选择“ Ubuntu 64位”&#xff0c;然后点击“下一…

软件工程---净室软件工程

净室软件工程是一种软件开发方法&#xff0c;旨在通过形式化的数据和严格的测试来提高软件的可靠性和减少缺陷的数量。它的核心思想是在软件开发过程中最小化或消除软件缺陷&#xff0c;从而提高软件的质量和可靠性。这种方法强调在软件生命周期的早期阶段使用形式化方法进行规…

迷你世界脚本区域接口:Area

区域接口&#xff1a;Area 彼得兔 更新时间: 2023-12-18 11:35:14 具体函数名及描述如下: 序号 函数名 函数描述 1 createAreaRect(...) 创建矩形区域 2 createAreaRectByRange(...) 创建矩形区域(通过范围) 3 destroyArea(...) 销毁区域 4 getAre…

C# 牵手DeepSeek:打造本地AI超能力

一、引言 在人工智能飞速发展的当下&#xff0c;大语言模型如 DeepSeek 正掀起新一轮的技术变革浪潮&#xff0c;为自然语言处理领域带来了诸多创新应用。随着数据隐私和安全意识的提升&#xff0c;以及对模型部署灵活性的追求&#xff0c;本地部署 DeepSeek 成为众多开发者和…

Linux--基础命令3

大家好&#xff0c;今天我们继续学习Linux的基础命令 mv命令 mv命令是move的缩写&#xff0c;可以用来移动文件或者将文件改名 move(rename) files&#xff0c;经常⽤来备份⽂件或者目录 语法: mv [ 选项 ] 源⽂件或目录 目标⽂件或目录 mv src[文件、目录] dst[路径、文…

【每日八股】计算机网络篇(三):IP

目录 DNS 查询服务器的基本流程DNS 采用 TCP 还是 UDP&#xff0c;为什么&#xff1f;默认使用 UDP 的原因需要使用 TCP 的场景&#xff1f;总结 DNS 劫持是什么&#xff1f;解决办法&#xff1f;浏览器输入一个 URL 到显示器显示的过程&#xff1f;URL 解析TCP 连接HTTP 请求页…

探究DeepSeek R1与OpenAI模型文本相似度背后的秘密

摘要 一项由Copyleaks进行的新研究显示&#xff0c;DeepSeek R1生成的文本在风格上与OpenAI模型的相似度高达74.2%。这一发现引发了对DeepSeek训练数据来源和独特性的质疑。Copyleaks作为专业检测文本抄袭和AI生成内容的平台&#xff0c;其研究结果具有重要参考价值。此相似度揭…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.2.3案例:电商订单日志每秒10万条写入优化

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 Elasticsearch批量写入性能调优实战&#xff1a;2.2.3 案例&#xff1a;电商订单日志每秒10万条写入优化1. 原始架构与瓶颈分析1.1 初始集群配置1.2 性能瓶颈定位 2. 全链路…

统计Excel列中某值出现的次数

统计Excel列中某值出现的次数&#xff1a; 1、COUNTIF 函数用于计算满足特定条件的单元格数量。假设要统计 A 列中值为 “苹果” 出现的次数&#xff0c;在其他单元格中输入公式&#xff1a;COUNTIF(A:A,“苹果”)。其中&#xff0c;A:A表示要统计的范围是 A 列&#xff0c;&q…

nnUNet报错

nnUNet报错处理 Traceback (most recent call last):File "/opt/conda/envs/nnunet/lib/python3.11/threading.py", line 1045, in _bootstrap_innerself.run()File "/opt/conda/envs/nnunet/lib/python3.11/threading.py", line 982, in runself._target…

Compose Multiplatform+Kotlin Multiplatfrom 第四弹跨平台

文章目录 引言功能效果开发准备依赖使用gradle依赖库MVIFlow设计富文本显示 总结 引言 Compose Multiplatformkotlin Multiplatfrom 今天已经到compose v1.7.3&#xff0c;从界面UI框架上实战开发看&#xff0c;很多api都去掉实验性注解&#xff0c;表示稳定使用了&#xff01;…

(十一)基于vue3+mapbox-GL实现模拟高德实时导航轨迹播放

要在 Vue 3 项目中结合 Mapbox GL 实现类似高德地图的实时导航轨迹功能,您可以按照以下步骤进行: 安装依赖: 首先,安装 mapbox-gl 和 @turf/turf 这两个必要的库: npm install mapbox-gl @turf/turf引入 Mapbox GL: 在组件中引入 mapbox-gl 并初始化地图实例: <templ…

智慧园区大数据云平台建设总体方案,平台方案架构-智慧园区大数据平台(320页原件Word)

第一章 项目建设背景及现状 1.1. 项目建设背景 1.2. 项目建设必要性 1.3. 项目建设目标 1.4. 建设原则 第二章 园区创新发展趋势 2.1园区经济向生态型转变 2.2 园区企业向高新型转变 2.3园区管理向城市化转变 第三章 工业园区大数据存在的问题 3.1信息化配套设施及服…

NeurIPS24 Oral!多模态融合+目标检测全新里程碑!

最近发现多模态融合目标检测实在太热了&#xff01;顶会频出&#xff01;像是NeurIPS24 Oral上端到端算法E2E-MFD&#xff1b;ECCV24上性能提升30.8&#xff05;的FRN&#xff1b;TPAMI24上推理效率狂飙270&#xff05;倍的FSF…… 主要在于&#xff1a;一方面&#xff0c;其能…

网络编程——http

在Linux系统中使用C语言实现HTTP客户端或服务器通常涉及使用套接字编程和一些HTTP协议的基本知识。下面是一个简单的示例&#xff0c;展示了如何用C语言实现一个HTTP客户端&#xff0c;向一个HTTP服务器发送请求并接收响应。 1. HTTP客户端示例 (C语言) 这个例子展示了如何用C…