最近真是懶得一X,直接上代碼。。。。。
最近搞Qt,需要利用QGis實現(xiàn)一些地理坐標顯示還有插值圖渲染功能。折騰了一大圈,終于實現(xiàn)了,記錄一下,分享給需要的同學們。( ̄︶ ̄)↗
安裝QGis啥的就自己百度吧,很傻瓜,就是慢。。。
1. 引入相關(guān)頭文件
#include <qgsapplication.h>
#include <qgsproviderregistry.h>
#include <qgsmapcanvas.h>
#include <qgsvectorlayer.h>
#include <qgsproject.h>
#include <qgsrasterlayer.h>
#include <QDialog>
#include <QFileDialog>
#include <QMessageBox>
#include "ogrsf_frmts.h"
// 功能函數(shù)的頭文件
#include <qgssinglesymbolrenderer.h>
#include <qgsinterpolator.h>
#include <qgstininterpolator.h>
#include <qgsgridfilewriter.h>
#include "qgssinglebandpseudocolorrenderer.h"
#include <qgsrastershader.h>
2.修改主函數(shù)
注意此處用Release模式運行(不知道為啥,反正Debug就是錯!!╮(╯_╰)╭)
#include <qgsapplication.h>
int main(int argc, char *argv[])
{
//QApplication a(argc, argv); 正常qt application的初始化
QgsApplication a(argc, argv, true);
QgsApplication::setPrefixPath("D:\\SoftWares\\QGIS\\install\\apps\\qgis\\plugins", true);
// 此處用自己的安裝路徑下面的庫
QgsApplication::initQgis(); //初始化QGIS應用
APP w;
w.show();
return a.exec();
}
3. 添加圖層向量
定義變量
QgsMapCanvas* mapCanvas; // 地圖畫布
//QList<QgsMapCanvasLayer> mapCanvasLayerSet; // 地圖畫布所用的圖層集合
QList<QgsMapLayer*> layers;
QPushButton* train_button;
實現(xiàn)函數(shù)
void onClickedBtnAddVectorLayers()
{
QString filename = QFileDialog::getOpenFileName(this, tr("open vector"), "", "*.shp");
QStringList temp = filename.split(QDir::separator());
QString basename = temp.at(temp.size() - 1);
QgsVectorLayer* vecLayer = new QgsVectorLayer(filename, basename, "ogr");
if (!vecLayer->isValid())
{
QMessageBox::critical(this, "error", "layer is invalid");
return;
}
QgsProject::instance()->addMapLayer(vecLayer);
//mapCanvas->setVisible(true);
layers.append(vecLayer);
mapCanvas->setExtent(vecLayer->extent());
mapCanvas->setLayers(layers);
mapCanvas->zoomToFullExtent();
//mapCanvas->freeze(false);
mapCanvas->refresh();
}
4. 添加柵格圖層
本實現(xiàn)方法將柵格屬性中的顏色表進行了自定義,實現(xiàn)了彩色漸變??梢宰孕行薷模。?!
void onClickedBtnAddRasterLayers()
{
QString filename = QFileDialog::getOpenFileName(this, tr("open vector"), "", "*.tif");
QStringList temp = filename.split(QDir::separator());
QString basename = temp.at(temp.size() - 1);
QgsRasterLayer* rasterLayer = new QgsRasterLayer(filename, basename, "gdal");
if (!rasterLayer->isValid())
{
QMessageBox::critical(this, "error", "layer is invalid");
return;
}
// 尋找柵格圖層數(shù)據(jù)中的最大值和最小值
double max_value = 0, min_value = 100000,op=0;
max_value = rasterLayer->dataProvider()->bandStatistics(1).maximumValue;
min_value = rasterLayer->dataProvider()->bandStatistics(1).minimumValue;
op = (max_value - min_value) / 4;
//ui.lineEdit->setText(QString::number(max_value));
//ui.lineEdit_2->setText(QString::number(min_value));
//獲取當前默認Qgis工程
QgsProject* project = QgsProject::instance();
project->addMapLayer(rasterLayer);
//構(gòu)建一個柵格ColorRampItem列表,每個ColorRampItem表示柵格數(shù)據(jù)一個值對應一個顏色
QList<QgsColorRampShader::ColorRampItem> crlist;
//添加填充色
crlist.append(QgsColorRampShader::ColorRampItem(min_value, QColor(143, 131, 86, 255), QString("Fill")));
//添加云色
crlist.append(QgsColorRampShader::ColorRampItem(min_value+op, QColor(171, 221, 164, 255), QString("Cloud")));
//添加海洋水體顏色
crlist.append(QgsColorRampShader::ColorRampItem(min_value+op*2, QColor(255, 255, 191, 255), QString("Sea")));
//添加陸地顏色
crlist.append(QgsColorRampShader::ColorRampItem(min_value + op * 3, QColor(253, 174, 97, 255), QString("Land")));
//添加積雪顏色
crlist.append(QgsColorRampShader::ColorRampItem(max_value, QColor(215, 25, 28, 255), QString("Snow")));
//構(gòu)建新的QgsColorRampShader 著色器
QgsColorRampShader* crshader = new QgsColorRampShader(0, 100, nullptr, QgsColorRampShader::Type::Interpolated);
//將顏色列表添加到著色器中
crshader->setColorRampItemList(crlist);
//構(gòu)建柵格著色器,我也不知道為啥要包裝這么多層
QgsRasterShader* rasterShader = new QgsRasterShader();
//設置渲染函數(shù)為剛剛新建的QgsColorRampShader 著色器
rasterShader->setRasterShaderFunction(crshader);
//構(gòu)建一個偽彩色單波段渲染器,使用前面的柵格著色器作為輸入,我也不明白為什么這么麻煩
QgsSingleBandPseudoColorRenderer* pseudRender = new QgsSingleBandPseudoColorRenderer(
rasterLayer->dataProvider(), 1, rasterShader);
//柵格圖層設置偽彩色單波段渲染器
rasterLayer->setRenderer(pseudRender);
layers.append(rasterLayer);
mapCanvas->setExtent(rasterLayer->extent());
mapCanvas->setLayers(layers);
mapCanvas->zoomToFullExtent();
mapCanvas->refresh();
}
5. 生成TIN插值圖
void onClickedBtnGenerateTINMap()
{
// 路徑可修改為自己的 .shp 文件路徑
QgsVectorLayer* exp5Layer = new QgsVectorLayer("D:/newShp.shp", "shapefile", "ogr");
const int index = 0;
QgsInterpolator::LayerData ld5;
ld5.source = exp5Layer;
ld5.interpolationAttribute = index;
ld5.sourceType = QgsInterpolator::SourceType::SourcePoints;
ld5.valueSource = QgsInterpolator::ValueSource::ValueAttribute;
QList<QgsInterpolator::LayerData> lds;
lds.append(ld5);
QgsTinInterpolator* itp = new QgsTinInterpolator(lds);
QgsWkbTypes::Type wkbType = exp5Layer->wkbType();
QgsFields fields = exp5Layer->fields();
// 范圍選擇圖層范圍,參數(shù)也可按自己需求修改(不明白參數(shù)的意思,可以先用QGis的Desktop軟件試一試,功能對應)
QgsRectangle rect = exp5Layer->extent();
int ncol = (rect.xMaximum() - rect.xMinimum()) / 5;
int nrow = (rect.yMaximum() - rect.yMinimum()) / 5;
double current_y_value = rect.yMaximum() - 0.1 / 2.0;
double current_x_value = rect.xMinimum() + 0.1 / 2.0;
double interpolatedValue;
QgsGridFileWriter* writer = new QgsGridFileWriter(itp, "D:/d.tif", rect, ncol, nrow);
writer->writeFile();
}
效果圖如下

[參考鏈接]
https://zhuanlan.zhihu.com/p/268609488
https://docs.qgis.org/3.16/en/docs/training_manual/processing/interpolation.html?highlight=interpolation
https://blog.csdn.net/deirjie/article/details/50413117
http://caiyi.tech/post.html?postKey=qgis_dev_1_env_setup
https://www.codenong.com/cs106838694/