libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions
airportdb.h File Reference
#include "avl.h"
#include "geom.h"
#include "list.h"
#include "helpers.h"
#include "htbl.h"
#include "thread.h"
Include dependency graph for airportdb.h:

Go to the source code of this file.

Data Structures

struct  airportdb_t
 
struct  ramp_start_t
 
struct  runway_end_t
 
struct  runway_t
 
struct  freq_info_t
 
struct  airport_t
 
struct  arpt_index_t
 

Macros

#define AIRPORTDB_IDENT_LEN   8
 
#define AIRPORTDB_ICAO_LEN   8
 
#define AIRPORTDB_IATA_LEN   4
 
#define AIRPORTDB_CC_LEN   4
 
#define recreate_cache(__db)   adb_recreate_cache((__db), 0)
 
#define find_nearest_airports   adb_find_nearest_airports
 
#define free_nearest_airport_list   adb_free_nearest_airport_list
 
#define set_airport_load_limit   adb_set_airport_load_limit
 
#define load_nearest_airport_tiles   adb_load_nearest_airport_tiles
 
#define unload_distant_airport_tiles   adb_unload_distant_airport_tiles
 
#define airport_lookup   adb_airport_lookup
 
#define airport_lookup_global   adb_airport_lookup_global
 
#define airport_lookup_by_ident   adb_airport_lookup_by_ident
 
#define airport_lookup_by_icao   adb_airport_lookup_by_icao
 
#define airport_lookup_by_iata   adb_airport_lookup_by_iata
 
#define airport_index_walk   adb_airport_index_walk
 
#define airport_find_runway   adb_airport_find_runway
 
#define matching_airport_in_tile_with_TATL    adb_matching_airport_in_tile_with_TATL
 
#define airportdb_xp11_airac_cycle   adb_airportdb_xp_airac_cycle
 

Enumerations

enum  ramp_start_type_t { RAMP_START_GATE , RAMP_START_HANGAR , RAMP_START_TIEDOWN , RAMP_START_MISC }
 
enum  rwy_surf_t {
  RWY_SURF_ASPHALT = 1 , RWY_SURF_CONCRETE = 2 , RWY_SURF_GRASS = 3 , RWY_SURF_DIRT = 4 ,
  RWY_SURF_GRAVEL = 5 , RWY_SURF_DRY_LAKEBED = 12 , RWY_SURF_WATER = 13 , RWY_SURF_SNOWICE = 14 ,
  RWY_SURF_TRANSPARENT = 15
}
 
enum  freq_type_t {
  FREQ_TYPE_REC , FREQ_TYPE_CTAF , FREQ_TYPE_CLNC , FREQ_TYPE_GND ,
  FREQ_TYPE_TWR , FREQ_TYPE_APP , FREQ_TYPE_DEP
}
 

Functions

void airportdb_create (airportdb_t *db, const char *xpdir, const char *cachedir)
 
void airportdb_destroy (airportdb_t *db)
 
void airportdb_lock (airportdb_t *db)
 
void airportdb_unlock (airportdb_t *db)
 
bool_t adb_recreate_cache (airportdb_t *db, int app_version)
 
list_tadb_find_nearest_airports (airportdb_t *db, geo_pos2_t my_pos)
 
void adb_free_nearest_airport_list (list_t *l)
 
void adb_set_airport_load_limit (airportdb_t *db, double limit)
 
void adb_load_nearest_airport_tiles (airportdb_t *db, geo_pos2_t my_pos)
 
void adb_unload_distant_airport_tiles (airportdb_t *db, geo_pos2_t my_pos)
 
airport_t * adb_airport_lookup (airportdb_t *db, const char *icao, geo_pos2_t pos)
 
airport_t * adb_airport_lookup_global (airportdb_t *db, const char *icao)
 
airport_t * adb_airport_lookup_by_ident (airportdb_t *db, const char *ident)
 
size_t adb_airport_lookup_by_icao (airportdb_t *db, const char *icao, void(*found_cb)(airport_t *airport, void *userinfo), void *userinfo)
 
