Skip to content

coordinates

cosmica.utils.coordinates

__all__ module-attribute

__all__ = [
    "calc_dcm_eci2ecef",
    "ecef2aer",
    "geodetic2ecef",
    "greenwichsrt",
    "juliandate",
]

calc_dcm_eci2ecef

calc_dcm_eci2ecef(
    time: datetime64 | NDArray[datetime64],
) -> NDArray[float64]

Calculate the direction cosine matrix from ECI to ECEF.

Input is UTC time. If the input is a single time, the output is a 3x3 matrix. If the input is an array of times, the output is a Nx3x3 array.

Source code in src/cosmica/utils/coordinates.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def calc_dcm_eci2ecef(time: np.datetime64 | npt.NDArray[np.datetime64]) -> npt.NDArray[np.float64]:
    """Calculate the direction cosine matrix from ECI to ECEF.

    Input is UTC time.
    If the input is a single time, the output is a 3x3 matrix.
    If the input is an array of times, the output is a Nx3x3 array.
    """
    gst = greenwichsrt(time)
    if isinstance(gst, float):
        return np.array(
            [
                [np.cos(gst), np.sin(gst), 0],
                [-np.sin(gst), np.cos(gst), 0],
                [0, 0, 1],
            ],
        )
    else:
        return np.stack(
            [
                np.stack(
                    [
                        np.cos(gst),
                        np.sin(gst),
                        np.zeros_like(gst),
                    ],
                    axis=-1,
                ),
                np.stack(
                    [
                        -np.sin(gst),
                        np.cos(gst),
                        np.zeros_like(gst),
                    ],
                    axis=-1,
                ),
                np.stack(
                    [
                        np.zeros_like(gst),
                        np.zeros_like(gst),
                        np.ones_like(gst),
                    ],
                    axis=-1,
                ),
            ],
            axis=-2,
        )

ecef2aer

ecef2aer(
    x,
    y,
    z,
    lat0,
    lon0,
    h0,
    ell: Ellipsoid | None = None,
    deg: bool = True,
) -> tuple

compute azimuth, elevation and slant range from an Observer to a Point with ECEF coordinates.

ECEF input location is with units of meters

Parameters
float

ECEF x coordinate (meters)

y : float ECEF y coordinate (meters) z : float ECEF z coordinate (meters) lat0 : float Observer geodetic latitude lon0 : float Observer geodetic longitude h0 : float observer altitude above geodetic ellipsoid (meters) ell : Ellipsoid, optional reference ellipsoid deg : bool, optional degrees input/output (False: radians in/out)

Returns

az : float azimuth to target el : float elevation to target srange : float slant range [meters]

Source code in .venv/lib/python3.13/site-packages/pymap3d/aer.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def ecef2aer(
    x,
    y,
    z,
    lat0,
    lon0,
    h0,
    ell: Ellipsoid | None = None,
    deg: bool = True,
) -> tuple:
    """
    compute azimuth, elevation and slant range from an Observer to a Point with ECEF coordinates.

    ECEF input location is with units of meters

    Parameters
    ----------

    x : float
        ECEF x coordinate (meters)
    y : float
        ECEF y coordinate (meters)
    z : float
        ECEF z coordinate (meters)
    lat0 : float
        Observer geodetic latitude
    lon0 : float
        Observer geodetic longitude
    h0 : float
         observer altitude above geodetic ellipsoid (meters)
    ell : Ellipsoid, optional
        reference ellipsoid
    deg : bool, optional
        degrees input/output  (False: radians in/out)

    Returns
    -------
    az : float
         azimuth to target
    el : float
         elevation to target
    srange : float
         slant range [meters]
    """

    xEast, yNorth, zUp = ecef2enu(x, y, z, lat0, lon0, h0, ell, deg=deg)

    return enu2aer(xEast, yNorth, zUp, deg=deg)

geodetic2ecef

geodetic2ecef(
    lat,
    lon,
    alt,
    ell: Ellipsoid | None = None,
    deg: bool = True,
) -> tuple

point transformation from Geodetic of specified ellipsoid (default WGS-84) to ECEF

Parameters

lat target geodetic latitude lon target geodetic longitude alt target altitude above geodetic ellipsoid (meters) ell : Ellipsoid, optional reference ellipsoid deg : bool, optional degrees input/output (False: radians in/out)

Returns

ECEF (Earth centered, Earth fixed) x,y,z

x target x ECEF coordinate (meters) y target y ECEF coordinate (meters) z target z ECEF coordinate (meters)

Source code in .venv/lib/python3.13/site-packages/pymap3d/ecef.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
def geodetic2ecef(
    lat,
    lon,
    alt,
    ell: Ellipsoid | None = None,
    deg: bool = True,
) -> tuple:
    """
    point transformation from Geodetic of specified ellipsoid (default WGS-84) to ECEF

    Parameters
    ----------

    lat
           target geodetic latitude
    lon
           target geodetic longitude
    alt
         target altitude above geodetic ellipsoid (meters)
    ell : Ellipsoid, optional
          reference ellipsoid
    deg : bool, optional
          degrees input/output  (False: radians in/out)


    Returns
    -------

    ECEF (Earth centered, Earth fixed)  x,y,z

    x
        target x ECEF coordinate (meters)
    y
        target y ECEF coordinate (meters)
    z
        target z ECEF coordinate (meters)
    """

    if deg:
        lat = radians(lat)
        lon = radians(lon)

    if ell is None:
        ell = Ellipsoid.from_name("wgs84")

    # radius of curvature of the prime vertical section
    N = ell.semimajor_axis**2 / hypot(ell.semimajor_axis * cos(lat), ell.semiminor_axis * sin(lat))
    # Compute cartesian (geocentric) coordinates given (curvilinear) geodetic coordinates.
    x = (N + alt) * cos(lat) * cos(lon)
    y = (N + alt) * cos(lat) * sin(lon)
    z = (N * (ell.semiminor_axis / ell.semimajor_axis) ** 2 + alt) * sin(lat)

    return x, y, z

greenwichsrt

greenwichsrt(time: datetime64) -> float
greenwichsrt(time: NDArray[datetime64]) -> NDArray[float64]
greenwichsrt(time)
Source code in src/cosmica/utils/coordinates.py
38
39
def greenwichsrt(time):
    return _greenwichsrt(juliandate(time))

juliandate

juliandate(time: datetime64) -> float
juliandate(time: NDArray[datetime64]) -> NDArray[float64]
juliandate(time)
Source code in src/cosmica/utils/coordinates.py
26
27
def juliandate(time):
    return pd.to_datetime(time).to_julian_date()