QGIS二次开发四:实现图层列表

这篇具有很好参考价值的文章主要介绍了QGIS二次开发四:实现图层列表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在实际开发中我们通常会遇到同时显示多个图层,并且还要实时显示和隐藏各图层的需求,如同 ArcGIS 的图层列表那样,界面左侧显示图层列表,列出当前已加载的所有图层,同时每个图层前面有复选框可以控制图层的显示/隐藏;界面右侧为画布,按图层列表的适当顺序显示所有未隐藏的图层。具体该怎么实现呢?

代码 

#include <qgsapplication.h>	// 管理图形界面
#include <qgsproviderregistry.h>	// 设置并检查数据插件目录
#include <qgsmapcanvas.h>	// 创建画布
#include <qgsvectorlayer.h>	// 用于创建矢量图层
#include <qgslayertree.h>	// 提供命名空间,包含用于层树操作的辅助函数
#include <qgslayertreemodel.h>	// 创建模型
#include <qgslayertreeview.h>	// 创建view
#include <qboxlayout.h>		// 创建布局
#include <qgsproject.h>	// 管理qgis工程的头文件

// 自定义控件LayerTreeDemo,继承自QWidget
class LayerTreeDemo :
	public QWidget
{
public:

	LayerTreeDemo(QWidget * parent = 0);

private:
	// 画布
	QgsMapCanvas mMapCanvas;
	// 图层树 View
	// QgsLayerTreeView 是 QTreeView 的子类,进而是QWidget的子类
	QgsLayerTreeView mLayerTreeView;
	// 更新画布图层的“事件回调”
	void updateCanvasLayerSet();
};

// 构造函数
LayerTreeDemo::LayerTreeDemo(QWidget * parent) :
	QWidget(parent),
	mMapCanvas(this),
	mLayerTreeView(this) {
	// layerTreeRoot() 返回指向项目层树的根(不可见)节点的指针
	QgsLayerTree* pLayerTreeRoot = QgsProject::instance()->layerTreeRoot();
	// visibilityChanged当树中节点的检查状态被更改时触发
	QObject::connect(pLayerTreeRoot, &QgsLayerTreeNode::visibilityChanged, this, &LayerTreeDemo::updateCanvasLayerSet);
	// 模型监听层树中的更改,并适当地发出更改信号,以便使用该模型的任何视图都相应地更新,参数填根节点
	QgsLayerTreeModel* pLayerTreeModel = new QgsLayerTreeModel(pLayerTreeRoot);
	// 设置模型标志	QgsLayerTreeModel::Flag,Flag为枚举类型
	// AllowNodeChangeVisibility允许用户使用复选框设置节点可见性
	pLayerTreeModel->setFlag(QgsLayerTreeModel::AllowNodeChangeVisibility);
	// model只接收QgsLayerTreeModel,视图进行模型的绑定
	mLayerTreeView.setModel(pLayerTreeModel);
	// 设置一下最大宽度以便给画布留出更多显示空间,是QWidget的函数
	mLayerTreeView.setMaximumWidth(200);  
	// 创建一个水平布局
	QHBoxLayout* pLayout = new QHBoxLayout();
	// addWidget()传入一个指针
	// mLayerTreeView控件放在左边
	pLayout->addWidget(&mLayerTreeView);
	// mMapCanvas控件放在右边
	pLayout->addWidget(&mMapCanvas);
	// 设置布局到此窗体,setLayout是QWidget的函数
	this->setLayout(pLayout);
	this->resize(1000, 600);  // 设置窗体尺寸为 1000 * 600
	this->setWindowTitle(u8"QGIS 二次开发:图层树");  // 设置窗体标题
	// 从磁盘 .shp 文件创建矢量图层
	QgsVectorLayer* pVectorLayer_1 = new QgsVectorLayer("E:\\TestImage\\深圳各区矢量图\\宝安区\\宝安区_中华人民共和国.shp", "中华人民共和国");
	QgsVectorLayer* pVectorLayer_2 = new QgsVectorLayer("E:\\TestImage\\深圳各区矢量图\\宝安区\\宝安区_省界.shp", "省界");
	QgsVectorLayer* pVectorLayer_3 = new QgsVectorLayer("E:\\TestImage\\深圳各区矢量图\\宝安区\\宝安区_市界.shp", "市界");
	QgsVectorLayer* pVectorLayer_4 = new QgsVectorLayer("E:\\TestImage\\深圳各区矢量图\\宝安区\\宝安区_县界.shp", "县界");
	QgsVectorLayer* pVectorLayer_5 = new QgsVectorLayer("E:\\TestImage\\深圳各区矢量图\\宝安区\\宝安区_乡镇边界.shp", "乡镇边界");
	// 确认图层是否创建成功
	qDebug() << "Is layer valid:" << pVectorLayer_1->isValid();
	qDebug() << "Is layer valid:" << pVectorLayer_2->isValid();
	qDebug() << "Is layer valid:" << pVectorLayer_3->isValid();
	qDebug() << "Is layer valid:" << pVectorLayer_4->isValid();
	qDebug() << "Is layer valid:" << pVectorLayer_5->isValid();
	// 把图层添加到工程,越先添加的图层,越靠近底部
	QgsProject::instance()->addMapLayer(pVectorLayer_1);
	QgsProject::instance()->addMapLayer(pVectorLayer_2);
	QgsProject::instance()->addMapLayer(pVectorLayer_3);
	QgsProject::instance()->addMapLayer(pVectorLayer_4);
	QgsProject::instance()->addMapLayer(pVectorLayer_5);
	// 执行回调函数,将图层添加到画布
	updateCanvasLayerSet();
	// 缩放到全图
	mMapCanvas.zoomToFullExtent();
}

