How to read an IGC file¶
aerofiles has the aerofiles.igc.Reader class for reading IGC files:
with open('track.igc', 'r') as f:
igc = Reader().read(f)
The result is returned in igc which is a dict containing the IGC
file content. The most important keys are header and
fix_records. The other keys are mainly self explanatory. Every
value consists of two elements. The first is an array of error
messages for this key and the second one is a list of the
elements. For example igc["fix_records"][0] is a list of possible
errors (normally empty) and igc["fix_records"][1] is a list of the
fixes. See below for more details.
The constructor of aerofiles.igc.Reader takes an optional
argument skip_duplicates which defaults to False. If you set
it to true, then all GPS fixes which contain the same time as a
previous one will be skipped and not returned as a result.
Headers¶
The header consists of all header elements of the IGC file. Here is an
example of igc["header"][1]:
{'competition_class': '15m Motor Glider',
'competition_id': 'XYZ-78910',
'copilot': 'Smith-Barry John A',
'firmware_revision': '6.4',
'fix_accuracy': 35,
'glider_model': 'Schleicher ASH-25',
'glider_registration': 'ABCD-1234',
'gps_channels': 12,
'gps_datum': 'WGS-1984',
'gps_manufacturer': 'MarconiCanada',
'gps_max_alt': {'unit': 'm', 'value': 10000},
'gps_model': 'Superstar',
'hardware_revision': '3.0',
'logger_manufacturer': 'Manufacturer',
'logger_model': 'Model',
'pilot': 'Bloggs Bill D',
'pressure_sensor_manufacturer': 'Sensyn',
'pressure_sensor_max_alt': {'unit': 'm', 'value': 11000},
'pressure_sensor_model': 'XYZ1111',
'time_zone_offset': 3.0,
'utc_date': datetime.date(2001, 7, 16)}],
}
GPS Fixes¶
The following example IGC file is read. For simplicity it is very short and misses some mandatory fields:
HFDTE160701
HFTZNTIMEZONE:-6.00
B1602405407121N00249342WA002800042120509950
The GPS fixes are found in igc["fix_records"][1] and are a list of
dicts for every fix:
[{'ENL': 950,
'FXA': 205,
'SIU': 9,
'datetime': datetime.datetime(2001, 7, 16, 16, 2, 40, tzinfo=<aerofiles.util.timezone.TimeZoneFix object at 0x7fd061c02390>),
'datetime_local': datetime.datetime(2001, 7, 16, 10, 2, 40, tzinfo=<aerofiles.util.timezone.TimeZoneFix object at 0x7fd061c02120>),
'gps_alt': 421,
'lat': 54.11868333333334,
'lon': -2.8223666666666665,
'pressure_alt': 280,
'time': datetime.time(16, 2, 40),
'validity': 'A'}]
Most values should be self explanatory.
An important aspect are dates, times and timezones. IGC files store
all times in UTC. This means that "time" is the time of the fix as
found in the IGC and it is always in UTC [1]. The times of the fixes
are always increasing as the recording takes part. Normally a flight
is recorded during daylight and so you may assume, that there is no
roll over taking part. However, as IGC files are recorded in UTC this
might not be true. If you record a flight in timezone “-06:00” and you
start your flight at “17:59”, then UTC time is already “23:59”. The
B record one minute later will be at “00:00”, so it is less than
the previous time. You have to handle this yourself, if you use
"time".
A solution for this problem is "datetime", which is available since
aerofiles v1.4.0. It is a timezone aware instance of
datetime.datetime with a timezone of UTC. The date part is taking
from the header field HFDTE and the time is taken from the B
record. It will be always incrementing, as it also contains a date
(which may increase as well in the above example).
If your IGC file contains a HFTZN header telling the timezone
where the recording took place, then you will also find
"datetime_local". It is the datetime of the fix converted to local
time with the given timezone from the header. This is probably the
datetime, you are looking for. Please note, that the IGC file
specification does not handle a change of timezone during flight. So
if you cross borders to a different timezone or daylight savings
change occur during flight, then there is no way to record this change
in an IGC file. The times of the fixes will then be wrong.