A VidMap draw tool for use with vNAS. It is a spiritual successor to VidMapper, but slightly more complex and aimed at managing maps and map sets.
While VidMapper is aimed at drawing ad hoc maps for smaller TRACONs, FacilityMapper is designed to build maps on the AIRAC cycle for entire ARTCCs. It is based on a manifest.json
file, which is effectively a list of "recipes" for your facility maps, making it easy to issue updates on the cycle no matter what changes.
All maps are run through optimization prior to being written to file. Depending on the procedure, map type, and options, the way the source data defines the paths can cause several duplicate segments. Removing any segments that have already been drawn can save anywhere between a few and several thousand lines. For Composite maps, this optimization is run again after the two maps are combined.
Prior to loading them into vNAS Data Admin, use GeoJSON.io or a similar tool to verify the output so that you can adjust the manifest.json
as necessary. The way certain procedures are coded varies, so the end result might not match what you might expect. In these cases, a simple change to the manifest.json
will solve the issue. For example, certain SIDs and STARs do not have a core
section, and are made completely of runway and enroute transitions around a single point. In these cases, the procedure will not look correct unless draw_runway_transitions
is set to true
.
See Manifest File Format for more details.
- Python3.8 or Later (Tested with Python 3.10.12)
cifparse
- Install
cifparse
with:
pip install cifparse
- Download the FAA CIFP zip file. Copy the
FAACIFP18
file from the zip into the./navdata
directory. - Create a manifest file.
- Run the script (see Drawing the Facility for more detail).
Examples:
example_manifest.json
: Basic example manifest file showing all of the fields and their defaults, available in the root folder.example_zdc_manifest.json
: Completed manifest showing the options used for a "production" build, available in the root folder.
More detail, and images of the various settings is available in EXAMPLES.
The manifest.json
file has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
maps |
* | array |
An array of Map Objects |
The map object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
map_type |
* | string |
A string representing the map type. Supported map types are: "CONTROLLED" , "IAP" , "LABEL" , "RESTRICTIVE" , "RUNWAYS" , "SID" , "VECTORSID" , "STAR" and "COMPOSITE" . |
|
definition |
* | object |
A Definition Object. |
The definition object has fields that depend on the map type being defined.
The SID object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
airport_id |
* | string |
A string representing the ICAO identifier for the airport. | |
procedure_id |
* | string |
A string representing the computer code of the procedure, in the format "AAA#" or "AAAAA#" ("JCOBY#" ), where the # is the literal # symbol. |
|
line_type |
string |
"solid" |
A string representing the line type that should be drawn. Supported line types are: "solid" , "longDashed" , "shortDashed" , "longDashShortDash" , "arrows" , and "none" . |
|
draw_symbols |
bool |
false |
A boolean value that tells the script to draw a symbol at the fix location. The symbol is driven by the data in the CIFP, and clips the line around the point. | |
symbol_scale |
float |
1.0 |
A float value representing the scale of the symbols. | |
draw_altitudes |
bool |
false |
A boolean value that tells the script to draw the speed restriction (if present) for the fix near the fix location. | |
draw_speeds |
bool |
false |
A boolean value that tells the script to draw the altitude restriction(s) (if present) for the fix near the fix location. | |
draw_names |
bool |
false |
A boolean value that tells the script to draw the name of the fix near the fix location. | |
x_offset |
float |
0 |
A float value representing the lateral text offset in nautical miles (positive for East and negative for West). | |
y_offset |
float |
0 |
A float value representing the vertical text offset in nautical miles (positive for North and negative for South). | |
text_scale |
float |
1.0 |
A float value representing the scale of the text. | |
line_height |
float |
1.5 * text_scale |
A float value representing the line height of the text, used in spacing the fix name, altitude, and speed. | |
draw_enroute_transitions |
bool |
true |
A boolean value that tells the script to draw the enroute transitions. | |
draw_runway_transitions |
bool |
false |
A boolean value that tells the script to draw the runway transitions. NOTE: Many SID runway transitions have performance/altitude-based points. These are not currently supported, so the line draws might be odd in this segment for now. | |
file_name |
string |
{airportId}_{mapType}_{procedureId} |
A string representing the filename that the map will be saved to ("003_JCOBY" ). |
The STAR object is defined using the same properties as SID.
Vectored SIDs don't have any specific path information, so it is being offered as a special type in cases where the map is still desired. Unlike the SID and STAR types, the Vector SID does not print any path information, and defaults to printing the symbols and names.
The Vector SID object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
airport_id |
* | string |
A string representing the ICAO identifier for the airport. | |
procedure_id |
* | string |
A string representing the computer code of the procedure, in the format "AAA#" or "AAAAA#" ("JCOBY#" ), where the # is the literal # symbol. |
|
draw_symbols |
bool |
true |
A boolean value that tells the script to draw a symbol at the fix location. The symbol is driven by the data in the CIFP. | |
symbol_scale |
float |
1.0 |
A float value representing the scale of the symbols. | |
draw_names |
bool |
true |
A boolean value that tells the script to draw the name of the fix near the fix location. | |
x_offset |
float |
0 |
A float value representing the lateral text offset in nautical miles (positive for East and negative for West). | |
y_offset |
float |
0 |
A float value representing the vertical text offset in nautical miles (positive for North and negative for South). | |
text_scale |
float |
1.0 |
A float value representing the scale of the text. | |
line_height |
float |
1.5 * text_scale |
A float value representing the line height of the text, used in spacing the fix name, altitude, and speed. | |
file_name |
string |
{airportId}_{mapType}_{procedureId} |
A string representing the filename that the map will be saved to ("003_CPTAL" ). |
The interpretation of the paths is still relatively limited. As such, more advanced draws like those on RTF legs are not yet supported.
The IAP object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
airport_id |
* | string |
A string representing the ICAO identifier for the airport. | |
procedure_id |
* | string |
A string representing the computer code of the procedure. These aren't always straightforward. See ICAO IAP Codes for more detail. | |
line_type |
string |
"solid" |
A string representing the line type that should be drawn. Supported line types are: "solid" , "longDashed" , "shortDashed" , "longDashShortDash" , and "none" . |
|
draw_symbols |
bool |
false |
A boolean value that tells the script to draw a symbol at the fix location. The symbol is driven by the data in the CIFP, and clips the line around the point. | |
symbol_scale |
float |
1.0 |
A float value representing the scale of the symbols. | |
draw_altitudes |
bool |
false |
A boolean value that tells the script to draw the speed restriction (if present) for the fix near the fix location. | |
draw_speeds |
bool |
false |
A boolean value that tells the script to draw the altitude restriction(s) (if present) for the fix near the fix location. | |
draw_names |
bool |
false |
A boolean value that tells the script to draw the name of the fix near the fix location. | |
x_offset |
float |
0 |
A float value representing the lateral text offset in nautical miles (positive for East and negative for West). | |
y_offset |
float |
0 |
A float value representing the vertical text offset in nautical miles (positive for North and negative for South). | |
text_scale |
float |
1.0 |
A float value representing the scale of the text. | |
line_height |
float |
1.5 * text_scale |
A float value representing the line height of the text, used in spacing the fix name, altitude, and speed. | |
transition_ids |
array |
An array of strings representing the names of the transitions to include. | ||
draw_missed |
bool |
false |
A boolean value that tells the script to draw the missed approach. (Generally functional but not recommended for use.) | |
file_name |
string |
{airportId}_{mapType}_{procedureId} |
A string representing the filename that the map will be saved to ("003_KOKV_VDMA" ). |
Prefix | Type | Example |
---|---|---|
B | LOC/BC | B30L |
D | VOR/DME | D25 |
F | FMS | Deprecated |
G | IGS | Deprecated |
H | RNP | H21-Y |
I | ILS | I01R |
J | GNSS | Deprecated |
L | LOC | L17 |
M | MLS | Deprecated |
N | NDB | N34 |
P | GPS | P04 |
Q | NDB/DME | Q06R |
R | RNAV | R14 |
S | VORTAC | S13 |
T | TACAN | Deprecated |
U | SDF | Deprecated |
V | VOR | V22 |
W | MLS-A | Deprecated |
X | LDA | X19-Y |
Y | MLS-B/C | Deprecated |
...and because the CIFP is an FAA product, these additional oddities that seem to be specific to procedures not tied to a specific runway:
Prefix | Type | Example |
---|---|---|
GPS | GPS | GPS-A |
LBC | LOC/BC | LBC-A |
LDA | LDA | LDA-A |
LOC | LOC | LOC-A |
NDB | NDB | NDB-A |
RNV | RNAV | RNV-A |
VDM | VOR/DME | VDM-A |
VOR | VOR | VOR-A |
The Controlled object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
airport_id |
* | string |
A string representing the identifier for the controlled airspace. | |
file_name |
string |
{mapType}_{controlledId} |
A string representing the filename that the map will be saved to. |
NOTE: For most airspace, the airport_id
is straightforward, but for certain areas within Class B, it might not be obvious. It may be worth opening the CIFP file and searching for the entry. If your program supports regex, you can search with SUSAUC...{airportId}
to see if anything pops up. For Washington DC, the Class B is centered on KDCA
(and not KIAD
or KBWI
), whereas for NY it is centered on KJFK
(and not KEWR
or KLGA
).
Restrictive airspace covers all airspace: Alert (A), Caution (C), Danger (D), Military Operations Area (M), Prohibited (P), Restricted (R), Training (T), and Warning (W).
The Restrictive object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
restrictive_id |
* | string |
A string representing the identifier for the restrictive airspace. | |
file_name |
string |
{mapType}_{restrictiveId} |
A string representing the filename that the map will be saved to. |
NOTE: Naming in the CIFP file is mostly standardized, but has some quirks, particularly for MOAs. It may be worth opening the CIFP file and searching for the entry. For example, Stumpy Point MOA appears in the file as STUMPY PT
. If your program supports regex, you can search with SUSAUR..M
and start typing the MOA name right after the M
(e.g., SUSAUR..MDEMO
for the DEMO MOA). For longer names, the name may actually be truncated. The Tombstone MOA, for example, is truncated as TOMBSTON A
, TOMBSTON B
and TOMBSTON C
.
The Runways object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
airport_ids |
* | array |
An array of string representing the ICAO identifiers for the airports. | |
file_name |
* | string |
A string representing the filename that the map will be saved to. |
The Label object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
lines |
* | array |
An array of Label Line objects. | |
file_name |
* | string |
A string representing the filename that the map will be saved to. |
The Label Line object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
line |
* | string |
A text line of supported characters. | |
lat |
* | float |
A float value representing the latitude. | |
lon |
* | float |
A float value representing the longitude. | |
text_scale |
float |
1.0 |
A float value representing the scale of the text. |
NOTE: The "origin" of the text is at the bottom left corner.
A Composite Map is a map made up of other maps. This is useful in cases where you would like to show several SIDs on a single map. As best practice, all Composites should be listed at the end of the manifest to ensure that the relevant maps are generated before trying to combine them.
The Composite object has the following properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
file_names |
* | string |
A string representing the filenames to combine into a single map. | |
file_name |
* | string |
A string representing the filename that the map will be saved to. | |
delete_originals |
bool |
false |
A boolean value that tells the script to delete the original maps after combining them. |
The following characters are currently supported:
Type | Supported |
---|---|
Numeric | 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 |
Alpha | A ,B ,C ,D ,E ,F ,G ,H ,I ,J ,K ,L ,M ,N ,O ,P ,Q ,R ,S ,T ,U ,V ,W ,X ,Y ,Z |
Other | + ,- ,. ,⎵ (space) |
What the characters look like is shown in EXAMPLES.
Run the following command:
python3 main.py
The resulting file(s) will be in ./vidmaps
.
--nodraw
is available to skip the draw step. This is useful to run with the other command line options if you wish to run those steps only.
python3 main.py --nodraw
--purge
is available to quickly clean up the vidmap directory.
python3 main.py --purge
--refresh
is available to refresh the database data. By default, the script will skip parsing the CIFP to save time if it has already parsed it into a database (found at ./navdata/FAACIFP18.db
). Run this command any time you replace the FAACIFP18
file.
python3 main.py --refresh
--manifest
is available to specify different manifest files. By default, the script looks for a file named manifest.json
in the program root, but additional manifests can be created with different file names in the manifests
directory, and built using --manifest
.
python3 main.py --manifest example_manifest.json