libigc is a Python library designed to parse and analyze IGC (International Gliding Commission) flight recorder logs. It provides functionality to detect thermals, analyze flight patterns, and extract valuable information from glider flight data.
You can install libigc using pip:
pip install libigc
Here's a simple example of how to use libigc to parse an IGC file and extract basic flight information:
from libigc import Flight
# Parse an IGC file
flight = Flight.create_from_file("path/to/your/file.igc")
# Check if the flight is valid
if flight.valid:
print("Flight is valid")
print(f"Takeoff time: {flight.takeoff_fix.timestamp}")
print(f"Landing time: {flight.landing_fix.timestamp}")
print(f"Number of thermals: {len(flight.thermals)}")
else:
print("Flight is invalid")
print("Reasons:", flight.notes)
libigc provides various methods to analyze flight data:
# Iterate through thermals
for i, thermal in enumerate(flight.thermals):
print(f"Thermal {i+1}:")
print(f" Start time: {thermal.enter_fix.timestamp}")
print(f" End time: {thermal.exit_fix.timestamp}")
print(f" Duration: {thermal.time_change()} seconds")
print(f" Altitude gain: {thermal.alt_change()} meters")
print(f" Average vertical velocity: {thermal.vertical_velocity():.2f} m/s")
# Analyze glides
for i, glide in enumerate(flight.glides):
print(f"Glide {i+1}:")
print(f" Start time: {glide.enter_fix.timestamp}")
print(f" End time: {glide.exit_fix.timestamp}")
print(f" Duration: {glide.time_change()} seconds")
print(f" Distance: {glide.track_length:.2f} km")
print(f" Average speed: {glide.speed():.2f} km/h")
print(f" Glide ratio: {glide.glide_ratio():.2f}")
# Access individual fixes
for fix in flight.fixes:
print(f"Time: {fix.timestamp}, Lat: {fix.lat}, Lon: {fix.lon}, Alt: {fix.alt}")
libigc provides functions to export flight data in various formats:
from libigc.lib.dumpers import (
dump_thermals_to_wpt_file,
dump_thermals_to_cup_file,
dump_flight_to_kml,
dump_flight_to_csv
)
# Dump thermals to a .wpt file
dump_thermals_to_wpt_file(flight, "thermals.wpt")
# Dump thermals to a .cup file (SeeYou format)
dump_thermals_to_cup_file(flight, "thermals.cup")
# Dump flight to KML format
dump_flight_to_kml(flight, "flight.kml")
# Dump flight data to CSV files
dump_flight_to_csv(flight, "track.csv", "thermals.csv")
libigc supports parsing and validating flight tasks:
from libigc import Task, Turnpoint
# Create a task from an LK8000 task file
task = Task.create_from_lkt_file("task.lkt")
# Or create a task manually
turnpoints = [
Turnpoint(lat=50.0, lon=14.0, radius=3.0, kind="start_exit"),
Turnpoint(lat=51.0, lon=15.0, radius=0.5, kind="cylinder"),
Turnpoint(lat=52.0, lon=16.0, radius=3.0, kind="goal_cylinder")
]
task = Task(turnpoints, start_time=36000, end_time=64800) # 10:00 to 18:00
# Check if the flight completed the task
reached_turnpoints = task.check_flight(flight)
if len(reached_turnpoints) == len(task.turnpoints):
print("Task completed!")
else:
print(f"Reached {len(reached_turnpoints)} out of {len(task.turnpoints)} turnpoints")
libigc comes with a demo script that can be run from the command line:
python -m libigc.examples.libigc_demo path/to/your/file.igc
This will print a summary of the flight and save thermal and track data to CSV files.
The Flight
class is the main entry point for working with IGC files.
create_from_file(filename)
: Creates a Flight object from an IGC file._check_altitudes()
: Validates altitude data._compute_ground_speeds()
: Calculates ground speeds._compute_flight()
: Determines flying status for each fix._compute_circling()
: Detects circling (thermalling) behavior._find_thermals()
: Identifies thermal segments in the flight.fixes
: List of GNSSFix objects.thermals
: List of Thermal objects.glides
: List of Glide objects.takeoff_fix
: GNSSFix object representing takeoff.landing_fix
: GNSSFix object representing landing.alt_source
: Altitude data source ("PRESS" or "GNSS").valid
: Boolean indicating if the flight data is valid.notes
: List of notes about the flight data validity.Represents a single fix in the IGC file.
timestamp
: Unix timestamp of the fix.lat
: Latitude in degrees.lon
: Longitude in degrees.alt
: Altitude in meters.gsp
: Ground speed in km/h.bearing
: Aircraft bearing in degrees.bearing_change_rate
: Rate of bearing change in degrees/second.flying
: Boolean indicating if the aircraft is flying at this fix.circling
: Boolean indicating if the aircraft is circling at this fix.Represents a thermal detected in the flight.
time_change()
: Duration of the thermal in seconds.alt_change()
: Altitude gained in the thermal in meters.vertical_velocity()
: Average vertical velocity in m/s.enter_fix
: GNSSFix object at the start of the thermal.exit_fix
: GNSSFix object at the end of the thermal.Represents a glide between thermals.
time_change()
: Duration of the glide in seconds.speed()
: Average ground speed during the glide in km/h.alt_change()
: Altitude change during the glide in meters.glide_ratio()
: Glide ratio (distance traveled / altitude lost).enter_fix
: GNSSFix object at the start of the glide.exit_fix
: GNSSFix object at the end of the glide.track_length
: Total track length of the glide in kilometers.Represents a flight task.
create_from_lkt_file(filename)
: Creates a Task object from an LK8000 task file.check_flight(flight)
: Checks if a Flight object has completed the task.turnpoints
: List of Turnpoint objects.start_time
: Task start time (seconds past midnight).end_time
: Task end time (seconds past midnight).Represents a single turnpoint in a task.
in_radius(fix)
: Checks if a GNSSFix is within the turnpoint's radius.lat
: Latitude of the turnpoint in degrees.lon
: Longitude of the turnpoint in degrees.radius
: Radius of the turnpoint cylinder in kilometers.kind
: Type of turnpoint (e.g., "start_exit", "cylinder", "goal_cylinder").If you find an IGC file that libigc doesn't handle correctly, please open an issue on the GitHub repository. Include the problematic IGC file and a description of the expected behavior.
To contribute code:
libigc is released under the MIT License. See the LICENSE file in the repository for full details.
To publish to PyPI, you'll need to:
pip install twine
bumpversion patch --allow-dirty
(or minor/major) to update the version number in setup.py
python setup.py sdist bdist_wheel
twine upload dist/*