Incomplete parser
This commit is contained in:
BIN
.igc.c.swp
Normal file
BIN
.igc.c.swp
Normal file
Binary file not shown.
3320
20bf1b30-2b33-4174-87aa-abe78cf1db7c.igc
Normal file
3320
20bf1b30-2b33-4174-87aa-abe78cf1db7c.igc
Normal file
File diff suppressed because it is too large
Load Diff
7
README.md
Normal file
7
README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# igcp: IGC flight data parser
|
||||||
|
|
||||||
|
Work in progress.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
GNU GPL v3
|
||||||
89
igc.c
Normal file
89
igc.c
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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 <xamidev@riseup.net>
|
||||||
|
* @license GNU GPL v3
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "igc.h"
|
||||||
|
|
||||||
|
void parse_igc_file(FILE* fp)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
char* line = NULL;
|
||||||
|
|
||||||
|
while (getline(&line, &len, fp) != -1)
|
||||||
|
{
|
||||||
|
switch(line[0])
|
||||||
|
{
|
||||||
|
case DATAPOINT:
|
||||||
|
struct IGC_DataPoint* dp = (struct IGC_DataPoint*)malloc(sizeof(struct IGC_DataPoint));
|
||||||
|
char hour[3], min[3], sec[3] = {0};
|
||||||
|
char lat_d[3], lat_m[3], lat_s[4] = {0};
|
||||||
|
char lon_d[4], lon_m[3], lon_s[4] = {0};
|
||||||
|
|
||||||
|
memcpy(hour, line+1, 2);
|
||||||
|
memcpy(min, line+3, 2);
|
||||||
|
memcpy(sec, line+5, 2);
|
||||||
|
memcpy(lat_d, line+7, 2);
|
||||||
|
memcpy(lat_m, line+9, 2);
|
||||||
|
memcpy(lat_s, line+11, 3);
|
||||||
|
memcpy(lon_d, line+15, 3);
|
||||||
|
memcpy(lon_m, line+18, 2);
|
||||||
|
memcpy(lon_s, line+20, 3);
|
||||||
|
|
||||||
|
dp->hour = atoi(hour);
|
||||||
|
dp->minute = atoi(min);
|
||||||
|
dp->second = atoi(sec);
|
||||||
|
dp->lat.deg = atoi(lat_d);
|
||||||
|
dp->lat.min = atoi(lat_m);
|
||||||
|
dp->lat.sec = atoi(lat_s);
|
||||||
|
dp->lat.cardinal = line[14] == NORTH ? NORTH : SOUTH;
|
||||||
|
dp->lon.deg = atoi(lon_d);
|
||||||
|
dp->lon.min = atoi(lon_m);
|
||||||
|
dp->lon.sec = atoi(lon_s);
|
||||||
|
dp->lon.cardinal = line[23] == EAST ? EAST : WEST;
|
||||||
|
|
||||||
|
printf("%s", line);
|
||||||
|
printf("Data point: %d:%d:%d | %d°%d'%d\"%c %d°%d'%d\"%c\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);
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <file>\n", argv[0]);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char filename[NAME_MAX] = {0};
|
||||||
|
strncpy(filename, argv[1], NAME_MAX-1);
|
||||||
|
|
||||||
|
FILE* fp = fopen(filename, "r");
|
||||||
|
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
printf("Couldn't open file %s\n", filename);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_igc_file(fp);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
65
igc.h
Normal file
65
igc.h
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* IGC parser
|
||||||
|
* @brief parse IGC file, get all data points, compute average horizontal/vertical speed, print to STDOUT
|
||||||
|
*
|
||||||
|
* @author xamidev <xamidev@riseup.net>
|
||||||
|
* @license GNU GPL v3
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IGC_H
|
||||||
|
#define IGC_H
|
||||||
|
|
||||||
|
#define NAME_MAX 256
|
||||||
|
#define TMP_SIZE 8
|
||||||
|
|
||||||
|
void parse_igc_file(FILE* fp);
|
||||||
|
|
||||||
|
enum IGC_RecordType
|
||||||
|
{
|
||||||
|
MANUFACTURER = 'A',
|
||||||
|
METADATA = 'H',
|
||||||
|
EXTENSION = 'I',
|
||||||
|
J_EXTENSION = 'J',
|
||||||
|
DECLARATION = 'C',
|
||||||
|
SATELLITES = 'F',
|
||||||
|
DATAPOINT = 'B',
|
||||||
|
DIFFERENTIAL_GPS = 'D',
|
||||||
|
PILOT_EVENT = 'E',
|
||||||
|
GEN_PURPOSE_PLACEHOLDER = 'K',
|
||||||
|
COMMENT = 'L',
|
||||||
|
SEC_KEY = 'G'
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Cardinals
|
||||||
|
{
|
||||||
|
NORTH = 'N',
|
||||||
|
SOUTH = 'S',
|
||||||
|
EAST = 'E',
|
||||||
|
WEST = 'W'
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Coord
|
||||||
|
{
|
||||||
|
char cardinal;
|
||||||
|
int deg;
|
||||||
|
int min;
|
||||||
|
int sec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IGC_DataPoint
|
||||||
|
{
|
||||||
|
// timestamp
|
||||||
|
int hour;
|
||||||
|
int minute;
|
||||||
|
int second;
|
||||||
|
|
||||||
|
// coordinates
|
||||||
|
struct Coord lat;
|
||||||
|
struct Coord lon;
|
||||||
|
|
||||||
|
// altitude
|
||||||
|
int baro_alt;
|
||||||
|
int gps_alt;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user