libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
|
#include "avl.h"
#include "geom.h"
#include "list.h"
#include "helpers.h"
#include "htbl.h"
#include "thread.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 |
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_t * | adb_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) |
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.
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.
For each airport, we need to obtain the following pieces of information:
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.
#define airport_find_runway adb_airport_find_runway |
Definition at line 396 of file airportdb.h.
#define airport_index_walk adb_airport_index_walk |
Definition at line 390 of file airportdb.h.
#define airport_lookup adb_airport_lookup |
Definition at line 370 of file airportdb.h.
#define airport_lookup_by_iata adb_airport_lookup_by_iata |
Definition at line 386 of file airportdb.h.
#define airport_lookup_by_icao adb_airport_lookup_by_icao |
Definition at line 382 of file airportdb.h.
#define airport_lookup_by_ident adb_airport_lookup_by_ident |
Definition at line 378 of file airportdb.h.
#define airport_lookup_global adb_airport_lookup_global |
Definition at line 374 of file airportdb.h.
#define AIRPORTDB_CC_LEN 4 |
Definition at line 264 of file airportdb.h.
#define AIRPORTDB_IATA_LEN 4 |
Definition at line 263 of file airportdb.h.
#define AIRPORTDB_ICAO_LEN 8 |
Definition at line 262 of file airportdb.h.
#define AIRPORTDB_IDENT_LEN 8 |
Definition at line 261 of file airportdb.h.
#define airportdb_xp11_airac_cycle adb_airportdb_xp_airac_cycle |
Definition at line 405 of file airportdb.h.
#define find_nearest_airports adb_find_nearest_airports |
Definition at line 349 of file airportdb.h.
#define free_nearest_airport_list adb_free_nearest_airport_list |
Definition at line 353 of file airportdb.h.
#define load_nearest_airport_tiles adb_load_nearest_airport_tiles |
Definition at line 359 of file airportdb.h.
#define matching_airport_in_tile_with_TATL adb_matching_airport_in_tile_with_TATL |
Definition at line 400 of file airportdb.h.
#define recreate_cache | ( | __db | ) | adb_recreate_cache((__db), 0) |
Definition at line 346 of file airportdb.h.
#define set_airport_load_limit adb_set_airport_load_limit |
Definition at line 356 of file airportdb.h.
#define unload_distant_airport_tiles adb_unload_distant_airport_tiles |
Definition at line 366 of file airportdb.h.
enum freq_type_t |
Definition at line 241 of file airportdb.h.
enum ramp_start_type_t |
Definition at line 168 of file airportdb.h.
enum rwy_surf_t |
Definition at line 187 of file airportdb.h.
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.
arpt | The airport in which to perform to search. |
rwy_id | A 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_p | Mandatory 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_p | Mandatory 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. |
B_TRUE
if the search was successful, B_FALSE
otherwise. Definition at line 3477 of file airportdb.c.
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.
db | Database to perform the index walk on. |
found_cb | Callback 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_cb | You 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. |
userinfo | Custom pointer user info argument, which will be passed to the found_cb callback function in its second argument. |
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.
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.
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.
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.
db | Database in which to perform the lookup. |
icao | The 4-letter ICAO code to look for. |
found_cb | Callback 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. |
userinfo | Optional user info pointer, which will be passed to every call to found_cb in its second argument. |
Definition at line 3328 of file airportdb.c.
airport_t * adb_airport_lookup_by_ident | ( | airportdb_t * | db, |
const char * | ident | ||
) |
Searches for an airport in the database by unique identifier.
db | Database in which to perform the lookup. |
ident | The 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). |
Definition at line 3262 of file airportdb.c.
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.
db | The airportdb on which to perform the lookup. |
icao | The ICAO code of the airport. If there are duplicate airports matching the ICAO code, which airport is returned cannot be predicted. |
Definition at line 3411 of file airportdb.c.
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.
xpdir | A path to the X-Plane installation directory. |
cycle | Mandatory return argument. If the search is successful, this will be filled with the AIRAC cycle number. |
B_TRUE
if the determination succeeded, B_FALSE
otherwise. Definition at line 2098 of file airportdb.c.
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().
Definition at line 2953 of file airportdb.c.
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.
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.
db | The database for which to perform the load. |
my_pos | The 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.
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.
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.
db | Database instance which was previously initialized using airportdb_create(). |
app_version | An 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. |
B_TRUE
if successful, B_FALSE
if cache creation failed. Definition at line 2499 of file airportdb.c.
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).
db | The database for which to set the load limit. |
limit | The distance limit in meters. |
Definition at line 3049 of file airportdb.c.
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.
db | The database for which to perform the unload. |
my_pos | The 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.
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.
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.
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.
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.