openscope

Airport Format

The airport JSON file must be in “assets/airports”; the filename should be icao.json where icao is the lowercase four-letter ICAO airport identifier, such as ksfo or kmsp. If this is a new airport, an entry must also be added to airportLoadList.json in alphabetical order. See the airport load list documentation for information on the correct structure to use.

Example

Note: The code block shown below is an abbreviated version of ksea.json.

{
    "airac": 1801,
    "radio": {
        "twr": "Seatle Tower",
        "app": "Seattle Approach",
        "dep": "Seattle Departure"
    },
    "icao": "KSEA",
    "iata": "SEA",
    "magnetic_north": 16,
    "ctr_radius": 110,
    "ctr_ceiling": 15000,
    "initial_alt": 15000,
    "position": ["N47d26.99m0", "W122d18.71m0", "432ft"],
    "rangeRings": {
        "enabled": true,
        "center": ["N47d26.99m0", "W122d18.71m0"],
        "radius_nm": 5.0,
    },
    "has_terrain": true,
    "wind": {
        "angle": 150,
        "speed": 9
    },
    "arrivalRunway": "16R",
    "departureRunway": "16L",
    "defaultMaps": ["Base Map"],
    "airspace": [
        {
            "floor": 0,
            "ceiling": 150,
            "airspace_class": "B",
            "poly": [
                ["N47.83333330", "W121.69999940"],
                ["N47.95335007", "W121.97603665"],
                ["N48.30000000", "W121.96666670"],
                ["N48.30000000", "W122.30000000"],
                ["N48.20000000", "W122.45000000"]
            ]
        }
    ],
    "fixes": {
        "_NEZUG070010": ["N47d34.80m0", "W122d03.84m0"],
        "_NEZUG070PAE139": ["N47d34.77m0", "W122d05.11m0"],
        "_NICHY250SEA230": ["N47d19.92m0", "W122d42.78m0"],
        "_OLM161026": ["N46d32.31m0", "W122d54.11m0"],
        "_SEA161002": ["N47d24.12m0", "W122d18.58m0"],
        "_SEA341004": ["N47d30.12m0", "W122d18.58m0"],
        "_SUMMA326017": ["N46d53.20m0", "W122d07.08m0"],
        "AAYRR": ["N46d38.81m0", "W123d43.34m0"],
        "BOANE": ["N47d59.10m0", "W122d43.52m0"],
        "EUG"  : ["N44d07.25m0", "W123d13.37m0", "Eugene"],
        "FEPOT": ["N47d04.85m0", "W123d13.13m0"],
        "GEG"  : ["N47d33.90m0", "W117d37.61m0"],
        "KRUZR": ["N48d04.65m0", "W120d34.68m0", "cruiser"],
        "ONSET": ["N48d57.48m0", "W118d00.00m0"],
        "PAE"  : ["N47d55.19m0", "W122d16.67m0", "Paine"],
        "WESET": ["N47d24.35m0", "W122d19.10m0"],
        "YXC"  : ["N49d33.30m0", "W116d05.26m0"],
        "ZUVEN": ["N47d47.98m0", "W122d25.15m0"]
    },
    "restricted": [
        {
            "name": "P-51",
            "height": "2500ft",
            "poly": [
                ["N47.7737128", "W122.7710456"],
                ["N47.7189169", "W122.7706794"],
                ["N47.6924411", "W122.7388044"],
                ["N47.6932556", "W122.6940508"],
                ["N47.7723906", "W122.6948667"]
            ]
        }
    ],
    "runways":[
        {
            "name": ["16L", "34R"],
            "end": [
                [47.463767, -122.307749, "432.5ft"],
                [47.431201, -122.308035, "346.8ft"]
            ],
            "ils": [true, true],
        },
        {
            "name": ["16R", "34L"],
            "end": [
                [47.463806, -122.317884, "415.0ft"],
                [47.440562, -122.318092, "356.3ft"]
            ],
            "ils": [true, true],
        }
    ],
    "sids": {
        "SUMMA1": {
            "icao": "SUMMA1",
            "name": "Summa One",
            "altitude": 7000,
            "rwy": {
                "KSEA16L": ["NEVJO"],
                "KSEA16R": ["NEVJO"],
                "KSEA34L": [["NEZUG", "A40+"], "^_NEZUG070PAE139", "_SUMMA326017"],
                "KSEA34R": [["NEZUG", "A40+"], "^_NEZUG070PAE139", "_SUMMA326017"]
            },
            "exitPoints": {
                "BKE": ["SUMMA", "BKE"],
                "LKV": ["SUMMA", "LKV"],
                "SUMMA": ["SUMMA"]
            },
            "draw": [
                ["NEVJO", "SUMMA"],
                ["NEZUG", "_NEZUG070PAE139", "_SUMMA326017", "SUMMA"],
                ["SUMMA", "LKV*"],
                ["SUMMA*", "BKE*"]
            ]
        }
    },
    "stars": {
        "CHINS2": {
            "icao": "CHINS2",
            "name": "Chins Two",
            "entryPoints": {
                "CHINS": [],
                "IMB": ["IMB", "SUNED", "YKM"],
                "PDT": ["PDT", "BRUKK", "SUNED", "YKM"],
                "SUNED": ["SUNED", "YKM"]
            },
            "body": ["CHINS"],
            "rwy": {
                "KSEA16L": [["RADDY", "A160+|S270"], ["HUMPP", "A150-"], ["AUBRN", "A120|S250"], "#343"],
                "KSEA16R": [["RADDY", "A160+|S270"], ["HUMPP", "A150-"], ["AUBRN", "A120|S250"], "#343"],
                "KSEA34L": [["RADDY", "A120|S250"], "HUMPP", "AUBRN", "#250"],
                "KSEA34R": [["RADDY", "A120|S250"], "HUMPP", "AUBRN", "#250"]
            },
            "draw": [
                ["IMB*", "SUNED*", "YKM"],
                ["PDT*", "BRUKK", "SUNED", "YKM"],
                ["YKM", "CHINS*", "RADDY", "HUMPP", "AUBRN"]
            ]
        }
    },
    "spawnPatterns": [
        {
            "origin": "KSEA",
            "destination": "",
            "category": "departure",
            "route": "KSEA.SUMMA1.BKE",
            "altitude": "",
            "speed": "",
            "method": "random",
            "rate": 9,
            "airlines": [
                ["aal", 4],
                ["aca", 1],
                ["asa", 3]
            ]
        },
        {
            "origin": "",
            "destination": "KSEA",
            "category": "arrival",
            "route": "PDT.CHINS2.KSEA",
            "altitude": [18000, 36000],
            "speed": 320,
            "method": "random",
            "rate": 15,
            "airlines": [
                ["aal", 4],
                ["aca", 1],
                ["asa", 3]
            ]
        },
        {
            "origin": "",
            "destination": "",
            "category": "overflight",
            "route": "PDT..PSC..ELN..RADDY..AUBRN..GIGHR..ELMAA..HQM",
            "altitude": [18000, 36000],
            "speed": 320,
            "method": "random",
            "rate": 15,
            "airlines": [
                ["aal", 4],
                ["aca", 1],
                ["asa", 3]
            ]
        }
    ],
    "maps": [
        {
            "name": "Base Map",
            "lines": [
                ["N47.46706920", "W122.43465440", "N47.46816390", "W122.43651330"],
                ["N47.46635080", "W122.43369000", "N47.46706920", "W122.43465440"],
                ["N47.46975860", "W122.43977560", "N47.47109720", "W122.44296940"],
                ["N47.46816390", "W122.43651330", "N47.46975860", "W122.43977560"],
                ["N47.46549330", "W122.43386170", "N47.46635080", "W122.43369000"]
            ]
        }
    ]
}

