diff --git a/Track.cpp b/Track.cpp index 8a6e3c0..9a0b6a4 100644 --- a/Track.cpp +++ b/Track.cpp @@ -30,65 +30,81 @@ bool ParseFile(std::vector &out_tracks, xml_document<> doc; // character type defaults to char doc.parse<0>(&file_str[0]); // 0 means default parse flags - xml_node<> *node = recursive_find_next_node(doc.first_node(), "trkpt"); - if(!node) + xml_node<> *seg_node = recursive_find_next_node(doc.first_node(), "trkseg"); + if(!seg_node) { - std::cerr << "Couldn't find a node for file \"" << file_and_path << "\"." << std::endl; + std::cerr << "Couldn't find any nodes for file \"" + << file_and_path + << "\"." << std::endl; return false; } Track t; - // recursively search for all trkpt nodes: - for(; node; node = recursive_find_next_node(node->next_sibling(), "trkpt")) + for(int seg_count = 0; + seg_node; + ++seg_count, seg_node = recursive_find_next_node(seg_node->next_sibling(), "trkseg")) { - 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()) + xml_node<> *node = recursive_find_next_node(seg_node, "trkpt"); + if(!node) { - 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__); - } - } + std::cerr << "Couldn't find a node for file \"" + << file_and_path + << "\" #" << seg_count << "." << std::endl; + return false; } - auto ele_node = node->first_node("ele"); - if(ele_node) + + // recursively search for all trkpt nodes: + for(; node; node = recursive_find_next_node(node->next_sibling(), "trkpt")) { - 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", + 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__); - } } - - 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: @@ -118,9 +134,10 @@ bool ParseFile(std::vector &out_tracks, else if(p.ele > t.max.ele) t.max.ele = p.ele; } - p.lat *= 500; - p.lon *= 500; - p.ele *= 0.2; + // 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); @@ -140,8 +157,16 @@ void draw(const Track &track) glBegin(GL_LINE_STRIP); for(auto p : track.points) { - auto val = (50 + (p.ele * 10)) / 180.0; - glColor3d(val / 2.0, val / 2.0, val / 2.0); + // 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(); diff --git a/Track.h b/Track.h index 2b03980..3cd65e4 100644 --- a/Track.h +++ b/Track.h @@ -18,6 +18,8 @@ public: }; static std::vector tracks; +static std::vector>> track_groups; +static int random_group; bool ParseFile(std::vector &out_tracks, const std::string &file_and_path); diff --git a/main.cpp b/main.cpp index 23b6d33..71936cf 100644 --- a/main.cpp +++ b/main.cpp @@ -68,24 +68,24 @@ void display() asdf += 0.02; if(asdf > 15.0) asdf = -15.0; - gluLookAt(-15.0, 30.0, -asdf, /* eye is at */ - 0.0, 5.0, 0.0, /* center is at */ + // gluLookAt(-15.0, 30.0, -asdf, /* eye is at */ + // 0.0, 5.0, 0.0, /* center is at */ + // 0.0, 1.0, 0.0); /* up is in positive Y direction */ + gluLookAt(-20.0, 20.0, 8.0, /* eye is at */ + -5.0, 2.5, 0.0, /* center is at */ 0.0, 1.0, 0.0); /* up is in positive Y direction */ draw_origin(); // DRAW TRACKS: - for(auto track : tracks) - draw(track); + for(auto track : track_groups[random_group].second) + draw(*track); glutSwapBuffers(); } void init() { - // dvereb: - srand(time(NULL)); - glColor3d(1.0, 1.0, 1.0); /* Enable a single OpenGL light. */ @@ -116,6 +116,9 @@ int main(int argc, char *argv[]) return -1; } + // dvereb: + srand(time(NULL)); + std::vector files; for(const auto& entry : std::experimental::filesystem::directory_iterator(argv[1])) { @@ -129,10 +132,103 @@ int main(int argc, char *argv[]) // NORMALIZE TRACKS TO VIEWPORT: bool first = true; - float min_lat, min_lon, min_ele, max_lat, max_lon, max_ele; - for(auto &track : tracks) + + // NOTE(dev): + // We're trying to determine groups of tracks that overlap + // First, put all the tracks in their own group + // Second, keep checking to see if any groups overlap until there are no changes + // std::vector>> track_groups; + for(const auto &track : tracks) { - for(auto &p : track.points) + // Build a header-only copy of each track + Track header; + header.min = track.min; + header.max = track.max; + std::vector vec; + vec.push_back(&track); + + std::pair> p; + p.first = header; + p.second = vec; + // Point to the actual Track with the header info + track_groups.push_back(p); + } + + for(bool no_changes = false; !no_changes; ) + { + no_changes = true; + for(auto i = 0; i < track_groups.size(); ++i) + { + for(auto j = 0; j < track_groups.size(); /* no increment here */) + { + if(j == i) + { + ++j; + continue; + } + bool lat_overlap = false; + bool lon_overlap = false; + if(track_groups[j].first.min.lat <= track_groups[i].first.max.lat + && track_groups[j].first.max.lat >= track_groups[i].first.min.lat) + lat_overlap = true; + if(track_groups[j].first.min.lon <= track_groups[i].first.max.lon + && track_groups[j].first.max.lon >= track_groups[i].first.min.lon) + lon_overlap = true; + if(lat_overlap && lon_overlap) + { + no_changes = false; + track_groups[i].first.min.lat = std::fmin(track_groups[i].first.min.lat, + track_groups[j].first.min.lat); + track_groups[i].first.min.lon = std::fmin(track_groups[i].first.min.lon, + track_groups[j].first.min.lon); + track_groups[i].first.min.ele = std::fmin(track_groups[i].first.min.ele, + track_groups[j].first.min.ele); + track_groups[i].first.max.lat = std::fmax(track_groups[i].first.max.lat, + track_groups[j].first.max.lat); + track_groups[i].first.max.lon = std::fmax(track_groups[i].first.max.lon, + track_groups[j].first.max.lon); + track_groups[i].first.max.ele = std::fmax(track_groups[i].first.max.ele, + track_groups[j].first.max.ele); + + // Add tracks vector to make one big one + track_groups[i].second.insert(track_groups[i].second.end(), + track_groups[j].second.begin(), + track_groups[j].second.end()); + + track_groups.erase(track_groups.begin() + j); + if(j < i) + --i; + } + else + ++j; + } + } + } + + std::cout << "Generated " << track_groups.size() << " track groups:" << std::endl; + int count = 0; + for(const auto &track_group : track_groups) + { + ++count; + std::cout << "Track #" << count << ", including " << track_group.second.size() + << " tracks:" << std::endl; + std::cout << " lat" + << " " << track_group.first.min.lat + << "-" << track_group.first.max.lat << std::endl; + std::cout << " lon" + << " " << track_group.first.min.lat + << "-" << track_group.first.max.lat << std::endl; + std::cout << " ele" + << " " << track_group.first.min.lat + << "-" << track_group.first.max.lat << std::endl; + } + std::cout << std::endl; + + random_group = 0; + float min_lat, max_lat, min_lon, max_lon, min_ele, max_ele; + for(auto &track : track_groups[random_group].second) + { + for(auto &p : track->points) { if(first) { @@ -158,16 +254,32 @@ int main(int argc, char *argv[]) } } } + std::cout << "min_lat: " << min_lat << " max_lat: " << max_lat << ", " + << "min_lon: " << min_lon << " max_lon: " << max_lon << ", " + << "min_ele: " << min_ele << " max_ele: " << max_ele << std::endl; auto lat_diff = min_lat + ((max_lat - min_lat) / 2.0); auto lon_diff = min_lon + ((max_lon - min_lon) / 2.0); auto ele_diff = min_ele; - for(auto &track : tracks) + for(auto &track : track_groups[random_group].second) { - for(auto &p : track.points) + for(auto &track : tracks) { - p.lat -= lat_diff; - p.lon -= lon_diff; - p.ele -= ele_diff; + track.max.lat -= lat_diff; + track.max.lon -= lon_diff; + track.max.ele -= ele_diff; + track.min.lat -= lat_diff; + track.min.lon -= lon_diff; + track.min.ele -= ele_diff; + for(auto &p : track.points) + { + p.lat -= lat_diff; + p.lon -= lon_diff; + p.ele -= ele_diff; + + p.lat *= 500; + p.lon *= 500; + p.ele *= 0; + } } }