Split up files. Added rapidxml for xml parsing.
This commit is contained in:
parent
a5175799ba
commit
40d41361fc
6
Makefile
6
Makefile
@ -1,2 +1,4 @@
|
||||
a.out: main.cpp
|
||||
clang++ -std=c++17 -g -o a.out main.cpp -lGL -lGLU -lglut -lstdc++fs
|
||||
a.out: *.cpp
|
||||
clang++ -std=c++17 -g -o a.out main.cpp \
|
||||
camera/Camera.cpp Track.cpp Xml.cpp \
|
||||
-lGL -lGLU -lglut -lstdc++fs
|
||||
|
152
Track.cpp
Normal file
152
Track.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include "Track.h"
|
||||
#include "Xml.h"
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
bool ParseFile(std::vector<Track> &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<> *node = recursive_find_next_node(doc.first_node(), "trkpt");
|
||||
if(!node)
|
||||
{
|
||||
std::cerr << "Couldn't find a <trkpt> node 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"))
|
||||
{
|
||||
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;
|
||||
}
|
||||
p.lat *= 500;
|
||||
p.lon *= 500;
|
||||
p.ele *= 0.2;
|
||||
}
|
||||
|
||||
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;
|
||||
glColor3d(val / 2.0, val / 2.0, val / 2.0);
|
||||
glVertex3f(p.lat, p.ele, p.lon);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// usleep(100000);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
27
Track.h
Normal file
27
Track.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef TRACK_H
|
||||
#define TRACK_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct Point {
|
||||
float lat;
|
||||
float lon;
|
||||
float ele;
|
||||
};
|
||||
|
||||
struct Track {
|
||||
public:
|
||||
std::vector<Point> points;
|
||||
Point min;
|
||||
Point max;
|
||||
};
|
||||
|
||||
static std::vector<Track> tracks;
|
||||
|
||||
bool ParseFile(std::vector<Track> &out_tracks,
|
||||
const std::string &file_and_path);
|
||||
|
||||
void draw(const Track &track);
|
||||
|
||||
#endif
|
26
Xml.cpp
Normal file
26
Xml.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "Xml.h"
|
||||
|
||||
using namespace rapidxml;
|
||||
|
||||
xml_node<>* recursive_find_next_node(xml_node<> *node, const std::string &node_name)
|
||||
{
|
||||
if(!node)
|
||||
return nullptr;
|
||||
|
||||
// go through each sibling node...
|
||||
for(; node; node = node->next_sibling())
|
||||
{
|
||||
if(node->name() == node_name)
|
||||
return node;
|
||||
|
||||
// first make sure none of the children nodes have this name, too.
|
||||
if(node->first_node() != nullptr)
|
||||
{
|
||||
auto child_node = recursive_find_next_node(node->first_node(), node_name);
|
||||
if(child_node)
|
||||
return child_node;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
13
Xml.h
Normal file
13
Xml.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef XML_H
|
||||
#define XML_H
|
||||
|
||||
#include "rapidxml.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
rapidxml::xml_node<>* recursive_find_next_node(
|
||||
rapidxml::xml_node<> *node,
|
||||
const std::string &node_name
|
||||
);
|
||||
|
||||
#endif
|
172
main.cpp
172
main.cpp
@ -1,11 +1,13 @@
|
||||
#include "rapidxml.hpp"
|
||||
#include "camera/Camera.h"
|
||||
#include "Xml.h"
|
||||
#include "Track.h"
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <math.h> // fmod
|
||||
#include <unistd.h>
|
||||
@ -14,119 +16,41 @@
|
||||
GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */
|
||||
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
|
||||
|
||||
struct Point {
|
||||
float lat;
|
||||
float lon;
|
||||
float ele;
|
||||
};
|
||||
|
||||
static std::vector<std::vector<Point> > tracks;
|
||||
|
||||
bool ParseFile(std::vector<std::vector<Point>> &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 -2;
|
||||
}
|
||||
|
||||
std::string line = "";
|
||||
bool first = true;
|
||||
float diff_lat, diff_lon, diff_ele;
|
||||
std::vector<Point> track;
|
||||
while(std::getline(ifs, line))
|
||||
{
|
||||
// get starting position of field NAME
|
||||
auto lat = line.find("lat=\"");
|
||||
if(lat == std::string::npos)
|
||||
continue;
|
||||
// get ending position of field DATA
|
||||
auto lat_to = line.find("\"", lat);
|
||||
if(lat_to == std::string::npos)
|
||||
continue;
|
||||
|
||||
// get starting position of field NAME
|
||||
auto lon = line.find("lon=\"", lat_to);
|
||||
if(lon == std::string::npos)
|
||||
continue;
|
||||
// get ending position of field DATA
|
||||
auto lon_to = line.find("\"", lon);
|
||||
if(lon_to == std::string::npos)
|
||||
continue;
|
||||
|
||||
auto ele = line.find("<ele>", lon_to);
|
||||
if(ele == std::string::npos)
|
||||
continue;
|
||||
auto ele_to = line.find("</ele>", ele);
|
||||
if(ele_to == std::string::npos)
|
||||
continue;
|
||||
|
||||
Point p;
|
||||
try {
|
||||
p.lat = std::atof(line.substr(lat + 5, lat_to).c_str()) * 200;
|
||||
p.lon = std::atof(line.substr(lon + 5, lon_to).c_str()) * 200;
|
||||
p.ele = std::atof(line.substr(ele + 5, ele_to).c_str()) * 0.1;
|
||||
} catch (const std::exception &e) {
|
||||
std::cerr << "Error in file " << file_and_path
|
||||
<< ", line \"" << line << "\"."
|
||||
<< std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
track.push_back(p);
|
||||
}
|
||||
out_tracks.push_back(track);
|
||||
ifs.close();
|
||||
}
|
||||
Camera camera;
|
||||
|
||||
// TODO(dev):
|
||||
// As per https://www.opengl.org/resources/libraries/glut/spec3/node11.html
|
||||
// "Therefore, GLUT programs should not assume the window was created at the specified size or position.
|
||||
// A GLUT program should use the window's reshape callback to determine the true size of the window."
|
||||
|
||||
void draw(const std::vector<Point> &points)
|
||||
{
|
||||
// glLineWidth(1.0f);
|
||||
|
||||
// Draw bike path
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for(auto p : points)
|
||||
{
|
||||
auto val = (50 + (p.ele * 10)) / 180.0;
|
||||
glColor3d(val, val, val);
|
||||
glVertex3f(p.lat, p.ele, p.lon);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// usleep(100000);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void draw_origin()
|
||||
{
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// X:
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glColor3d(0, 0, 0);
|
||||
glVertex3f(-10.0f, 0.0f, 0.0f);
|
||||
glColor3d(255, 0, 0);
|
||||
glVertex3f(-1.0f, 0.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glColor3d(0, 0, 0);
|
||||
glVertex3f(10.0f, 0.0f, 0.0f);
|
||||
glEnd();
|
||||
|
||||
// Y:
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(0.0f, -10.0f, 0.0f);
|
||||
glColor3d(0, 255, 0);
|
||||
glVertex3f(0.0f, -1.0f, 0.0f);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glColor3d(0, 0, 0);
|
||||
glVertex3f(0.0f, 10.0f, 0.0f);
|
||||
glEnd();
|
||||
|
||||
// Z:
|
||||
glColor3d(0, 0, 255);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(0.0f, 0.0f, -10.0f);
|
||||
glColor3d(0, 0, 255);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glColor3d(0, 0, 0);
|
||||
glVertex3f(0.0f, 0.0f, 10.0f);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@ -136,12 +60,16 @@ void display()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
|
||||
glLineWidth(1.0f);
|
||||
|
||||
//camera.RotateYaw(0.01);
|
||||
|
||||
static double asdf = -10.0;
|
||||
asdf += 0.02;
|
||||
if(asdf > 15.0)
|
||||
asdf = -15.0;
|
||||
gluLookAt(-15, 12.0, -asdf, /* eye is at */
|
||||
0.0, 6.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 */
|
||||
|
||||
draw_origin();
|
||||
@ -197,18 +125,55 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
for(auto file : files)
|
||||
{
|
||||
// NOTE(dev): OLD:
|
||||
if(!ParseFile(tracks, file))
|
||||
return -3; // couldn't parse file
|
||||
ParseFile(tracks, file);
|
||||
|
||||
// NOTE(dev): NEW:
|
||||
// TODO(dev): Xml Parser
|
||||
// NORMALIZE TRACKS TO VIEWPORT:
|
||||
bool first = true;
|
||||
float min_lat, min_lon, min_ele, max_lat, max_lon, max_ele;
|
||||
for(auto &track : tracks)
|
||||
{
|
||||
for(auto &p : track.points)
|
||||
{
|
||||
if(first)
|
||||
{
|
||||
first = false;
|
||||
min_lat = max_lat = p.lat;
|
||||
min_lon = max_lon = p.lon;
|
||||
min_ele = max_ele = p.ele;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p.lat < min_lat)
|
||||
min_lat = p.lat;
|
||||
else if(p.lat > max_lat)
|
||||
max_lat = p.lat;
|
||||
if(p.lon < min_lon)
|
||||
min_lon = p.lon;
|
||||
else if(p.lon > max_lon)
|
||||
max_lon = p.lon;
|
||||
if(p.ele < min_ele)
|
||||
min_ele = p.ele;
|
||||
else if(p.ele > max_ele)
|
||||
max_ele = p.ele;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 &p : track.points)
|
||||
{
|
||||
p.lat -= lat_diff;
|
||||
p.lon -= lon_diff;
|
||||
p.ele -= ele_diff;
|
||||
}
|
||||
}
|
||||
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA | GLUT_MULTISAMPLE);
|
||||
glutInit(&argc, argv);
|
||||
glutCreateWindow("test opengl program");
|
||||
glutCreateWindow("3D GPX Viewer");
|
||||
glutDisplayFunc(display);
|
||||
|
||||
// NOTE(dev): lmfao:
|
||||
@ -216,6 +181,9 @@ int main(int argc, char *argv[])
|
||||
glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR);
|
||||
|
||||
init();
|
||||
camera.Init();
|
||||
camera.Fly(50);
|
||||
camera.RotatePitch(-89 * M_PI / 180.0);
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
|
2596
rapidxml.hpp
Executable file
2596
rapidxml.hpp
Executable file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user