Property Descriptions

Base Airport Properties

All properties in this section are required

"radio": {
    "twr": "Seatle Tower",
    "app": "Seattle Approach",
    "dep": "Seattle Departure"
},
"wind": {
    "angle": 150,
    "speed": 9
},

Airspace

All properties in this section are required for each airspace section At least one airspace definition is required for an airport

"airspace": [
    {
        "floor": 0,
        "ceiling": 150,
        "airspace_class": "B",
        "poly": [
            ["N47.83333330", "W121.69999940"],
            ["N47.95335007", "W121.97603665"],
            ["N48.30000000", "W121.96666670"],
            ["N48.30000000", "W122.30000000"],
            ["N48.20000000", "W122.45000000"]
        ]
    }
],

Position definition of the airport airspace. Multiple airspace areas may be defined and will all be included in the airspace. This allows for advanced airspace stratification.

"labelPositions": [
    ["N48.20000000", "W122.45000000"],
    ["N47.83333330", "W121.69999940"]
],

Fixes

All fixes listed within the Standard Routes need to be defined within this section

"fixes": {
    "_NEZUG070010": ["N47d34.80m0", "W122d03.84m0"],
    "_NEZUG070PAE139": ["N47d34.77m0", "W122d05.11m0"],
    "_NICHY250SEA230": ["N47d19.92m0", "W122d42.78m0"],
    "_OLM161026": ["N46d32.31m0", "W122d54.11m0"],
    "_SEA161002": ["N47d24.12m0", "W122d18.58m0"],
    "_SEA341004": ["N47d30.12m0", "W122d18.58m0"],
    "_SUMMA326017": ["N46d53.20m0", "W122d07.08m0"],
    "AAYRR": ["N46d38.81m0", "W123d43.34m0"],
    "BOANE": ["N47d59.10m0", "W122d43.52m0"],
    "EUG"  : ["N44d07.25m0", "W123d13.37m0", "Eugene"],
    "FEPOT": ["N47d04.85m0", "W123d13.13m0"],
    "GEG"  : ["N47d33.90m0", "W117d37.61m0"],
    "KRUZR": ["N48d04.65m0", "W120d34.68m0", "cruiser"],
    "ONSET": ["N48d57.48m0", "W118d00.00m0"],
    "PAE"  : ["N47d55.19m0", "W122d16.67m0", "Paine"],
    "WESET": ["N47d24.35m0", "W122d19.10m0"],
    "YXC"  : ["N49d33.30m0", "W116d05.26m0"],
    "ZUVEN": ["N47d47.98m0", "W122d25.15m0"]
},