size_t adb_airport_lookup_by_iata (airportdb_t *db, const char *iata, void(*found_cb)(airport_t *airport, void *userinfo), void *userinfo)
 
size_t adb_airport_index_walk (const airportdb_t *db, void(*found_cb)(const arpt_index_t *idx, void *userinfo), void *userinfo)
 
bool_t adb_airport_find_runway (airport_t *arpt, const char *rwy_id, runway_t **rwy_p, unsigned *end_p)
 
airport_t * adb_matching_airport_in_tile_with_TATL (airportdb_t *db, geo_pos2_t pos, const char *search_icao)
 
bool_t adb_airportdb_xp_airac_cycle (const char *xpdir, int *cycle)
 

Detailed Description

The airport database is the primary repository of knowledge about airports, runways and bounding boxes.

To start using the airport database, first initialize an airportdb_t using airportdb_create(). This doesn't actually populate the database. You will then want to call adb_recreate_cache() on the initialized database, to actually make sure it is up to date. Subsequently, you can start using the various airport lookup and query functions to interrogate the database. When done, use airportdb_destroy() to free the database and its resources.

See also
airportdb_create()
adb_recreate_cache()
airportdb_destroy()
adb_airport_lookup_global()
adb_airport_index_walk()

Implementation Details

The airport database is composed of two data structures:

Of these, apt_dat is the primary repository of knowledge - once an airport is gone from apt_dat, it is freed. An airport may or may not be geo-referenced in the geo_table. Once all loading of an airport is complete, it WILL be geo-referenced.

The geo_table is actually comprised of tile_t data structures. A tile_t refers to a 1x1 degree geographical tile at specific coordinates and contains its own private airport_t tree, which is again organized by abstract identifier, allowing us to step through all the airports in a tile or quickly locate one based on identifier.

During normal operation, not all airports from all over the world are loaded into memory, as that would use quite a bit of memory and delay startup. Instead, only the closets 9 tiles around the aircraft are present. New tiles are loaded as the aircraft repositions and the old ones are released. Loading a tile first populates the global apt_dat with all its airports, which are then geo-referenced in the newly created tile. Releasing a tile is the converse, ultimately ending in the airports being purged from apt_dat and freed.

The 9-tile rule can result in strange behavior close to the poles, where the code might think of close by airports as being very far away and thus not load them. Luckily, there are only about 4 airports beyond 80 degrees latitude (north or south), all of which are very special non-regular airports, so we just ignore those.

Airport Data Construction Method

For each airport, we need to obtain the following pieces of information:

  1. The abstract airport identifier.
    • Optional ICAO identifier, on a 1302 icao_code line.
    • Optional IATA identifier, on a 1302 iata_code line.
  2. The airport reference point latitude, longitude and elevation.
  3. The airport's transition altitude and transition level (if published).
  4. For each runway:
    • Runway width.
    • Each threshold's geographical position and elevation.
    • If the threshold is displaced, the amount of displacement.
    • For each end, if available, the optimal glidepath angle and threshold clearing height.

First we examine all installed scenery. That means going through each apt.dat declared in scenery_packs.ini and the global default apt dat to find these kinds of records:

Prior to X-Plane 11, apt.dat's didn't necessarily contain the '1302' records, so we had to pull those from the Airports.txt in the navdata directory for the built-in GNS430. Starting from X-Plane 11, Airports.txt is gone and this data has been relocated to the apt.dat.

A further complication of the absence of an Airports.txt is that this file contained both the GPA and TCH for each runway and although it did sometimes require some fuzzy matching to account for outdated scenery not exactly matching the navdata, we could obtain this information from one place.

