Metadata-Version: 2.4
Name: aviconv-asterix
Version: 0.4.0
Summary: Bidirectional EUROCONTROL ASTERIX codec: CAT010 (surface movement), CAT011 (A-SMGCS data), CAT020 (multilateration), CAT021 (ADS-B), CAT034 (monoradar service messages), CAT048 (monoradar target reports), and CAT062 (system tracks) to/from JSON.
Project-URL: Homepage, https://github.com/ams-mmd/aviconv
Project-URL: Documentation, https://ams-mmd.github.io/aviconv/
Project-URL: Source, https://github.com/ams-mmd/aviconv
Project-URL: Issues, https://github.com/ams-mmd/aviconv/issues
Author: aviconv contributors
License: MIT
Keywords: a-smgcs,ads-b,asterix,aviation,cat010,cat011,cat020,cat021,cat034,cat048,cat062,eurocontrol,mlat,monoradar,surveillance
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: aviconv-core<0.1,>=0.0.3
Requires-Dist: click>=8.1
Requires-Dist: pydantic>=2.7
Description-Content-Type: text/markdown

# aviconv-asterix

Bidirectional EUROCONTROL **ASTERIX** codec — part of the
[aviconv](https://github.com/ams-mmd/aviconv) converter family.

Supported categories (pinned editions):

| Category | Content | Edition |
| -------- | ------- | ------- |
| CAT010   | Monosensor Surface Movement Data | **1.1** |
| CAT011   | Transmission of A-SMGCS Data | **1.3** |
| CAT020   | Multilateration Target Reports | **1.10** |
| CAT021   | ADS-B Target Reports | **2.6** |
| CAT034   | Transmission of Monoradar Service Messages | **1.29** |
| CAT048   | Monoradar Target Reports | **1.32** |
| CAT062   | SDPS System Track Data | **1.20** |

## Scope

**Bidirectional.** ASTERIX is a binary sensor/tracker wire format;
aviconv both decodes it into typed, JSON-serialisable records and
encodes records back to binary. As of 0.2.0, `encode(decode(b)) == b`
holds byte-exact for every record carried through `iter_records` (see
[docs/packages/asterix.md](../../docs/packages/asterix.md) for the raw vs.
typed encode paths and the decode-subset LSB-quantisation table).

A *decode subset* of each category is mapped to typed fields (data
source, times, WGS-84 positions, flight levels, velocities, identity);
every other present data item is still measured via its UAP layout and
preserved hex-encoded in `raw_items`, so nothing on the wire is
silently dropped. If a record sets an FSPEC bit with no UAP entry
(edition mismatch), that data block is undecodable — the block LEN is
used to resynchronise at the next block (`--skip-errors`).

**CAT048 position is polar, not WGS-84.** I048/040 carries slant range
+ azimuth relative to the reporting radar, not a lat/lon — ASTERIX does
not carry the radar site's own position, so no georeferencing is
possible from a CAT048 record alone. `Cat048Record` exposes `rho_nm`
and `theta_deg` and deliberately has no `lat`/`lon` field.

**Position honesty extends to CAT010/CAT020, each in its own way.**
`Cat020Record` carries WGS-84 (`lat`/`lon`) *and* local Cartesian
(`x_m`/`y_m`) as two independent wire items — both may be present on
the same record, and neither is ever derived from the other.
`Cat010Record` instead carries exactly one of three position kinds
depending on sensor type — polar (`rho_m`/`theta_deg`, sensor-relative,
in **metres**, not the NM `Cat048Record` uses), WGS-84 (`lat`/`lon`), or
local Cartesian (`x_m`/`y_m`) — and the other two stay `None` rather
than being synthesised across kinds. `Cat011Record` (A-SMGCS fused
system tracks) mirrors `Cat020Record`'s two-kind shape rather than
`Cat010Record`'s three-kind one — WGS-84 (`lat`/`lon`) and local
Cartesian (`x_m`/`y_m`) are two independent wire items, both exposed
when present, neither ever derived from the other; there is no polar
flavour, since fused tracks are not sensor-relative.

## Usage

```python
from aviconv_asterix import encode_records, iter_records

records = list(iter_records(open("radar.ast", "rb").read()))
print(records[0].callsign, records[0].lat, records[0].lon)

encode_records(records) == open("radar.ast", "rb").read()  # True
```

Every record decoded via `iter_records` carries its original octets in
`raw_items`; re-encoding it (unmodified or not) re-emits those octets
verbatim, byte-exact, regardless of any typed-field edits made via
`model_copy`. Records built from scratch (no `raw_items`) encode from
their typed fields instead, via each item's `build` callable — see
[docs/packages/asterix.md](../../docs/packages/asterix.md) for which items
have one wired.

CLI (NDJSON, one record per line):

```
aviconv asterix decode radar.ast
aviconv asterix decode - < radar.ast          # binary stdin
aviconv asterix decode radar.ast --skip-errors -o out.ndjson

aviconv asterix encode records.ndjson -o radar.ast
aviconv asterix decode radar.ast | aviconv asterix encode -   # round-trip
```

## Licence

MIT. The ASTERIX category specifications are published by EUROCONTROL;
this package is not endorsed by or affiliated with EUROCONTROL.