Each navaid located within or around the airport airspace in latitude, longitude: see lat, lon, elev for formatting. Real life fixes are defined thusly:

"AAYRR": ["N46d38.81m0", "W123d43.34m0"]

Each fix can have an optional third parameter which defines how the name is pronounced by the speech engine. This parameter can either be a real place name (appearing on the charts) or a logical pronunciation of an arbitrary letter combination. Capitalization of this parameter does not affect the way the fix is pronounced in-sim.

"EUG"  : ["N44d07.25m0", "W123d13.37m0", "Eugene"],
"KRUZR": ["N48d04.65m0", "W120d34.68m0", "cruiser"],
"PAE"  : ["N47d55.19m0", "W122d16.67m0", "Paine"],

You will notice in the list above there is a fix definition preprended with an _. This is called an invisible fix. A few examples of uses for these fixes include:

  1. To simulate DME arcs (can be seen in SAEZ)
  2. To simulate initial climbs (e.g. Climb runway heading until LON 2DME)
  3. To simulate radial intercepts (e.g. Intercept radial 180 to OLM)

They’re used when we need aircraft to fly over a location that doesn’t have an actual fix or waypoint. A fix should be created and should be named using the following conventions:

"_RWY33L": [42.354662, -70.991598]
"_RWY33L01DME": [42.342838, -70.975751]
"_RWY12BSTER081": [25.810667, -80.322667]
"_RWY1LPIE116": [27.848198, -82.546200]
"_AUTUM220015": [42.324333, -71.736833]
"_FIXXA030FIXXB180"
"_SIPLY233STINS324": [37.47860, -122.60090]
"_SEA104TCM40DME": [47.074500, -121.516167],
"_RWY16LPAE10DME": [47.754500, -122.308000]

Restricted Airspace

Areas of restricted airspace may be added to the restricted property of the airport file. This is an array containing restricted areas such as the example below:

"restricted": [
    {
        "name": "P-51",
        "height": "2500ft",
        "poly": [
            ["N47.7737128", "W122.7710456"],
            ["N47.7189169", "W122.7706794"],
            ["N47.6924411", "W122.7388044"],
            ["N47.6932556", "W122.6940508"],
            ["N47.7723906", "W122.6948667"]
        ]
    }
],
"labelPositions": [
    ["N47.7737128", "W122.7710456"],
    ["N47.7723906", "W122.6948667"]
],

Runways

"runways": [
    {
        "name": ["16L", "34R"],
        "end": [
            [47.463767, -122.307749, "432.5ft"],
            [47.431201, -122.308035, "346.8ft"]
        ],
        "ils": [false, true],
        "ils_distance":[30, 25],
        "loc_maxDist": [28, 20],
        "glideslope": [3.00, 2.50]
    }
],

