Skip to content

[Bug]: TypeError: Ellipsoid.__init__() got an unexpected keyword argument 'flattening' #101

@swiss-knight

Description

@swiss-knight

What happened?

Hi,

pymap3d 2.8.0 allows to convert data from a local tangent plane (LTP-ENU) to a geodetic frame using the enu2geodetic function:

Help on function enu2geodetic in module pymap3d.enu:

enu2geodetic(e, n, u, lat0, lon0, h0, ell: 'Ellipsoid' = None, deg: 'bool' = True) -> 'tuple'
    East, North, Up to target to geodetic coordinates



    Parameters
    ----------
    e : float
        East ENU coordinate (meters)
    n : float
        North ENU coordinate (meters)
    u : float
        Up ENU 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)
    
    
    Results
    -------
    lat : float
          geodetic latitude
    lon : float
          geodetic longitude
    alt : float
          altitude above ellipsoid  (meters)

e.g.:

import pymap3d
print(pymap3d.__version__) # 2.8.0

# Observer point on the WGS84 ellipsoid
lat0, lon0, h0 = 47.368614, 8.537506, 400

# 3D Cartesian point coordinates relative to the observer's LTP
e, n, u = 1000, 1000, 200

pm.enu2geodetic(e, n, u, lat0, lon0, h0, ell=None, deg=True)

Out [1]: 47.377606963984135, 8.550746545445332, 600.156728355468

The problem is that the current documentation fits with pymap3d 2.8.0, whereas pymap3d version 3.1.0 is available on pypi: https://pypi.org/project/pymap3d/ and the signature of this exact same function function has changed:

Help on function enu2geodetic in module pymap3d.enu:

enu2geodetic(e, n, u, lat0, lon0, h0, ell: 'Ellipsoid' = Ellipsoid(model='wgs84', name='WGS-84 (1984)', semimajor_axis=6378137.0, semiminor_axis=6356752.31424518, flattening=0.0033528106647473664, thirdflattenin
g=0.0016792203863836474, eccentricity=0.0818191908426201), deg: 'bool' = True) -> 'tuple'
    East, North, Up to target to geodetic coordinates
    
    Parameters
    ----------
    e : float
        East ENU coordinate (meters)
    n : float
        North ENU coordinate (meters)
    u : float
        Up ENU 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)
    
    
    Results
    -------
    lat : float
          geodetic latitude
    lon : float
          geodetic longitude
    alt : float
          altitude above ellipsoid  (meters)

So it's no longer aligned with the current documentation.

And when trying to use the newest version in a vanilla way, it fails:

import pymap3d
print(pymap3d.__version__) # 3.1.0

from pymap3d import Ellipsoid

# Copied from the help above:
pm.enu2geodetic(e, n, u, lat0, lon0, h0, ell=Ellipsoid(model='wgs84', name='WGS-84 (1984)', semimajor_axis=6378137.0, semiminor_axis=6356752.31424518, flattening=0.0033528106647473664, thirdflattening=0.0016792203863836474, eccentricity=0.0818191908426201), deg=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Ellipsoid.__init__() got an unexpected keyword argument 'flattening'

Same error with thirdflattening and eccentricity.

The only way that is working is:

pm.enu2geodetic(e, n, u, lat0, lon0, h0, ell=Ellipsoid(model='wgs84', name='WGS-84 (1984)', semimajor_axis=6378137.0, semiminor_axis=6356752.31424518), deg=True)

Out [1]: (np.float64(47.377606963984135), np.float64(8.55074654544533), np.float64(600.156728355468))

But this is particularly funny because when you print a defined ellipsoid it actually shows those values that were raising unexpected keyword argument 🤪:

import pymap3d
from pymap3d import Ellipsoid

ell = Ellipsoid(
    model="wgs84",
    name="WGS-84 (1984)",
    semimajor_axis=6378137,
    semiminor_axis=6356752.314245179,
)

print(ell)

Out [4]: Ellipsoid(model='wgs84', name='WGS-84 (1984)', semimajor_axis=6378137, semiminor_axis=6356752.314245179, flattening=0.0033528106647475126, thirdflattening=0.0016792203863837205, eccentricity=0.08181919084262189)

Also, when having ell=None as in the code using pymap3d version 2.8.0 before, it fails in pymap3d 3.1.0:

pm.enu2geodetic(e, n, u, lat0, lon0, h0, ell=None, deg=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.11/dist-packages/pymap3d/enu.py", line 156, in enu2geodetic
    x, y, z = enu2ecef(e, n, u, lat0, lon0, h0, ell, deg=deg)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pymap3d/ecef.py", line 532, in enu2ecef
    x0, y0, z0 = geodetic2ecef(lat0, lon0, h0, ell, deg=deg)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/pymap3d/ecef.py", line 78, in geodetic2ecef
    N = ell.semimajor_axis**2 / hypot(
        ^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'semimajor_axis'

Therefore, this is currently a breaking change.

I installed pymap3d 3.1.0 from pypi on Ubuntu 22.04 / Python 3.11.2

Thanks a lot 🙏!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions