Take-off airfield
The rule behind Take-off place and time zone. The time zone half is in Flight analysis §8.2.
Reference implementation: vulture-ios/Packages/Airports/Sources/Airports/AirportManager.swift
(airport(for coordinate:)) and vulture-ios/Packages/Persistence/Sources/Persistence/Extensions/CoreData/CoreFlight+CoreData.swift
(processTakeoff(with:)).
The airports table
Section titled “The airports table”vulture-ios/Packages/Airports/Sources/Airports/Resources/airports.json: 47,991 airfields, 4.6 MB
(1.3 MB gzipped). Built by vulture-ios/Scripts/prepare_airports.rb from the
OurAirports CSVs (public domain): only small_airport,
medium_airport and large_airport, with their radio frequencies.
One JSON array of objects with one-letter keys:
| Key | Field | Type | Example |
|---|---|---|---|
a | name: the OurAirports municipality, or the airfield name when there is none | string | "Genk" |
b | latitude | number | 51.0154 |
c | longitude | number | 5.52647 |
d | country, ISO 3166-1 alpha-2 (iso_country) | string | "BE" |
e | code: the OurAirports ident (the ICAO code where one exists; unique in the file) | string | "EBZW" |
f | frequencies, optional | [{ "s": description, "r": MHz }] | [{"s":"Genk radio","r":"120.4"}] |
g | elevation in feet, optional | string | "278" |
So a flight from Zwartberg (EBZW) reads “Genk 🇧🇪”: the town, not the airfield’s own name.
Every platform ships this file, byte for byte, so the same flight gets the same airfield everywhere. To refresh it, run the script in vulture-ios and copy the result.
Lookup
Section titled “Lookup”airport(for: coordinate):
- No coordinate → no airfield.
- Take the airfield with the smallest distance to the coordinate. The distance is the
Mappackage’sCLLocationCoordinate2D.distance(from:)(vulture-ios/Packages/Map/Sources/Map/Helpers/CLLocationCoordinate2D+Calculations.swift): a haversine on a sphere of radius 6,371 km, notCLLocation.distance. Android uses its port,core.geo.distance. (The time zone lookup is the other way round: it measures withCLLocation.) On a tie, the first one in file order wins (iOS sorts with Swift’s stable sort). - If that airfield is more than 3,000 m away, there is no airfield. Out-landing fields and hill sites usually end up here.
The result fills three fields on the flight:
| Flight field | From |
|---|---|
takeoffCode | e |
takeoffName | a |
takeoffCountryCode | d |
When it runs
Section titled “When it runs”- Once per flight, when the flight is first saved to the logbook. The coordinate is the
analysed take-off fix (
Flight.takeoffFix, the first fix with theTAKEOFFevent). isTakeoffProcessedis then set totrue, also when no airfield was found or the flight has no take-off fix. A processed flight is never looked up again, so a pilot’s edit or a sync from another device is never overwritten.- The fields and the flag are part of the flight’s sync record (sync schema).
Where it is used
Section titled “Where it is used”| Use | Rule |
|---|---|
| Flight detail | The code in the info tab; the location is takeoffName and the flag of takeoffCountryCode, joined by a space (iOS CoreFlight.takeoffLocation). |
| Logbook search | Matches takeoffCode and takeoffName. |
| Logbook countries filter | One entry per distinct takeoffCountryCode of the logbook’s flights. A country is matched without regard to case. The section is hidden when there are none. |
| Charron scoreboard | The start ICAO code is looked up by code (airport(for icao:), the first exact match); ZZZZ and unknown codes stay as sent. |