Runways are defined in pairs because a runway can be used from either direction. This makes defining runways a little tricky, so special attention should be paid to how the data is set up. For each property, the first value will be considered part of the first runway and the second property for the second runway. If you were to take the above example and extract each runway’s properties, you would end up with the following two objects:

// Runway 16L
{
    "name": "16L",
    "end": [
        [47.463767, -122.307749, "432.5ft"]
    ],
    "ils": false
}

// Runway 34R
{
    "name": "34R",
    "end": [
        [47.431201, -122.308035, "346.8ft"]
    ],
    "ils": true
}

Airways

"airways": {
    "J100": ["HEC", "CLARR", "LAS", "NORRA", "BCE"],
    "J146": ["LAS", "NOOTN"],
    "J9": ["HEC", "CLARR", "LAS", "NORRA", "AVERS", "URIAH", "BERYL",  "MLF"],
    "J92": ["BTY", "BLD", "KADDY", "PRFUM", "CADDU", "DRK"],
    "Q15": ["CHILY", "DOVEE", "BIKKR"],
    "V8": ["PHYLI", "MMM", "MEADS", "ACLAM", "WINDS", "LYNSY", "SHUSS", "GFS", "HEC"]
},

Each fix along each airway in successive order (direction does not matter). And of course, all fixes entered here must be defined in the fixes section.

Instrument Procedures

Supported Instrument Procedures currently include only SIDs and STARs, and each contain three components:

  1. Entry - the starting point of the procedure (can include many different entry points)
  2. Body - shared segment that all aircraft on the route will follow
  3. Exit - the ending point of the procedure (can include many different exit points)

This structure is used to work with both SIDs and STARs within the app. Though it’s not important to know for an airport file, it is a good thing to keep in mind.

Fix Instruction Symbols

Fixes within a segment might include an instruction and/or restrictions. Fixes can be defined in several different ways:

// fix name only
"16L": ["IMB", "SUNED", "YKM"]

// fix name with fly-over instruction
"16L": ["IMB", "^SUNED", "YKM"]

// fix name with holding instruction
"16L": ["IMB", "@SUNED", "YKM"]

// fix name with altitude restriction
"16L": ["IMB", ["SUNED", "A70"], "YKM"]

// fix name with speed restriction
"16L": ["IMB", ["SUNED", "S200"], "YKM"]

// fix name with at/below and at/above altitude and speed restrictions
"16L": ["IMB", ["SUNED", "A70+|S250-"], "YKM"]

// fix name with ranged altitude and speed restrictions
"16L": ["IMB", ["SUNED", "A70+|A100-|S210+|S250-"], "YKM"]

These definitions can be used within any entryPoints, body or exitPoints segment of a procedure.

SIDs

All properties in this section are required for each route definition

"sids": {
    "SUMMA1": {
        "icao": "SUMMA1",
        "name": "Summa One",
        "altitude": 7000,
        "rwy": {
            "KSEA16L": ["NEVJO"],
            "KSEA16R": ["NEVJO"],
            "KSEA34L": [["NEZUG", "A40+"], "^_NEZUG070PAE139", "_SUMMA326017"],
            "KSEA34R": [["NEZUG", "A40+"], "^_NEZUG070PAE139", "_SUMMA326017"]
        },
        "body": [],
        "exitPoints": {
            "BKE": ["SUMMA", "BKE"],
            "LKV": ["SUMMA", "LKV"],
            "SUMMA": ["SUMMA"]
        },
        "draw": [
            ["NEVJO", "SUMMA"],
            ["NEZUG", "_NEZUG070PAE139", "_SUMMA326017", "SUMMA"],
            ["SUMMA", "LKV*"],
            ["SUMMA*", "BKE*"]
        ]
    }
},

SID is an acronym for Standard Instrument Departure.

"SUMMA1": {
    "icao": "SUMMA1"
}

Every possible rwy/body/exitPoint combination must result at least one fix. There must be at least one exitPoint, and it cannot be empty.

STARs

All properties in this section are required for each route definition

