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

前言

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

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

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数据了
### 回答1: qgsmapcanvas.panaction()是一个在QGIS中用于平移地图视图的函数。平移是指通过移动地图视图来改变地图显示的方式。 使用qgsmapcanvas.panaction()函数,可以在地图视图中执行平移操作。平移操作可以通过不同的方式来触发,例如使用鼠标拖拽地图视图或者通过编程方式调用函数来执行平移操作。 在调用qgsmapcanvas.panaction()函数时,可以传入一些参数来指定平移的方式和平移的距离。例如,可以选择通过指定一个“增量”参数来控制每次平移的距离,也可以选择指定一个“目标”参数来指定要平移到的目标位置。 在执行平移操作时,地图视图会根据指定的参数来改变地图的显示范围,从而实现平移效果。平移操作可以改变地图的中心点或者改变地图的显示范围,从而让用户可以在地图视图中浏览不同的地理位置。 总结来说,qgsmapcanvas.panaction()是一个QGIS中用于执行平移操作的函数。通过调用这个函数,可以在地图视图中平移到不同的地理位置,改变地图的显示范围和中心点。平移操作可以通过不同的方式触发,例如通过鼠标拖拽或者编程方式调用函数。 ### 回答2: qgsmapcanvas.panaction()是QGIS中的一个函数,它用于在地图画布上执行平移操作。平移操作允许用户在地图上移动视图,以便查看不同区域的特定位置或要素。 当调用qgsmapcanvas.panaction()函数时,它会启动地图画布上的平移操作。用户可以使用鼠标来拖动视图,将地图画布上的位置平移至他们想要查看的位置。 此函数与其他函数结合使用,以创建平移工具或操纵地图视图。例如,可以使用按钮或菜单项调用qgsmapcanvas.panaction()函数,以在用户点击时启动平移操作。 平移操作对于导航大型地图和定位特定要素非常有用。用户可以通过拖动地图画布上的位置,将视图平移到他们感兴趣的区域,以更好地了解地理数据。 总之,qgsmapcanvas.panaction()是QGIS中用于在地图画布上执行平移操作的函数。它使用户能够通过拖动视图来平移到不同区域,以便查看感兴趣的位置或要素。 ### 回答3: qgsmapcanvas.panaction()是一个在QGIS地图窗口中执行平移操作的函数。平移操作是指将地图窗口中的视图沿着水平或垂直方向移动一定的距离。 该函数的作用是触发地图窗口的平移操作。调用这个函数后,用户可以使用鼠标来拖拽地图窗口中的视图,从而实现地图的平移效果。 平移操作对于在QGIS中浏览地图数据非常有用。它可以帮助用户在放大或缩小地图视图时,移动地图的焦点,以便更好地查看感兴趣的区域。 这个函数的使用方法很简单。通常,我们可以在一个按钮或是地图窗口的右键菜单中添加一个槽函数,当用户单击按钮或是右键菜单项时,调用qgsmapcanvas.panaction()来触发平移操作。 总之,qgsmapcanvas.panaction()是一个调用地图窗口的平移操作的函数。它允许用户使用鼠标来拖拽地图视图,从而实现地图的平移效果。这个函数在QGIS中浏览地图数据时非常有用,可以帮助用户更好地查看感兴趣的区域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷动软件工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值