Пример #1
0
    def _sigmaInv(self, xi, eta):
        '''(INTERNAL) Invert C{sigma} using Newton's method.

           @return: 2-Tuple C{(u, v)}.

           @see: C{void TMExact::sigmainv(real xi, real eta,
                                          real &u, real &v)}.

           @raise EllipticError: No convergence.
        '''
        u, v, trip = self._sigmaInv0(xi, eta)
        if trip:
            self._iteration = 0
        else:
            U, V = Fsum(u), Fsum(v)
            # min iterations = 2, max = 7, mean = 3.9
            for self._iteration in range(1, _TRIPS):  # GEOGRAPHICLIB_PANIC
                sncndn6 = self._sncndn6(u, v)
                X, E, _ = self._sigma3(v, *sncndn6)
                dw, dv  = self._sigmaDwd( *sncndn6)
                X  = xi - X
                E -= eta
                u, du = U.fsum2_(X * dw,  E * dv)
                v, dv = V.fsum2_(X * dv, -E * dw)
                if trip:
                    break
                trip = hypot2(du, dv) < _TOL_10
            else:
                t = unstr(self._sigmaInv.__name__, xi, eta)
                raise EllipticError(_no_convergence_, txt=t)
        return u, v
Пример #2
0
    def _zetaInv(self, taup, lam):
        '''(INTERNAL) Invert C{zeta} using Newton's method.

           @return: 2-Tuple C{(u, v)}.

           @see: C{void TMExact::zetainv(real taup, real lam,
                                         real &u, real &v)}.

           @raise EllipticError: No convergence.
        '''
        psi = asinh(taup)
        sca = 1.0 / hypot1(taup)
        u, v, trip = self._zetaInv0(psi, lam)
        if trip:
            self._iteration = 0
        else:
            stol2 = _TOL_10 / max(psi**2, 1.0)
            U, V = Fsum(u), Fsum(v)
            # min iterations = 2, max = 6, mean = 4.0
            for self._iteration in range(1, _TRIPS):  # GEOGRAPHICLIB_PANIC
                sncndn6 = self._sncndn6(u, v)
                T, L, _ = self._zeta3(  *sncndn6)
                dw, dv  = self._zetaDwd(*sncndn6)
                T  = (taup - T) * sca
                L -= lam
                u, du = U.fsum2_(T * dw,  L * dv)
                v, dv = V.fsum2_(T * dv, -L * dw)
                if trip:
                    break
                trip = hypot2(du, dv) < stol2
            else:
                t = unstr(self._zetaInv.__name__, taup, lam)
                raise EllipticError(_no_convergence_, txt=t)
        return u, v
Пример #3
0
    def __init__(self, a_ellipsoid, f, name):
        '''(INTERNAL) New C{Ecef...}.
        '''
        try:
            E = a_ellipsoid
            if f is None:
                if isinstance(E, Datum):
                    self._datum = E
                    E = E.ellipsoid
                elif not isinstance(E, Ellipsoid):
                    raise TypeError
                if not name:
                    name = E.name

            elif isscalar(E) and isscalar(f):
                a = float(E)
                f_ = (1.0 / f) if f else 0  # sphere
                b = None if f_ else a
                E = Ellipsoid(a, b, f_, name='_' + name)

            else:
                raise ValueError

            if not (E.a > 0 and E.f < 1):
                raise ValueError

        except (TypeError, ValueError):
            t = unstr(self.classname, a=E, f=f)
            raise EcefError('%s invalid: %s' % ('ellipsoid', t))

        self._E = E
        if name:
            self.name = name
Пример #4
0
def _notError(inst, name, args, kwds):  # PYCHOK no cover
    '''(INTERNAL) Format an error message.
    '''
    n = _DOT_(classname(inst, prefixed=True), _dunder_name(name, name))
    m = _COMMASPACE_.join(
        modulename(c, prefixed=True) for c in inst.__class__.__mro__[1:-1])
    return _COMMASPACE_(unstr(n, *args, **kwds), Fmt.PAREN(_MRO_, m))
Пример #5
0
def _notError(inst, name, args, kwds):  # PYCHOK no cover
    '''(INTERNAL) Format an error message.
    '''
    n = _dot_(classname(inst, prefixed=True), _dunder_name(name, name))
    m = _COMMA_SPACE_.join(
        modulename(c, prefixed=True) for c in inst.__class__.__mro__[1:-1])
    t = '%s, MRO(%s)' % (unstr(n, *args, **kwds), m)
    return t
Пример #6
0
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{cosineAndoyerLambert},
             L{cosineForsytheAndoyerLambert}, L{cosineLaw}, L{euclidean},
             L{flatLocal}/L{hubeny}, L{flatPolar}, L{haversine}, L{thomas}
             and 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 = unstr(equirectangular_.__name__,
                  lat1,
                  lon1,
                  lat2,
                  lon2,
                  limit=limit)
        raise LimitError('delta exceeds limit', txt=t)

    if adjust:  # scale delta lon
        d_lon *= _scale_deg(lat1, lat2)

    d2 = hypot2(d_lat, d_lon)  # degrees squared!
    return Distance4Tuple(d2, d_lat, d_lon, ulon2 - lon2)
Пример #7
0
def _2sum(a, b):  # by .testFmath
    '''(INTERNAL) Precision C{2sum} of M{a + b}.
    '''
    s = a + b
    if not isfinite(s):
        raise _OverflowError(unstr(_2sum.__name__, a, b), txt=str(s))
    if abs(a) < abs(b):
        a, b = b, a
    return s, b - (s - a)
