使用libxml2解析资源3卫星影像xml
项目场景
使用C++解析ZY3卫星影像的xml,获取其四个角点的经纬度坐标,输出为txt
解决方案
使用xml2库,在ubuntu可以通过以下命令简单安装:
sudo apt-get install libxml2
如果安装后包含xml2相关头文件报错,可以尝试通过软链接解决:
sudo ln -s /usr/include/libxml2/libxml /usr/include/libxml
windows下应该可以通过cmake安装,我没试过,应该不难,详见GNOME/libxml2。
方法很简单,通过xml的树结构一层一层地去解析,找到目标(角点经纬度)。以左上点为例,那么就是sensor_corrected_metadata
>productInfo
>ProductGeographicRange
>LeftTopPoint
>Longtitude
、Latitude
这么一个路径。同理,可以获取其他三个点的坐标。
对其他参数或者其他卫星的xml或者任意xml,也同样可以根据该方法进行解析。
具体实现:
#include<iostream>
#include<vector>
#include<string>
// sudo apt-get install libxml2
// sudo ln -s /usr/include/libxml2/libxml /usr/include/libxml
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
using namespace std;
int getCornerPoints(string xmlPath, vector<vector<double>>& CornerPoints )
{
xmlDocPtr doc; //定义解析文档指针
xmlNodePtr curNode; //定义结点指针(你需要它为了在各个结点间移动)
xmlChar *szKey; //临时字符串变量
char *szDocName=(char *)xmlPath.data();
cout.precision(12);
doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER); //解析文件
//检查解析文档是否成功,如果不成功,libxml将指一个注册的错误并停止。
//一个常见错误是不适当的编码。XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存。
//如果文档是这样,libxml将自动地为你转换到UTF-8。更多关于XML编码信息包含在XML标准中.
if (NULL == doc)
{
cout<<"Xml not parsed successfully\n";
return -1;
}
curNode = xmlDocGetRootElement(doc); //确定文档根元素
/*检查确认当前文档中包含内容*/
if (NULL == curNode)
{
cout<<"empty xml\n";
xmlFreeDoc(doc);
return -1;
}
/*在这个例子中,我们需要确认文档是正确的类型。“root”是在这个示例中使用文档的根类型。*/
if (xmlStrcmp(curNode->name, BAD_CAST "sensor_corrected_metadata"))
{
cout<<"Xml of the wrong type, root node != sensor_corrected_metadata";
xmlFreeDoc(doc);
return -1;
}
int deep=0;
ParserXML(deep,curNode);
cout<<deep<<endl;
curNode = curNode->xmlChildrenNode;
while (curNode != NULL) {
if ((!xmlStrcmp(curNode->name, (const xmlChar *)"productInfo"))) {
curNode = curNode->xmlChildrenNode;
break;
}
curNode= curNode->next;
}
while (curNode != NULL) {
if ((!xmlStrcmp(curNode->name, (const xmlChar *)"ProductGeographicRange"))) {
curNode = curNode->xmlChildrenNode;
break;
}
curNode= curNode->next;
}
CornerPoints.clear();
vector<double> LonLat;
while (curNode != NULL)
{
if ((!xmlStrcmp(curNode->name, (const xmlChar *)"LeftTopPoint")))
{
cout<<curNode->name<<endl;
xmlNodePtr PointNode=curNode->xmlChildrenNode;
while (PointNode != NULL) {
if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Longtitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
}
else if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Latitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
CornerPoints.push_back(LonLat);
LonLat.clear();
}
PointNode= PointNode->next;
}
}
else if ((!xmlStrcmp(curNode->name, (const xmlChar *)"RightTopPoint")))
{
cout<<curNode->name<<endl;
xmlNodePtr PointNode=curNode->xmlChildrenNode;
while (PointNode != NULL) {
if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Longtitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
}
else if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Latitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
CornerPoints.push_back(LonLat);
LonLat.clear();
}
PointNode= PointNode->next;
}
}
else if ((!xmlStrcmp(curNode->name, (const xmlChar *)"RightBottomPoint")))
{
cout<<curNode->name<<endl;
xmlNodePtr PointNode=curNode->xmlChildrenNode;
while (PointNode != NULL) {
if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Longtitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
}
else if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Latitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
CornerPoints.push_back(LonLat);
LonLat.clear();
}
PointNode= PointNode->next;
}
}
else if ((!xmlStrcmp(curNode->name, (const xmlChar *)"LeftBottomPoint")))
{
cout<<curNode->name<<endl;
xmlNodePtr PointNode=curNode->xmlChildrenNode;
while (PointNode != NULL) {
if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Longtitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
}
else if ((!xmlStrcmp(PointNode->name, (const xmlChar *)"Latitude")))
{
cout<<"\t"<<PointNode->name<<"\t";
szKey = xmlNodeGetContent(PointNode);
cout<<szKey<<endl;
LonLat.push_back(stof((char*)szKey));
CornerPoints.push_back(LonLat);
LonLat.clear();
}
PointNode= PointNode->next;
}
}
curNode= curNode->next;
}
for(int i=0;i<CornerPoints.size();i++)
{
cout<<CornerPoints[i][0]<<"\t"<<CornerPoints[i][1]<<endl;
}
return 0;
}