diff --git a/makefile b/makefile index f6e56d1..226bbda 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ all: - gcc -Wall -g src/graphics.c src/linkage.c src/igc.c src/main.c -I./include -L./lib -lraylib -lGL -lEGL -lGLESv2 -lm -lpthread -ldl -lrt -lX11 + gcc -Wall -g src/coords.c src/graphics.c src/linkage.c src/igc.c src/main.c -I./include -L./lib -lraylib -lGL -lEGL -lGLESv2 -lm -lpthread -ldl -lrt -lX11 clean: rm a.out diff --git a/src/coords.c b/src/coords.c new file mode 100644 index 0000000..3a9135e --- /dev/null +++ b/src/coords.c @@ -0,0 +1,51 @@ +/* + * IGC parser - coordinates transformation + * @brief parse IGC file, get all data points, compute average horizontal/vertical speed, print to STDOUT + * + * As per standard: https://xp-soaring.github.io/igc_file_format/igc_format_2008.html + * https://xp-soaring.github.io/igc_file_format/igc_fr_specification_with_al8_2023-2-1_0.pdf + * + * @author xamidev + * @license GNU GPL v3 + */ + +#include "igc.h" +#include + +// Approximate radius of the Earth, in kilometers +#define EARTH_RADIUS 6371*1000 + +void compute_decimal_coords(struct IGC_DataPoint* dp) +{ + double lat = dp->lat.deg + dp->lat.min/60.0 + dp->lat.sec/3600.0; + double lon = dp->lon.deg + dp->lon.min/60.0 + dp->lon.sec/3600.0; + + if (dp->lat.cardinal == SOUTH) + { + lat = -lat; + } + + if (dp->lon.cardinal == WEST) + { + lon = -lon; + } + + dp->lat.decimal = lat; + dp->lon.decimal = lon; + + printf("DEBUG: %lf, %lf\n", dp->lat.decimal, dp->lon.decimal); +} + +void compute_cartesian_coords(struct IGC_DataPoint* dp) +{ + double rad_lat = dp->lat.decimal*(M_PI/180.0); + double rad_lon = dp->lon.decimal*(M_PI/180.0); + printf("DEBUG: %lf, %lf\n", rad_lat, rad_lon); + + double x = EARTH_RADIUS * cos(rad_lat) * cos(rad_lon); + double y = EARTH_RADIUS * cos(rad_lat) * sin(rad_lon); + + dp->lon.meters = x; + dp->lat.meters = y; + printf("DEBUG: x=%lf, y=%lf\n", x, y); +} diff --git a/src/coords.h b/src/coords.h new file mode 100644 index 0000000..6ca0ba6 --- /dev/null +++ b/src/coords.h @@ -0,0 +1,18 @@ +/* + * IGC parser + * @brief parse IGC file, get all data points, compute average horizontal/vertical speed, print to STDOUT + * + * As per standard: https://xp-soaring.github.io/igc_file_format/igc_format_2008.html + * https://xp-soaring.github.io/igc_file_format/igc_fr_specification_with_al8_2023-2-1_0.pdf + * + * @author xamidev + * @license GNU GPL v3 + */ + +#ifndef COORDS_H +#define COORDS_H + +void compute_decimal_coords(struct IGC_DataPoint* dp); +void compute_cartesian_coords(struct IGC_DataPoint* dp); + +#endif diff --git a/src/igc.c b/src/igc.c index 1757c99..6fb3030 100644 --- a/src/igc.c +++ b/src/igc.c @@ -16,6 +16,7 @@ #include #include "igc.h" #include "linkage.h" +#include "coords.h" struct IGC_DataPoint* parse_datapoint(char* line) { @@ -58,6 +59,8 @@ struct IGC_DataPoint* parse_datapoint(char* line) void show_datapoint(struct IGC_DataPoint* dp) { printf("Data point: %02d:%02d:%02d | %d°%d'%d\"%c %d°%d'%d\"%c | Baro: %dm GPS: %dm\n", dp->hour, dp->minute, dp->second, dp->lat.deg, dp->lat.min, dp->lat.sec, dp->lat.cardinal, dp->lon.deg, dp->lon.min, dp->lon.sec, dp->lon.cardinal, dp->baro_alt, dp->gps_alt); + compute_decimal_coords(dp); + compute_cartesian_coords(dp); } void show_header_info(struct IGC_Header* hdr) diff --git a/src/igc.h b/src/igc.h index 6e63aa3..6682dc9 100644 --- a/src/igc.h +++ b/src/igc.h @@ -13,6 +13,7 @@ #define NAME_MAX 256 #define TMP_SIZE 8 +#include #include "linkage.h" enum IGC_RecordType @@ -41,10 +42,17 @@ enum Cardinals struct Coord { + // Sexagesimal (Deg/min/sec Cardinal) char cardinal; int deg; int min; int sec; + + // Decimal degrees + double decimal; + + // Cartesian units (meters) + double meters; }; struct IGC_Header