Skip to content
pure-Python (Numpy optional) 3D coordinate conversions for geospace ecef enu eci
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github pytest / ci template Oct 13, 2019
archive black Sep 24, 2019
examples fix small latitude displacement vdist Sep 26, 2019
paper @hugoledoux comments Mar 5, 2018
tests begin adding more benchmarks Oct 8, 2019
.coveragerc breakout tests, add more parameters, improve coverage, remove depreca… Sep 23, 2019
.flake8 add geodetic <=> isometric Sep 23, 2019
.gitattributes linguist [ci skip] Aug 10, 2018
.gitignore validate Matlab function parameters Jul 23, 2018
.lgtm.yml lgtm meta Feb 22, 2019
.nojekyll move Jan 29, 2018 docs, remove unneeded appveyor Aug 12, 2019
LICENSE.txt correct Ellipsoid imports Jun 30, 2019 Update Sep 24, 2019
mypy.ini correct Ellipsoid imports Jun 30, 2019
pyproject.toml vincenty: add vdist unit tests and use numpy.vectorize Sep 9, 2019
pytest.ini pytest / ci template Oct 13, 2019
setup.cfg vers 2.1.0 Sep 24, 2019 finish adding new functions, apply black code style Sep 24, 2019

image image astronomer

Actions Status Actions Status

Language grade: Python image PyPi Download stats

Python 3-D coordinate conversions

Pure Python (no prerequistes beyond Python itself) 3-D geographic coordinate conversions and geodesy. API similar to popular $1000 Matlab Mapping Toolbox routines for:

PyMap3D is intended for non-interactive use on massively parallel (HPC) and embedded systems. Includes some relevant Vallado algorithms.

API docs

Thanks to our contributors.


Pymap3d is compatible with Python ≥ 3.5 including PyPy. Numpy and AstroPy are optional; algorithms from Vallado and Meeus are used if AstroPy is not present.


python3 -m pip install pymap3d

or for the latest development code:

git clone

pip install -e pymap3d

One can verify Python functionality after installation by:

pytest pymap3d -r a -v


Where consistent with the definition of the functions, all arguments may be arbitrarily shaped (scalar, N-D array).

import pymap3d as pm

x,y,z = pm.geodetic2ecef(lat,lon,alt)

az,el,range = pm.geodetic2aer(lat, lon, alt, observer_lat, observer_lon, 0)

Python argument unpacking can be used for compact function arguments with scalars or arbitrarily shaped N-D arrays:

aer = (az,el,slantrange)
obslla = (obs_lat,obs_lon,obs_alt)

lla = pm.aer2geodetic(*aer,*obslla)

where tuple lla is comprised of scalar or N-D arrays (lat,lon,alt).

Example scripts are in the examples directory.


Popular mapping toolbox functions ported to Python include the following, where the source coordinate system (before the "2") is converted to the desired coordinate system:

aer2ecef  aer2enu  aer2geodetic  aer2ned
ecef2aer  ecef2enu  ecef2enuv  ecef2geodetic  ecef2ned  ecef2nedv
ecef2eci  eci2ecef  eci2aer  aer2eci
enu2aer  enu2ecef   enu2geodetic
geodetic2aer  geodetic2ecef  geodetic2enu  geodetic2ned
ned2aer  ned2ecef   ned2geodetic
azel2radec radec2azel
vreckon vdist
track2 departure meanm 
rcurve rsphere 

Additional functions:

  • loxodrome_inverse: rhumb line distance and azimuth between ellipsoid points (lat,lon) akin to Matlab distance('rh', ...) and azimuth('rh', ...)
  • loxodrome_direct
  • geodetic latitude transforms to/from: parametric, authalic, isometric, and more in pymap3d.latitude


array vs scalar

Use of pymap3d on embedded systems or other streaming data applications often deal with scalar position data. These data are handled efficiently with the Python math stdlib module. Vector data can be handled via list comprehension.

Those needing multidimensional data with SIMD and other Numpy and/or PyPy accelerated performance can do so automatically by installing Numpy. pymap3d seamlessly falls back to Python's math module if Numpy isn't present. To keep the code clean, only scalar data can be used without Numpy. As noted above, use list comprehension if you need vector data without Numpy.


  • Atmospheric effects neglected in all functions not invoking AstroPy. Would need to update code to add these input parameters (just start a GitHub Issue to request).
  • Planetary perturbations and nutation etc. not fully considered.


As compared to PyProj:

  • PyMap3D does not require anything beyond pure Python -- not even Numpy is required except for ECI (let us know if this is an issue).
  • PyMap3D API is similar to Matlab Mapping Toolbox, while PyProj's interface is quite distinct
  • PyMap3D intrinsically handles local coordinate systems such as ENU, while PyProj ENU requires some additional effort.
  • PyProj is oriented towards points on the planet surface, while PyMap3D handles points on or above the planet surface equally well, particularly important for airborne vehicles and remote sensing.


At this time, AstroPy.Units.Quantity is not supported. Let us know if this is of interest. Impacts on performance would have to be considered before making Quantity a first-class citizen. For now, you can workaround by passing in the .value of the variable.

You can’t perform that action at this time.