GPX-Visualizer/main.cpp
2021-03-14 00:07:29 -05:00

223 lines
5.0 KiB
C++

#include "rapidxml.hpp"
#include <GL/glut.h>
#include <experimental/filesystem>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <math.h> // fmod
#include <unistd.h>
#include <vector>
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();
}
// 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:
glColor3d(255, 0, 0);
glVertex3f(-1.0f, 0.0f, 0.0f);
glColor3d(0, 0, 0);
glVertex3f(10.0f, 0.0f, 0.0f);
// Y:
glColor3d(0, 255, 0);
glVertex3f(0.0f, -1.0f, 0.0f);
glColor3d(0, 0, 0);
glVertex3f(0.0f, 10.0f, 0.0f);
// Z:
glColor3d(0, 0, 255);
glVertex3f(0.0f, 0.0f, -10.0f);
glColor3d(0, 0, 0);
glVertex3f(0.0f, 0.0f, 10.0f);
glEnd();
}
void display()
{
// RESET:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
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 */
0.0, 1.0, 0.0); /* up is in positive Y direction */
draw_origin();
// DRAW TRACKS:
for(auto track : tracks)
draw(track);
glutSwapBuffers();
}
void init()
{
// dvereb:
srand(time(NULL));
glColor3d(1.0, 1.0, 1.0);
/* Enable a single OpenGL light. */
// glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
// glLightfv(GL_LIGHT0, GL_POSITION, light_position);
// glEnable(GL_LIGHT0);
// glEnable(GL_LIGHTING);
/* Use depth buffering for hidden surface elimination. */
glEnable(GL_DEPTH_TEST);
/* Setup the view of the cube. */
glMatrixMode(GL_PROJECTION);
gluPerspective( /* field of view in degree */ 70.0,
/* aspect ratio */ 1.0,
/* Z near */ 1.0, /* Z far */ 1000.0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(-10.0, 25.0, -10.0, /* eye is at */
0.0, 0.0, 0.0, /* center is at */
0.0, 1.0, 0.0); /* up is in positive Y direction */
}
int main(int argc, char *argv[])
{
if(argc != 2)
{
std::cerr << "You pust pass the folder which contains gpx files." << std::endl;
return -1;
}
std::vector<std::string> files;
for(const auto& entry : std::experimental::filesystem::directory_iterator(argv[1]))
{
auto extension = entry.path().extension();
if(extension == ".gpx")
files.push_back(entry.path().string());
}
for(auto file : files)
{
// NOTE(dev): OLD:
if(!ParseFile(tracks, file))
return -3; // couldn't parse file
// NOTE(dev): NEW:
// TODO(dev): Xml Parser
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA | GLUT_MULTISAMPLE);
glutInit(&argc, argv);
glutCreateWindow("test opengl program");
glutDisplayFunc(display);
// NOTE(dev): lmfao:
// glutSetCursor(GLUT_CURSOR_SPRAY);
glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR);
init();
glutMainLoop();
return 0;
}