使用GDAL库实现对dem的修改

一、代码

#include "iostream"
#include "string"
#include "gdal_priv.h"
#include "cpl_conv.h"
#include "gdalwarper.h"
#include "stdlib.h"


typedef unsigned short UINT;

int main()
{
	//Opening the File
	GDALAllRegister();

	std::string pszFilename("srtm30plus_stripped.tif");

	//创建dem实体
	GDALDataset *poDataset;
	poDataset = (GDALDataset*)GDALOpen(pszFilename.c_str(), GA_ReadOnly);
	if (poDataset == NULL)
	{
		std::cout << "OPEN GEOTIFF FAIL!" << std::endl;
		return -1;
	}

	//Getting Dataset Information
	double adfGeoTransform[6];
	float width = poDataset->GetRasterXSize();
	float height = poDataset->GetRasterYSize();
	float nBands = poDataset->GetRasterCount();

	std::cout << "Driver: " << poDataset->GetDriver()->GetDescription() << " , "
		<< poDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME) << std::endl;

	std::cout << "Size is " << width << " x " <<
		height << " x " << nBands << std::endl;

	if (poDataset->GetProjectionRef() != NULL)
	{
		std::cout << "Projection is" << poDataset->GetProjectionRef() << std::endl;
	}

	if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None)
	{
		std::cout << "Origin = ( " << adfGeoTransform[0] << " , " << adfGeoTransform[3]
			<< " )" << std::endl;
		std::cout << "Pixel Size = ( " << adfGeoTransform[1] << " , " << adfGeoTransform[5]
			<< " )" << std::endl;
	}


	//Fetching a Raster Band
	GDALRasterBand *poBand;
	int nBlockXSize, nBlockYSize;
	int bGotMin, bGotMax;
	double adfMinMax[2];
	poBand = poDataset->GetRasterBand(1);
	poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
	std::cout << "Block = " << nBlockXSize << " x " << nBlockYSize << " , " <<
		"Type = " << GDALGetDataTypeName(poBand->GetRasterDataType()) << " , " <<
		"ColorInterp = " << GDALGetColorInterpretationName(poBand->GetColorInterpretation()) << std::endl;
	adfMinMax[0] = poBand->GetMinimum(&bGotMin);
	adfMinMax[1] = poBand->GetMaximum(&bGotMax);
	
	if (!(bGotMin&&bGotMax))
	{
		GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
	}
	std::cout << "Min = " << adfMinMax[0] << " , " << " Max = " << adfMinMax[1] << std::endl;
	if (poBand->GetOverviewCount() > 0)
	{
		std::cout << "Band has " << poBand->GetOverviewCount() << " overviews." << std::endl;
	}
	if (poBand->GetColorTable() != NULL)
	{
		std::cout << "Band has a color table with " << poBand->GetColorTable()->GetColorEntryCount() <<
			" entries." << std::endl;
	}


	//Reading Raster Data And Create File
	float **pafScanline=new float *[nBands];
	if (pafScanline == NULL)
	{
		std::cout << "UINT **pafScanline = new UINT *[nBands]; failed!" << std::endl;
		return -1;
	}
	float **pafScanlineOutput = new float *[nBands];
	if (pafScanlineOutput == NULL)
	{
		std::cout << "UINT **pafScanlineOutput = new UINT *[nBands]; failed!" << std::endl;
		return -1;
	}

	int nXSize = poBand->GetXSize();
	int nYSize = poBand->GetYSize();
	//pafScanline = (float *)CPLMalloc(sizeof(float)*nXSize*nYSize);
	//poBand->RasterIO(GF_Read, 0, 0, nXSize, nYSize,
	//	pafScanline, nXSize, nYSize, /*poBand->GetRasterDataType()*/GDT_Float32, 0, 0);

	const char *pszFormat = "GTiff";
	GDALDriver *poDriver;
	poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);

	GDALDataset *poDstDs;
	const char *pszDstFilename = "srtm_30m_output.tif";
	char **papxzOptions = NULL;

	poDstDs = poDriver->Create(pszDstFilename, nXSize, nYSize, poDataset->GetRasterCount(),
		GDT_Float32, papxzOptions);

	//一次处理xHei=400行数据  分块处理
	int xHei = 400;
	int timePerxH = nYSize / xHei + 1;

	//防止无符号数越界
	int tmp = 0;

	//开始分块处理
	//i表示分块处理需处理次数计数
	for (int i = 0; i < timePerxH - 1; i++)
	{
		for (int j = 0; j < nBands; j++)
		{
			pafScanline[j] = new float[nXSize*xHei];
			if (pafScanline[j] == NULL)
			{
				std::cout << "pafScanline[j] = new UINT[Width*xHei]; failed!" << std::endl;
				return -1;
			}
			pafScanlineOutput[j] = new float[nXSize*xHei];
			if (pafScanlineOutput[j] == NULL)
			{
				std::cout << "pafScanlineOutput[j] = new UINT[Width*xHei]; failed!" << std::endl;
				return -1;
			}
		}
		poBand->RasterIO(GF_Read, 0, i*xHei, nXSize, xHei, pafScanline[0],
			nXSize, xHei, GDT_Float32, 0, 0);

		//pafScanline像素操作
		for (int i = 0; i < nBands; i++)
		{
			for (int j = 0; j < xHei; j++)
			{
				for (int k = 0; k < nXSize; k++)
				{
					if (pafScanline[i][j*nXSize + k] < 0)
					{
						//std::cout << "修改前" << pafScanline[i][j*nXSize + k] << std::endl;
						pafScanline[i][j*nXSize + k] = 0;
						//std::cout << "修改后" << pafScanline[i][j*nXSize + k] << std::endl;
					}

					pafScanlineOutput[i][j*nXSize + k] = pafScanline[i][j*nXSize + k];
				}
			}
		}
		poDstDs->GetRasterBand(1)->RasterIO(GF_Write, 0, xHei*i, nXSize, xHei,
			pafScanlineOutput[0], nXSize, xHei, GDT_Float32, 0, 0);

		for (int j = 0; j < nBands; j++)
		{
			delete []pafScanline[j];
			pafScanline[j] = NULL;

			delete []pafScanlineOutput[j];
			pafScanlineOutput[j] = NULL;
		}

	}

	//剩余行数处理
	int foreH = (timePerxH - 1)*xHei;
	int leftH = nYSize - foreH;
	for (int j = 0; j < nBands; j++)
	{
		pafScanline[j] = new float[nXSize*leftH];
		if (pafScanline[j] == NULL)
		{
			std::cout << "pafScanline[j] = new UINT[Width*leftH]; failed!" << std::endl;
			return -1;
		}
		pafScanlineOutput[j] = new float[nXSize*leftH];
		if (pafScanlineOutput[j] == NULL)
		{
			std::cout << "pafScanlineOutput[j] = new UINT[Width*leftH]; failed!" << std::endl;
			return -1;
		}
	}
	poBand->RasterIO(GF_Read, 0, foreH, nXSize, leftH, pafScanline[0], nXSize, 
		leftH, GDT_Float32, 0, 0);
	//pafScanline像素操作
	for (int i = 0; i < nBands; i++)
	{
		for (int j = 0; j < xHei; j++)
		{
			for (int k = 0; k < nXSize; k++)
			{
				if (pafScanline[i][j*nXSize + k] < 0)
				{
					//std::cout << "修改前" << pafScanline[i][j*nXSize + k] << std::endl;
					pafScanline[i][j*nXSize + k] = 0;
					//std::cout << "修改后" << pafScanline[i][j*nXSize + k] << std::endl;
				}

				pafScanlineOutput[i][j*nXSize + k] = pafScanline[i][j*nXSize + k];
				//std::cout << "pafScanlineOutput的数据 :" << pafScanlineOutput[i][j*nXSize + k] << std::endl;
			}
		}
	}
	poDstDs->GetRasterBand(1)->RasterIO(GF_Write, 0, foreH, nXSize, leftH, 
		pafScanlineOutput[0], nXSize, leftH, GDT_Float32, 0, 0);
	for (int j = 0; j < nBands; j++)
	{
		delete[]pafScanline[j];
		pafScanline[j] = NULL;

		delete[]pafScanlineOutput[j];
		pafScanlineOutput[j] = NULL;
	}

	delete pafScanline;
	pafScanline = NULL;
	delete pafScanlineOutput;
	pafScanlineOutput = NULL;

	poDstDs->SetGeoTransform(adfGeoTransform);
	poDstDs->SetProjection(poDataset->GetProjectionRef());



	GDALClose(poDataset);

	system("pause");
	return 0;
}

