Header parsing
This commit is contained in:
@@ -4,6 +4,11 @@ Work in progress.
|
|||||||
|
|
||||||
Goals are: parsing an IGC file containing flight data, giving analytics about the flight, and if I really have time to kill, making some kind of (3D??) view of the flight..
|
Goals are: parsing an IGC file containing flight data, giving analytics about the flight, and if I really have time to kill, making some kind of (3D??) view of the flight..
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- header parsing
|
||||||
|
- data point doubly linked list
|
||||||
|
- Raylib 3d 3rd person flight line visualization????
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
GNU GPL v3
|
GNU GPL v3
|
||||||
|
|||||||
69
igc.c
69
igc.c
@@ -49,18 +49,62 @@ struct IGC_DataPoint* parse_datapoint(char* line)
|
|||||||
dp->lon.cardinal = line[23] == EAST ? EAST : WEST;
|
dp->lon.cardinal = line[23] == EAST ? EAST : WEST;
|
||||||
dp->baro_alt = atoi(baro_alt);
|
dp->baro_alt = atoi(baro_alt);
|
||||||
dp->gps_alt = atoi(gps_alt);
|
dp->gps_alt = atoi(gps_alt);
|
||||||
|
|
||||||
printf("Data point: %d:%d:%d | %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);
|
|
||||||
|
|
||||||
return dp;
|
return dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_header_record(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_header_info(struct IGC_Header* hdr)
|
||||||
|
{
|
||||||
|
printf("*** Flight information:\nDate: %02d/%02d/%02d\nPilot: %sCopilot: %sAircraft: %sRegistration: %s", hdr->day, hdr->month, hdr->year, hdr->pilot_name, hdr->crew2_name, hdr->aircraft_name, hdr->aircraft_registration_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IGC_Header* parse_header_record(struct IGC_Header* hdr, char* line)
|
||||||
{
|
{
|
||||||
if (strncmp(line, "HFDTEDATE", 9) == 0)
|
if (strncmp(line, "HFDTEDATE", 9) == 0)
|
||||||
{
|
{
|
||||||
|
strtok(line, ":");
|
||||||
|
char* date_str = strtok(NULL, ":");
|
||||||
|
char day[3], month[3], year[3] = {0};
|
||||||
|
|
||||||
|
memcpy(day, date_str, 2);
|
||||||
|
memcpy(month, date_str+2, 2);
|
||||||
|
memcpy(year, date_str+4, 2);
|
||||||
|
|
||||||
|
hdr->day = atoi(day);
|
||||||
|
hdr->month = atoi(month);
|
||||||
|
hdr->year = atoi(year);
|
||||||
}
|
}
|
||||||
|
if (strncmp(line, "HFPLTPILOTINCHARGE", 18) == 0)
|
||||||
|
{
|
||||||
|
strtok(line, ":");
|
||||||
|
strncpy(hdr->pilot_name, strtok(NULL, ":"), SMALL_NAME_MAX);
|
||||||
|
}
|
||||||
|
if (strncmp(line, "HFCM2CREW2", 10) == 0)
|
||||||
|
{
|
||||||
|
strtok(line, ":");
|
||||||
|
strncpy(hdr->crew2_name, strtok(NULL, ":"), SMALL_NAME_MAX);
|
||||||
|
}
|
||||||
|
if (strncmp(line, "HFGTYGLIDERTYPE", 15) == 0)
|
||||||
|
{
|
||||||
|
strtok(line, ":");
|
||||||
|
strncpy(hdr->aircraft_name, strtok(NULL, ":"), SMALL_NAME_MAX);
|
||||||
|
}
|
||||||
|
if (strncmp(line, "HFGIDGLIDERID", 13) == 0)
|
||||||
|
{
|
||||||
|
strtok(line, ":");
|
||||||
|
strncpy(hdr->aircraft_registration_no, strtok(NULL, ":"), SMALL_NAME_MAX);
|
||||||
|
}
|
||||||
|
if (strncmp(line, "HFDTMGPSDATUM", 13) == 0)
|
||||||
|
{
|
||||||
|
strtok(line, ":");
|
||||||
|
strncpy(hdr->gps_datum, strtok(NULL, ":"), SMALL_NAME_MAX);
|
||||||
|
}
|
||||||
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_igc_file(FILE* fp)
|
void parse_igc_file(FILE* fp)
|
||||||
@@ -68,23 +112,36 @@ void parse_igc_file(FILE* fp)
|
|||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char* line = NULL;
|
char* line = NULL;
|
||||||
|
|
||||||
|
struct IGC_Header* hdr = (struct IGC_Header*)calloc(1, sizeof(struct IGC_Header));
|
||||||
|
|
||||||
while (getline(&line, &len, fp) != -1)
|
while (getline(&line, &len, fp) != -1)
|
||||||
{
|
{
|
||||||
switch(line[0])
|
switch(line[0])
|
||||||
{
|
{
|
||||||
|
case MANUFACTURER:
|
||||||
|
printf("Manufacturer info: %s", line);
|
||||||
|
break;
|
||||||
|
case COMMENT:
|
||||||
|
printf("Comment: %s", line);
|
||||||
|
break;
|
||||||
case DATAPOINT:
|
case DATAPOINT:
|
||||||
struct IGC_DataPoint* dp = parse_datapoint(line);
|
struct IGC_DataPoint* dp = parse_datapoint(line);
|
||||||
|
// show_datapoint(dp);
|
||||||
// Doubly linked list of points (so theyre joined in chronological order; opens possibilities for analysis later)
|
// Doubly linked list of points (so theyre joined in chronological order; opens possibilities for analysis later)
|
||||||
// append_datapoint(dp);
|
// append_datapoint(dp);
|
||||||
break;
|
break;
|
||||||
case HEADER:
|
case HEADER:
|
||||||
parse_header_record(line);
|
hdr = parse_header_record(hdr, line);
|
||||||
break;
|
break;
|
||||||
|
case SEC_KEY:
|
||||||
|
printf("Security key found: %s", line);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unrecognized record type '%c'\n", line[0]);
|
printf("Unhandled record type '%c'\n", line[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
show_header_info(hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
|
|||||||
33
igc.h
33
igc.h
@@ -9,11 +9,10 @@
|
|||||||
#ifndef IGC_H
|
#ifndef IGC_H
|
||||||
#define IGC_H
|
#define IGC_H
|
||||||
|
|
||||||
|
#define SMALL_NAME_MAX 32
|
||||||
#define NAME_MAX 256
|
#define NAME_MAX 256
|
||||||
#define TMP_SIZE 8
|
#define TMP_SIZE 8
|
||||||
|
|
||||||
void parse_igc_file(FILE* fp);
|
|
||||||
|
|
||||||
enum IGC_RecordType
|
enum IGC_RecordType
|
||||||
{
|
{
|
||||||
MANUFACTURER = 'A',
|
MANUFACTURER = 'A',
|
||||||
@@ -27,7 +26,7 @@ enum IGC_RecordType
|
|||||||
PILOT_EVENT = 'E',
|
PILOT_EVENT = 'E',
|
||||||
GEN_PURPOSE_PLACEHOLDER = 'K',
|
GEN_PURPOSE_PLACEHOLDER = 'K',
|
||||||
COMMENT = 'L',
|
COMMENT = 'L',
|
||||||
SEC_KEY = 'G'
|
SEC_KEY = 'G',
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Cardinals
|
enum Cardinals
|
||||||
@@ -53,16 +52,18 @@ struct IGC_Header
|
|||||||
int year;
|
int year;
|
||||||
|
|
||||||
// Not exhaustive
|
// Not exhaustive
|
||||||
char pilot_name[NAME_MAX] = {0};
|
char pilot_name[NAME_MAX];
|
||||||
char crew2_name[NAME_MAX] = {0};
|
char crew2_name[NAME_MAX];
|
||||||
char aircraft_name[NAME_MAX] = {0};
|
char aircraft_name[NAME_MAX];
|
||||||
char aircraft_registration_no[NAME_MAX] = {0};
|
char aircraft_registration_no[NAME_MAX];
|
||||||
char gps_datum[NAME_MAX] = {0};
|
char gps_datum[NAME_MAX];
|
||||||
char firmware_ver[NAME_MAX] = {0};
|
|
||||||
char hardware_ver[NAME_MAX] = {0};
|
// (not too important; ignored for now, may be part of "verbose" setting later)
|
||||||
char frtype[NAME_MAX] = {0};
|
char firmware_ver[NAME_MAX];
|
||||||
char press_alt_sensor[NAME_MAX] = {0};
|
char hardware_ver[NAME_MAX];
|
||||||
}
|
char frtype[NAME_MAX];
|
||||||
|
char press_alt_sensor[NAME_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
struct IGC_DataPoint
|
struct IGC_DataPoint
|
||||||
{
|
{
|
||||||
@@ -80,4 +81,10 @@ struct IGC_DataPoint
|
|||||||
int gps_alt;
|
int gps_alt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void parse_igc_file(FILE* fp);
|
||||||
|
struct IGC_DataPoint* parse_datapoint(char* line);
|
||||||
|
void show_datapoint(struct IGC_DataPoint* dp);
|
||||||
|
void show_header_info(struct IGC_Header* hdr);
|
||||||
|
struct IGC_Header* parse_header_record(struct IGC_Header* hdr, char* line);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user