So for X-Plane 11, we've implemented a new method of obtaining this information. By default, if a runway has an instrument approach (unless ifr_only=B_FALSE), it will have an entry in CIFP. Runway entries in APPCH-type procedures specify the TCH and GPA in columns 24 and 29 (ARINC 424 fields 4.1.9.1.85-89 and 4.1.9.1.103-106). We only use the first such occurence. If there are multiple approaches to the runway, they should all end up with the same TCH and GPA. This should cover pretty much every case. In the rare case where we don't get the TCH and GPA this way, we try a fallback mechanism. Almost every instrument approach runway has some kind of visual glideslope indication (VGSI) right next to it. We can extract the location of those from the apt.dat file. These VGSIs are located in the exact touchdown point and have a fixed GPA. So we simply look for a VGSI close to the runway's centerline and that is aligned with the runway, compute the longitudinal displacement of this indicator from the runway threshold and using the indicator's GPA compute the optimal TCH.

Definition in file airportdb.h.

Macro Definition Documentation

◆ airport_find_runway

#define airport_find_runway   adb_airport_find_runway

Definition at line 396 of file airportdb.h.

◆ airport_index_walk

#define airport_index_walk   adb_airport_index_walk

Definition at line 390 of file airportdb.h.

◆ airport_lookup

#define airport_lookup   adb_airport_lookup

Definition at line 370 of file airportdb.h.

◆ airport_lookup_by_iata

#define airport_lookup_by_iata   adb_airport_lookup_by_iata

Definition at line 386 of file airportdb.h.

◆ airport_lookup_by_icao

#define airport_lookup_by_icao   adb_airport_lookup_by_icao

Definition at line 382 of file airportdb.h.

◆ airport_lookup_by_ident

#define airport_lookup_by_ident   adb_airport_lookup_by_ident

Definition at line 378 of file airportdb.h.

◆ airport_lookup_global

#define airport_lookup_global   adb_airport_lookup_global

Definition at line 374 of file airportdb.h.

◆ AIRPORTDB_CC_LEN

#define AIRPORTDB_CC_LEN   4

Definition at line 264 of file airportdb.h.

◆ AIRPORTDB_IATA_LEN

#define AIRPORTDB_IATA_LEN   4

Definition at line 263 of file airportdb.h.

◆ AIRPORTDB_ICAO_LEN

#define AIRPORTDB_ICAO_LEN   8

Definition at line 262 of file airportdb.h.

◆ AIRPORTDB_IDENT_LEN

#define AIRPORTDB_IDENT_LEN   8

Definition at line 261 of file airportdb.h.

◆ airportdb_xp11_airac_cycle

#define airportdb_xp11_airac_cycle   adb_airportdb_xp_airac_cycle

Definition at line 405 of file airportdb.h.

◆ find_nearest_airports

#define find_nearest_airports   adb_find_nearest_airports

Definition at line 349 of file airportdb.h.

◆ free_nearest_airport_list

#define free_nearest_airport_list   adb_free_nearest_airport_list

Definition at line 353 of file airportdb.h.

◆ load_nearest_airport_tiles

#define load_nearest_airport_tiles   adb_load_nearest_airport_tiles

Definition at line 359 of file airportdb.h.

◆ matching_airport_in_tile_with_TATL

#define matching_airport_in_tile_with_TATL    adb_matching_airport_in_tile_with_TATL

Definition at line 400 of file airportdb.h.

◆ recreate_cache

#define recreate_cache (   __db)    adb_recreate_cache((__db), 0)

Definition at line 346 of file airportdb.h.

◆ set_airport_load_limit

#define set_airport_load_limit   adb_set_airport_load_limit

Definition at line 356 of file airportdb.h.

◆ unload_distant_airport_tiles

#define unload_distant_airport_tiles   adb_unload_distant_airport_tiles

Definition at line 366 of file airportdb.h.

Enumeration Type Documentation

◆ freq_type_t

Enumerator
FREQ_TYPE_REC 

Pre-recorded message ATIS, AWOS or ASOS

FREQ_TYPE_CTAF 

Common Traffic Advisory Frequency

FREQ_TYPE_CLNC 

Clearance Delivery

FREQ_TYPE_GND 

Ground

FREQ_TYPE_TWR 

Tower

FREQ_TYPE_APP 

Approach

