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:
-
–coordsList 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–Parse an AOI from a GeoJSON string.
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_widthDistance) –Full swath width as Distance.
off_nadir
classmethod
off_nadir(swath_width: Distance, max_off_nadir: Angle) -> Self
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:
-
–scenarioScenario containing spacecraft with
imaging_payload. -
–aoisList of (id, Aoi) tuples defining the areas of interest.
-
–ensembleOptional pre-computed Ensemble.
-
–stepOptional time step for event detection (default: 60s).
-
–body_fixed_frameOptional 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
Return all intervals for all (spacecraft, AOI) pairs.