最近在写一个栅格计算器,用到了两个类,一个是QgsRasterCalculatorEntry,另一个是QgsRasterCalculator。这两个类就可以实现栅格计算器的功能。
在使用QgsRasterCalculatorEntry与QgsRasterCalculator这两个类之前要引入一个头文件#include <qgsrastercalculator.h>,这个头文件是专为栅格计算而设计的,如果引用这个头文件后程序会出现一些错误,可以参考我上一篇的文章——QGis二次开发引用头文件后遇到无法解析的外部符号可以解决问题。
下面就来实现栅格计算:
1.首先先获取栅格影像的路径,也是导入数据
// 获取文件名称
QStandardItemModel *model = (QStandardItemModel *) ui.treeView_bands->model();
QStandardItem *item = model->item(0, 0);
QString filename = item->text();
QFileInfo fileinfo(filename);
qDebug() << filename << endl;
// 创建一个栅格图层
QgsRasterLayer *my_rasterLayer = nullptr;
my_rasterLayer = new QgsRasterLayer(fileinfo.filePath(),fileinfo.completeBaseName());// fileinfo是输入文件名称信息
if (! my_rasterLayer->isValid())
{
qDebug() << "图层指针为空" << endl; return;
}
// 测试输入的图层有效
qDebug() << "图层不为空" << endl;
我这里的文件路径是放在Qt中QTreeView的item里了,所以我获取文件路径是上面的形式,你可以直接把文件的路径传给QString然后创建一个栅格图层也是一样的。
2.创建参与波段计算的集合QgsRasterCalculatorEntry
// 创建参与波段集
QVector<QgsRasterCalculatorEntry> entries;
QgsRasterCalculatorEntry entry;
entry.bandNumber = 1;
entry.raster = my_rasterLayer;
entry.ref = QStringLiteral("landsat@1");
QgsRasterCalculatorEntry entry2;
entry2.bandNumber = 2;
entry2.raster = my_rasterLayer;
entry2.ref = QStringLiteral("landsat2");
entries << entry<<entry2;
3.创建输出影像的信息
// 获取坐标系统
QgsCoordinateReferenceSystem crs;
crs = my_rasterLayer->crs();
// 获取范围
QgsRectangle extent = my_rasterLayer->extent();
// 创建临时文件
QTemporaryFile tmpFile;
tmpFile.open(); // fileName is no avialable until open文件名在打开之前是不可访问的
QString tmpName = tmpFile.fileName();
tmpFile.close();
qDebug() << "开始计算" << endl;
// 获取行与列的值
int cols = my_rasterLayer->width();
int rows = my_rasterLayer->height();
4.栅格计算
// 波段计算(栅格计算)
QgsRasterCalculator rc(QStringLiteral("\"landsat2\" + \"landsat@1\""),
tmpName,
QStringLiteral("GTiff"),
extent, crs, my_rasterLayer->width(), my_rasterLayer->height(), entries);
if (static_cast<int>(rc.processCalculation()) == 0)// 一定要有这个判断,否则计算失败
{
qDebug() << "计算失败" << endl;
}
// 创建输出结果
QgsRasterLayer *result = new QgsRasterLayer(tmpName, QStringLiteral("result"));
if (! result->isValid())
{
QMessageBox::information(NULL, "提示", "计算失败");
return;
}
// 显示输出结果在画布中(如果没有创建画布可以不要这一行)
QgsProject::instance()->addMapLayer(result);
qDebug() << filename << endl;
总结:
以上的代码可以实现栅格计算了,下面附上一个总代码,把上面的代码合在一起。
// 获取文件名称
QStandardItemModel *model = (QStandardItemModel *) ui.treeView_bands->model();
QStandardItem *item = model->item(0, 0);
QString filename = item->text();
QFileInfo fileinfo(filename);
qDebug() << filename << endl;
// 创建一个栅格图层
QgsRasterLayer *my_rasterLayer = nullptr;
my_rasterLayer = new QgsRasterLayer(fileinfo.filePath(),fileinfo.completeBaseName());// fileinfo是输入文件名称信息
if (! my_rasterLayer->isValid())
{
qDebug() << "图层指针为空" << endl; return;
}
// 测试输入的图层有效
qDebug() << "图层不为空" << endl;
//QgsProject::instance()->addMapLayer(my_rasterLayer);
// 创建参与波段集
QVector<QgsRasterCalculatorEntry> entries;
QgsRasterCalculatorEntry entry;
entry.bandNumber = 1;
entry.raster = my_rasterLayer;
entry.ref = QStringLiteral("landsat@1");
QgsRasterCalculatorEntry entry2;
entry2.bandNumber = 2;
entry2.raster = my_rasterLayer;
entry2.ref = QStringLiteral("landsat2");
entries << entry<<entry2;
// 获取坐标系统
QgsCoordinateReferenceSystem crs;
crs = my_rasterLayer->crs();
// 获取范围
QgsRectangle extent = my_rasterLayer->extent();
// 创建临时文件
QTemporaryFile tmpFile;
tmpFile.open(); // fileName is no avialable until open文件名在打开之前是不可访问的
QString tmpName = tmpFile.fileName();
tmpFile.close();
qDebug() << "开始计算" << endl;
// 获取行与列的值
int cols = my_rasterLayer->width();
int rows = my_rasterLayer->height();
// 波段计算(栅格计算)
QgsRasterCalculator rc(QStringLiteral("\"landsat2\" + \"landsat@1\""),
tmpName,
QStringLiteral("GTiff"),
extent, crs, my_rasterLayer->width(), my_rasterLayer->height(), entries);
if (static_cast<int>(rc.processCalculation()) == 0)// 一定要有这个判断,否则计算失败,返回值是0-7,0为成功
{
qDebug() << "计算成功" << endl;
}
// 创建输出结果
QgsRasterLayer *result = new QgsRasterLayer(tmpName, QStringLiteral("result"));
if (! result->isValid())
{
QMessageBox::information(NULL, "提示", "计算失败");
return;
}
// 显示输出结果在画布中(如果没有创建画布可以不要这一行)
QgsProject::instance()->addMapLayer(result);
qDebug() << filename << endl;