"stars": {
    "CHINS2": {
        "icao": "CHINS2",
        "name": "Chins Two",
        "entryPoints": {
            "CHINS": [],
            "IMB": ["IMB", "SUNED", "YKM"],
            "PDT": ["PDT", "BRUKK", "SUNED", "YKM"],
            "SUNED": ["SUNED", "YKM"]
        },
        "body": ["CHINS"],
        "rwy": {
            "KSEA16L": [["RADDY", "A160+|S270"], ["HUMPP", "A150-"], ["AUBRN", "A120|S250"], "#343"],
            "KSEA16R": [["RADDY", "A160+|S270"], ["HUMPP", "A150-"], ["AUBRN", "A120|S250"], "#343"],
            "KSEA34L": [["RADDY", "A120|S250"], "HUMPP", "AUBRN", "#250"],
            "KSEA34R": [["RADDY", "A120|S250"], "HUMPP", "AUBRN", "#250"]
        },
        "draw": [
            ["IMB*", "SUNED*", "YKM"],
            ["PDT*", "BRUKK", "SUNED", "YKM"],
            ["YKM", "CHINS*", "RADDY", "HUMPP", "AUBRN"]
        ]
    }
},

STAR is an acronym for Standard Terminal Arrival Route.

"CHINS2": {
    "icao": "CHINS2"
}

Spawn Patterns

At least one spawnPattern is required to get aircraft populating into the app

"spawnPatterns": [
    {
        "origin": "KSEA",
        "destination": "",
        "category": "departure",
        "route": "KSEA.SUMMA1.BKE",
        "altitude": "",
        "speed": "",
        "method": "random",
        "rate": 9,
        "airlines": [
            ["aal", 4],
            ["aca", 1],
            ["asa", 3]
        ]
    },
    {
        "origin": "",
        "destination": "KSEA",
        "category": "arrival",
        "route": "PDT.CHINS2.KSEA",
        "altitude": [18000, 36000],
        "speed": 320,
        "method": "random",
        "rate": 15,
        "airlines": [
            ["aal", 4],
            ["aca", 1],
            ["asa", 3]
        ]
    },
    {
        "origin": "",
        "destination": "",
        "category": "overflight",
        "route": "PDT..PSC..ELN..RADDY..AUBRN..GIGHR..ELMAA..HQM",
        "altitude": [18000, 36000],
        "speed": 320,
        "method": "random",
        "rate": 15,
        "airlines": [
            ["aal", 4],
            ["aca", 1],
            ["asa", 3]
        ]
    }
],

Contains the parameters used to determine how and where aircraft are spawned into the simulation. At least one spawnPattern is required so that aircraft can be added to the simulation.

see spawnPatternReadme.md for more detailed descriptions on data shape and format of a spawnPattern

Maps

At least one map is required for the airport to be loaded into the simulation. In addition to the maps, a defaultMaps property is required to have at least one name referenced. An maps not listed in defaultMaps will not be rendered by default.

"maps": [
    {
        "name": "Base Map",
        "lines": [
            ["N47.46706920", "W122.43465440", "N47.46816390", "W122.43651330"],
            ["N47.46635080", "W122.43369000", "N47.46706920", "W122.43465440"],
            ["N47.46975860", "W122.43977560", "N47.47109720", "W122.44296940"],
            ["N47.46816390", "W122.43651330", "N47.46975860", "W122.43977560"],
            ["N47.46549330", "W122.43386170", "N47.46635080", "W122.43369000"]
        ]
    }
]

Markings on the scope that depict various characteristics of the airspace. When available, this will be an actual Radar Video Map used by the real-world facility.


Reference

Latitude, Longitude, Elevation

For lat, lon, elev values, these formats are acceptable:

Note: For lat, lon values, just omit the elevation.

ICAO and IATA identifiers

Identifiers are unique codes used to differentiate airports, fixes, aircraft, etc. (ex: “KSFO” for the San Francisco Airport). ICAO (the International Civil Aviation Organization) is an international aviation authority that sets safety and consistency standards that make worldwide travel more standardized. ICAO maintains many lists of things they assign their own identifiers (such as aircraft type designators, airport identifiers, etc). Wherever we have those identifiers stored, they will have the label “icao”.

IATA is another international aviation organization (like ICAO) which maintains their own set of identifiers. We include the IATA identifiers for airports in all airport .json files, though they are not currently used for anything.

Flight Level

Flight levels are described by a number, which is this nominal altitude (or, pressure altitude) in hecto-feet, while being a multiple of 500 ft, therefore always ending on 0 or 5. Therefore, a pressure altitude of, for example, 32,000 feet is referred to as “flight level 320”.

Flight levels are usually designated in writing as FLxxx, where xxx is a two or three-digit number indicating the pressure altitude in units of 100 feet. In radio communications, FL290 would be pronounced as “flight level two nine(r) zero.” The phrase “flight level” makes it clear that this refers to the standardized pressure altitude.