GDAL处理地理图像坐标计算
本文讲解如何使用GDAL处理地理图像时,通过使用行列号计算和转换成tiff图像的地理坐标:
tif中坐标计算的方法如下,其中Col表示该坐标点处图像的列号,ROW表示该坐标点处图像的行号。
比如图像左上角Col为0,ROW为0,图像右下角Col为图像宽度,ROW为图像高度。
Xgeo = GT(0) + Col*GT(1) + Row*GT(2)
Ygeo = GT(3) + Col*GT(4) + Row*GT(5)
#include
#include
#include
#include
#include
#include
#define BYTE float //方便数据类型的修改
int main()
{
//tif文件读取
GDALAllRegister(); //注册所有的驱动
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");//以防中文名不能正常读取
int num_iamge_size = 0;
char *file_path_name = "../高程.tif";
GDALDataset *poDataset = (GDALDataset *)GDALOpen(file_path_name, GA_ReadOnly);//GDAL数据集
if (poDataset == NULL)
{
std::cout << "指定的文件不能打开!" << std::endl;
return 0;
}
//获取图像波段
GDALRasterBand *poBand1;
poBand1 = poDataset->GetRasterBand(1);
//获取图像的尺寸
int nImgSizeX = poDataset->GetRasterXSize();
int nImgSizeY = poDataset->GetRasterYSize();
std::cout << "ImageX = " << nImgSizeX << ", ImageY = " << nImgSizeY << std::endl;
//获取坐标变换系数
double trans[6];
CPLErr aaa = poDataset->GetGeoTransform(trans);
//读取图像高程数据
BYTE *pafScanblock1; //开辟缓存区
pafScanblock1 = (BYTE *)CPLMalloc(sizeof(BYTE)*(nImgSizeX)*(nImgSizeY));
poBand1->RasterIO(GF_Read, 0, 0, nImgSizeX, nImgSizeY, pafScanblock1, nImgSizeX, nImgSizeY, GDALDataType(poBand1->GetRasterDataType()), 0, 0);
std::ofstream out("../输出-坐标点.txt");
std::ofstream out_range("../输出-范围坐标点.txt");
//放开此段代码,最后一列和最后一行数据不计算经纬高或者XYZ
nImgSizeX -= 1;
nImgSizeY -= 1;
//范围
//trans[6] 数组adfGeoTransform保存的是仿射变换中的一些参数,分别含义见下
/*
trans[0] 左上角x坐标
trans[1] 东西方向分辨率
trans[2] 旋转角度, 0表示图像 "北方朝上"
trans[3] 左上角y坐标
trans[4] 旋转角度, 0表示图像 "北方朝上"
trans[5] 南北方向分辨率
*/
double UpLeft_Xgeo = trans[0];
double UpLeft_Ygeo = trans[3];
double DownRight_Xgeo = trans[0] + nImgSizeX * trans[1] + nImgSizeY* trans[2];
double DownRight_Ygeo = trans[3] + nImgSizeX * trans[4] + nImgSizeY * trans[5];
out_range << std::setprecision(15) << UpLeft_Xgeo << "," << UpLeft_Ygeo << "\n";
out_range << std::setprecision(15) << DownRight_Xgeo << "," << UpLeft_Ygeo << "\n";
out_range << std::setprecision(15) << DownRight_Xgeo << "," << DownRight_Ygeo << "\n";
out_range << std::setprecision(15) << UpLeft_Xgeo << "," << DownRight_Ygeo << "\n";
out_range.close();
//逐像素遍历,获取Xgeo,Ygeo,elevation(原tif数据是地理坐标系,此处就是经纬度;原tif数据是投影坐标系,此处就是XYZ,单位是米;)
for (int i = 0; i <= nImgSizeX; i++)
{
for (int j = 0; j <= nImgSizeY; j++)
{
//
double Xgeo = trans[0] + i*trans[1] + j*trans[2];
double Ygeo = trans[3] + i*trans[4] + j*trans[5];
读取图像高程数据
//BYTE *pafScanblock1; //开辟缓存区
//pafScanblock1 = (BYTE *)CPLMalloc(sizeof(BYTE)*(1)*(1));
//poBand1->RasterIO(GF_Read, i, j, 1, 1, pafScanblock1, 1, 1, GDALDataType(poBand1->GetRasterDataType()), 0, 0);
BYTE elevation = *pafScanblock1;
num_iamge_size++;
pafScanblock1++;
//std::cout << i << ", " << j << ", " << std::setprecision(15) << Xgeo << ", " << Ygeo << ", " << elevation << std::endl;
out << i << "," << j << "," << std::setprecision(12) << Xgeo << "," << Ygeo << "," << elevation << "\n";
}
}
std::cout << "总计:" << num_iamge_size << std::endl;
out.close();
delete poDataset;
return 0;
}