FREQ_TYPE_DEP 

Departure

Definition at line 241 of file airportdb.h.

◆ ramp_start_type_t

enum ramp_start_type_t

Definition at line 168 of file airportdb.h.

◆ rwy_surf_t

enum rwy_surf_t

Definition at line 187 of file airportdb.h.

Function Documentation

◆ adb_airport_find_runway()

bool_t adb_airport_find_runway ( airport_t *  arpt,
const char *  rwy_id,
runway_t **  rwy_p,
unsigned *  end_p 
)

Performs a search in an airport for a runway matching a given runway ID at one of its ends.

Parameters
arptThe airport in which to perform to search.
rwy_idA 0-leading, NUL-terminated runway ID. This runway ID is matched against a either end of all runways at the airport. Examples: "05", "09R", "25C", "36L".
rwy_pMandatory return argument, which will be filled with a pointer to the matching runway structure, if found. If not found, this will be set to NULL.
end_pMandatory return argument, which will be filled with the index (0 or 1) of the matching runway_end structure, if found. If not found, this will be left unchanged. This index points into the ends field in the returned runway structure.
Returns
B_TRUE if the search was successful, B_FALSE otherwise.

Definition at line 3477 of file airportdb.c.

◆ adb_airport_index_walk()

size_t adb_airport_index_walk ( const airportdb_t db,
void(*)(const arpt_index_t *idx, void *userinfo)  found_cb,
void *  userinfo 
)

Provides a method for walking the entire airport index in the database. This is an entirely in-memory operation, so is relatively fast. However, keep in mind that there are typically >30,000 airports in the index, so don't do this too frequently.

Parameters
dbDatabase to perform the index walk on.
found_cbCallback which will be called with each airport in the index. The idx argument is filled with the arpt_index_t information about each airport found. The userinfo argument will be filled with whatever is provided in the userinfo argument to the adb_airport_index_walk() function.
found_cbYou may provide a NULL value for this argument, which will not call any callbacks and can be simply used to grab the return value of this function.
userinfoCustom pointer user info argument, which will be passed to the found_cb callback function in its second argument.
Returns
The total number of airport in the index. If you passed NULL for the found_cb argument, this will avoid walking the index entirely, simply returning the number of airports in the index.

Definition at line 3443 of file airportdb.c.

◆ adb_airport_lookup()

airport_t * adb_airport_lookup ( airportdb_t db,
const char *  icao,
geo_pos2_t  pos 
)

Legacy lookup function by ICAO ID. Airports without valid ICAO IDs won't show up here. The search is also restricted to a narrow zone around ‘pos’ (within a 3x3 degree square). Use adb_airport_lookup_global() for a search at any arbitrary location.

Definition at line 3382 of file airportdb.c.

◆ adb_airport_lookup_by_iata()

size_t adb_airport_lookup_by_iata ( airportdb_t db,
const char *  iata,
void(*)(airport_t *airport, void *userinfo)  found_cb,
void *  userinfo 
)

Lookup by IATA ID, with support for duplicates.

Arguments and return value are the same as adb_airport_lookup_by_icao(), except the lookup is done by the IATA code, rather than ICAO code.

Definition at line 3355 of file airportdb.c.

◆ adb_airport_lookup_by_icao()

size_t adb_airport_lookup_by_icao ( airportdb_t db,
const char *  icao,
void(*)(airport_t *airport, void *userinfo)  found_cb,
void *  userinfo 
)

Lookup by ICAO ID, with support for duplicates.

Parameters
dbDatabase in which to perform the lookup.
icaoThe 4-letter ICAO code to look for.
found_cbCallback which will be called with each airport matching the ICAO ID. The airport argument is filled with the airport information about each airport found. The userinfo argument will be filled with whatever is provided in the userinfo argument to the adb_airport_index_walk() function.
userinfoOptional user info pointer, which will be passed to every call to found_cb in its second argument.
Returns
The number of airports found.

Definition at line 3328 of file airportdb.c.

◆ adb_airport_lookup_by_ident()

