使用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参数如下截图: