Skip to content

Coverage

Compute when spacecraft can observe ground areas of interest.

Overview

The imaging analysis module determines when a spacecraft's sensor footprint intersects a geographic polygon (AOI). It works by computing the sub-satellite point at each time step and checking whether the sensor's ground-accessible range (swath width plus off-nadir pointing capability) reaches the AOI.

The analysis integrates with the existing event detection framework, so imaging windows are computed via root-finding on a continuous signal function — the same approach used for visibility analysis.

Quick Example

import lox_space as lox

# 1. Define the sensor payload
payload = lox.ImagingPayload.nadir_only(290.0 * lox.km)       # Sentinel-2-like
# payload = lox.ImagingPayload.off_nadir(20 * lox.km, 30 * lox.deg)  # off-nadir pointing

# 2. Create spacecraft with the payload attached
sc = lox.Spacecraft("S2A", sgp4_propagator, imaging_payload=payload)

# 3. Build a scenario
scenario = lox.Scenario(t0, t1, spacecraft=[sc])

# 4. Define areas of interest
rome = lox.Aoi([(12.2, 41.7), (12.7, 41.7), (12.7, 42.1), (12.2, 42.1), (12.2, 41.7)])

# Or from GeoJSON
sicily = lox.Aoi.from_geojson('{"type":"Polygon","coordinates":[[[13,37],[16,37],[16,39],[13,39],[13,37]]]}')

# 5. Run the analysis
analysis = lox.ImagingAnalysis(
    scenario,
    aois=[("rome", rome), ("sicily", sicily)],
    step=30 * lox.seconds,
)
results = analysis.compute()

# 6. Inspect results
for iv in results.intervals("S2A", "rome"):
    print(f"{iv.start()}{iv.end()}  ({float(iv.duration()):.0f}s)")

Sensor Models

Nadir-Only

For sensors that image straight down (e.g. Sentinel-2), the accessible ground range equals half the swath width:

payload = lox.ImagingPayload.nadir_only(290.0 * lox.km)

Off-Nadir Pointing

For satellites that can point away from nadir to image targets, the accessible range is the sum of the off-nadir ground range and half the swath width:

payload = lox.ImagingPayload.off_nadir(
    swath_width=20.0 * lox.km,
    max_off_nadir=30.0 * lox.deg,
)

The off-nadir ground range is computed geometrically from the spacecraft altitude, the maximum off-nadir angle, and the body's mean radius.

Attaching Payloads to Spacecraft

Spacecraft without a payload are silently skipped during analysis:

# With payload — will be included in imaging analysis
sc1 = lox.Spacecraft("imager", orbit, imaging_payload=payload)

# Without payload — will be skipped
sc2 = lox.Spacecraft("relay", orbit)

scenario = lox.Scenario(t0, t1, spacecraft=[sc1, sc2])
# Only sc1 will produce imaging windows

Aoi

An area of interest (AOI) defined as a geographic polygon.

Coordinates follow GeoJSON convention: longitude/latitude in degrees.

Parameters:

  • coords

    List of (longitude, latitude) tuples forming the polygon exterior ring. The ring should be closed (first == last).

Examples:

>>> aoi = lox.Aoi([(10, 45), (11, 45), (11, 46), (10, 46), (10, 45)])
>>> aoi = lox.Aoi.from_geojson('{"type":"Polygon","coordinates":[[[10,45],[11,45],[11,46],[10,46],[10,45]]]}')

Methods:

from_geojson classmethod

from_geojson(geojson: str) -> Self

Parse an AOI from a GeoJSON string.

Expects a GeoJSON Polygon geometry, Feature, or FeatureCollection.


ImagingPayload

Imaging sensor payload describing a spacecraft's ground coverage capability.

Defines the sensor's swath width and optional off-nadir pointing capability. Assign to a spacecraft via the imaging_payload parameter.

Examples:

>>> payload = lox.ImagingPayload.nadir_only(20.0 * lox.km)
>>> payload = lox.ImagingPayload.off_nadir(20.0 * lox.km, 30.0 * lox.deg)
>>> sc = lox.Spacecraft("sat1", orbit, imaging_payload=payload)

Methods:

  • nadir_only

    Create a payload for a nadir-only sensor.

  • off_nadir

    Create a payload for a sensor with off-nadir pointing capability.

nadir_only classmethod

nadir_only(swath_width: Distance) -> Self

Create a payload for a nadir-only sensor.

Parameters:

  • swath_width

    (Distance) –

    Full swath width as Distance.

off_nadir classmethod

Create a payload for a sensor with off-nadir pointing capability.

Parameters:

  • swath_width

    (Distance) –

    Full swath width as Distance.

  • max_off_nadir

    (Angle) –

    Maximum off-nadir angle as Angle.


ImagingAnalysis

AOI imaging analysis: computes imaging windows for spacecraft over AOIs.

Imaging payloads are read from each spacecraft; spacecraft without a payload are silently skipped.

Parameters:

  • scenario

    Scenario containing spacecraft with imaging_payload.

  • aois

    List of (id, Aoi) tuples defining the areas of interest.

  • ensemble

    Optional pre-computed Ensemble.

  • step

    Optional time step for event detection (default: 60s).

  • body_fixed_frame

    Optional body-fixed frame override.

Examples:

>>> payload = lox.ImagingPayload.off_nadir(20.0 * lox.km, 30.0 * lox.deg)
>>> sc = lox.Spacecraft("sat1", orbit, imaging_payload=payload)
>>> scenario = lox.Scenario(t0, t1, spacecraft=[sc])
>>> aoi = lox.Aoi.from_geojson('{"type":"Polygon","coordinates":[[[10,45],[11,45],[11,46],[10,46],[10,45]]]}')
>>> imaging = lox.ImagingAnalysis(scenario, aois=[("rome", aoi)])
>>> results = imaging.compute()

Methods:

  • compute

    Compute imaging intervals for all (spacecraft, AOI) pairs.

compute

compute() -> ImagingResults

Compute imaging intervals for all (spacecraft, AOI) pairs.

If no ensemble was provided, the scenario is propagated automatically. Spacecraft without an imaging payload are skipped.


ImagingResults

Results of an imaging analysis.

Provides access to imaging intervals for each (spacecraft, AOI) pair.

Methods:

  • all_intervals

    Return all intervals for all (spacecraft, AOI) pairs.

  • intervals

    Return imaging intervals for a specific pair.

all_intervals

all_intervals() -> dict[tuple[str, str], list[Interval]]

Return all intervals for all (spacecraft, AOI) pairs.

intervals

Return imaging intervals for a specific pair.

Parameters:

  • spacecraft_id

    (str) –

    Spacecraft identifier.

  • aoi_id

    (str) –

    AOI identifier.

Returns:

  • list[Interval]

    List of Interval objects, or empty list if pair not found.