4. qgis c++二次开发 map canvas介绍

news2024/12/23 13:06:10

文章目录

  • 前言
  • Map canvas
    • QGis软件中的Map canvas
    • 代码添加Map canvas
      • Map Canvas创建和显示
    • QGis中的QGraphicsItem
    • 二次开发中的Item
  • Layer Tree
    • QGis软件中的Layer Tree
    • 代码实现layer tree
  • QgsProject(项目管理)
    • QGis软件中的项目管理
    • 代码实现
  • 总结

前言

前几篇文章分别介绍了qgis二次开发的

  • 环境搭建
  • 整体框架
  • 初始化

在显示GIS数据之前,需要首先介绍一下map canvas,毕竟在将颜料(GIS地图等数据)画在画布(map canvas)之前,首先要创建画布(map canvas)。

  • 说明:文章中的示例代码均来自开源项目qgis_cpp_api_apps

Map canvas

QGis软件中的Map canvas

  • 官方文档training_manual 有一节Navigating the Map Canvas专门讲述了Map Canvas
  • 下图空白区域左侧为图层树(Layer tree),右侧为Map Canvas
    在这里插入图片描述

代码添加Map canvas

Map canvas is a class for displaying all GIS data types on a canvas.

在这里插入图片描述

  • QgsMapCanvas是Map canvas,类的详细内容见文档
  • QgsMapCanvas本质是一个QGraphicsViewQGraphicsView是Qt Graphics View Framework框架的一个类,Graphics View Framework是Qt提供的一个用于管理大量2D图形项目并与之交互的框架。
    在这里插入图片描述
    • QGraphicsView提供了视图,相当于画布
    • QGraphicsItem图形类的基类,可以显示在canvas的组件,QgsMapCanvasItem是该类的子类
    • QGraphicsScene用于管理item

Map Canvas创建和显示

  • Map Canvas创建代码如下
void ll_qgis_base_lib::initialize(QMainWindow *mainWindow)
{
    mMainWindow = mainWindow;

    mMapCanvas = new QgsMapCanvas;
    mMapCanvas->enableAntiAliasing(true);
    mMapCanvas->setCachingEnabled(true);
    mMapCanvas->setCanvasColor(QColor(255,255,255));
    mMapCanvas->setVisible(true);

    initLayerTreeView();
    initMaptools();
}
  • ll_qgis_base_lib类是qgis_cpp_api_apps项目的一个库,由于Map canvas和Layer tree很通用,所以将这两个放在库中
  • mMapCanvas添加到父Widget即可显示Map canvas
void MainWindow::initStackwidgetPageCanvas()
{
    auto gridLayout = new QGridLayout;
    gridLayout->addWidget((QWidget*)mApp->mapCanvas());
    ui->page_canvas->setLayout(gridLayout);
    addDockWidget(Qt::LeftDockWidgetArea,mApp->layerTreeDock());
}

QGis中的QGraphicsItem

在这里插入图片描述

  • Measure功能使用了QgsRubberBand类,上图中的三角形就是用QgsRubberBand类绘制的

二次开发中的Item

在这里插入图片描述

  • QgsMapCanvasItem是一个抽象类,用于放置在地图画布上的项目。
  • QgsRubberband类是一个用于在地图上绘制临时特征(例如数字化线条)的类。类图如下
    在这里插入图片描述
  • 如下代码实现在图层上画三角形
void MainWindow::rubberBandPolygonSlot()
{
    //添加shapefile
    QString filename = QStringLiteral("maps/shapefile/protected_areas.shp");
    QFileInfo ff(filename);
    mApp->addVectorLayer(filename,ff.baseName());
    zoomToFirstLayer<QgsVectorLayer*>();
    //定义三个点
    QgsPointXY point1(20.34013,-33.90453);
    QgsPointXY point2(20.49744,-33.91126);
    QgsPointXY point3(20.41396,-33.93079);
    //新建PolygonGeometry类型的RubberBand
    mRubberBandPolygon = new QgsRubberBand(mApp->mapCanvas(),QgsWkbTypes::PolygonGeometry);
    //添加三个点
    mRubberBandPolygon->addPoint(point1);
    mRubberBandPolygon->addPoint(point2);
    mRubberBandPolygon->addPoint(point3);
    //设置线宽颜色等属性
    mRubberBandPolygon->setWidth(4);
    mRubberBandPolygon->setColor(QColor(222,155,67));
    mRubberBandPoint = new QgsRubberBand(mApp->mapCanvas(),QgsWkbTypes::PointGeometry);
    mRubberBandPoint->addPoint(point1);
    mRubberBandPoint->addPoint(point2);
    mRubberBandPoint->addPoint(point3);
    mRubberBandPoint->setWidth(6);
    mRubberBandPoint->setColor(QColor(222,155,67));
    mRubberBandPolygon->show();
    mRubberBandPoint->show();
}
  • 以下代码实现删除QgsGraphicsItem
