Pos (Position)
Geodetic position handling with lazy coordinate conversion between XYZ (ECEF) and LLA (Lat/Lon/Alt).
Overview
gri-pos provides the Pos class for working with geospatial positions. Initialize with either XYZ or LLA coordinates; the other representation is computed and cached on first access. Pos supports distance calculations, coordinate deltas, translations, and tolerance-based equality.
Vel extends Pos with velocity and Acc extends Vel with acceleration. Both use the same lazy-loaded TriplePoint pattern for frame conversion (ECEF/ENU).
All coordinate types (XYZ, LLA, ENU, NED, AER) are numpy.ndarray subclasses, so they work directly in numpy and scipy operations.
Requires Python 3.12+.
Mathematical Background
Positions use the WGS-84 reference ellipsoid. LLA coordinates are geodetic latitude (degrees), longitude (degrees), and altitude above the ellipsoid (meters). XYZ coordinates are Earth-Centered, Earth-Fixed (ECEF) in meters. Conversion between LLA and XYZ uses iterative methods accurate to sub-millimeter precision.
Equality comparison uses per-coordinate tolerances: LLA defaults to ~1 cm accuracy (1e-7 degrees for lat/lon, 0.01 m for altitude).
Documentation
The wheel ships its documentation inside the package, in gri_pos/docs/, so it
is available wherever the package is installed:
overview.md-- the classes, frames, and gotchasapi_summary.md-- every public class, method, and signature (generated)
Print the directory with
python -c "import gri_pos, pathlib; print(pathlib.Path(gri_pos.__file__).parent / 'docs')".
Every example in those files is run by the test suite.
Installation
pip install gri-pos
For development:
git clone https://gitlab.com/geosol-foss/python/gri-pos.git
cd gri-pos
uv sync
Quick Start
from gri_pos import Pos
# Create from LLA or XYZ
p1 = Pos.LLA(40.0, -105.0, 1600.0)
p2 = Pos.XYZ(-1270367.0, -4800297.0, 4091069.0)
# Access either representation (lazy-computed)
print(p1.xyz) # ECEF coordinates (meters)
print(p2.lla) # Geodetic lat, lon, alt
# Distance calculations
dist = p1.dist_m(p2) # 3D Euclidean (meters)
surf = p1.dist_surface_m(p2) # Vincenty surface distance
fast_surf = p1.dist_surface_simple_m(p2) # Fast spherical approximation
# Coordinate deltas
enu = p1.delta_enu(p2) # East, North, Up offset
aer = p1.delta_aer(p2) # Azimuth, Elevation, Range
# Translation (create new position from offset)
p3 = p1.translate_enu([100, 200, 0])
Pos Class
Creating Positions
from gri_pos import Pos, XYZ, LLA
# Static constructors (preferred)
p = Pos.LLA(40.0, -105.0, 1600.0)
p = Pos.XYZ(-1270367.0, -4800297.0, 4091069.0)
# From existing objects
p = Pos(XYZ(-1270367.0, -4800297.0, 4091069.0))
p = Pos(LLA(40.0, -105.0, 1600.0))
p = Pos(other_pos) # Copy
Distance Methods
| Method | Algorithm | Accuracy |
|---|---|---|
dist_m(other) |
3D Euclidean (XYZ) | Exact straight-line |
dist_surface_m(other) |
Vincenty (oblate spheroid) | ~0.5 mm |
dist_surface_simple_m(other) |
Spherical approximation | Good for <500 km |
Delta and Translation
All delta/translate methods accept and return numpy-compatible types:
enu = p1.delta_enu(p2) # Returns ENU (east, north, up)
ned = p1.delta_ned(p2) # Returns NED (north, east, down)
aer = p1.delta_aer(p2) # Returns AER (azimuth_deg, elevation_deg, range_m)
xyz = p1.delta_xyz(p2) # Returns XYZ delta
p3 = p1.translate_enu(enu)
p3 = p1.translate_ned(ned)
p3 = p1.translate_aer(aer)
Coordinate Types
All types are numpy.ndarray subclasses with named attributes:
| Type | Attributes | Units |
|---|---|---|
XYZ |
x, y, z |
meters (ECEF) |
LLA |
lat_deg, lon_deg, alt_m |
degrees, degrees, meters |
ENU |
east, north, up |
meters |
NED |
north, east, down |
meters |
AER |
azim_deg, elev_deg, range_m |
degrees, degrees, meters |
Dependencies
- gri-utils: Coordinate conversion and distance functions
- numpy: Array operations
Other Projects
Current list of other GRI FOSS Projects we are building and maintaining.
License
MIT License. See LICENSE for details.
Release files for gri-pos 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gri_pos-0.2.4.tar.gz | 36.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gri_pos-0.2.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.6 kB
Release files / gri_pos-0.2.4.tar.gz
| Download URL | gri_pos-0.2.4.tar.gz |
|---|---|
| Size | 36.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
52fd314f375857066c34af2c376dd507e0744444b825c10a68344da5dedf2b4a
|
|
BLAKE2b-256 checksum How to use checksums |
cba5ff8aac716e1d7d28e00f3cadd2855f1a0d7139ac20e8e6d98dd97e8591b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / gri_pos-0.2.4-py3-none-any.whl
| Download URL | gri_pos-0.2.4-py3-none-any.whl |
|---|---|
| Size | 29.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
de85cf6700ba7592da096b53a9a9c235e60ad6194b80cff77461bc1b2941d481
|
|
BLAKE2b-256 checksum How to use checksums |
5ade9ffd1723a0e7b440794d39f9b24b7fdfa5f13bf329fd0d624463ffeb9eb7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|