替代GDA中的获取rpc函数poDataset->GetMetadata(“RPC“)

9 篇文章 0 订阅

使用gdal获取经纬度可以通过API this->poDataset->GetMetadata(“RPC”)来自动实现定位rpc文件,并且将内容读入到char** papszRPC变量中。
如果用这个API则显得僵化,灵活度不够,要提前初始化变量poDataset(打开输入的影像),再进行下面的经纬度转换。
这个函数是避免一系列操作,特殊时候,如:一个rpc对应多张影像得时候就非常实用

//gdal要解析经纬度一般操作
	char** papszRPC = this->poDataset->GetMetadata("RPC");//获取了rpc文件中的内容到二维数组中,这个函数是要替代得部分
	GDALRPCInfo oInfo;//将获取的RPC信息构造成结构体
	GDALExtractRPCInfo(papszRPC, &oInfo);//格式化到结构体oInfo变量中

新发现了在gdal_mdreader.h头文件中有以下函数,可以读取rpc、rpb文件和保存rpc\rpb文件,但是不知道是gdal版本问题还是编译问题,带入了这个函数会出现LNK错误,等后面有空了再研究吧。

char** GDALLoadRPBFile( const CPLString& osFilePath );
char** GDALLoadRPCFile( const CPLString& osFilePath );
char** GDALLoadIMDFile( const CPLString& osFilePath );
bool GDALCheckFileHeader(const CPLString& soFilePath,
                               const char * pszTestString,
                               int nBufferSize = 256);

CPLErr GDALWriteRPBFile( const char *pszFilename, char **papszMD );
CPLErr GDALWriteRPCTXTFile( const char *pszFilename, char **papszMD );
CPLErr GDALWriteIMDFile( const char *pszFilename, char **papszMD );

在这里插入图片描述

下面是我写的替代函数:

//zph 2021.6.10
//外部传入rpc文件,返回rpc中的字符串,可以满足GDALExtractRPCInfo函数来解析
//2021.9.26 修复由于RPC文件中间空格过多(不是很标准的RPC,但是所有字段都有),造成的解析错误。
char** GetRPCFileMetadata(char* rpcPath)//手工写一个读取rpc文件的函数,返回读取rpc 文件char**
{
	printf("Begin to Analysis RPC File:%s\n", rpcPath);
	char** RPC_Char = new char*[15];
	RPC_Char[14] = NULL;
	ifstream in(rpcPath);
	string line;
	string result;//组合的长名称
	int i = 0;
	if (in)
	{

		while (getline(in, line))
		{
			if (i < 10)
			{
				int start_P = line.find(":");
				line.replace(start_P, 1, "=");

				int index = 0;
				while ((index = line.find("= ", index)) != string::npos)
				{//把等于号后面的空格都删掉
					line.erase(index+1, 1);
				}
				
				switch (i)
				{
				case 0:
					RPC_Char[6] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[6], "%s", line.c_str());
					break;
				case 1:
					RPC_Char[12] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[12], "%s", line.c_str());
					break;
				case 2:
					RPC_Char[2] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[2], "%s", line.c_str());
					break;
				case 3:
					RPC_Char[8] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[8], "%s", line.c_str());
					break;
				case 4:
					RPC_Char[0] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[0], "%s", line.c_str());
					break;
				case 5:
					RPC_Char[7] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[7], "%s", line.c_str());
					break;
				case 6:
					RPC_Char[13] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[13], "%s", line.c_str());
					break;
				case 7:
					RPC_Char[3] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[3], "%s", line.c_str());
					break;
				case 8:
					RPC_Char[9] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[9], "%s", line.c_str());
					break;
				case 9:
					RPC_Char[1] = new char[strlen(line.c_str()) + 10];//6
					sprintf(RPC_Char[1], "%s", line.c_str());
					break;
				default:
					break;
				}

			}
			else
			{
				int start_P2 = line.find(":");
				int index = 0;
				while ((index = line.find(": ", index)) != string::npos)
				{//把冒号后面的空格都删掉
					line.erase(index + 1, 1);
				}
				line.replace(0, start_P2+1, "");//替换后就是带符号的纯数字
				
				if (i >= 10 && i < 30)
				{
					result = result + line;
					result = result + " ";
				}
				if (i == 30)
				{
					RPC_Char[5] = new char[strlen(result.c_str()) + 30];//6
					sprintf(RPC_Char[5], "LINE_NUM_COEFF=%s", result.c_str());
					result.clear();
				}
				if (i >= 30 && i < 50)
				{
					result = result + line;
					result = result + " ";
				}
				if (i == 50)
				{
					RPC_Char[4] = new char[strlen(result.c_str()) + 30];//6
					sprintf(RPC_Char[4], "LINE_DEN_COEFF=%s", result.c_str());
					result.clear();
				}
				if (i >= 50 && i < 70)
				{
					result = result + line;
					result = result + " ";
				}
				if (i == 70)
				{
					RPC_Char[11] = new char[strlen(result.c_str()) + 30];//6
					sprintf(RPC_Char[11], "SAMP_NUM_COEFF=%s", result.c_str());
					result.clear();
				}

				if (i >= 70 && i < 90)
				{
					result = result + line;
					result = result + " ";
				}

			}
			i++;
			if (i == 90)
			{
				RPC_Char[10] = new char[strlen(result.c_str()) + 30];//6
				sprintf(RPC_Char[10], "SAMP_DEN_COEFF=%s", result.c_str());
				result.clear();
			}


		}
	}
	else
	{
		cout << "no rpc file:" << rpcPath << endl;
	}
	printf("Success Analysis RPC File:%s\n", rpcPath);
	return RPC_Char;
}

//释放方法

for (int i = 0; i < 15; i++)
	{
		if (RPC_Char[i] != NULL)
		{
			delete[]RPC_Char[i];
		}
	}
	delete[]RPC_Char;

2023.1.31更新

今天突然发现this->poDataset->GetMetadata(“RPC”);这个函数真正功能,它是获取影像元数据的RPC,什么意思呢,请接下来:
1、一般情况下RPC文件是外部的一个txt文件,使用单个对RPC文件进行解析即可;
2、同时也有另一种存储RPC的方式,将RPC信息写入到影像内部的RPC域里,这种影像需从影像中将RPC解析出来,怎么读取出来呢,就是this->poDataset->GetMetadata(“RPC”)方法。
python解析自带RPC参数如下截图:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值