if(mVertexMarker)
    mApp->mapCanvas()->scene()->removeItem(mVertexMarker);

Layer Tree

QGis软件中的Layer Tree

在这里插入图片描述

  • Layer Tree用于管理图层
  • Layer Tree和Map canvas建立连接,可以对图层进行操作

代码实现layer tree

在这里插入图片描述

  • 代码如下
void ll_qgis_base_lib::initLayerTreeView()
{
    //添加DockWidget作为图层树的容器
    mLayerTreeDock = new QgsDockWidget(tr("Layer Tree"));
    mLayerTreeDock->setObjectName( QStringLiteral( "Layers" ) );
    mLayerTreeDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );

    //创建Model
    QgsLayerTreeModel* model = new QgsLayerTreeModel(QgsProject::instance()->layerTreeRoot(),this);
    model->setFlag( QgsLayerTreeModel::AllowNodeReorder );
    model->setFlag( QgsLayerTreeModel::AllowNodeRename );
    model->setFlag( QgsLayerTreeModel::AllowNodeChangeVisibility );
    model->setFlag( QgsLayerTreeModel::ShowLegendAsTree );
    model->setFlag( QgsLayerTreeModel::UseEmbeddedWidgets );
    model->setFlag( QgsLayerTreeModel::UseTextFormatting );
    model->setAutoCollapseLegendNodes( 10 );

    //创建View,mLayerTreeView会在库外使用,所以需要添加getter方法,
    mLayerTreeView = new QgsLayerTreeView();
    mLayerTreeView->setModel(model);

    //Map Canvas和Layer Tree View建立联系,这样通过QgsProject::instance()->addMapLayer添加图层后,会自动添加在图层树以及会在canvas渲染图层
    mLayerTreeMapCanvasBridge = new QgsLayerTreeMapCanvasBridge(QgsProject::instance()->layerTreeRoot(),mMapCanvas,this);
    connect( mLayerTreeMapCanvasBridge, &QgsLayerTreeMapCanvasBridge::canvasLayersChanged, mMapCanvas, &QgsMapCanvas::setLayers );

    //Layer Tree View右键菜单实现
    mLayerTreeView->setMenuProvider(new ll_qgis_base_layertreeview_menu(mMainWindow,mLayerTreeView,mMapCanvas));
    connect(QgsProject::instance()->layerTreeRegistryBridge(),SIGNAL(addedLayersToLayerTree(QList<QgsMapLayer*>)),
            this,SLOT(slot_autoSelectAddedLayer(QList<QgsMapLayer*>)));
}
  • 主要涉及了以下类QgsDockWidget,QgsLayerTreeModel,QgsLayerTreeView,QgsLayerTreeMapCanvasBridge
  • QgsDockWidget是一个Qt Dock Widget,用于显示图层树
  • QgsLayerTreeViewQgsLayerTreeModel实现了树的功能
  • QgsLayerTreeMapCanvasBridge类负责从图层树中更新QgsMapCanvas的图层

QgsProject(项目管理)

QGis的项目可以保存为项目文档,后缀名为“qgz”或“qgs”。在QGIS 3以前,只能通过“qgs”文件保存项目。“qgs”文件的本质是存储图层的信息等的XML文件。在QGIS 3以后,“qgz”格式采用ZIP压缩方法,不仅包含“qgs”文件,还包括附属数据库(Auxiliary Storage)文件(后缀名为“qgd”)。自QGIS 3.2以来,“qgz”文件成为QGIS项目的默认存储格式,本书也使用“qgz”文件存储QGIS项目。

QGis软件中的项目管理

  • 新建项目,在Project菜单中可以新建一个空工程
    在这里插入图片描述
  • 保存项目 可以选择项目名称和位置
    在这里插入图片描述在这里插入图片描述

代码实现

Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
QgsProject is available both as a singleton (QgsProject::instance()) and for use as standalone objects. The QGIS project singleton always gives access to the canonical project reference open within the main QGIS application.

  • QgsProject代表QGis中的一个项目,包含项目管理、图层管理以及其他功能,QgsProject的详细内容见官方文档。
  • QgsProject是一个单例类,通过方法QgsProject::instance()即可调用其方法,以下是QgsProject的一些常用函数
  • QgsProject的最常用的功能是添加图层,调用QgsProject::instance()->addMapLayer(vecLayer);后会在Map Canvas显示,也会添加到Layer tree中,如下代码添加一个shape文件
