Пример #1
0
    def _all(globalocals):
        from pygeodesy.interns import NN as _NN, _attribute_, _COMMASPACE_, \
                                     _DOT_, _module_, _s_  # PYCHOK expected
        from pygeodesy.streprs import Fmt as _Fmt  # PYCHOK expected
        # collect all public module and attribute names and check
        # that modules are imported from this package, 'pygeodesy'
        # (but the latter only when not bundled with PyInstaller or
        # Py2Exe, since the file-layout is different.  Courtesy of
        # GilderGeek<https://GitHub.com/mrJean1/PyGeodesy/issues/31>)
        ns = list(lazily._ALL_INIT)
        # XXX   ps = () if _isfrozen else set([_pygeodesy_] + __name__.split(_DOT_))
        for mod, attrs in lazily._ALL_LAZY.enums():
            if mod not in globalocals:
                t = _DOT_(_pygeodesy_, mod)
                raise ImportError('missing %s%s: %s' % (_module_, _NN, t))
            ns.append(mod)
            # check that all other public attributes do exist
            if attrs and isinstance(attrs, tuple):
                t = tuple(a for a in attrs if a not in globalocals)
                if t:
                    s = _Fmt.SQUARE(_s_, len(t)) if len(t) > 1 else _NN
                    t = _COMMASPACE_.join(
                        _DOT_(_pygeodesy_, mod, a) for a in t)
                    raise ImportError('missing %s%s: %s' % (_attribute_, s, t))
                ns.extend(attrs)
# XXX       if ps:  # check that mod is a _pygeodesy_ module
# XXX           m = globalocals[mod]  # assert(m.__name__ == mod)
# XXX           f = getattr(m, '__file__', _NN)
# XXX           d = dirname(abspath(f)) if f else pygeodesy_abspath
# XXX           p = getattr(m, '__package__', _NN) or _pygeodesy_
# XXX           if p not in ps or d != pygeodesy_abspath:
# XXX               raise ImportError('foreign module: %s from %r' % (_DOT_(p, mod), f or p))
        return tuple(set(ns))  # remove duplicates
Пример #2
0
 def __setitem__(self, key, value):
     '''Set item B{C{key}} to B{C{value}}.
     '''
     if key == _name_:
         raise KeyError(
             _EQUAL_(Fmt.SQUARE(self.classname, key), repr(value)))
     dict.__setitem__(self, key, value)
Пример #3
0
    def latlon(self, latlonh):
        '''Set the lat- and longitude and optionally the height.

           @arg latlonh: New lat-, longitude and height (2- or
                        3-tuple of C{degrees} and C{meter}).

           @raise TypeError: Height of B{C{latlonh}} not C{scalar} or
                             B{C{latlonh}} not C{list} or C{tuple}.

           @raise ValueError: Invalid B{C{latlonh}} or M{len(latlonh)}.

           @see: Function L{parse3llh} to parse a B{C{latlonh}} string
                 into a 3-tuple (lat, lon, h).
        '''
        _xinstanceof(list, tuple, latlonh=latlonh)

        if len(latlonh) == 3:
            h = Height(latlonh[2], name=Fmt.SQUARE(latlonh=2))
        elif len(latlonh) != 2:
            raise _ValueError(latlonh=latlonh)
        else:
            h = self._height

        lat = Lat(latlonh[0])  # parseDMS2(latlonh[0], latlonh[1])
        lon = Lon(latlonh[1])
        self._update(lat != self._lat or
                     lon != self._lon or h != self._height)
        self._lat, self._lon, self._height = lat, lon, h
Пример #4
0
    def __init__(self, knots, weight=None, name=NN):
        '''New L{HeightLSQBiSpline} interpolator.

           @arg knots: The points with known height (C{LatLon}s).
           @kwarg weight: Optional weight or weights for each B{C{knot}}
                          (C{scalar} or C{scalar}s).
           @kwarg name: Optional name for this height interpolator (C{str}).

           @raise HeightError: Insufficient number of B{C{knots}} or
                               an invalid B{C{knot}} or B{C{weight}}.

           @raise LenError: Unequal number of B{C{knots}} and B{C{weight}}s.

           @raise ImportError: Package C{numpy} or C{scipy} not found
                               or not installed.

           @raise SciPyError: A C{LSQSphereBivariateSpline} issue.

           @raise SciPyWarning: A C{LSQSphereBivariateSpline} warning
                                as exception.
        '''
        np, spi = self._NumSciPy()

        xs, ys, hs = self._xyhs3(knots)
        n = len(hs)

        w = weight
        if isscalar(w):
            w = float(w)
            if w <= 0:
                raise HeightError(weight=w)
            w = [w] * n
        elif w is not None:
            m, w = len2(w)
            if m != n:
                raise LenError(HeightLSQBiSpline, weight=m, knots=n)
            w = map2(float, w)
            m = min(w)
            if m <= 0:
                raise HeightError(Fmt.SQUARE(weight=w.find(m)), m)
        try:
            T = 1.0e-4  # like SciPy example
            ps = np.array(_ordedup(xs, T, PI2 - T))
            ts = np.array(_ordedup(ys, T, PI - T))
            self._ev = spi.LSQSphereBivariateSpline(ys,
                                                    xs,
                                                    hs,
                                                    ts,
                                                    ps,
                                                    eps=EPS,
                                                    w=w).ev
        except Exception as x:
            raise _SciPyIssue(x)

        if name:
            self.name = name