Пример #8
0
 def __init__(self, *args, **kwds):
     if args:  # args override kwds
         if len(args) != 1:
             t = unstr(self.classname, *args, **kwds)
             raise _ValueError(args=len(args), txt=t)
         kwds = _xkwds(dict(args[0]), **kwds)
     if _name_ in kwds:
         _Named.name.fset(self, kwds.pop(_name_))  # see _Named.name
     dict.__init__(self, kwds)
Пример #9
0
 def __init__(self, *args, **kwds):
     if args:  # args override kwds
         if len(args) != 1:
             t = unstr(self.classname, *args, **kwds)
             raise ValueError('invalid: ' + t)
         kwds.update(dict(args[0]))
     if _NAME_ in kwds:
         _Named.name.fset(self, kwds.pop(_NAME_))  # see _Named.name
     dict.__init__(self, kwds)
Пример #10
0
 def __new__(cls, *args):
     '''New L{_NamedTuple} initialized with B{C{positional}} arguments.
     '''
     self = tuple.__new__(cls, args)
     ns = self._Names_
     if not (isinstance(ns, tuple) and len(ns) > 1):  # XXX > 0
         raise _TypeError(_dot_(self.classname, _Names_), ns)
     if len(ns) != len(args) or not ns:
         raise LenError(cls, args=len(args), ns=len(ns))
     if _name_ in ns:
         t = unstr(_dot_(self.classname, _Names_), *ns)
         raise _NameError(_name_, _name_, txt=t)
     return self
Пример #11
0
def notOverloaded(inst, name, *args, **kwds):  # PYCHOK no cover
    '''Raise an C{AssertionError} for a method or property not overloaded.

       @arg name: Method, property or name (C{str}).
       @arg args: Method or property positional arguments (any C{type}s).
       @arg kwds: Method or property keyword arguments (any C{type}s).
    '''
    n = getattr(name, '__name__', name)
    n = '%s %s' % (notOverloaded.__name__,
                   _dot_(classname(inst, prefixed=True), n))
    m = ', '.join(
        modulename(c, prefixed=True) for c in inst.__class__.__mro__[1:-1])
    raise AssertionError('%s, MRO(%s)' % (unstr(n, *args, **kwds), m))
Пример #12
0
def unStr(name, *args, **kwds):
    '''DEPRECATED, use function L{unstr}.
    '''
    from pygeodesy.streprs import unstr
    return unstr(name, *args, **kwds)
Пример #13
0
def _xkwds_Error(_xkwds_func, kwds, name_default):
    from pygeodesy.streprs import unstr
    t = unstr(_xkwds_func.__name__, kwds, **name_default)
    n = ('multiple ' if name_default else 'no ') + _name_
    return _AssertionError(t, txt=n + '=default kwargs')
Пример #14
0
def _trilaterate(point1,
                 distance1,
                 point2,
                 distance2,
                 point3,
                 distance3,
                 radius=R_M,
                 height=None,
                 useZ=False,
                 **LatLon_LatLon_kwds):
    # (INTERNAL) Locate a point at given distances from
    # three other points, see LatLon.triangulate above

    def _nd2(p, d, r, _i_, *qs):  # .toNvector and angular distance squared
        for q in qs:
            if p.isequalTo(q, EPS):
                raise _ValueError(points=p, txt=_coincident_)
        return p.toNvector(), (Scalar(d, name=_distance_ + _i_) / r)**2

    r = Radius_(radius)

    n1, r12 = _nd2(point1, distance1, r, _1_)
    n2, r22 = _nd2(point2, distance2, r, _2_, point1)
    n3, r32 = _nd2(point3, distance3, r, _3_, point1, point2)

    # the following uses x,y coordinate system with origin at n1, x axis n1->n2
    y = n3.minus(n1)
    x = n2.minus(n1)
    z = None

    d = x.length  # distance n1->n2
    if d > EPS_2:  # and y.length > EPS_2:
        X = x.unit()  # unit vector in x direction n1->n2
        i = X.dot(y)  # signed magnitude of x component of n1->n3
        Y = y.minus(X.times(i)).unit()  # unit vector in y direction
        j = Y.dot(y)  # signed magnitude of y component of n1->n3
        if abs(j) > EPS_2:
            # courtesy Carlos Freitas <https://GitHub.com/mrJean1/PyGeodesy/issues/33>
            x = fsum_(r12, -r22, d**2) / (2 * d)  # n1->intersection x- and ...
            y = fsum_(r12, -r32, i**2, j**2, -2 * x * i) / (
                2 * j)  # ... y-component
            # courtesy AleixDev <https://GitHub.com/mrJean1/PyGeodesy/issues/43>
            z = fsum_(max(r12, r22, r32), -(x**2),
                      -(y**2))  # XXX not just r12!
            if z > EPS:
                n = n1.plus(X.times(x)).plus(Y.times(y))
                if useZ:  # include Z component
                    Z = X.cross(Y)  # unit vector perpendicular to plane
                    n = n.plus(Z.times(sqrt(z)))
                if height is None:
                    h = fidw((point1.height, point2.height, point3.height),
                             map1(fabs, distance1, distance2, distance3))
                else:
                    h = Height(height)
                kwds = _xkwds(LatLon_LatLon_kwds, height=h)
                return n.toLatLon(**
                                  kwds)  # Nvector(n.x, n.y, n.z).toLatLon(...)

    # no intersection, d < EPS_2 or abs(j) < EPS_2 or z < EPS
    t = NN(_no_, _intersection_, _SPACE_)
    raise IntersectionError(point1=point1,
                            distance1=distance1,
                            point2=point2,
                            distance2=distance2,
                            point3=point3,
                            distance3=distance3,
                            txt=unstr(t, z=z, useZ=useZ))