예제 #1
0
def resolution2(prec1, prec2=None):
    '''Determine the (geographic) resolutions of given L{Geohash}
       precisions.

       @arg prec1: The given primary (longitudinal) precision
                   (C{int} 1..12).
       @kwarg prec2: Optional, secondary (latitudinal) precision
                     (C{int} 1..12).

       @return: 2-Tuple (C{res1, res2}) with the (geographic) resolutions
                (C{degrees}) where C{res2} is C{res1} if no I{prec2} is
                given.

       @raise ValueError: Invalid B{C{prec1}} or B{C{prec2}}.

       @see: C++ class U{Geohash
             <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1Geohash.html>}.
    '''
    res1, res2 = 360.0, 180.0

    if prec1:
        p = 5 * max(0, min(Precision_(prec1, name='prec1', low=None),
                           _MaxPrec))
        res1 = res2 = ldexp(res1, -(p - p // 2))

    if prec2:
        p = 5 * max(0, min(Precision_(prec2, name='prec2', low=None),
                           _MaxPrec))
        res2 = ldexp(res2, -(p // 2))

    return res1, res2
예제 #2
0
    def __new__(cls, cll, precision=3, name=''):
        '''New L{Georef} from an other L{Georef} instance or georef
           C{str} or from a C{LatLon} instance or lat-/longitude C{str}.

           @arg cll: Cell or location (L{Georef} or C{str}, C{LatLon}
                     or C{str}).
           @kwarg precision: Optional, the desired georef resolution
                             and length (C{int} 0..11), see function
                             L{wgrs.encode} for more details.
           @kwarg name: Optional name (C{str}).

           @return: New L{Georef}.

           @raise RangeError: Invalid B{C{cll}} lat- or longitude.

           @raise TypeError: Invalid B{C{cll}}.

           @raise WGRSError: INValid or non-alphanumeric B{C{cll}}.
        '''
        h = None

        if isinstance(cll, Georef):
            g, p = _2geostr2(str(cll))
            self = str.__new__(cls, g)
            self._latlon = LatLon2Tuple(*cll._latlon)
            self._name = cll._name
            self._precision = p  # cll._precision

        elif isstr(cll):
            if ',' in cll:
                lat, lon, h = _2fllh(*parse3llh(cll, height=None))
                g = encode(lat, lon, precision=precision, height=h)  # PYCHOK false
                self = str.__new__(cls, g)
                self._latlon = LatLon2Tuple(lat, lon)
                self._precision = Precision_(precision, high=_MaxPrec)
            else:
                self = str.__new__(cls, cll.upper())
                self._decode()

        else:  # assume LatLon
            try:
                lat, lon, h = _2fllh(cll.lat, cll.lon)
                h = getattr(cll, 'height', h)
            except AttributeError:
                raise IsnotError('valid', **{Georef.__name__: cll})
            g = encode(lat, lon, precision=precision, height=h)  # PYCHOK false
            self = str.__new__(cls, g)
            self._latlon = LatLon2Tuple(lat, lon)
            self._precision = Precision_(precision, high=_MaxPrec)

        if h not in (None, _MISSING):
            self._height = Height(h)
        if name:
            self.name = name
        return self
예제 #3
0
    def __new__(cls, cll, precision=1, name=''):
        '''New L{Garef} from an other L{Garef} instance or garef
           C{str} or from a C{LatLon} instance or lat-/longitude C{str}.

           @arg cll: Cell or location (L{Garef} or C{str}, C{LatLon}
                     or C{str}).
           @kwarg precision: Optional, the desired garef resolution
                             and length (C{int} 0..2), see function
                             L{gars.encode} for more details.
           @kwarg name: Optional name (C{str}).

           @return: New L{Garef}.

           @raise RangeError: Invalid B{C{cll}} lat- or longitude.

           @raise TypeError: Invalid B{C{cll}}.

           @raise GARSError: INValid or non-alphanumeric B{C{cll}}.
        '''
        if isinstance(cll, Garef):
            g, p = _2garstr2(str(cll))
            self = str.__new__(cls, g)
            self._latlon = LatLon2Tuple(*cll._latlon)
            self._name = cll._name
            self._precision = p  # cll._precision

        elif isstr(cll):
            if ',' in cll:
                lat, lon = _2fll(*parse3llh(cll))
                cll = encode(lat, lon, precision=precision)  # PYCHOK false
                self = str.__new__(cls, cll)
                self._latlon = LatLon2Tuple(lat, lon)
                self._precision = Precision_(precision, high=_MaxPrec)
            else:
                self = str.__new__(cls, cll.upper())
                self._decode()

        else:  # assume LatLon
            try:
                lat, lon = _2fll(cll.lat, cll.lon)
            except AttributeError:
                raise TypeError('%s: %r' % (Garef.__name__, cll))
            cll = encode(lat, lon, precision=precision)  # PYCHOK false
            self = str.__new__(cls, cll)
            self._latlon = LatLon2Tuple(lat, lon)
            self._precision = Precision_(precision, high=_MaxPrec)

        if name:
            self.name = name
        return self
예제 #4
0
파일: dms.py 프로젝트: rbpdqdat/PyGeodesy
def precision(form, prec=None):
    '''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.
    '''
    try:
        p = _F_prec[form]
    except KeyError:
        raise _ValueError(form=form)

    if prec is not None:
        from pygeodesy.units import Precision_
        _F_prec[form] = Precision_(prec=prec, low=-9, high=9)

    return p
예제 #5
0
def encode(lat, lon, precision=3, height=None, radius=None):  # MCCABE 14
    '''Encode a lat-/longitude as a C{georef} of the given precision.

       @arg lat: Latitude (C{degrees}).
       @arg lon: Longitude (C{degrees}).
       @kwarg precision: Optional, the desired C{georef} resolution and length
                         (C{int} 0..11).
       @kwarg height: Optional, height in C{meter}, see U{Designation of area
                      <https://WikiPedia.org/wiki/World_Geographic_Reference_System>}.
       @kwarg radius: Optional, radius in C{meter}, see U{Designation of area
                      <https://WikiPedia.org/wiki/World_Geographic_Reference_System>}.

       @return: The C{georef} (C{str}).

       @raise RangeError: Invalid B{C{lat}} or B{C{lon}}.

       @raise WGRSError: Invalid B{C{precision}}, B{C{height}} or B{C{radius}}.

       @note: The B{C{precision}} value differs from U{Georef<https://
              GeographicLib.SourceForge.io/html/classGeographicLib_1_1Georef.html>}.
              The C{georef} length is M{2 * (precision + 1)} and the
              C{georef} resolution is I{15°} for B{C{precision}} 0, I{1°}
              for 1, I{1′} for 2, I{0.1′} for 3, I{0.01′} for 4, ...
              M{10**(2 - precision)}.
    '''
    def _option(name, m, m2_, K):
        f = Scalar_(m, name=name, Error=WGRSError)
        return '%s%d' % (name[0].upper(), int(m2_(f * K) + 0.5))

    def _pstr(p, x):
        return '%0*d' % (p, x)

    p = Precision_(precision, Error=WGRSError, low=0, high=_MaxPrec)

    lat, lon, _ = _2fllh(lat, lon)
    if lat == 90:
        lat *= EPS1_2

    xt, xd, x = _2divmod3(lon, _LonOrig_M)
    yt, yd, y = _2divmod3(lat, _LatOrig_M)

    g = _LonTile[xt], _LatTile[yt]
    if p > 0:
        g += _Degrees[xd], _Degrees[yd]
        p -= 1
        if p > 0:
            d = pow(_Base, _MaxPrec - p)
            x = _pstr(p, x // d)
            y = _pstr(p, y // d)
            g += x, y

    if radius is not None:  # R before H
        g += _option('radius', radius, m2NM, 1.0),
    if height is not None:  # H is last
        g += _option('height', height, m2ft, 1e-3),

    return ''.join(g)
예제 #6
0
def resolution(prec):
    '''Determine the (geographic) resolution of a given L{Garef} precision.

       @arg prec: The given precision (C{int}).

       @return: The (geographic) resolution (C{degrees}).

       @raise ValueError: Invalid B{C{prec}}.

       @see: Function L{gars.encode} for more C{precision} details.
    '''
    p = Precision_(prec, name='prec', low=None)
    return _Resolutions[max(0, min(p, _MaxPrec))]
예제 #7
0
def resolution(prec):
    '''Determine the (geographic) resolution of a given L{Georef} precision.

       @arg prec: The given precision (C{int}).

       @return: The (geographic) resolution (C{degrees}).

       @raise ValueError: Invalid B{C{prec}}.

       @see: Function L{wgrs.encode} for more C{precision} details.
    '''
    p = Precision_(prec, name='prec', low=None)
    if p < 1:
        r = float(_Tile)
    elif p == 1:
        r = 1.0
    else:
        r = 1.0 / (60.0 * pow(_Base, min(p, _MaxPrec) - 1))
    return r
예제 #8
0
파일: wgrs.py 프로젝트: rbpdqdat/PyGeodesy
def _2Precision(precision):
    '''(INTERNAL) Return a L{Precision_} instance.
    '''
    return Precision_(precision, Error=WGRSError, low=0, high=_MaxPrec)
예제 #9
0
def encode(lat, lon, precision=None):
    '''Encode a lat-/longitude as a C{geohash}, either to the specified
       precision or if not provided, to an automatically evaluated
       precision.

       @arg lat: Latitude (C{degrees}).
       @arg lon: Longitude (C{degrees}).
       @kwarg precision: Optional, the desired geohash length (C{int}
                         1..12).

       @return: The C{geohash} (C{str}).

       @raise GeohashError: Invalid B{C{lat}}, B{C{lon}} or B{C{precision}}.

       @example:

       >>> geohash.encode(52.205, 0.119,   7)  # 'u120fxw'
       >>> geohash.encode(52.205, 0.119,  12)  # 'u120fxwshvkg'
       >>> geohash.encode(52.205, 0.1188, 12)  # 'u120fxws0jre'
       >>> geohash.encode(52.205, 0.1188)      # 'u120fxw'
       >>> geohash.encode(     0, 0)           # 's00000000000'
    '''
    lat, lon = _2fll(lat, lon)

    if precision is None:
        # Infer precision by refining geohash until
        # it matches precision of supplied lat/lon.
        for p in range(1, _MaxPrec + 1):
            gh = encode(lat, lon, p)
            ll = map2(float, decode(gh))
            if abs(lat - ll[0]) < EPS and \
               abs(lon - ll[1]) < EPS:
                return gh
        p = _MaxPrec
    else:
        p = Precision_(precision, Error=GeohashError, low=1, high=_MaxPrec)

    s, w, n, e = _Bounds4

    b = i = 0
    d, gh = True, []

    while len(gh) < p:
        i += i
        if d:  # bisect longitude
            m = favg(e, w)
            if lon < m:
                e = m
            else:
                w = m
                i += 1
        else:  # bisect latitude
            m = favg(n, s)
            if lat < m:
                n = m
            else:
                s = m
                i += 1
        d = not d

        b += 1
        if b == 5:
            # 5 bits gives a character:
            # append it and start over
            gh.append(_GeohashBase32[i])
            b = i = 0

    return ''.join(gh)