#include "Track.h" #include "Xml.h" #include #include #include #include #include bool ParseFile(std::vector &out_tracks, const std::string &file_and_path) { std::ifstream ifs(file_and_path); if(!ifs.is_open()) { std::cerr << "Couldn't open " << file_and_path << "." << std::endl; return false; } // get size ifs.seekg(0, std::ios_base::end); auto end = ifs.tellg(); std::string file_str(end, '\0'); ifs.seekg(0, std::ios_base::beg); // back to beginning to read ifs.read(&file_str[0], end); // parse it (warning: possibly destructive / not const) using namespace rapidxml; xml_document<> doc; // character type defaults to char doc.parse<0>(&file_str[0]); // 0 means default parse flags xml_node<> *seg_node = recursive_find_next_node(doc.first_node(), "trkseg"); if(!seg_node) { std::cerr << "Couldn't find any nodes for file \"" << file_and_path << "\"." << std::endl; return false; } Track t; for(int seg_count = 0; seg_node; ++seg_count, seg_node = recursive_find_next_node(seg_node->next_sibling(), "trkseg")) { xml_node<> *node = recursive_find_next_node(seg_node, "trkpt"); if(!node) { std::cerr << "Couldn't find a node for file \"" << file_and_path << "\" #" << seg_count << "." << std::endl; return false; } // recursively search for all trkpt nodes: for(; node; node = recursive_find_next_node(node->next_sibling(), "trkpt")) { bool found_lat = false; bool found_lon = false; bool found_ele = false; Point p; for(xml_attribute<> *attr = node->first_attribute(); attr; attr = attr->next_attribute()) { if(std::string(attr->name()) == "lat") { try { p.lat = std::atof(attr->value()); found_lat = true; } catch(const std::exception &e) { syslog(LOG_USER|LOG_DEBUG,"%s:%d:%s Error Parsing lat", __FILE__,__LINE__,__PRETTY_FUNCTION__); } } if(std::string(attr->name()) == "lon") { try { p.lon = std::atof(attr->value()); found_lon = true; } catch(const std::exception &e) { syslog(LOG_USER|LOG_DEBUG,"%s:%d:%s Error Parsing lon", __FILE__,__LINE__,__PRETTY_FUNCTION__); } } } auto ele_node = node->first_node("ele"); if(ele_node) { try { p.ele = std::atof(ele_node->value()); found_ele = true; } catch(const std::exception &e) { syslog(LOG_USER|LOG_DEBUG,"%s:%d:%s Error Parsing ele", __FILE__,__LINE__,__PRETTY_FUNCTION__); } } if(found_lat && found_lon && found_ele) t.points.push_back(p); else if(found_lat || found_lon || found_ele) syslog(LOG_USER|LOG_DEBUG, "%s:%d:%s Incomplete trkpt", __FILE__,__LINE__,__PRETTY_FUNCTION__); } } // Bring track to a scale that we're comfortable rendering: // Grab stats: bool first = true; for(auto &p : t.points) { if(first) { first = false; t.min.lat = t.max.lat = p.lat; t.min.lon = t.max.lon = p.lon; t.min.ele = t.max.ele = p.ele; } else { if(p.lat < t.min.lat) t.min.lat = p.lat; else if(p.lat > t.max.lat) t.max.lat = p.lat; if(p.lon < t.min.lon) t.min.lon = p.lon; else if(p.lon > t.max.lon) t.max.lon = p.lon; if(p.ele < t.min.ele) t.min.ele = p.ele; else if(p.ele > t.max.ele) t.max.ele = p.ele; } // NOTE(dev): This must be done AFTER the translation so it doesn't get skewered // p.lat *= 500; // p.lon *= 500; // p.ele *= 0.04; } out_tracks.push_back(t); ifs.close(); std::cout << std::setw(6) << t.points.size() << " tracks points " << "found in \"" << file_and_path << "\"." << std::endl; return true; } void draw(const Track &track) { // glLineWidth(1.0f); // Draw bike path glBegin(GL_LINE_STRIP); for(auto p : track.points) { // auto val = (50 + (p.ele * 10)) / 180.0; // val /= 2.0; // double val = (p.ele - track.min.ele) / (track.max.ele - track.min.ele); // val /= 2.0 + 0.5; // val *= 255; // glColor3d(val, val, val); glColor3d(200, 200, 200); glVertex3f(p.lat, p.ele, p.lon); } glEnd(); glutPostRedisplay(); }