Coordinates usage
The main functions available in perseo_core.geometry.coordinates are:
xyz2llh: Convert XYZ ECEF cartesian coordinates to geodetic LLH (latitude, longitude, height)llh2xyz: Convert geodetic LLH coordinates to XYZ ECEF cartesian coordinatesutm2llh: Convert UTM (Easting, Northing, Height) coordinates to geodetic LLH (latitude, longitude, height)llh2utm: Convert geodetic LLH (latitude, longitude, height) coordinates to UTM (Easting, Northing, Height)ecef2eci: Transform positions and velocities from ECEF (ITRS) to ECI (GCRS) frameeci2ecef: Transform positions and velocities from ECI (GCRS) to ECEF (ITRS) frame
All functions support both scalar inputs and batch operations on arrays of coordinates.
ECEF <-> LLH conversion
Convert Earth-Centered Earth-Fixed (ECEF) cartesian coordinates to geodetic Latitude, Longitude, Height (LLH) and vice versa.
Batch coordinate conversion
import numpy as np
from perseo_core.geometry.coordinates import xyz2llh, llh2xyz
# multiple points (N, 3) array, lat [deg]/lon[deg]/height[m]
llh_coords_deg = np.array(
[
[-26.83470987, 151.1656039, 409.4544], # Point 1
[-26.94651144, 151.1438779, 390.5168], # Point 2
[-27.08563567, 150.2596331, 371.1494], # Point 3
[-27.30887139, 151.2719591, 385.2427], # Point 4
]
)
# convert all points at once, return (N, 3) array
xyz_array_from_deg = llh2xyz(coordinates=llh_coords_deg, radians=False)
# this is equivalent to:
llh_coords_rad = llh_coords_deg.copy()
llh_coords_rad[:, :2] = np.deg2rad(llh_coords_deg[:, :2])
# returns (N, 3) array
xyz_array_from_rad = llh2xyz(coordinates=llh_coords_rad)
# assessing equivalence
np.testing.assert_allclose(xyz_array_from_rad, xyz_array_from_deg, atol=1e-9)
# convert back
llh_coords_rad_back = xyz2llh(coordinates=xyz_array_from_rad)
# assessing equivalence
np.testing.assert_allclose(llh_coords_rad_back, llh_coords_rad, atol=1e-9)
UTM <-> LLH conversion
Convert Universal Transverse Mercator (UTM) coordinates to geodetic Latitude, Longitude, Height (LLH) and vice versa.
Batch coordinate conversion
import numpy as np
from perseo_core.geometry.coordinates import utm2llh, llh2utm
# multiple points (N, 3) array, lat [deg]/lon[deg]/height[m]
llh_coords_deg = np.array(
[
[45.46426566000277, 15.189507795238633, 0.0], # Point 1
[41.90278563201284, 12.496360621280552, 10.0], # Point 2
[40.85299745751111, 14.305005283852463, 175.0], # Point 3
]
)
# convert all points at once, return (N, 3) array
utm_array_from_deg = llh2utm(coordinates=llh_coords_deg, zone="33N", radians=False)
# this is equivalent to:
llh_coords_rad = llh_coords_deg.copy()
llh_coords_rad[:, :2] = np.deg2rad(llh_coords_deg[:, :2])
utm_array_from_rad = llh2utm(coordinates=llh_coords_rad, zone="33N")
# assessing equivalence
np.testing.assert_allclose(utm_array_from_rad, utm_array_from_deg, atol=1e-9)
# convert back
llh_coords_rad_back = utm2llh(coordinates=utm_array_from_rad, zone="33N")
# assessing equivalence
np.testing.assert_allclose(llh_coords_rad_back, llh_coords_rad, atol=1e-9)
ECEF <-> ECI conversion
Convert Earth-Centered Earth-Fixed (ECEF/ITRS) coordinates to Earth-Centered Inertial (ECI/GCRS) coordinates. This transformation accounts for Earth rotation at specific UTC times.
Batch ECEF to ECI
import numpy as np
from perseo_core.geometry.coordinates import ecef2eci, eci2ecef
from perseo_core.timing.precise_datetime import PreciseDateTime
# Multiple positions at different times
ecef_positions = np.array(
[
[3.724745197526000e06, -6.015622745767000e06, 1.321425413040000e05],
[3.684766194699000e06, -6.041272641007000e06, -9.076226593700000e04],
[3.640972112690000e06, -6.060645974807000e06, -3.135749264620000e05],
[3.593435105405000e06, -6.073707420235000e06, -5.360690852350000e05],
]
)
ecef_velocities = np.array(
[
[-1.35408519e03, -8.2027485e02, -7.4304872e03],
[-1.48086852e03, -6.1083496e02, -7.4261573e03],
[-1.56405031e03, -4.7056104e02, -7.4190789e03],
[-1.64611421e03, -3.2984706e02, -7.4086513e03],
]
)
# Times can be scalar (same time for all) or array (one time per position)
times_str = [
"2024-07-07T09:55:08.417634",
"2024-07-07T09:55:18.417635",
"2024-07-07T09:56:08.417635",
"2024-07-07T09:56:28.417634",
]
times = np.array([PreciseDateTime.from_utc_string(t) for t in times_str])
# Transform all at once
eci_positions, eci_velocities = ecef2eci(
positions=ecef_positions,
velocities=ecef_velocities,
times=times
)
# convert back
ecef_positions_back, ecef_velocities_back = eci2ecef(
positions=eci_positions,
velocities=eci_velocities,
times=times
)
# assessing equivalence
np.testing.assert_allclose(ecef_positions, ecef_positions_back, atol=1e-9)
np.testing.assert_allclose(ecef_velocities, ecef_velocities_back, atol=1e-9)