Coverage for pygeodesy/utily.py : 97%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*-
After I{(C) Chris Veness 2011-2015} published under the same MIT Licence**, see U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>} and U{Vector-based geodesy<https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>}.
@newfield example: Example, Examples ''' # make sure int division yields float quotient raise ImportError('%s 1/2 == %d' % ('division', division))
# all public contants, classes and functions
# R_M moved here to avoid circular imports
# <https://Numbers.Computation.Free.FR/Constants/Miscellaneous/digits.html>
'''(INTERNAL) Check C{Types} of all C{name=value} pairs. ''' # first letter of Type name I{pronounced} as vowel raise TypeError('%s not %s %s: %r' % (n, a, t, v))
'''Error raised for lat- or longitudinal deltas exceeding the B{C{limit}} in functions L{equirectangular} and L{equirectangular_}. '''
'''Make a valid name of alphanumeric and OKd characters.
@param name: The original name (C{str}). @keyword OKd: Other acceptable characters (C{str}). @keyword sub: Substitute for invalid charactes (C{str}).
@return: The modified name (C{str}).
@note: Leading and trailing whitespace characters are removed and intermediate whitespace characters are coalesced and substituted. '''
'''Clip a string to the given length limit.
@param bstr: String (C{bytes} or C{str}). @keyword limit: Length limit (C{int}). @keyword white: Whitespace replacement (C{str}).
@return: Un/-clipped B{C{bstr}}. '''
'''Convert radians to degrees and wrap M{[-270..+90]}.
@param rad: Angle (C{radians}).
@return: Angle in degrees, wrapped (C{degrees90}). '''
'''Convert radians to degrees and wrap M{[-180..+180]}.
@param rad: Angle (C{radians}).
@return: Angle in degrees, wrapped (C{degrees180}). '''
'''Convert radians to degrees and wrap M{[0..+360)}.
@param rad: Angle (C{radians}).
@return: Angle in degrees, wrapped (C{degrees360}). '''
'''Convert angle to distance along the equator or along a parallel at an other latitude.
@param deg: Angle (C{degrees}). @keyword radius: Mean earth radius (C{meter}). @keyword lat: Parallel latitude (C{degrees90}).
@return: Distance (C{meter}, same units as B{C{radius}}).
@raise RangeError: Latitude B{C{lat}} outside valid range and L{rangerrors} set to C{True}. '''
'''Return easting, northing string representations.
@param easting: Easting from false easting (C{meter}). @param northing: Northing from from false northing (C{meter}). @param prec: Precision in number of digits (C{int}). @param extras: Optional leading items (strings).
@return: B{C{extras}} + 2-Tuple C{(eastingStr, northingStr)}.
@raise ValueError: Invalid B{C{prec}}. ''' except IndexError: raise ValueError('%s invalid: %r' % ('prec', prec)) '%0*d' % (w, int(northing * p10)))
'''Convert a false east-/northing to non-negative float.
@param value: Value to convert (C{scalar}). @keyword name: Optional name of the value (C{str}). @keyword false: Optionally, value includes false origin (C{bool}). @keyword Error: Exception to raise (C{ValueError}).
@return: The value (C{float}).
@raise Error: Invalid or negative B{C{value}}. ''' raise ValueError except (TypeError, ValueError): raise Error('%s invalid: %r' % (name, value))
'''Convert I{International} or I{US Survey} feet to meter.
@param feet: Value in feet (C{scalar}). @keyword usurvery: Convert I{US Survey} feet (C{bool}), I{International} feet otherwise.
@return: Value in C{meter} (C{float}). ''' # US Survey 1200./3937. == 0.3048006096012192
'''Split a string in 2 halfs.
@param str2: String to split (C{str}).
@return: 2-Tuple (1st, 2nd) half (C{str}).
@raise ValueError: Zero or odd C{len}(B{str2}). ''' raise ValueError('%s invalid: %r' % ('str2', str2))
'''Check for an B{C{Numpy2LatLon}} points wrapper.
@param obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is an B{C{Numpy2LatLon}} instance, C{False} otherwise. ''' # isinstance(self, (Numpy2LatLon, ...))
'''Check for an B{C{LatLon2psxy}} points wrapper.
@param obj: The object (any C{type}).
@return: C{True} if B{C{obj}} is an B{C{LatLon2psxy}} instance, C{False} otherwise. ''' # isinstance(self, (LatLon2psxy, ...))
'''Check for sequence types.
@param obj: The object (any C{type}). @param excluded: Optional, exclusions (C{type}).
@note: Excluding C{tuple} implies excluding C{namedtuple}.
@return: C{True} if B{C{obj}} is a sequence, C{False} otherwise. ''' isinstance(obj, excluded) else: return isinstance(obj, _Seqs)
'''Check whether a class is a subclass of a super class.
@param sub: The sub class (C{class}). @param sup: The super class (C{class}).
@return: C{True} if B{C{sub}} is a subclass of B{C{sup}}. '''
'''Check for an B{C{Tuple2LatLon}} points wrapper.
@param obj: The object (any).
@return: C{True} if B{C{obj}} is an B{C{Tuple2LatLon}} instance, C{False} otherwise. ''' # isinstance(self, (Tuple2LatLon, ...))
'''Iterate over Numpy2 wrappers or other sequences exceeding the threshold.
@param obj: Points array, list, sequence, set, etc. (any).
@return: C{True} do, C{False} don't iterate. ''' except TypeError: return False
'''Get or set the L{iterNumpy2} threshold.
@keyword n: Optional, new threshold (C{int}).
@return: Previous threshold (C{int}).
@raise ValueError: Invalid B{C{n}}. ''' global _iterNumpy2len else: raise ValueError except (TypeError, ValueError): raise ValueError('%s invalid: %r' % ('n', n))
'''Get/set the raising of limit errors.
@keyword raiser: Choose C{True} to throw or C{False} to ignore L{LimitError} exceptions. Use C{None} to leave the setting unchanged.
@return: Previous setting (C{bool}). ''' global _limiterrors
'''Convert distance to angle along equator.
@param meter: Distance (C{meter}, same units as B{C{radius}}). @keyword radius: Mean earth radius (C{meter}).
@return: Angle (C{degrees}).
@raise ValueError: Invalid B{C{radius}}. ''' raise ValueError('%s invalid: %r' % ('radius', radius))
'''Convert meter to I{International} or I{US Survey} feet (C{ft}).
@param meter: Value in meter (C{scalar}). @keyword usurvery: Convert to I{US Survey} feet (C{bool}), I{International} feet otherwise.
@return: Value in C{feet} (C{float}). ''' # US Survey == 3937./1200. = 3.2808333333333333
'''Convert meter to kilo meter (km).
@param meter: Value in meter (C{scalar}).
@return: Value in km (C{float}). '''
'''Convert meter to nautical miles (NM).
@param meter: Value in meter (C{scalar}).
@return: Value in NM (C{float}). '''
'''Convert meter to statute miles (SM).
@param meter: Value in meter (C{scalar}).
@return: Value in SM (C{float}). '''
'''Decorator for C{Read_Only} property.
@param method: The callable to be decorated as C{property.getter}.
@note: Like standard Python C{property} without a C{property.setter} with a more descriptive error message when set. ''' '''Throws an C{AttributeError}, always. ''' raise AttributeError('Read_Only property: %r.%s = %r' % (self, method.__name__, ignored))
'''Convert and wrap degrees to radians M{[-PI..+PI]}.
@param deg: Angle (C{degrees}).
@return: Radians, wrapped (C{radiansPI}) '''
'''Convert and wrap degrees to radians M{[0..+2PI)}.
@param deg: Angle (C{degrees}).
@return: Radians, wrapped (C{radiansPI2}) '''
'''Convert and wrap degrees to radians M{[-3PI/2..+PI/2]}.
@param deg: Angle (C{degrees}).
@return: Radians, wrapped (C{radiansPI_2}) '''
'''(INTERNAL) 2-tuple (C{sin(r), cos(r)}) in quadrant C{q}. ''' else: # XXX sin(-0.0)?
'''Return the C{sine} and C{cosine} of angle(s).
@param rad: One or more angles (C{radians}).
@return: The C{sin(rad)} and C{cos(rad)} for each angle.
@see: U{GeographicLib<https://GeographicLib.SourceForge.io/html/ classGeographicLib_1_1Math.html#sincosd>} function U{sincosd <https://SourceForge.net/p/geographiclib/code/ci/release/tree/ python/geographiclib/geomath.py#l155>} and C++ U{sincosd <https://SourceForge.net/p/geographiclib/code/ci/release/tree/ include/GeographicLib/Math.hpp#l558>}. '''
'''Return the C{sine} and C{cosine} of an angle.
@param deg: One or more angles (C{degrees}).
@return: The C{sin(rad)} and C{cos(rad)} for each angle.
@see: U{GeographicLib<https://GeographicLib.SourceForge.io/html/ classGeographicLib_1_1Math.html#sincosd>} function U{sincosd <https://SourceForge.net/p/geographiclib/code/ci/release/tree/ python/geographiclib/geomath.py#l155>} and C++ U{sincosd <https://SourceForge.net/p/geographiclib/code/ci/release/tree/ include/GeographicLib/Math.hpp#l558>}. '''
'''Split an iterable into C{n} slices.
@param iterable: Items to be spliced (C{list}, C{tuple}, ...). @keyword n: Number of slices to generate (C{int}). @keyword fill: Fill value for missing items.
@return: Generator of B{C{n}} slices M{iterable[i::n] for i=0..n}.
@note: Each generated slice is a C{tuple} or a C{list}, the latter only if the B{C{iterable}} is a C{list}.
@raise ValueError: Non-C{int} or non-positive B{C{n}}.
@example:
>>> from pygeodesy import splice
>>> a, b = splice(range(10)) >>> a, b ((0, 2, 4, 6, 8), (1, 3, 5, 7, 9))
>>> a, b, c = splice(range(10), n=3) >>> a, b, c ((0, 3, 6, 9), (1, 4, 7], [2, 5, 8))
>>> a, b, c = splice(range(10), n=3, fill=-1) >>> a, b, c ((0, 3, 6, 9), (1, 4, 7, -1), (2, 5, 8, -1))
>>> list(splice(range(12), n=5)) [(0, 5, 10), (1, 6, 11), (2, 7), (3, 8), (4, 9)]
>>> splice(range(9), n=1) <generator object splice at 0x0...> ''' raise ValueError('%s %s=%s' % ('splice', 'n', n))
else: yield t
'''Compute the tangent of half angle.
@param rad: Angle (C{radians}).
@return: M{tan(rad / 2)} (C{float}). '''
'''Compute the tangent of half angle, 90 degrees rotated.
@param rad: Angle (C{radians}).
@return: M{tan((rad + PI/2) / 2)} (C{float}). '''
'''Unroll longitudinal delta and wrap longitude in degrees.
@param lon1: Start longitude (C{degrees}). @param lon2: End longitude (C{degrees}). @keyword wrap: Wrap and unroll to the M{(-180..+180]} range (C{bool}).
@return: 2-Tuple (delta B{C{lon2}}-B{lon1}, B{C{lon2}}) unrolled (C{degrees}, C{degrees}).
@see: Capability B{C{LONG_UNROLL}} in U{GeographicLib <https://GeographicLib.SourceForge.io/html/python/interface.html#outmask>}. '''
'''Unroll longitudinal delta and wrap longitude in radians.
@param rad1: Start longitude (C{radians}). @param rad2: End longitude (C{radians}). @keyword wrap: Wrap and unroll to the M{(-PI..+PI]} range (C{bool}).
@return: 2-Tuple (delta B{C{rad2}}-B{rad1}, B{C{rad2}}) unrolled (C{radians}, C{radians}).
@see: Capability B{C{LONG_UNROLL}} in U{GeographicLib <https://GeographicLib.SourceForge.io/html/python/interface.html#outmask>}. '''
'''Return the string representation of an invokation.
@param name: Function, method or class name (C{str}). @param args: Optional positional arguments. @keyword kwds: Optional keyword arguments.
@return: Representation (C{str}). '''
'''(INTERNAL) Angle wrapper M{((wrap-modulo)..+wrap]}.
@param angle: Angle (C{degrees} or C{radians}). @param wrap: Range (C{degrees} or C{radians}). @param modulo: Upper limit (360 C{degrees} or PI2 C{radians}).
@return: The B{C{angle}}, wrapped (C{degrees} or C{radians}). ''' # math.fmod(-1.5, 3.14) == -1.5, but -1.5 % 3.14 == 1.64 # math.fmod(-1.5, 360) == -1.5, but -1.5 % 360 == 358.5
'''Wrap degrees to M{[-270..+90]}.
@param deg: Angle (C{degrees}).
@return: Degrees, wrapped (C{degrees90}). '''
'''Wrap degrees to M{[-180..+180]}.
@param deg: Angle (C{degrees}).
@return: Degrees, wrapped (C{degrees180}). '''
'''Wrap degrees to M{[0..+360)}.
@param deg: Angle (C{degrees}).
@return: Degrees, wrapped (C{degrees360}). '''
'''Wrap radians to M{[-PI..+PI]}.
@param rad: Angle (C{radians}).
@return: Radians, wrapped (C{radiansPI}). '''
'''Wrap radians to M{[0..+2PI)}.
@param rad: Angle (C{radians}).
@return: Radians, wrapped (C{radiansPI2}). '''
'''Wrap radians to M{[-3PI/2..+PI/2]}.
@param rad: Angle (C{radians}).
@return: Radians, wrapped (C{radiansPI_2}). '''
# **) MIT License # # Copyright (C) 2016-2020 -- mrJean1 at Gmail -- All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. |