airport_t * adb_airport_lookup_by_ident ( airportdb_t db,
const char *  ident 
)

Searches for an airport in the database by unique identifier.

Parameters
dbDatabase in which to perform the lookup.
identThe unique identifier of the airport. Please note that X-Plane's airport identifiers needn't be exactly the same as their ICAO codes. Some airports don't have ICAO codes, or their ident and ICAO code are inconsistent (e.g. due to the ICAO code having been changed by the relevant civil aviation authority).
Returns
The airport structure if the airport was found, or NULL if not.

Definition at line 3262 of file airportdb.c.

◆ adb_airport_lookup_global()

airport_t * adb_airport_lookup_global ( airportdb_t db,
const char *  icao 
)

Performs an airport lookup without having to know its approximate location first. This is a legacy fallback version for the airport_lookup_by_icao() function. Airports without valid ICAO IDs won't show up here.

Parameters
dbThe airportdb on which to perform the lookup.
icaoThe ICAO code of the airport. If there are duplicate airports matching the ICAO code, which airport is returned cannot be predicted.
Returns
The airport structure of the airport, if found, or NULL if not.

Definition at line 3411 of file airportdb.c.

◆ adb_airportdb_xp_airac_cycle()

bool_t adb_airportdb_xp_airac_cycle ( const char *  xpdir,
int *  cycle 
)

Attempts to determine the AIRAC cycle currently in use in the navdata on X-Plane 11/12. Sadly, there doesn't seem to be a nice data field for this, so we need to do some fulltext searching.

Parameters
xpdirA path to the X-Plane installation directory.
cycleMandatory return argument. If the search is successful, this will be filled with the AIRAC cycle number.
Returns
B_TRUE if the determination succeeded, B_FALSE otherwise.

Definition at line 2098 of file airportdb.c.

◆ adb_find_nearest_airports()

list_t * adb_find_nearest_airports ( airportdb_t db,
geo_pos2_t  my_pos 
)

Locates all airports within the load limit distance of a geographic reference position. The airports are searched for in the apt_dat database and this function returns its result into the list argument. To set the load limit distance, use adb_set_airport_load_limit().

Returns
A list of airport structures. This list must be freed using adb_free_nearest_airport_list(). You may also not call adb_find_nearest_airports() multiple times without first freeing the returned list, as the linked list reuses the same list node inside of the airport structures.
When using an airportdb_t from multiple threads, make sure to lock database using airportdb_lock() before doing the lookup and working with the returned list. After freeing the list, call airportdb_unlock().

Definition at line 2953 of file airportdb.c.

◆ adb_free_nearest_airport_list()

void adb_free_nearest_airport_list ( list_t l)

Frees the list returned from find_nearest_airports().

You mustn't call find_nearest_airports() multiple times without first freeing the returned list, as the linked list reuses the same list node inside of the airport structures.

When using an airportdb_t from multiple threads, make sure to lock database using airportdb_lock() before doing the lookup and working with the returned list. After freeing the list, call airportdb_unlock().

Definition at line 2985 of file airportdb.c.

◆ adb_load_nearest_airport_tiles()

void adb_load_nearest_airport_tiles ( airportdb_t db,
geo_pos2_t  my_pos 
)

Performs a load of all airports within the distance load limit of a given position. The distance limit is set using adb_set_airport_load_limit(). A loaded airport has all its information resolved, such as the ECEF positions of the threshold, all bounding boxes constructed, etc.

Parameters
dbThe database for which to perform the load.
my_posThe 2-space geographic position around which to perform the load. This MUST be a valid geographic coordinate.

Definition at line 3066 of file airportdb.c.

◆ adb_matching_airport_in_tile_with_TATL()

airport_t * adb_matching_airport_in_tile_with_TATL ( airportdb_t db,
geo_pos2_t  pos,
const char *  search_icao 
)

Definition at line 3501 of file airportdb.c.

◆ adb_recreate_cache()

bool_t adb_recreate_cache ( airportdb_t db,
int  app_version 
)

