Skip to content

Topocentric

East-North-Zenith (ENZ) topocentric coordinate transformations.

Converts between Earth-Centered Earth-Fixed (ECEF) Cartesian coordinates and a local topocentric frame defined by East, North, and Zenith axes at an observer location on the Earth's surface. Also provides conversion from ENZ to azimuth, elevation, and range.

The ENZ frame is a right-handed coordinate system:

  • East (E): tangent to the surface, pointing geographic east
  • North (N): tangent to the surface, pointing geographic north
  • Zenith (Z): normal to the surface, pointing radially outward

All inputs and outputs use SI base units (metres, radians) unless use_degrees=True is specified.

position_enz_to_azel(x_enz, use_degrees=False)

Convert ENZ position to azimuth, elevation, and range.

Azimuth is measured clockwise from North (0° = North, 90° = East). Elevation is measured from the local horizon (0°) to zenith (90°).

At the zenith singularity (elevation = 90°), azimuth is defined as 0.

Parameters:

Name Type Description Default
x_enz ArrayLike

ENZ position [east, north, zenith] in m.

required
use_degrees bool

If True, return azimuth and elevation in degrees.

False

Returns:

Type Description
Array

[azimuth, elevation, range]. Azimuth in [0, 2pi) rad (or [0, 360) deg), elevation in [-pi/2, pi/2] rad, range in m.

Examples:

import jax.numpy as jnp
from astrojax.coordinates import position_enz_to_azel
x_enz = jnp.array([100.0, 0.0, 0.0])
azel = position_enz_to_azel(x_enz, use_degrees=True)
# azel ≈ [90.0, 0.0, 100.0]

relative_position_ecef_to_enz(location_ecef, r_ecef, use_geodetic=True)

Convert an ECEF position to ENZ relative to an observer station.

Computes the ENZ components of r_ecef - location_ecef by first determining the station's ellipsoidal coordinates (geodetic or geocentric) and then applying the ECEF→ENZ rotation.

Parameters:

Name Type Description Default
location_ecef ArrayLike

ECEF position of the observing station [x, y, z] in m.

required
r_ecef ArrayLike

ECEF position of the target object [x, y, z] in m.

required
use_geodetic bool

If True (default), use geodetic coordinates to define the local frame. If False, use geocentric.

True

Returns:

Type Description
Array

Relative position [east, north, zenith] in m.

Examples:

import jax.numpy as jnp
from astrojax.constants import R_EARTH
from astrojax.coordinates import relative_position_ecef_to_enz
x_sta = jnp.array([R_EARTH, 0.0, 0.0])
x_sat = jnp.array([R_EARTH + 500e3, 0.0, 0.0])
r_enz = relative_position_ecef_to_enz(x_sta, x_sat)

relative_position_enz_to_ecef(location_ecef, r_enz, use_geodetic=True)

Convert an ENZ relative position back to absolute ECEF.

Inverse of :func:relative_position_ecef_to_enz.

Parameters:

Name Type Description Default
location_ecef ArrayLike

ECEF position of the observing station [x, y, z] in m.

required
r_enz ArrayLike

Relative position [east, north, zenith] in m.

required
use_geodetic bool

If True (default), use geodetic coordinates to define the local frame. If False, use geocentric.

True

Returns:

Type Description
Array

Absolute ECEF position [x, y, z] in m.

Examples:

import jax.numpy as jnp
from astrojax.constants import R_EARTH
from astrojax.coordinates import relative_position_enz_to_ecef
x_sta = jnp.array([R_EARTH, 0.0, 0.0])
r_enz = jnp.array([0.0, 0.0, 500e3])
r_ecef = relative_position_enz_to_ecef(x_sta, r_enz)

rotation_ellipsoid_to_enz(x_ellipsoid, use_degrees=False)

Compute the rotation matrix from ECEF to East-North-Zenith (ENZ).

The input ellipsoidal coordinates specify the observer location. The returned 3x3 matrix transforms a vector in ECEF into the local ENZ frame at that location.

Parameters:

Name Type Description Default
x_ellipsoid ArrayLike

Ellipsoidal coordinates [lon, lat, alt]. Longitude and latitude in rad (or deg if use_degrees=True), altitude in m.

required
use_degrees bool

If True, interpret longitude and latitude as degrees.

False

Returns:

Type Description
Array

3x3 rotation matrix (ECEF → ENZ).

Examples:

import jax.numpy as jnp
from astrojax.coordinates import rotation_ellipsoid_to_enz
x_geo = jnp.array([30.0, 60.0, 0.0])
rot = rotation_ellipsoid_to_enz(x_geo, use_degrees=True)

rotation_enz_to_ellipsoid(x_ellipsoid, use_degrees=False)

Compute the rotation matrix from ENZ to ECEF.

This is the transpose of :func:rotation_ellipsoid_to_enz.

Parameters:

Name Type Description Default
x_ellipsoid ArrayLike

Ellipsoidal coordinates [lon, lat, alt]. Longitude and latitude in rad (or deg if use_degrees=True), altitude in m.

required
use_degrees bool

If True, interpret longitude and latitude as degrees.

False

Returns:

Type Description
Array

3x3 rotation matrix (ENZ → ECEF).

Examples:

import jax.numpy as jnp
from astrojax.coordinates import rotation_enz_to_ellipsoid
x_geo = jnp.array([30.0, 60.0, 0.0])
rot_inv = rotation_enz_to_ellipsoid(x_geo, use_degrees=True)