二、心得

要注意保存像素数据的数组需要和图像文件本身存储的数据类型相匹配,否则出来的数据是错误的。一般来说dem文件都十分巨大,在读入时需要注意分段。

参考文献

[原][osg][gdal]两种方式修改tiff高程
GDAL documentation

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用GDAL实现坐标系转换,需要先安装GDAL,并在代码中引用相关的头文件和文件。以下是一个简单的C++代码示例,演示了如何使用GDAL实现坐标系转换: ```c++ #include "gdal_priv.h" #include "ogr_spatialref.h" int main() { // 创建源坐标系 OGRSpatialReference srcSRS; srcSRS.SetWellKnownGeogCS("WGS84"); // 创建目标坐标系 OGRSpatialReference dstSRS; dstSRS.SetWellKnownGeogCS("NAD83"); // 创建坐标转换器 OGRCoordinateTransformation* transform = OGRCreateCoordinateTransformation(&srcSRS, &dstSRS); if (transform == NULL) { // 坐标转换器创建失败 return -1; } // 定义源坐标点 double srcX = 116.403963; double srcY = 39.915119; // 定义目标坐标点 double dstX, dstY; // 进行坐标转换 transform->Transform(1, &srcX, &srcY, &dstX, &dstY); // 输出转换结果 printf("Source: %lf, %lf\n", srcX, srcY); printf("Destination: %lf, %lf\n", dstX, dstY); // 释放坐标转换器 OGRCoordinateTransformation::DestroyCT(transform); return 0; } ``` 在这个示例中,我们首先创建了源坐标系和目标坐标系,然后使用OGRCreateCoordinateTransformation函数创建了一个坐标转换器。接着,我们定义了源坐标点的坐标值,然后使用Transform函数进行坐标转换,将源坐标点转换为目标坐标系中的点。最后,我们输出了转换结果,并释放了坐标转换器。 需要注意的是,这个示例中仅演示了如何进行基本的坐标转换,如果需要进行其他类型的坐标转换,例如投影坐标系之间的转换,需要进行更复杂的计算和处理。此时,我们可以使用GDAL提供的其他函数和类来实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值