Rebuilds all cache state from disk. This must be called only once, after calling airportdb_create() to actually populate the cache. On first run, the disk cache will be empty, and this function will interrogate X-Plane's installed scenery to rebuild the cache. If the cache already exists, this function checks for changes in X-Plane's scenery and/or navdata and if necessary rebuilds the cache, or simply loads it as-is.

Please note that on first run (or if a scenery change is detected), this function can take quite a bit of time to run (tens of seconds to minutes, if the machine is particularly slow and has lots of scenery). You are therefore encouraged to run it only once at startup. If you need to create multiple airportdb instances, create them in sequence, NOT in parallel! This function perform disk I/O an the cache is NOT designed for concurrent writing! Once created by the first instance of airportdb, subsequent airportdb instances will not need to rebuild and will simply read the cache as-is, so this function will return nearly instantly.

Be sure to configure the ‘ifr_only’ flag in the airportdb structure before calling this function. That flag specifies whether the cache should only contain airports with published instrument approaches, or if VFR-only airports should also be allowed.

Parameters
dbDatabase instance which was previously initialized using airportdb_create().
app_versionAn application-side version tag to apply to the cache. This can be used in any way you want. If the cache detects a change in the app_version tag, the cache will be recreated. You can use this to, for example, recreate the cache, if you changed your cache configuration between versions of your addon.
Returns
B_TRUE if successful, B_FALSE if cache creation failed.

Definition at line 2499 of file airportdb.c.

◆ adb_set_airport_load_limit()

void adb_set_airport_load_limit ( airportdb_t db,
double  limit 
)

Sets the distance limit within which airports are loaded from disk. A loaded airport has all its information resolved, such as the ECEF positions of the threshold, all bounding boxes constructed, etc. The default airport load limit for a newly created airportdb is 14,816 meters (8nm).

Parameters
dbThe database for which to set the load limit.
limitThe distance limit in meters.

Definition at line 3049 of file airportdb.c.

◆ adb_unload_distant_airport_tiles()

void adb_unload_distant_airport_tiles ( airportdb_t db,
geo_pos2_t  my_pos 
)

Unloads airports that are beyond the airport load limit distance from a given position. This frees some memory allocations for the airports. You should be calling this function at regular intervals as you move through the world, to make sure airports don't remain loaded forever. Use adb_set_airport_load_limit() to set the distance limit.

Parameters
dbThe database for which to perform the unload.
my_posThe 2-space geographic position to use as the reference. Airports beyond the load limit distance will be unloaded. You may pass a NULL_GEO_POS2 for this argument - this will make the airportdb unload all loaded airports.

Definition at line 3114 of file airportdb.c.

◆ airportdb_create()

void airportdb_create ( airportdb_t db,
const char *  xpdir,
const char *  cachedir 
)

Initializes an airportdb_t structure. Please note that this doesn't populate the data in the database. It simply sets up its memory state to be ready for operation. To load disk data into the database and actually start using it, call adb_recreate_cache() after initializing the airportdb structure. Use airportdb_destroy() to free the resources allocated by an airportdb_t.

Definition at line 3154 of file airportdb.c.

◆ airportdb_destroy()

void airportdb_destroy ( airportdb_t db)

Destroys an airportdb_t structure, after it has been initialized using airportdb_create().

Definition at line 3190 of file airportdb.c.

◆ airportdb_lock()

void airportdb_lock ( airportdb_t db)

Locks an airportdb_t structure, for use by multiple threads. Use airportdb_unlock() to release the lock. Locking is recursive, so airportdb_unlock() must be called as many times as airportdb_lock() to fully release the lock.

Definition at line 3231 of file airportdb.c.

◆ airportdb_unlock()

void airportdb_unlock ( airportdb_t db)

Unlocks an airportdb_t structure after it has been locked using airportdb_lock(). Locking is recursive, so airportdb_unlock() must be called as many times as airportdb_lock() to fully release the lock.

Definition at line 3243 of file airportdb.c.