void MainWindow::addShpSlot()
{
    QString filename = QStringLiteral("maps/shapefile/protected_areas.shp");
    QFileInfo ff(filename);
    //创建图层
    QgsVectorLayer* vecLayer = new QgsVectorLayer(filename,ff.baseName(),"ogr");
    if(!vecLayer->isValid())
    {
        QMessageBox::critical(this,tr("error"),tr("invalid layer"));
        return;
    }
    QgsProject::instance()->addMapLayer(vecLayer);
    zoomToFirstLayer<QgsVectorLayer*>();
}
  • 以下是QgsProject的常用函数
//读取项目文件
bool 	read (const QString &filename, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
bool 	read (Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
//保存项目文件
bool 	write ()
bool 	write (const QString &filename)
//添加单个图层
QgsMapLayer * 	addMapLayer (QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
//添加多个图层
QList< QgsMapLayer * > 	addMapLayers (const QList< QgsMapLayer * > &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Q_INVOKABLE QgsMapLayer *mapLayer (const QString &layerId) const
template<class T >
T mapLayer (const QString &layerId) const
QMap< QString, QgsMapLayer * > 	mapLayers (const bool validOnly=false) const
QList< QgsMapLayer * > 	mapLayersByShortName (const QString &shortName) const
template<typename T >
QVector< T > 	mapLayersByShortName (const QString &shortName) const
void 	removeAllMapLayers ()
void 	removeMapLayer (const QString &layerId)
void 	removeMapLayer (QgsMapLayer *layer)
void 	removeMapLayers (const QList< QgsMapLayer * > &layers)
void 	removeMapLayers (const QStringList &layerIds)

总结

  • QgsMapCanvas作为视图类提供了绘制的画布
  • QgsMapCanvasItem可以绘制在画布上的Item
  • QgsProject图层管理,尤其在添加图层时常用
  • 了解了这几个类,就可以学习如何显示GIS数据了

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

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

相关文章

软件测试担心失业,如何找一份稳定的技术性工作?没有35岁中年危机!

工作难找&#xff0c;大龄程序员屡次碰壁&#xff0c;感慨并担忧自己的未来没出路&#xff01; 经常有网友发帖留言&#xff1a; 今年1月4号被裁员&#xff0c;至今未找到工作&#xff0c;之前做的是软件测试&#xff0c;boss上沟通了3000多次&#xff0c;投简历200多次&#…

JimuReport 积木报表 v1.6.4 稳定版本正式发布 — 开源免费的低代码报表

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

高通新骁龙处理器将于明年上半年发布,携四大品牌厂商首发 | 百能云芯

高通&#xff08;Qualcomm&#xff09;即将于10月下旬正式亮相首款以Oryon架构打造的 PC CPU「Snapdragon X系列」&#xff0c;据悉&#xff0c;四大品牌联想、惠普&#xff08;HP&#xff09;、戴尔&#xff08;DELL&#xff09;及宏碁将是首波推出相关PC的品牌厂&#xff0c;…

【JAVA-Day45】Java常用类StringBuffer解析

Java常用类StringBuffer解析 Java常用类StringBuffer解析一、什么是StringBuffer类二、StringBuffer类的方法2.1 append方法2.2 insert方法2.3 delete方法2.4 replace方法2.5 reverse方法2.6 toString方法2.7 capacity方法2.8 length方法 三、StringBuffer类的应用场景深入了解…

AP5216 dc-dc平均电流型 LED降压恒流驱动器 全亮半亮9W车灯驱动IC​

1&#xff0c;​​产品描述 AP5216 是一款 PWM工作模式, 高效率、外 围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高 精度降压 LED 恒流驱动芯片。输出功率可达 9W&#xff0c;电流 1.0A。 AP5216 可实现全亮/半亮功能切换&#xff0c;通过 MODE 切换&#x…

浅谈智能照明控制系统在智慧建筑中的应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;新时期&#xff0c;建筑行业发展迅速&#xff0c;在信息化背景下&#xff0c;建筑功能逐渐拓展&#xff0c;呈现了智能化的发展态势。智能建筑更加安全、节能、环保&#xff0c;也符合绿色建筑理念。在建筑智…

【Hello Algorithm】暴力递归到动态规划(四)

动态规划的数组压缩技巧 - 机器人走格子问题 题目是leetcode62题目原题 表示如下 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中…

到底什么才是真正的商业智能(BI)

随着人工智能、云计算、大数据、互联网、物联网等新一代信息化、数字化技术在各行各业内开始大规模的应用&#xff0c;社会上的数字化、信息化程度不断加深&#xff0c;而数据价值也在这样的刺激下成为了个人、机构、企业乃至国家的重要战略资源&#xff0c;成为了继土地、劳动…

win11 搭建Apache webdav 设置用户名密码 加密授权访问以及多个不同目录访问

Apache webdav 的搭建应该比较简单,但是搭建后还遇到了一些问题,也就是设置了访问用户名密码,咋就不生效呢,苦苦思索两日,终于发现了问题,本文就是分两个方面来编写 一、搭建 1.下载Apache 官网下载: https://www.apachehaus.com/cgi-bin/download.plx 2.下载后解压…

【ECharts】仪表盘指针自定义形状

这里我把指针改为扇形图&#xff0c;如下 主要是通过如下代码实现自定义形状的指针&#xff1a; var option {series: [{pointer: {icon: image://data:image/png;base64,iVBORw0KGgoAAAANSU...,},}]}; 完整代码如下&#xff1a; var chartDom document.getElementById(my…

今日多写一行注释,明日维护少掉一根头发

&#x1f451; 个人主页 &#x1f451; &#xff1a;&#x1f61c;&#x1f61c;&#x1f61c;Fish_Vast&#x1f61c;&#x1f61c;&#x1f61c; &#x1f41d; 个人格言 &#x1f41d; &#xff1a;&#x1f9d0;&#x1f9d0;&#x1f9d0;说到做到&#xff0c;言出必行&am…

C++11——右值引用

文章目录 1. 左值和右值1.1 什么是左值1.2 什么是右值 2. 左值引用和右值引用2.1 左值引用的使用场景2.2 右值引用的使用场景 3.移动语义4. 完美转发 1. 左值和右值 1.1 什么是左值 左值&#xff0c;不能根据名字来判断&#xff0c;即左边的就是左值&#xff0c;这个是错误的…

Linux系统使用AndroidStudio创建桌面快捷键

Linux系统使用AndroidStudio创建桌面快捷键 系统&#xff1a;deepin 20.7 Android studio 版本&#xff1a;Android Studio Iguana | 2023.2.1 Canary 1 下载免安装最新版本后&#xff0c;是直接在安装包中启动的&#xff0c;但是有点麻烦&#xff0c;就需要设置一个桌面快捷菜…

数据分析案例-基于snownlp模型的MatePad11产品用户评论情感分析(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

禁用和开启笔记本电脑的键盘功能,最快的方式

笔记本键盘通常较小&#xff0c;按键很不方便&#xff0c;当我们外接了键盘时就不需要再使用自带的键盘了&#xff0c;而且午睡的时候&#xff0c;总是担心碰到笔记本的键盘&#xff0c;可能会删掉我们的代码什么的&#xff0c;所以就想着怎么禁用掉&#xff0c;下面是操作步骤…

消失的人!消除视频中不需要的人物

视频拍摄中拍摄了不相干或者是不需要出现的人物&#xff0c;想要从视频中去除&#xff0c;应该如何操作呢&#xff1f;有什么快捷方法可以轻松扣除视频中的人物&#xff1f; 我们在视频剪辑的时候都有这样的烦恼吧&#xff1f;就是在一段视频素材里有多余的人物出现&#xff0…

女性用品经营商城小程序的作用是什么

女性悦己消费增强&#xff0c;围绕女性产生的商品&#xff0c;品牌多且样式足&#xff0c;消费者可以随时购买到&#xff0c;但随着线上互联网深入人们生活&#xff0c;电商近些年发展迅速&#xff0c;传统女性用品线下经销商或品牌在实际经营中面临着痛点。 线上卖货是各商家…

大数据 DataX 详细安装教程

目录 一、环境准备 二、安装部署 2.1 二进制安装 2.2 python 3 支持 三、Data X 初体验 3.1 配置示例 3.1.1. 生成配置模板 3.1.2 创建配置文件 3.1.3 运行 DataX 3.1.4 结果显示 3.2 动态传参 3.2.1. 动态传参的介绍 3.2.2. 动态传参的案例 3.3 迸发设置 …

快速学会Typora和Markdowm常用语法

什么是Markdown&#xff1f; Markdown 是一种轻量标记语言&#xff0c;和 Word、PDF、HMTL 格式一样&#xff0c;可以用作文章或者网页的格式。 和其它的格式相比&#xff0c;Markdown 具备以下优势&#xff1a; 易学易用&#xff0c;逼格满满&#xff1b; 格式简洁&#xff…