Coverage for pygeodesy/dms.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 -*-
in various forms of degrees, minutes and seconds.
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 '''
_rangerrors, _ValueError _EW_, joined, _N_, _NS_, _PLUS_, \ _radians_, _S_, _SPACE_, _SW_, _W_, \ _0_, _0_5, _60_0, _360_0, _3600_0
F_DM: F_DM, F_MIN: F_DM, 'deg+min': F_DM, F__E: F__E, F__F: F__F, F__G: F__G, F_RAD: F_RAD, _radians_: F_RAD}
F_DEG: 6, F_MIN: 4, F_SEC: 2, F__E: 8, F__F: 8, F__G: 8, F_RAD: 5}
"'": S_MIN, '’': S_MIN, '′': S_MIN, '"': S_SEC, '″': S_SEC, '”': S_SEC}
'''(INTERNAL) Float deg, min, sec formatter'. '''
'''(INTERNAL) Convert degrees to C{str}, with/-out sign and/or suffix. ''' except (TypeError, ValueError) as x: raise _ValueError(deg=deg, txt=str(x))
else:
else:
else:
_0wpF( 2, 0, m), s_min, sep, _0wpF(w+2, p, s))
_0wpF(w+2, p, m))
else: # F in (F__E, F__F, F__G)
'''Convert bearing to a string.
@arg bearing: Bearing from North (compass C{degrees360}). @kwarg form: Optional B{C{bearing}} format (C{str} or L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G}, L{F_RAD}, L{F_D_}, L{F_DM_}, L{F_DMS_}, L{F_DEG_}, L{F_MIN_}, L{F_SEC_}, L{F__E_}, L{F__F_}, L{F__G_}, L{F_RAD_}, L{F_D__}, L{F_DM__}, L{F_DMS__}, L{F_DEG__}, L{F_MIN__}, L{F_SEC__}, L{F__E__}, L{F__F__}, L{F__G__} or L{F_RAD__}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg sep: Optional separator (C{str}).
@return: Compass degrees per the specified B{C{form}} (C{str}).
@JSname: I{toBrng}. '''
'''(INTERNAL) Helper for C{clipDegrees} and C{clipRadians}. ''' copysign(limit, angle), units) raise RangeError(t, txt=None)
'''Clip a lat- or longitude to the given range.
@arg deg: Unclipped lat- or longitude (C{degrees}). @arg limit: Valid B{C{-limit..+limit}} range (C{degrees}).
@return: Clipped value (C{degrees}).
@raise RangeError: If B{C{abs(deg)}} beyond B{C{limit}} and L{rangerrors} set to C{True}. '''
'''Clip a lat- or longitude to the given range.
@arg rad: Unclipped lat- or longitude (C{radians}). @arg limit: Valid B{C{-limit..+limit}} range (C{radians}).
@return: Clipped value (C{radians}).
@raise RangeError: If B{C{abs(rad)}} beyond B{C{limit}} and L{rangerrors} set to C{True}. '''
'''Convert bearing to a string suffixed with compass point.
@arg bearing: Bearing from North (compass C{degrees360}). @kwarg form: Optional B{C{bearing}} format (C{str} or L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G}, L{F_RAD}, L{F_D_}, L{F_DM_}, L{F_DMS_}, L{F_DEG_}, L{F_MIN_}, L{F_SEC_}, L{F__E_}, L{F__F_}, L{F__G_}, L{F_RAD_}, L{F_D__}, L{F_DM__}, L{F_DMS__}, L{F_DEG__}, L{F_MIN__}, L{F_SEC__}, L{F__E__}, L{F__F__}, L{F__G__} or L{F_RAD__}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg sep: Optional separator (C{str}).
@return: Compass degrees and point in the specified form (C{str}). '''
'''Convert bearing to a compass point.
@arg bearing: Bearing from North (compass C{degrees360}). @kwarg prec: Optional precision (1 for cardinal or basic winds, 2 for intercardinal or ordinal or principal winds, 3 for secondary-intercardinal or half-winds or 4 for quarter-winds).
@return: Compass point (1-, 2-, 3- or 4-letter C{str}).
@raise ValueError: Invalid B{C{prec}}.
@see: U{Dms.compassPoint <https://GitHub.com/chrisveness/geodesy/blob/master/dms.js>} and U{Compass rose<https://WikiPedia.org/wiki/Compass_rose>}.
@example:
>>> p = compassPoint(24, 1) # 'N' >>> p = compassPoint(24, 2) # 'NE' >>> p = compassPoint(24, 3) # 'NNE' >>> p = compassPoint(24) # 'NNE' >>> p = compassPoint(11, 4) # 'NbE' >>> p = compassPoint(30, 4) # 'NEbN'
>>> p = compassPoint(11.249) # 'N' >>> p = compassPoint(11.25) # 'NNE' >>> p = compassPoint(-11.25) # 'N' >>> p = compassPoint(348.749) # 'NNW' ''' except KeyError: raise _ValueError(prec=prec) # not round(), i.e. half-even rounding in Python 3, # but round-away-from-zero as int(b + 0.5) iff b is # non-negative, otherwise int(b + copysign(0.5, b))
_E_, 'EbS', 'ESE', 'SEbE', _SE_, 'SEbS', 'SSE', 'SbE', _S_, 'SbW', 'SSW', 'SWbS', _SW_, 'SWbW', 'WSW', 'WbS', _W_, 'WbN', 'WNW', 'NWbW', _NW_, 'NWbN', 'NNW', 'NbW') # cardinals
'''Convert degrees to a string in degrees, minutes B{I{or}} seconds.
@arg deg: Value in degrees (C{scalar}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg s_D: Symbol for degrees (C{str}). @kwarg s_M: Symbol for minutes (C{str}) or C{""}. @kwarg s_S: Symbol for seconds (C{str}) or C{""}. @kwarg neg: Optional sign for negative (C{'-'}). @kwarg pos: Optional sign for positive (C{''}).
@return: I{Either} degrees, minutes B{I{or}} seconds (C{str}). ''' except (TypeError, ValueError) as x: raise _ValueError(deg=deg, txt=str(x))
else:
'''Convert latitude to a string, optionally suffixed with N or S.
@arg deg: Latitude to be formatted (C{degrees}). @kwarg form: Optional B{C{deg}} format (C{str} or L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G}, L{F_D_}, L{F_RAD}, L{F_D_}, L{F_DM_}, L{F_DMS_}, L{F_DEG_}, L{F_MIN_} L{F_SEC_}, L{F__E_}, L{F__F_}, L{F__G_}, L{F_RAD_}, L{F_D__}, L{F_DM__}, L{F_DMS__}, L{F_DEG__}, L{F_MIN__}, L{F_SEC__}, L{F__E__}, L{F__F__}, L{F__G__} or L{F_RAD__}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg sep: Optional separator (C{str}).
@return: Degrees in the specified form (C{str}).
@JSname: I{toLat}. '''
'''Convert one or more C{LatLon} instances to strings.
@arg lls: Single or a list, sequence, tuple, etc. (C{LatLon}s). @kwarg form: Optional B{C{deg}} format (C{str} or L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G}, L{F_RAD}, L{F_D_}, L{F_DM_}, L{F_DMS_}, L{F_DEG_}, L{F_MIN_}, L{F_SEC_}, L{F__E_}, L{F__F_}, L{F__G_}, L{F_RAD_}, L{F_D__}, L{F_DM__}, L{F_DMS__}, L{F_DEG__}, L{F_MIN__}, L{F_SEC__}, L{F__E__}, L{F__F__}, L{F__G__} or L{F_RAD__}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg sep: Separator joining B{C{lls}} (C{str} or C{None}).
@return: A C{str} or C{tuple} of B{C{sep}} is C{None} or C{NN}. ''' else:
'''Convert longitude to a string, optionally suffixed with E or W.
@arg deg: Longitude to be formatted (C{degrees}). @kwarg form: Optional B{C{deg}} format (C{str} or L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G}, L{F_RAD}, L{F_D_}, L{F_DM_}, L{F_DMS_}, L{F_DEG_}, L{F_MIN_}, L{F_SEC_}, L{F__E_}, L{F__F_}, L{F__G_}, L{F_RAD_}, L{F_D__}, L{F_DM__}, L{F_DMS__}, L{F_DEG__}, L{F_MIN__}, L{F_SEC__}, L{F__E__}, L{F__F__}, L{F__G__} or L{F_RAD__}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg sep: Optional separator (C{str}).
@return: Degrees in the specified form (C{str}).
@JSname: I{toLon}. '''
'''Normalize all degree ˚, minute ' and second " symbols in a string to the default symbols %s, %s and %s.
@arg strDMS: DMS (C{str}). @kwarg norm: Optional replacement symbol, default symbol otherwise (C{str}).
@return: Normalized DMS (C{str}). ''' else:
'''Parse a lat- or longitude represention form [D]DDMMSS in degrees.
@arg strDDDMMSS: Degrees in any of several forms (C{str}) and types (C{float}, C{int}, other). @kwarg suffix: Optional, valid compass points (C{str}, C{tuple}). @kwarg sep: Optional separator between "[D]DD", "MM" and "SS" (%r). @kwarg clip: Optionally, limit value to -clip..+clip (C{degrees}).
@return: Degrees (C{float}).
@raise ParseError: Invalid B{C{strDDDMMSS}} or B{C{clip}} or the B{C{strDDDMMSS}} form is incompatible with the suffixed or B{C{suffix}} compass point.
@raise RangeError: Value of B{C{strDDDMMSS}} outside the valid range and L{rangerrors} set to C{True}.
@note: Type C{str} values "[D]DD", "[D]DDMM" and "[D]DDMMSS" for B{C{strDDDMMSS}} are parsed properly only if I{either} unsigned and suffixed with a valid, compatible, C{cardinal} L{compassPoint} I{or} if unsigned or signed, unsuffixed and with keyword argument B{C{suffix}} set to B{%r}, B{%r} or a compatible L{compassPoint}.
@note: Unlike function L{parseDMS}, type C{float}, C{int} and other non-C{str} B{C{strDDDMMSS}} values are interpreted form [D]DDMMSS. For example, C{int(1230)} is returned as 12.5 I{and not 1230.0} degrees. However, C{int(345)} is considered form "DDD" 345 I{and not "DDMM" 0345}, unless B{C{suffix}} specifies compass point B{%r}.
@see: Functions L{parseDMS}, L{parseDMS2} and L{parse3llh}. ''' t = t.replace(sep, NN).strip()
(P in S and s.isdigit()) or (P.isdigit() and s in '-0123456789+' # PYCHOK indent and S in ((_NS_, _EW_) + _WINDS))): # check [D]DDMMSS form and compass point raise ParseError('form %s applies %s-%s' % t) else: # try other forms
else: # float or int to [D]DDMMSS[.fff] # bump number of digits to match # the given, valid compass point # P = S # elif d > 1: # P = (_EW_ if (d & 1) else _NS_)[0]
else: else: # [D]DDMMSS[.sss]
strDDDMMSS=strDDDMMSS, suffix=suffix)
if __debug__: # no __doc__ at -O and -OO
'''(INTERNAL) Helper for C{parseDDDMMSS} and C{parseDMS}. '''
'''(INTERNAL) Helper for C{parseDDDMMSS} and C{parseDMS}. '''
else:
'''Parse a lat- or longitude representation C{"lat, lon"} in C{degrees}.
This is very flexible on formats, allowing signed decimal degrees, degrees and minutes or degrees minutes and seconds optionally suffixed by a cardinal compass point.
A variety of symbols, separators and suffixes are accepted, for example "3°37′09″W". Minutes and seconds may be omitted.
@arg strDMS: Degrees in any of several forms (C{str}) and types (C{float}, C{int}, other). @kwarg suffix: Optional, valid compass points (C{str}, C{tuple}). @kwarg sep: Optional separator between deg°, min′ and sec″ ("''"). @kwarg clip: Optionally, limit value to -clip..+clip (C{degrees}).
@return: Degrees (C{float}).
@raise ParseError: Invalid B{C{strDMS}} or B{C{clip}}.
@raise RangeError: Value of B{C{strDMS}} outside the valid range and L{rangerrors} set to C{True}.
@note: Inlike function L{parseDDDMMSS}, type C{float}, C{int} and other non-C{str} B{C{strDMS}} values are considered as decimal degrees. For example, C{int(1230)} is returned as 1230.0 I{and not as 12.5} degrees and C{float(345)} as 345.0 I{and not as 3.75} degrees!
@see: Functions L{parseDDDMMSS}, L{parseDMS2} and L{parse3llh}. '''
'''Parse a lat- and a longitude representions in C{degrees}.
@arg strLat: Latitude in any of several forms (C{str} or C{degrees}). @arg strLon: Longitude in any of several forms (C{str} or C{degrees}). @kwarg sep: Optional separator between deg°, min′ and sec″ (''). @kwarg clipLat: Keep latitude in B{C{-clipLat..+clipLat}} range (C{degrees}). @kwarg clipLon: Keep longitude in B{C{-clipLon..+clipLon}} range (C{degrees}).
@return: A L{LatLon2Tuple}C{(lat, lon)} in C{degrees}.
@raise ParseError: Invalid B{C{strLat}} or B{C{strLon}}.
@raise RangeError: Value of B{C{strLat}} or B{C{strLon}} outside the valid range and L{rangerrors} set to C{True}.
@note: See the B{Notes} at function L{parseDMS}.
@see: Functions L{parseDDDMMSS}, L{parseDMS} and L{parse3llh}. '''
parseDMS(strLon, suffix=_EW_, sep=sep, clip=clipLon))
'''Parse a string C{"lat lon [h]"} representing lat-, longitude in C{degrees} and optional height in C{meter}.
The lat- and longitude value must be separated by a separator character. If height is present it must follow, separated by another separator.
The lat- and longitude values may be swapped, provided at least one ends with the proper compass point.
@arg strllh: Latitude, longitude[, height] (C{str}, ...). @kwarg height: Optional, default height (C{meter}) or C{None}. @kwarg sep: Optional separator (C{str}). @kwarg clipLat: Keep latitude in B{C{-clipLat..+clipLat}} (C{degrees}). @kwarg clipLon: Keep longitude in B{C{-clipLon..+clipLon}} range (C{degrees}).
@return: A L{LatLon3Tuple}C{(lat, lon, height)} in C{degrees}, C{degrees} and C{float}.
@raise RangeError: Lat- or longitude value of B{C{strllh}} outside valid range and L{rangerrors} set to C{True}.
@raise ValueError: Invalid B{C{strllh}} or B{C{height}}.
@note: See the B{Notes} at function L{parseDMS}.
@see: Functions L{parseDDDMMSS}, L{parseDMS} and L{parseDMS2}.
@example:
>>> parse3llh('000°00′05.31″W, 51° 28′ 40.12″ N') (51.4778°N, 000.0015°W, 0) '''
else: raise ValueError
parseDMS(b, suffix=_EW_, clip=clipLon), h)
'''Parse a string representing angle in C{radians}.
@arg strRad: Degrees in any of several forms (C{str} or C{radians}). @kwarg suffix: Optional, valid compass points (C{str}, C{tuple}). @kwarg clip: Optionally, limit value to -clip..+clip (C{radians}).
@return: Radians (C{float}).
@raise ParseError: Invalid B{C{strRad}} or B{C{clip}}.
@raise RangeError: Value of B{C{strRad}} outside the valid range and L{rangerrors} set to C{True}. '''
if strRad[:1] == _MINUS_ or strRad[-1:] in _SW_: r = -r
'''Set the default precison for a given F_ form.
@arg form: L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G} or L{F_RAD} (C{str}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}.
@return: Previous precision (C{int}).
@raise ValueError: Invalid B{C{form}} or B{C{prec}} or B{C{prec}} outside valid range. ''' except KeyError: raise _ValueError(form=form)
'''Convert I{signed} C{degrees} to string, without suffix.
@arg deg: Degrees to be formatted (C{degrees}). @kwarg form: Optional B{C{deg}} format (C{str} or L{F_D}, L{F_DM}, L{F_DMS}, L{F_DEG}, L{F_MIN}, L{F_SEC}, L{F__E}, L{F__F}, L{F__G}, L{F_RAD}, L{F_D_}, L{F_DM_}, L{F_DMS_}, L{F_DEG_}, L{F_MIN_}, L{F_SEC_}, L{F__E_}, L{F__F_}, L{F__G_}, L{F_RAD_}, L{F_D__}, L{F_DM__}, L{F_DMS__}, L{F_DEG__}, L{F_MIN__}, L{F_SEC__}, L{F__E__}, L{F__F__}, L{F__G__} or L{F_RAD__}). @kwarg prec: Optional number of decimal digits (0..9 or C{None} for default). Trailing zero decimals are stripped for B{C{prec}} values of 1 and above, but kept for negative B{C{prec}}. @kwarg sep: Optional separator (C{str}). @kwarg ddd: Optional number of digits for deg° (2 or 3). @kwarg neg: Optional sign for negative degrees ('-'). @kwarg pos: Optional sign for positive degrees ('').
@return: Degrees in the specified form (C{str}). '''
# **) 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. |