def decode(geohash): '''Decode a geohash to lat-/longitude of the (approximate centre of) geohash cell, to reasonable precision. @arg geohash: To be decoded (L{Geohash}). @return: 2-Tuple C{"(latStr, lonStr)"} in (C{str}). @raise TypeError: The B{C{geohash}} is not a L{Geohash}, C{LatLon} or C{str}. @raise GeohashError: Invalid or null B{C{geohash}}. @example: >>> geohash.decode('u120fxw') # '52.205', '0.1188' >>> geohash.decode('sunny') # '23.708', '42.473' Saudi Arabia >>> geohash.decode('fur') # '69.6', '-45.7' Greenland >>> geohash.decode('reef') # '-24.87', '162.95' Coral Sea >>> geohash.decode('geek') # '65.48', '-17.75' Iceland ''' b = bounds(geohash) lat, lon = _2center(b) # round to near centre without excessive precision # ⌊2-log10(Δ°)⌋ decimal places, strip trailing zeros return (fstr(lat, prec=int(2 - log10(b.latN - b.latS))), fstr(lon, prec=int(2 - log10(b.lonE - b.lonW)))) # strings
def _clipped_(angle, limit, units): '''(INTERNAL) Helper for C{clipDegrees} and C{clipRadians}. ''' c = min(limit, max(-limit, angle)) if c != angle and rangerrors(): raise RangeError( '%s beyond %s %s' % (fstr(angle, prec=6), fstr(copysign(limit, angle), prec=3, ints=True), units)) return c
def _toStr(self, hemipole, B, cs, prec, sep): '''(INTERNAL) Return a string representation of this UTM/UPS coordinate. ''' z = '%02d%s' % (self.zone, (self.band if B else NN)) # PYCHOK band t = (z, hemipole, fstr(self.easting, prec=prec), fstr(self.northing, prec=prec)) if cs: t += (_n_a_ if self.convergence is None else degDMS( self.convergence, prec=8, pos=_PLUS_), _n_a_ if self.scale is None else fstr(self.scale, prec=8)) return t if sep is None else sep.join(t)
def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False): '''Compute the distance between two points using the U{Equirectangular Approximation / Projection <https://www.Movable-Type.co.UK/scripts/latlong.html#equirectangular>}. This approximation is valid for short distance of several hundred Km or Miles, see the B{C{limit}} keyword argument and the L{LimitError}. @arg lat1: Start latitude (C{degrees}). @arg lon1: Start longitude (C{degrees}). @arg lat2: End latitude (C{degrees}). @arg lon2: End longitude (C{degrees}). @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine of the mean latitude (C{bool}). @kwarg limit: Optional limit for lat- and longitudinal deltas (C{degrees}) or C{None} or C{0} for unlimited. @kwarg wrap: Wrap and L{unroll180} longitudes (C{bool}). @return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon, unroll_lon2)}. @raise LimitError: If the lat- and/or longitudinal delta exceeds the B{C{-limit..+limit}} range and L{limiterrors} set to C{True}. @see: U{Local, flat earth approximation <https://www.EdWilliams.org/avform.htm#flat>}, functions L{equirectangular}, L{cosineLaw}, L{euclidean}, L{flatLocal}, L{flatPolar}, L{haversine}, L{vincentys} and methods L{Ellipsoid.distance2}, C{LatLon.distanceTo*} and C{LatLon.equirectangularTo}. ''' d_lat = lat2 - lat1 d_lon, ulon2 = unroll180(lon1, lon2, wrap=wrap) if limit and _limiterrors \ and max(abs(d_lat), abs(d_lon)) > limit > 0: t = fstr((lat1, lon1, lat2, lon2), prec=4) raise LimitError('%s(%s, limit=%s) delta exceeds limit' % ('equirectangular_', t, fstr(limit, prec=2))) if adjust: # scale delta lon d_lon *= _scaled(lat1, lat2) d2 = hypot2(d_lat, d_lon) # degrees squared! return Distance4Tuple(d2, d_lat, d_lon, ulon2 - lon2)
def toStr(self, prec=6, sep=' ', m='m'): # PYCHOK expected '''Return a string representation of this L{Css} position. @kwarg prec: Optional number of decimal, unstripped (C{int}). @kwarg sep: Optional separator to join (C{str}). @kwarg m: Optional height units, default C{meter} (C{str}). @return: This position as C{"easting nothing"} C{str} in C{meter} plus C{" height"} and C{'m'} if heigth is non-zero (C{str}). ''' t = [fstr(self.easting, prec=prec), fstr(self.northing, prec=prec)] if self.height: # abs(self.height) > EPS t += ['%+.2f%s' % (self.height, m)] return sep.join(t)
def toStr(self, prec=6, sep=_SPACE_, m=_m_): # PYCHOK expected '''Return a string representation of this L{Css} position. @kwarg prec: Optional number of decimal, unstripped (C{int}). @kwarg sep: Optional separator to join (C{str}) or C{None} to return an unjoined C{tuple} of C{str}s. @kwarg m: Optional height units, default C{meter} (C{str}). @return: This position as C{"easting nothing"} C{str} in C{meter} plus C{" height"} and C{'m'} if heigth is non-zero (C{str}). ''' t = (fstr(self.easting, prec=prec), fstr(self.northing, prec=prec)) if self.height: # abs(self.height) > EPS t += ('%+.2f%s' % (self.height, m)), return t if sep is None else sep.join(t)
def toStr(self, prec=None, fmt=F__F_, ints=False): # PYCHOK prec=8, ... if fmt.startswith(_PERCENT_): # use regular formatting p = 8 if prec is None else prec return fstr(self, prec=p, fmt=fmt, ints=ints, sep=self._sep_) else: return _toDMS( self, fmt, prec, self._sep_, self._ddd_, self._suf_[0 if self > 0 else (1 if self < 0 else 2)])
def _clipped_(angle, limit, units): '''(INTERNAL) Helper for C{clipDegrees} and C{clipRadians}. ''' c = min(limit, max(-limit, angle)) if c != angle and _rangerrors: t = NN(fstr(angle, prec=6, ints=True), 'beyond', copysign(limit, angle), units) raise RangeError(t, txt=None) return c
def toStr(self, prec=0, sep=' ', m='m'): # PYCHOK expected '''Return a string representation of this L{Lcc} position. @kwarg prec: Optional number of decimal, unstripped (C{int}). @kwarg sep: Optional separator to join (C{str}). @kwarg m: Optional height units, default C{meter} (C{str}). @return: This Lcc as "easting nothing" C{str} in C{meter} plus " height" and 'm' if heigth is non-zero (C{str}). @example: >>> lb = Lcc(448251, 5411932.0001) >>> lb.toStr(4) # 448251.0 5411932.0001 >>> lb.toStr(sep=', ') # 448251, 5411932 ''' t = [fstr(self._easting, prec=prec), fstr(self._northing, prec=prec)] if self._height: t += ['%+.2f%s' % (self._height, m)] return sep.join(t)
def _toStr(self, hemipole, B, cs, prec, sep): '''(INTERNAL) Return a string for this ETM/UTM/UPS coordinate. ''' z = NN(Fmt.zone(self.zone), (self.band if B else NN)) # PYCHOK band t = (z, hemipole) + _fstrENH2(self, prec, None)[0] if cs: prec = cs if isint(cs) else 8 # for backward compatibility t += (_n_a_ if self.convergence is None else degDMS( self.convergence, prec=prec, pos=_PLUS_), _n_a_ if self.scale is None else fstr(self.scale, prec=prec)) return t if sep is None else sep.join(t)
def toRepr(self, prec=None, fmt=_SQUARE_, sep=_COMMA_SPACE_, **unused): # PYCHOK expected '''Return a string representation of this NED vector as length, bearing and elevation. @kwarg prec: Optional number of decimals, unstripped (C{int}). @kwarg fmt: Optional enclosing backets format (C{str}). @kwarg sep: Optional separator between NEDs (C{str}). @return: This Ned as "[L:f, B:degrees360, E:degrees90]" (C{str}). ''' from pygeodesy.dms import F_D, toDMS t = (fstr(self.length, prec=3 if prec is None else prec), toDMS(self.bearing, form=F_D, prec=prec, ddd=0), toDMS(self.elevation, form=F_D, prec=prec, ddd=0)) return _xzipairs('LBE', t, sep=sep, fmt=fmt)
def toRepr(self, prec=12, fmt=Fmt.g, ints=False, std=False): # PYCHOK prec=8, ... '''Return a representation of this C{Float}. @kwarg std: Use the standard C{repr} or the named representation (C{bool}). @see: Function L{fstr} for more documentation. ''' # XXX must use super(Float, self)... since # super()... only works for Python 3+ return super(Float, self).__repr__() if std else \ self._toRepr(fstr(self, prec=prec, fmt=fmt, ints=ints))
def toRepr(self, prec=None, fmt='[%s]', sep=', ', **unused): # PYCHOK expected '''Return a string representation of this NED vector as length, bearing and elevation. @kwarg prec: Optional number of decimals, unstripped (C{int}). @kwarg fmt: Optional enclosing backets format (C{str}). @kwarg sep: Optional separator between NEDs (C{str}). @return: This Ned as "[L:f, B:degrees360, E:degrees90]" (C{str}). ''' from pygeodesy.dms import F_D, toDMS t3 = (fstr(self.length, prec=3 if prec is None else prec), toDMS(self.bearing, form=F_D, prec=prec, ddd=0), toDMS(self.elevation, form=F_D, prec=prec, ddd=0)) return fmt % (sep.join('%s:%s' % t for t in zip('LBE', t3)), )
def _error(fun, lat, lon, e): '''(INTERNAL) Format an error ''' return '%s(%s): %s' % (fun.__name__, fstr((lat, lon)), e)
def _error(fun, lat, lon, e): '''(INTERNAL) Format an error ''' return _COLONSPACE_(Fmt.PAREN(fun.__name__, fstr((lat, lon))), e)
def toStr(self, prec=8, fmt=F__F, ints=False): # PYCHOK prec=8, ... return fstr(self, prec=prec, fmt=fmt, ints=ints)
def toStr(self, prec=12, fmt=Fmt.g, ints=False): # PYCHOK prec=8, ... '''Format this C{Float} as C{str}. @see: Function L{fstr} for more documentation. ''' return fstr(self, prec=prec, fmt=fmt, ints=ints)
def fStr(floats, prec=6, fmt='%.*f', ints=False, sep=_COMMA_SPACE_): '''DEPRECATED, use function L{fstr}. ''' from pygeodesy.streprs import fstr return fstr(floats, prec=prec, fmt=fmt, ints=ints, sep=sep)
def _error(fun, lat, lon, e): '''(INTERNAL) Format an error ''' return _item_cs(_item_ps(fun.__name__, fstr((lat, lon))), e)