效果
功能说明
软件可同时加载.tif栅格图片与.shp矢量图片、加载图片后可进行自由切换查看图层、可对加载的图片进行关闭 关闭后清空图层、可对加载的图片进行导出.qgs的QGIS工程、可对.qgs的QGis工程导入并导入后可进行自由切换查看图层。
源码
注意: 在加载tif栅格文件后会在该文件同级目录下自动创建.html文件。
注意: .shp文件目录下应该要有对应同名的.shx矢量字体文件,这样才能加载成功。
main.cpp
#include "QtWidgetsApplication1.h"
#include <QtWidgets/QApplication>#include <qgsapplication.h>int main(int argc, char *argv[])
{// 参数三: 如果需要GUI应用程序,则设置为true;对于仅控制台应用程序,设置falseQgsApplication a(argc, argv, true);QgsApplication::setPrefixPath("D:/Software/QGis-OSGeo4W/install/apps/qgis-ltr", true); // 设置qgis路径QgsApplication::setPluginPath("D:/Software/QGis-OSGeo4W/install/apps/qgis-ltr/plugins"); // 设置插件路径QgsApplication::initQgis(); // 初始化QGisQtWidgetsApplication1 w;w.show();return a.exec();
}
QtWidgetsApplication1.h
#pragma once#include <QtWidgets/QMainWindow>
#include "ui_QtWidgetsApplication1.h"#include <QtMath>
#include <qgsmapcanvas.h>class QtWidgetsApplication1 : public QMainWindow
{Q_OBJECTpublic:QtWidgetsApplication1(QWidget *parent = nullptr);~QtWidgetsApplication1();protected:// 将画布放在ui的Widget上,供显示void initQgsMapCanvas();// 加载本地.tif、.shp文件bool loadLocalFile(const QString &RasterFileName, const QString &VectorFileName);// 删除画布上所有图层并更新画布void removeMapLayers();protected slots:// 通过按钮驱动进行加载本地文件void on_btn_qgsLoadFile_clicked();// 保存QGIS工程项目void on_btn_SaveQgisProject_clicked();// 导入QGIS工程项目void on_btn_LoadQgisProject_clicked();// 关闭QGIS工程项目void on_btn_CloseQgisProject_clicked();// 切换显示画布上的矢量、栅格图层void sltQgsShowFile(int);private:Ui::QtWidgetsApplication1Class ui;// 画布QgsMapCanvas *qMapCanvas = nullptr;// 图层列表: qMapLayerList为真实使用,qVirtualMapLayerList为虚拟使用。真实使用时会增删、虚拟使用则仅在函数内增加后则不再增删。QList<QgsMapLayer*> qMapLayerList, qVirtualMapLayerList;
};
QtWidgetsApplication1.cpp
#include "QtWidgetsApplication1.h"#include <QMessageBox>
#include <QComboBox>
#include <QGridLayout>#include <qgsrasterlayer.h>
#include <qgsvectorlayer.h>
#include <qgsproject.h>const QString QGisProjectFileName = "qgs_project.qgs";QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QMainWindow(parent)
{ui.setupUi(this);initQgsMapCanvas();
}QtWidgetsApplication1::~QtWidgetsApplication1()
{removeMapLayers();QLayout *GridLayout = ui.qgsMapCanvasWidget->layout();if (GridLayout) {GridLayout->removeWidget(qMapCanvas);delete GridLayout; }GridLayout = nullptr;if (qMapCanvas) { delete qMapCanvas; }qMapCanvas = nullptr;
}void QtWidgetsApplication1::initQgsMapCanvas()
{// 创建地图画布对象qMapCanvas = new QgsMapCanvas(this);QGridLayout *GridLayout = new QGridLayout;GridLayout->addWidget(qMapCanvas);ui.qgsMapCanvasWidget->setLayout(GridLayout);
}bool QtWidgetsApplication1::loadLocalFile(const QString &RasterFileName, const QString &VectorFileName)
{// 创建矢量图层对象并加入本地文件QgsVectorLayer *qVectorLayer = new QgsVectorLayer(VectorFileName, "shp");if (!qVectorLayer->isValid()) { return false; }qMapLayerList << qVectorLayer;qVirtualMapLayerList << qVectorLayer;ui.cb_qgsShowFile->addItem("shp", 0); // 1为qVectorLayer所在qMapLayerList的序号// 创建光栅图层对象加入本地文件QgsRasterLayer *qRasterLayer = new QgsRasterLayer(RasterFileName, "tif");if (!qRasterLayer->isValid()) { return false; }// 设置对比度增强(主要用于栅格图像;矢量图像不需要)。参数1算法:线性直方图、参数2界限范围:实际最小最大值qRasterLayer->setContrastEnhancement(QgsContrastEnhancement::StretchToMinimumMaximum, QgsRasterMinMaxOrigin::MinMax);qMapLayerList << qRasterLayer;qVirtualMapLayerList << qRasterLayer;ui.cb_qgsShowFile->addItem("tif",1); // 0为qRasterLayer所在qMapLayerList的序号// 画布设置qMapCanvas->setLayers(qMapLayerList); // 设置应在画布中显示的图层列表qMapCanvas->setDestinationCrs(qMapLayerList[0]->crs()); // 设置目标坐标参照系为输入光栅图层的坐标系qMapCanvas->setExtent(qMapLayerList[0]->extent()); // 设置画布范围为输入光栅图层的范围qMapCanvas->setCurrentLayer(qMapLayerList[0]); // 设置画布当前图层为输入光栅图层qMapCanvas->refresh(); // 刷新画布// 将图层列表添加到已加载图层的映射中QgsProject::instance()->addMapLayers(qMapLayerList);return true;
}void QtWidgetsApplication1::removeMapLayers()
{if (!qMapLayerList.isEmpty()) {qMapLayerList.clear(); qVirtualMapLayerList.clear();}qMapCanvas->setLayers(QList<QgsMapLayer*>());qMapCanvas->refresh();
}void QtWidgetsApplication1::on_btn_qgsLoadFile_clicked()
{loadLocalFile("./world.tif", "./china.shp");ui.cb_qgsShowFile->setEnabled(true);ui.btn_qgsLoadFile->setEnabled(false);connect(ui.cb_qgsShowFile, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QtWidgetsApplication1::sltQgsShowFile);
}void QtWidgetsApplication1::on_btn_SaveQgisProject_clicked()
{// 工程文件扩展名为: .qgz、.qgsQgsProject::instance()->setFileName(QGisProjectFileName);QgsProject::instance()->write();
}void QtWidgetsApplication1::on_btn_LoadQgisProject_clicked()
{/*****************************************************************/int aaa = QgsProject::instance()->count();int aaa1 = qMapCanvas->layerCount();// 加载前先将之前的画布、画布上的图层清空removeMapLayers();int ccc = QgsProject::instance()->count();int ccc2 = qMapCanvas->layerCount();/* 重要: 以上测试说明当qMapLayerList删除,那么对应画布的layer与工程实例的mapLayer也会自动清空! *//*****************************************************************/if (!QgsProject::instance()->read(QGisProjectFileName)){QMessageBox::critical(this, "ERROR", "load QGIS Project fail!", QMessageBox::Yes);return;}qMapLayerList = qVirtualMapLayerList = QgsProject::instance()->mapLayers().values();qMapCanvas->setLayers(qMapLayerList); // 设置画布当前图层为输入光栅图层qMapCanvas->setDestinationCrs(qMapLayerList[0]->crs()); // 设置目标坐标参照系为输入光栅图层的坐标系qMapCanvas->setExtent(qMapLayerList[0]->extent()); // 设置画布范围为输入光栅图层的范围qMapCanvas->setCurrentLayer(qMapLayerList[0]); // 设置画布当前图层为输入光栅图层qMapCanvas->refresh(); // 刷新画布ui.cb_qgsShowFile->addItem("shp", 0); // 1为qVectorLayer所在qMapLayerList的序号ui.cb_qgsShowFile->addItem("tif", 1); // 0为qRasterLayer所在qMapLayerList的序号ui.cb_qgsShowFile->setEnabled(true);ui.btn_qgsLoadFile->setEnabled(false);connect(ui.cb_qgsShowFile, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QtWidgetsApplication1::sltQgsShowFile);qDebug() << "AA:" << QgsProject::instance()->count() << " " << QgsProject::instance()->mapLayers().count() << " " << qMapCanvas->layerCount() << " " << qMapLayerList.size() << " " << qVirtualMapLayerList.size();
}void QtWidgetsApplication1::on_btn_CloseQgisProject_clicked()
{// 加载前先将之前的画布、画布上的图层清空removeMapLayers();disconnect(ui.cb_qgsShowFile, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QtWidgetsApplication1::sltQgsShowFile);ui.cb_qgsShowFile->setEnabled(false);ui.btn_qgsLoadFile->setEnabled(true);ui.cb_qgsShowFile->clear();QgsProject::instance()->clear();
}void QtWidgetsApplication1::sltQgsShowFile(int index)
{/* 重要: 以下操作说明qMapLayerList变化,那么对应画布的layer与工程实例的mapLayer也会自动变化! */if (qVirtualMapLayerList.size() > index){qMapLayerList.clear();qMapLayerList << qVirtualMapLayerList[index];qMapCanvas->setLayers(qMapLayerList); // 设置画布当前图层为输入光栅图层qMapCanvas->setDestinationCrs(qMapLayerList[0]->crs()); // 设置目标坐标参照系为输入光栅图层的坐标系qMapCanvas->setExtent(qMapLayerList[0]->extent()); // 设置画布范围为输入光栅图层的范围qMapCanvas->refresh(); // 刷新画布}
}
QtWidgetsApplication1.ui
关注
笔者 - jxd