Пример #5
0
 def _points2(self, points):
     '''(INTERNAL) Check a set of points.
     '''
     np, ps = Hausdorff._points2(self, points)
     for i, p in enumerate(ps):
         if not callable(getattr(p, _distanceTo_, None)):
             raise HausdorffError(Fmt.SQUARE(_points_, i),
                                  p,
                                  txt=_distanceTo_)
     return np, ps
Пример #6
0
def _xyhs(lls, off=True, name='llis'):
    # map (lat, lon, h) to (x, y, h) in radians, offset as
    # x: 0 <= lon <= PI2, y: 0 <= lat <= PI if off is True
    # else x: -PI <= lon <= PI, y: -PI_2 <= lat <= PI_2
    if off:
        xf = yf = _0_0
    else:  # undo offset
        xf, yf = PI, PI_2
    try:
        for i, ll in enumerate(lls):
            yield (max(0.0, radiansPI2(ll.lon + 180.0)) - xf), \
                  (max(0.0, radiansPI( ll.lat +  90.0)) - yf), ll.height
    except AttributeError as x:
        raise HeightError(Fmt.SQUARE(name, i), ll, txt=str(x))
Пример #7
0
    def _validate(self, _OK=False):  # see .EcefMatrix
        '''(INTERNAL) One-time check of C{_Names_} and C{_Units_}
           for each C{_NamedUnit} I{sub-class separately}.
        '''
        ns = self._Names_
        if not (isinstance(ns, tuple) and len(ns) > 1):  # XXX > 0
            raise _TypeError(_DOT_(self.classname, _Names_), ns)
        for i, n in enumerate(ns):
            if not _xvalid(n, _OK=_OK):
                t = Fmt.SQUARE(_Names_, i)
                raise _ValueError(_DOT_(self.classname, t), n)

        us = self._Units_
        if not isinstance(us, tuple):
            raise _TypeError(_DOT_(self.classname, _Units_), us)
        if len(us) != len(ns):
            raise LenError(self.__class__, _Units_=len(us), _Names_=len(ns))
        for i, u in enumerate(us):
            if not (u is None or callable(u)):
                t = Fmt.SQUARE(_Units_, i)
                raise _TypeError(_DOT_(self.classname, t), u)

        self.__class__._validated = True
Пример #8
0
    def add(self, key, value, *values):
        '''Add C{[key] = value}, typically C{[attr] = mod}.

           @raise AssertionError: The B{C{key}} already
                                  exists with different
                                  B{C{value}}.
        '''
        if key in self:
            val = self[key]  # duplicate OK
            if val != value and val not in values:  # PYCHOK no cover
                from pygeodesy.streprs import Fmt as _Fmt
                t = _Fmt.SQUARE(_imports_, key), val, value
                raise AssertionError('%s: %r, not %r' % t)
        else:
            self[key] = value
Пример #9
0
 def __call__(self,
              lo,
              hi,
              prec=0,
              lopen=False,
              ropen=False,
              join=_COMMASPACE_):
     '''Return the range as C{"(lo, hi)"}, C{"(lo, hi]"},
        C{"[lo, hi)"} or C{"[lo, hi]"}.
     '''
     from pygeodesy.streprs import Fmt  # PYCHOK re-imported
     r = NN(Fmt.f(lo, prec=prec), join, Fmt.f(hi, prec=prec))
     if lopen:
         r = Fmt.PAREN(r) if ropen else Fmt.LOPEN(r)
     else:
         r = Fmt.ROPEN(r) if ropen else Fmt.SQUARE(r)
     return r
