Annotations
Overview
The nav.annotation subsystem produces the per-image summary-PNG
overlay. Every NavModel exposes a
to_annotations(context) method that returns a fresh
Annotations collection holding the
labels and graphical primitives for that one model’s contribution
(body silhouettes, ring polylines, star markers, etc.). The
orchestrator merges every model’s collection into
annotations via
add_annotations(); the
top-level driver (navigate_image_files())
then calls
combine() to render the
final RGB overlay and composites it onto the contrast-stretched source
image before writing the PNG.
Class hierarchy
The subsystem is intentionally narrow: four shipping types and no abstract base.
Annotation— a single typed primitive (line, polyline, marker, text). Each instance carries an RGBA overlay array, an overlay color, an optional avoid-mask used by the label placer, and a list of attachedAnnotationTextInfoentries.AnnotationTextInfo— text payload + placement parameters (anchor location, arrow style, font color). The placement constants (TEXTINFO_TOP,TEXTINFO_BOTTOM_LEFT,TEXTINFO_LEFT_ARROW, etc.) name the twelve supported anchor / arrow combinations.TextLocInfo— the label placer’s per-text resolution result (chosen pixel position, arrow tail, fitness score).Annotations— collection ofAnnotationinstances. Subclass ofNavBaseso it inheritsconfigandlogger.
Pipeline
Annotation flow during a single navigation run:
Per-model emission. Each
NavModelbuilds itsAnnotationscollection into_annotations(context). Concrete bodies / rings / stars use the shared helpers onNavModelBodyBaseandNavModelRingsBaseso the silhouette / polyline rendering is consistent across models.Orchestrator merge. The orchestrator’s
_collect_annotationsstep builds an emptyAnnotationsand callsadd_annotations()for each surviving model’s contribution. The merged collection is recorded onannotations.Final composition.
navigate_image_files()callscombine()with the navigation offset.combineruns the label placer (consulting eachAnnotation’s avoid-mask), shifts every overlay by the offset, and produces a single RGB overlay array. The driver composites that overlay over the contrast-stretched source image and writes the PNG.
Reading the per-image PNG therefore tells the operator three things in
one image: what was in the source (background), what each
NavModel
predicted (overlay), and where the orchestrator placed the predictions
relative to the data (the offset shift applied at composition time).
Configuration
The nav.annotation subsystem itself consumes no YAML
configuration. The label / color knobs live in the per-NavModel
config blocks instead:
bodies.label_*,bodies.outline_thicken,bodies.min_text_areainsrc/nav/config_files/config_040_bodies.yaml(consumed viaNavModelBodyBase).rings.label_*insrc/nav/config_files/config_050_rings.yaml(consumed viaNavModelRingsBase).stars.label_*andstars.label_star_colorinsrc/nav/config_files/config_030_stars.yaml(consumed viaNavModelStars).
Each per-NavModel page documents the relevant subset:
Body Navigation Model,
Ring Navigation Model, and
Star Navigation Model.
Per-model annotation contributions
Body —
to_annotations()emits a body silhouette outline plus a body-name label with leader arrow. The label placer scans the limb for a clear gap and falls back to a coarse grid when no per-limb candidate fits.Ring —
to_annotations()emits one polyline per surviving ring edge plus a per-planet label.Star —
to_annotations()emits a per-star marker plus an optional per-star magnitude label.Simulated body / rings — the simulated NavModels reuse their catalog-driven counterparts’ annotation helpers, so a simulated scene’s PNG overlay is visually indistinguishable from a real scene’s.
Titan — the placeholder
to_annotations()returns an empty collection.
API reference
The autodocumented API surface is at nav.annotation.