void LayerTreeDemo::updateCanvasLayerSet()
{
	// 设置应该在画布上显示的层列表
	// layerTreeRoot()返回一个QgsLayerTreeNode
	// checkedLayers()返回属于此节点或其子节点的所有已选中层的列表
	mMapCanvas.setLayers(QgsProject::instance()->layerTreeRoot()->checkedLayers());
	// 重新绘制画布地图
	mMapCanvas.refresh();
}

int main(int argc, char **argv)
{
	// 创建 QgsApplication 实例
	QgsApplication app(argc, argv, true);

	// 设置并检查数据插件目录
	QgsProviderRegistry::instance("D:\\OSGeo4W\\apps\\qgis-ltr\\plugins");

	// 控制台打印已载入的插件目录
	qDebug() << "QGIS data providers loaded:" << QgsProviderRegistry::instance()->providerList();

	// 设置 GDAL 数据目录环境变量
	qputenv("GDAL_DATA", "D:\\OSGeo4W\\apps\\gdal\\share\\gdal");

	// 创建主窗体
	LayerTreeDemo w;
	w.show();

	// 启动 QgsApplication 实例
	return app.exec();
}

讲解

一、QgsLayerTreeView

头文件<qgslayertreeview.h>

继承自QTreeView,进而继承自QWidget

QGIS API Documentation: QgsLayerTreeView Class Reference

二、QgsProject

需要头文件<qgsproject.h>

QGIS API Documentation: QgsProject Class Reference

封装一个QGIS项目,包括一组地图层及其样式、布局、注释、画布等。

QgsProject既可以作为单个对象(QgsProject::instance())使用,也可以作为独立对象使用。QGIS项目单例总是允许访问主QGIS应用程序中打开的规范项目引用。

layerTreeRoot() 返回指向项目层树的根(不可见)节点的指针。QGIS二次开发四:实现图层列表,QGIS,qgis,qt

 三、QgsLayerTree

头文件<qgslayertree.h>

QGIS API Documentation: QgsLayerTree Class Reference

QGIS二次开发四:实现图层列表,QGIS,qgis,qt

 四、QgsLayerTreeModel

头文件<qgslayertreemodel.h>

QGIS API Documentation: QgsLayerTreeModel Class Reference

QgsLayerTreeModel类是Qt项目视图框架的模型实现。该模型可以在任何QTreeView中使用,但是建议与QgsLayerTreeView一起使用,它为层树处理带来了额外的功能。模型监听层树中的更改,并适当地发出更改信号,以便使用该模型的任何视图都相应地更新。模型的行为可以用标志来定制。例如,是否显示图例或是否允许更改层树。

 QGIS二次开发四:实现图层列表,QGIS,qgis,qt

 五、void QgsLayerTreeView::setModel(QAbstractItemModel * model)

QGIS API Documentation: QgsLayerTreeView Class Reference

model只接收QgsLayerTreeModel

六、addMapLayer()

 QGIS API Documentation: QgsProject Class Reference

QGIS二次开发四:实现图层列表,QGIS,qgis,qt把图层添加到工程和把图层添加到画布两者并没有必然关系。加入工程的图层并不一定在画布上显示(如隐藏的图层),加入画布的图层也并不一定属于工程(如额外创建一个 QgsMapCanvas 显示与当前工程无关的图层,一个例子是 QGIS 软件选择坐标系的时候,界面上会有一个小画布显示当前所选坐标系在地球上的适用范围)。

 七、setLayers()

QGIS API Documentation: QgsMapCanvas Class Reference

QGIS二次开发四:实现图层列表,QGIS,qgis,qt

 设置应该在画布上显示的层列表 

八、checkedLayers()

QGIS API Documentation: QgsLayerTreeNode Class Reference

QGIS二次开发四:实现图层列表,QGIS,qgis,qt

 属于QgsLayerTreeNode的函数,返回属于此节点或其子节点的所有已选中层的列表。

