转换代码在文章下方:
1.gps数据存储在文本中,如下所示:
每一行一个数据,数据使用逗号隔开,第一个为时间,第二个为经度,第三个维度,第四个为高度
2.使用tinyxml2将文件转换为标准的gpx格式文件,转换之后的结果如下:
3.转换后的gpx文件可以使用QGIS程序导入查验
转换代码如下:
kml转换代码
int writeKMLFIle(const std::string fileName, const std::vector<GPS_DATA>&data) {
using namespace tinyxml2;
tinyxml2::XMLDocument doc;
tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration();
doc.InsertFirstChild(declaration);
XMLElement* kml = doc.NewElement("kml ");
kml->SetAttribute("xmlns", "http://www.opengis.net/kml/2.2");
XMLElement* Document = doc.NewElement("Document");
Document->SetAttribute("id", "root_doc");
doc.InsertEndChild(Document);
XMLElement* Placemark = doc.NewElement("Placemark");
XMLElement* name_p = doc.NewElement("name");
Placemark->InsertEndChild(name_p);
XMLElement* Style = doc.NewElement("Style");
XMLElement* LineStyle = doc.NewElement("LineStyle");
Style->InsertEndChild(LineStyle);
Placemark->InsertEndChild(Style);
XMLElement* LineString = doc.NewElement("LineString");
XMLElement* coordinates = doc.NewElement("coordinates");
std::string strCoor = "";
for (int i = 0; i < data.size(); ++i) {
auto dat = data[i];
strCoor +=dat.strLong+","+ dat.strLati+","+dat.strAlti+"\n";
}
coordinates->SetText(strCoor.c_str());
LineString->InsertEndChild(coordinates);
Placemark->InsertEndChild(LineString);
Document->InsertEndChild(Placemark);
kml->InsertEndChild(Document);
doc.InsertEndChild(kml);
return doc.SaveFile(fileName.c_str());
}
#include "../tinyxml2.h"
#include <fstream>
#include <string>;
#include <vector>
struct GPS_DATA {
std::string strTime;
std::string strLong;
std::string strLati;
std::string strAlti;
};
int readCSVFile(const std::string fileName, std::vector<GPS_DATA>&data);
int writeGPXFile(const std::string fileName,const std::vector<GPS_DATA>&data);
int main(int argc,char** argv)
{
std::string Nname = "C:\\Users\\op\\Desktop\\gpsdata/gps-2021-12-9-9-22-1.csv";
std::vector<GPS_DATA> gpsdata;
gpsdata.reserve(3 * 3600 / 6);
int nLIne = readCSVFile(Nname, gpsdata);
printf("input data has %d\n", nLIne);
int res = writeGPXFile("gps.gpx", gpsdata);
if (res == 0) {
printf("create gpx data successful!\n");
}
else {
printf("create gpx data error = %d!\n", res);
}
system("pause");
return 0;
}
void splitString(const std::string& istr,const std::string &s_str,std::vector<std::string>& vstr)
{
if (istr.empty())return;
auto p = istr.find_first_of(s_str);
if ( p!= istr.npos) {
vstr.push_back(istr.substr(0,p));
splitString(istr.substr(p+1), s_str, vstr);
}
else {
vstr.push_back(istr);
}
}
int readCSVFile(const std::string fileName, std::vector<GPS_DATA>& data)
{
std::ifstream ifs(fileName);
if (!ifs.is_open()) {
printf("can't open file %s!\n", fileName.c_str());
return -1;
}
do {
std::string str;
std::getline(ifs, str);
if (str.empty())
break;
std::vector < std::string > vstr;
splitString(str,",", vstr);
if (vstr.size() == 4) {
GPS_DATA gd{ vstr[0],vstr [1],vstr [2],vstr [3]};
data.push_back(gd);
}
} while (true);
return data.size();
}
int writeGPXFile(const std::string fileName, const std::vector<GPS_DATA>&data)
{
using namespace tinyxml2;
tinyxml2::XMLDocument doc;
tinyxml2::XMLDeclaration* declaration = doc.NewDeclaration();
doc.InsertFirstChild(declaration);
XMLElement* root = doc.NewElement("gpx ");
root->SetAttribute("version", 1.00f);
XMLElement* trackName = doc.NewElement("name");
trackName->SetText("track--1");
root->InsertFirstChild(trackName);
XMLElement* tracks = doc.NewElement("trk");
XMLElement* tracks_sg = doc.NewElement("trkseg");
for (int i = 0; i < data.size(); ++i) {
XMLElement* trkpt = doc.NewElement("trkpt");
trkpt->SetAttribute("lat", data[i].strLati.c_str());
trkpt->SetAttribute("lon", data[i].strLong.c_str());
XMLElement* ele = doc.NewElement("ele");
ele->SetText(data[i].strAlti.c_str());
XMLElement* time = doc.NewElement("time");
time->SetText(data[i].strTime.c_str());
trkpt->InsertEndChild(ele);
trkpt->InsertEndChild(time);
tracks_sg->InsertEndChild(trkpt);
}
tracks->InsertFirstChild(tracks_sg);
root->InsertEndChild(tracks);
doc.InsertEndChild(root);
return doc.SaveFile(fileName.c_str());
}