TypeScript parser for AIXM 5.1.1 aeronautical data with temporal model and GML geometry
TypeScript
0
6 commits
updated Sep 9, 2026
First JavaScript/TypeScript parser for AIXM 5.1.1 (Aeronautical Information Exchange Model) with geodesic geometry, temporal model, and GeoJSON output.
aixm-to-geojson input.xml output.geojsonnpm install aixm-parser
import { parse } from 'aixm-parser';
import { readFileSync } from 'fs';
const xml = readFileSync('Donlon.xml', 'utf-8');
const result = await parse(xml);
// High-level accessors
const airports = result.airports();
const airspaces = result.airspaces();
const navaids = result.navaids();
console.log(`${airports.length} airports, ${airspaces.length} airspaces, ${navaids.length} navaids`);
// Access typed properties
for (const apt of airports) {
console.log(apt.properties.name, apt.properties.locationIndicatorICAO);
}
npm install -g aixm-parser # or: npx -p aixm-parser aixm-to-geojson ...
aixm-to-geojson input.xml output.geojson
aixm-to-geojson input.xml --pretty > out.geojson
aixm-to-geojson input.xml output.geojson --stats --tolerance 50
Options: --keep-null (keep features without geometry), --tolerance <m> (densification, default 100), --pretty, --stats.
// Convert all features to a GeoJSON FeatureCollection
const geojson = result.toGeoJSON();
// Skip features without geometry (e.g. organisations, frequencies)
const spatial = result.toGeoJSON({ skipNullGeometry: true });
// Or convert individual features
import { featureToGeoJSON, extractGeometry } from 'aixm-parser';
const feature = result.features[0];
const geoFeature = featureToGeoJSON(feature);
const geometry = extractGeometry(feature.xmlChunk);
Supported GML geometry types:
gml:Point / aixm:ElevatedPoint (elevation as third coordinate)gml:CircleByCenterPoint (densified on WGS84 ellipsoid)gml:ArcByCenterPoint (geodesic arc via Karney algorithm)gml:GeodesicString / gml:Geodesic (great circle segments)gml:Curve / aixm:ElevatedCurve (compound curves with multiple segments)gml:PolygonPatch with exterior/interior ringsaixm:Surface / aixm:ElevatedSurfaceresult.toGeoJSON() additionally:
<gml:pointProperty xlink:href="#id"/> across the whole documentRoute features from their RouteSegment LineStrings (MultiLineString)AIXM features change over time through TimeSlices. Query the state at any point in time:
// Get feature state at a specific timestamp
const state = result.featureAt('uuid.abc-123', new Date('2024-06-01'));
console.log(state.properties.name); // merged from BASELINE + deltas
console.log(state.activeTemporalOverlays); // number of active TEMPDELTAs
// Low-level: compute state from a raw feature
import { computeState, getTimeline } from 'aixm-parser';
const timeline = getTimeline(rawFeature); // all states in chronological order
const current = computeState(rawFeature, new Date());
AIXM features reference each other via xlink:href. The built-in registry resolves them:
const { registry } = await parse(xml);
// Resolve a single reference
const airport = registry.resolve('urn:uuid:abc-123');
const navaid = registry.resolve('#NAV_DON');
// Resolve all pending references
const resolved = registry.resolveAll();
const unresolved = resolved.filter(r => !r.target);
// Reverse lookup: who references this feature?
const referencing = registry.getReferencingFeatures('uuid-of-airport');
// Build the full reference graph
const graph = registry.buildGraph();
// Detect circular references
const cycles = registry.detectCircularRefs();
Arc and circle geometry is computed on the WGS84 ellipsoid using the Karney algorithm:
import { densifyArcByCenterPoint, densifyCircle, geodesicDistance } from 'aixm-parser';
// Arc from 090 to 270 degrees clockwise, radius 5km
const arc = densifyArcByCenterPoint(
{ lon: -1.0, lat: 51.0 }, 5000, 90, 270, true, 100
);
// Circle with 15 NM radius
const circle = densifyCircle(
{ lon: -22.1, lat: 52.37 }, 15 * 1852, 100
);
// Distance between two points
const dist = geodesicDistance(
{ lon: -0.1278, lat: 51.5074 }, // London
{ lon: 2.3522, lat: 48.8566 } // Paris
);
30 AIXM feature types with TypeScript interfaces:
| Category | Types |
|---|---|
| Aerodromes | AirportHeliport, Runway, RunwayDirection, Taxiway, Apron, AircraftStand, TouchDownLiftOff |
| Airspace | Airspace |
| Navigation | Navaid, VOR, DME, NDB, TACAN, DesignatedPoint, MarkerBeacon, Localizer, Glidepath |
| Routes | Route, RouteSegment, HoldingPattern |
| Obstacles | VerticalStructure, ObstacleArea |
| Services | AirTrafficControlService, SearchRescueService, InformationService, RadioCommunicationChannel |
| Organization | OrganisationAuthority, Unit, GeoBorder, SpecialDate |
parse(xml, options?)Main entry point. Returns a ParseResult with:
| Property | Description |
|---|---|
features | Raw features as extracted from XML |
typed | Typed features with structured properties |
registry | Feature registry for cross-reference resolution |
featureAt(id, date?) | Get feature state at a point in time |
airspaces() | All Airspace features |
airports() | All AirportHeliport features |
runways() | All Runway features |
navaids() | All navaid features (VOR, DME, NDB, TACAN, Navaid) |
waypoints() | All DesignatedPoint features |
routes() | All Route features |
routeSegments() | All RouteSegment features |
obstacles() | All VerticalStructure features |
toGeoJSON(options?) | Convert to GeoJSON FeatureCollection |
diagnostics() | Parse and reference-resolution diagnostics |
interface ParseOptions {
errorMode?: 'strict' | 'lenient'; // default: 'lenient'
}
interface GmlToGeoJSONOptions {
toleranceMeters?: number; // densification tolerance, default: 100
skipNullGeometry?: boolean; // omit features without geometry
pointResolver?: (gmlId: string) => Position | null; // custom center resolver
}
MIT
6 commits
TypeScript
100.0%
TypeScript parser for AIXM 5.1.1 aeronautical data with temporal model and GML geometry
TypeScript
0
6 commits
updated Sep 9, 2026
First JavaScript/TypeScript parser for AIXM 5.1.1 (Aeronautical Information Exchange Model) with geodesic geometry, temporal model, and GeoJSON output.
aixm-to-geojson input.xml output.geojsonnpm install aixm-parser
import { parse } from 'aixm-parser';
import { readFileSync } from 'fs';
const xml = readFileSync('Donlon.xml', 'utf-8');
const result = await parse(xml);
// High-level accessors
const airports = result.airports();
const airspaces = result.airspaces();
const navaids = result.navaids();
console.log(`${airports.length} airports, ${airspaces.length} airspaces, ${navaids.length} navaids`);
// Access typed properties
for (const apt of airports) {
console.log(apt.properties.name, apt.properties.locationIndicatorICAO);
}
npm install -g aixm-parser # or: npx -p aixm-parser aixm-to-geojson ...
aixm-to-geojson input.xml output.geojson
aixm-to-geojson input.xml --pretty > out.geojson
aixm-to-geojson input.xml output.geojson --stats --tolerance 50
Options: --keep-null (keep features without geometry), --tolerance <m> (densification, default 100), --pretty, --stats.
// Convert all features to a GeoJSON FeatureCollection
const geojson = result.toGeoJSON();
// Skip features without geometry (e.g. organisations, frequencies)
const spatial = result.toGeoJSON({ skipNullGeometry: true });
// Or convert individual features
import { featureToGeoJSON, extractGeometry } from 'aixm-parser';
const feature = result.features[0];
const geoFeature = featureToGeoJSON(feature);
const geometry = extractGeometry(feature.xmlChunk);
Supported GML geometry types:
gml:Point / aixm:ElevatedPoint (elevation as third coordinate)gml:CircleByCenterPoint (densified on WGS84 ellipsoid)gml:ArcByCenterPoint (geodesic arc via Karney algorithm)gml:GeodesicString / gml:Geodesic (great circle segments)gml:Curve / aixm:ElevatedCurve (compound curves with multiple segments)gml:PolygonPatch with exterior/interior ringsaixm:Surface / aixm:ElevatedSurfaceresult.toGeoJSON() additionally:
<gml:pointProperty xlink:href="#id"/> across the whole documentRoute features from their RouteSegment LineStrings (MultiLineString)AIXM features change over time through TimeSlices. Query the state at any point in time:
// Get feature state at a specific timestamp
const state = result.featureAt('uuid.abc-123', new Date('2024-06-01'));
console.log(state.properties.name); // merged from BASELINE + deltas
console.log(state.activeTemporalOverlays); // number of active TEMPDELTAs
// Low-level: compute state from a raw feature
import { computeState, getTimeline } from 'aixm-parser';
const timeline = getTimeline(rawFeature); // all states in chronological order
const current = computeState(rawFeature, new Date());
AIXM features reference each other via xlink:href. The built-in registry resolves them:
const { registry } = await parse(xml);
// Resolve a single reference
const airport = registry.resolve('urn:uuid:abc-123');
const navaid = registry.resolve('#NAV_DON');
// Resolve all pending references
const resolved = registry.resolveAll();
const unresolved = resolved.filter(r => !r.target);
// Reverse lookup: who references this feature?
const referencing = registry.getReferencingFeatures('uuid-of-airport');
// Build the full reference graph
const graph = registry.buildGraph();
// Detect circular references
const cycles = registry.detectCircularRefs();
Arc and circle geometry is computed on the WGS84 ellipsoid using the Karney algorithm:
import { densifyArcByCenterPoint, densifyCircle, geodesicDistance } from 'aixm-parser';
// Arc from 090 to 270 degrees clockwise, radius 5km
const arc = densifyArcByCenterPoint(
{ lon: -1.0, lat: 51.0 }, 5000, 90, 270, true, 100
);
// Circle with 15 NM radius
const circle = densifyCircle(
{ lon: -22.1, lat: 52.37 }, 15 * 1852, 100
);
// Distance between two points
const dist = geodesicDistance(
{ lon: -0.1278, lat: 51.5074 }, // London
{ lon: 2.3522, lat: 48.8566 } // Paris
);
30 AIXM feature types with TypeScript interfaces:
| Category | Types |
|---|---|
| Aerodromes | AirportHeliport, Runway, RunwayDirection, Taxiway, Apron, AircraftStand, TouchDownLiftOff |
| Airspace | Airspace |
| Navigation | Navaid, VOR, DME, NDB, TACAN, DesignatedPoint, MarkerBeacon, Localizer, Glidepath |
| Routes | Route, RouteSegment, HoldingPattern |
| Obstacles | VerticalStructure, ObstacleArea |
| Services | AirTrafficControlService, SearchRescueService, InformationService, RadioCommunicationChannel |
| Organization | OrganisationAuthority, Unit, GeoBorder, SpecialDate |
parse(xml, options?)Main entry point. Returns a ParseResult with:
| Property | Description |
|---|---|
features | Raw features as extracted from XML |
typed | Typed features with structured properties |
registry | Feature registry for cross-reference resolution |
featureAt(id, date?) | Get feature state at a point in time |
airspaces() | All Airspace features |
airports() | All AirportHeliport features |
runways() | All Runway features |
navaids() | All navaid features (VOR, DME, NDB, TACAN, Navaid) |
waypoints() | All DesignatedPoint features |
routes() | All Route features |
routeSegments() | All RouteSegment features |
obstacles() | All VerticalStructure features |
toGeoJSON(options?) | Convert to GeoJSON FeatureCollection |
diagnostics() | Parse and reference-resolution diagnostics |
interface ParseOptions {
errorMode?: 'strict' | 'lenient'; // default: 'lenient'
}
interface GmlToGeoJSONOptions {
toleranceMeters?: number; // densification tolerance, default: 100
skipNullGeometry?: boolean; // omit features without geometry
pointResolver?: (gmlId: string) => Position | null; // custom center resolver
}
MIT
6 commits
TypeScript
100.0%