九、refresh() 

 QGIS API Documentation: QgsMapCanvas Class Reference

对画布的地图进行重新绘画 。

运行效果

QGIS二次开发四:实现图层列表,QGIS,qgis,qt

参考文章 文章页 | mriiiron's blog 文章来源地址https://www.toymoban.com/news/detail-637013.html

到了这里,关于QGIS二次开发四:实现图层列表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Ubuntu 22.04 配置 QGIS二次开发环境

    源码地址: https://github.com/qgis/QGIS/releases QGIS 官方指导文档地址: https://github.com/qgis/QGIS/blob/release-3_26/INSTALL.md(此处为3.26的指导文档,可以自行修改查看) sudo apt-get install bison ca-certificates ccache cmake cmake-curses-gui dh-python doxygen expect flex flip gdal-bin git graphviz grass-dev libexiv2-dev l

    2024年02月16日
    浏览(40)
  • QGIS二次开发:集成二维CAD控件MxDraw

    本文记录在QGIS中集成MxDraw控件的方法。 参见笔者博文“FreeCAD二次开发:集成二维CAD控件MxDraw”所述的安装方法。 参见笔者博文\\\"Windows 10下编译安装QGIS\\\"所述的编译安装方法。 按照QGIS的管理,Qt ui文件可放到src/ui目录及其子目录下。因此,可将MxDrawView.ui拷贝到src/ui/gd目录下,

    2024年02月15日
    浏览(26)
  • QGIS3.28的二次开发一:编译工程

    更新:最近写了个3.18.3版本的编译教程,没有出现任何问题。 QGIS3.18编译教程_程序员班长的博客-CSDN博客 环境:VS2019+OSGeo4W+CMake_3.26+Cygwin64+QGIS_3.28 注意:一定要按照步骤顺序来! VS2019下载链接 https://my.visualstudio.com/Downloads?q=visual%20studio%202019wt.mc_id=o~msft~vscom~older-downloads 下载完

    2024年02月15日
    浏览(35)
  • QGIS3.28的二次开发九:添加矢量要素

    对矢量要素的编辑是 GIS 软件很重要的功能点之一,也是最难实现的功能点之一。编辑矢量要素涉及到很多方面的考虑,包括且不限于矢量要素的几何类型,拓扑关系,构成要素的节点的增删改,编辑会话 (session) 的启动、回溯和提交,要素属性的增删改等。本文不会也不可能

    2024年02月12日
    浏览(31)
  • Qt下开发基于QGIS的应用程序

    由于有在背景地图上进行动态轨迹(曲线)显示的需要,故采用Qt+QGIS的方案! Qt5.12.12,VS2015编译器,QGIS3.10.1。 在配置之前,电脑是新装机的系统,没有任何相关软件版本。 在Qt官网(https://download.qt.io/)或国内镜像网站(https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt)或网络搜索

    2024年02月14日
    浏览(40)
  • QGIS开发五:VS使用QT插件创建UI界面

    前面我们说了在创建项目时创建的是一个空项目,即不使用 Qt 提供的综合开发套件 Qt Creator,也不使用 Qt Visual Studio Tools 这类工具。 但是后面发现,如果我想要有更加满意的界面布局,还是要自己写一个UI文件,如果不使用QT插件,在VS中导入自己的UI文件编译起来不是那么容

    2024年02月13日
    浏览(44)
  • QGIS开发五:使用UI文件

    前面我们说了在创建项目时创建的是一个空项目,即不使用 Qt 提供的综合开发套件 Qt Creator,也不使用 Qt Visual Studio Tools 这类工具。 但是后面发现,如果我想要有更加满意的界面布局,还是要自己写一个UI文件,如果不使用QT插件,在VS中导入自己的UI文件编译起来不是那么容

    2024年02月13日
    浏览(29)
  • QGIS--开发OpenSCENARIO动态场景(三)--制作动态场景

    目录 一、添加scenario,carla的环境变量 二、打开QGIS3,连接carla 三、添加车辆 1. 在已选地图上添加环境 2. 添加ego小车 3.添加adversary小车  四、添加场景操作 1.设置adversary加速行驶  2.设置adversary车辆匀速行驶: 3.设置adversary车辆减速运动: 界面详细: 五、添加ego车辆 运行时

    2024年02月02日
    浏览(28)
  • 【QT+QGIS跨平台编译】之三:【OpenSSL+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

    OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。这个包广泛被应用在互联网的网页服务器上。 SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。SSL能使用户/服务器应用

    2024年01月22日
    浏览(58)
  • 【QT+QGIS跨平台编译】之五:【curl+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

    (libcurl编译,依赖OpenSSL、libSSH2等库) curl(CommandLine Uniform Resource Locator)主要功能就是用不同的协议连接和沟通不同的服务器,相当封装了的socket。 libcurl支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传(当然你也可

    2024年01月23日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包