Turbo87 / utm

Bidirectional UTM-WGS84 converter for python
http://pypi.python.org/pypi/utm
MIT License
486 stars 101 forks source link

Version 0.5.0 with numpy fails on Decimal values #40

Open emakarov opened 5 years ago

emakarov commented 5 years ago

UTM version:

pip freeze | grep utm
utm==0.5.0

Numpy version:

pip freeze | grep numpy
numpy==1.16.4

(tested on some other numpy versions below 1.16.4)

Code:

from decimal import *
import utm
lat, lon = 1.286834229215, 103.796852963067
utm.from_latlon(Decimal(lat), Decimal(lon))

fails with such traceback:

~/dev/envs/p3/lib/python3.6/site-packages/utm/conversion.py in from_latlon(latitude, longitude, force_zone_number, force_zone_letter)
    187        .. _[1]: http://www.jaworski.ca/utmzones.htm
    188     """
--> 189     if not in_bounds(latitude, -80.0, 84.0):
    190         raise OutOfRangeError('latitude out of range (must be between 80 deg S and 84 deg N)')
    191     if not in_bounds(longitude, -180.0, 180.0):

~/dev/envs/p3/lib/python3.6/site-packages/utm/conversion.py in in_bounds(x, lower, upper, upper_strict)
     47         return lower <= x < upper
     48     elif use_numpy:
---> 49         return lower <= mathlib.min(x) and mathlib.max(x) <= upper
     50     return lower <= x <= upper
     51

~/dev/envs/p3/lib/python3.6/site-packages/numpy/core/fromnumeric.py in amin(a, axis, out, keepdims, initial)
   2616     """
   2617     return _wrapreduction(a, np.minimum, 'min', axis, None, out, keepdims=keepdims,
-> 2618                           initial=initial)
   2619
   2620

~/dev/envs/p3/lib/python3.6/site-packages/numpy/core/fromnumeric.py in _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs)
     82                 return reduction(axis=axis, dtype=dtype, out=out, **passkwargs)
     83             else:
---> 84                 return reduction(axis=axis, out=out, **passkwargs)
     85
     86     return ufunc.reduce(obj, axis, dtype, out, **passkwargs)

TypeError: Required argument 'other' (pos 1) not found
TheBB commented 5 years ago

We're going to have to wrap a few of the math functions if we want to support Decimals in numpy-mode I think. Few numpy functions understand them, even when used as straight-up scalars, including some we need: sin, cos, radians, degrees, max and min. Interestingly sqrt is fine with them.

I'm not sure if numpy would consider this a bug.

emakarov commented 5 years ago

I'm not sure about numpy strategy about Decimal support in future. The issue was found working with django project where lat/lon values are kept in decimals in database.

I see two options: 1) Consider this not a bug and raise specific Exception about attribute type (I think it's less preferred variant) 2) Cast Decimals to float explicitly in the code of utm

emakarov commented 5 years ago

the situation is also following:

if you call numpy.max with single float argument, it works if you call numpy.max with array of floats, it works if you call numpy.max with array of Decimals, it works if you call numpy.max with single Decimal, it fails