Пример #10
0
    def __init__(self, knots, beta=2, name=NN, **distanceTo_kwds):
        '''New L{HeightIDWdistanceTo} interpolator.

           @arg knots: The points with known height (C{LatLon}s).
           @kwarg beta: Inverse distance power (C{int} 1, 2, or 3).
           @kwarg name: Optional name for this height interpolator (C{str}).
           @kwarg distanceTo_kwds: Optional keyword arguments for the
                                   B{C{points}}' C{LatLon.distanceTo}
                                   method.

           @raise HeightError: Insufficient number of B{C{knots}} or
                               an invalid B{C{knot}} or B{C{beta}}.

           @raise ImportError: Package U{geographiclib
                  <https://PyPI.org/project/geographiclib>} missing
                  iff B{C{points}} are L{ellipsoidalKarney.LatLon}s.

           @note: All B{C{points}} I{must} be instances of the same
                  ellipsoidal or spherical C{LatLon} class, I{not
                  checked however}.
        '''
        n, self._ks = len2(knots)
        if n < self._kmin:
            raise _insufficientError(self._kmin, knots=n)
        for i, k in enumerate(self._ks):
            if not callable(getattr(k, _distanceTo_, None)):
                raise HeightError(Fmt.SQUARE(_knots_, i), k, txt=_distanceTo_)

        # use knots[0] class and datum to create
        # compatible points in _HeightBase._height
        # instead of class LatLon_ and datum None
        self._datum = self._ks[0].datum
        self._LLis = self._ks[0].classof

        self.beta = beta
        if name:
            self.name = name
        if distanceTo_kwds:
            self._distanceTo_kwds = distanceTo_kwds
Пример #11
0
def points2(points, closed=True, base=None, Error=PointsError):
    '''Check a path or polygon represented by points.

       @arg points: The path or polygon points (C{LatLon}[])
       @kwarg closed: Optionally, consider the polygon closed,
                      ignoring any duplicate or closing final
                      B{C{points}} (C{bool}).
       @kwarg base: Optionally, check all B{C{points}} against
                    this base class, if C{None} don't check.
       @kwarg Error: Exception to raise (C{ValueError}).

       @return: A L{Points2Tuple}C{(number, points)} with the number
                of points and the points C{list} or C{tuple}.

       @raise PointsError: Insufficient number of B{C{points}}.

       @raise TypeError: Some B{C{points}} are not B{C{base}}
                         compatible.
    '''
    n, points = len2(points)

    if closed:
        # remove duplicate or closing final points
        while n > 1 and points[n-1] in (points[0], points[n-2]):
            n -= 1
        # XXX following line is unneeded if points
        # are always indexed as ... i in range(n)
        points = points[:n]  # XXX numpy.array slice is a view!

    if n < (3 if closed else 1):
        raise Error(points=n, txt=_too_(_few_))

    if base and not (isNumpy2(points) or isTuple2(points)):
        for i in range(n):
            base.others(points[i], name=Fmt.SQUARE(points=i))

    return Points2Tuple(n, points)
Пример #12
0
def fidw(xs, ds, beta=2):
    '''Interpolate using using U{Inverse Distance Weighting
       <https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW).

       @arg xs: Known values (C{scalar}[]).
       @arg ds: Non-negative distances (C{scalar}[]).
       @kwarg beta: Inverse distance power (C{int}, 0, 1, 2, or 3).

       @return: Interpolated value C{x} (C{float}).

       @raise LenError: Unequal or zero C{len(B{ds})} and C{len(B{xs})}.

       @raise ValueError: Invalid B{C{beta}}, negative B{C{ds}} value,
                          weighted B{C{ds}} below L{EPS}.

       @note: Using C{B{beta}=0} returns the mean of B{C{xs}}.
    '''
    n, xs = len2(xs)
    d, ds = len2(ds)
    if n != d or n < 1:
        raise LenError(fidw, xs=n, ds=d)

    d, x = min(zip(ds, xs))
    if d > EPS and n > 1:
        b = -Int_(beta=beta, low=0, high=3)
        if b < 0:
            ds = tuple(d**b for d in ds)
            d = fsum(ds)
            if d < EPS:
                raise _ValueError(ds=d)
            x = fdot(xs, *ds) / d
        else:
            x = fmean(xs)
    elif d < 0:
        raise _ValueError(Fmt.SQUARE(ds=ds.index(d)), d)
    return x
Пример #13
0
 def _xy2(lls):
     try:  # like _xyhs above, but keeping degrees
         for i, ll in enumerate(lls):
             yield ll.lon, ll.lat
     except AttributeError as x:
         raise HeightError(Fmt.SQUARE(llis=i), ll, txt=str(x))
Пример #14
0
 def _Error(i):
     return WGRSError(Fmt.SQUARE(georef=i), georef)
Пример #15
0
 def __getitem__(self, key):
     '''Get the value of an item by B{C{key}}.
     '''
     if key == _name_:
         raise KeyError(Fmt.SQUARE(self.classname, key))
     return dict.__getitem__(self, key)
Пример #16
0
 def _Error(i):
     return GARSError(garef=Fmt.SQUARE(repr(garef), i))