예제 #1
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
예제 #2
0
 def _height(self, lats, lons, Error=HeightError):
     if isscalar(lats) and isscalar(lons):
         llis = LatLon_(lats, lons)
     else:
         n, lats = len2(lats)
         m, lons = len2(lons)
         if n != m:
             raise Error('non-matching %s: %s vs %s' % ('len', n, m))
         llis = [LatLon_(*ll) for ll in zip(lats, lons)]
     return self(llis)  # __call__(lli) or __call__(llis)
예제 #3
0
 def _height(self, lats, lons, Error=HeightError):
     LLis, d = self._LLis, self.datum
     if isscalar(lats) and isscalar(lons):
         llis = LLis(lats, lons, datum=d)
     else:
         n, lats = len2(lats)
         m, lons = len2(lons)
         if n != m:
             # format a LenError, but raise an Error
             e = LenError(self.__class__, lats=n, lons=m, txt=None)
             raise e if Error is LenError else Error(str(e))
         llis = [LLis(*ll, datum=d) for ll in zip(lats, lons)]
     return self(llis)  # __call__(lli) or __call__(llis)
예제 #4
0
def fractional(points, fi, LatLon=None, **LatLon_kwds):
    '''Return the point at a given I{fractional} index.

       @arg points: The points (C{LatLon}[], L{Numpy2LatLon}[],
                    L{Tuple2LatLon}[] or C{other}[]).
       @arg fi: The fractional index (C{float} or C{int}).
       @kwarg LatLon: Optional class to return the I{intermediate},
                      I{fractional} point (C{LatLon}) or C{None}.
       @kwarg LatLon_kwds: Optional B{C{LatLon}} keyword arguments,
                           ignored of B{C{LatLon=None}}.

       @return: A B{C{LatLon}} or if B{C{LatLon}} is C{None}, a
                L{LatLon2Tuple}C{(lat, lon)} for B{C{points[fi]}} if
                I{fractional} index B{C{fi}} is C{int}, otherwise the
                intermediate point between B{C{points[int(fi)]}} and
                B{C{points[int(fi) + 1]}} for C{float} I{fractional}
                index B{C{fi}}.

       @raise IndexError: Fractional index B{C{fi}} invalid or
                          B{C{points}} not subscriptable.
    '''
    try:
        if not (isscalar(fi) and 0 <= fi < len(points)):
            raise IndexError
        p = _fractional(points, fi)
    except (IndexError, TypeError):
        raise _IndexError(fractional.__name__, fi)

    if LatLon and isinstance(p, LatLon2Tuple):
        p = LatLon(*p, **LatLon_kwds)
    return p
예제 #5
0
    def fadd(self, iterable):
        '''Accumulate more values from an iterable.

           @arg iterable: Sequence, list, tuple, etc. (C{scalar}s).

           @raise OverflowError: Partial C{2sum} overflow.

           @raise TypeError: Non-scalar B{C{iterable}} value.

           @raise ValueError: Invalid or non-finite B{C{iterable}} value.
        '''
        if isscalar(iterable):  # for backward compatibility
            iterable = tuple(iterable)

        ps = self._ps
        for a in map(float, iterable):  # _iter()
            if not isfinite(a):
                raise _ValueError(iterable=a, txt=_not_(_finite_))
            i = 0
            for p in ps:
                a, p = _2sum(a, p)
                if p:
                    ps[i] = p
                    i += 1
            ps[i:] = [a]
            self._n += 1
        # assert self._ps is ps
        self._fsum2_ = None
예제 #6
0
    def __imul__(self, other):
        '''Multiply this instance by a scalar or an other instance.

           @arg other: L{Fsum} instance or C{scalar}.

           @return: This instance, updated (L{Fsum}).

           @raise TypeError: Invalid B{C{other}} type.

           @see: Method L{Fsum.fmul}.
        '''
        if isscalar(other):
            self.fmul(other)
        elif isinstance(other, Fsum):
            ps = list(other._ps)  # copy
            if ps:
                s = self.fcopy()
                self.fmul(ps.pop())
                while ps:  # self += s * ps.pop()
                    p = s.fcopy()
                    p.fmul(ps.pop())
                    self.fadd(p._ps)
            else:
                self._ps = []  # zero
                self._fsum2_ = None
        else:
            raise _TypeError(_SPACE_(self, '*=', repr(other)))
        return self
예제 #7
0
def _x3d2(start, end, wrap, n, hs):
    # see <https://www.EdWilliams.org/intersect.htm> (5) ff
    a1, b1 = start.philam

    if isscalar(end):  # bearing, make a point
        a2, b2 = _destination2(a1, b1, PI_4, radians(end))
    else:  # must be a point
        _Trll.others(end, name='end' + n)
        hs.append(end.height)
        a2, b2 = end.philam

    db, b2 = unrollPI(b1, b2, wrap=wrap)
    if max(abs(db), abs(a2 - a1)) < EPS:
        raise ValueError('intersection %s%s null: %r' % ('path', n,
                                                         (start, end)))

    # note, in EdWilliams.org/avform.htm W is + and E is -
    b21, b12 = db * 0.5, -(b1 + b2) * 0.5

    sb21, cb21, sb12, cb12, \
    sa21,    _, sa12,    _ = sincos2(b21, b12, a1 - a2, a1 + a2)

    x = _Nvector(sa21 * sb12 * cb21 - sa12 * cb12 * sb21,
                 sa21 * cb12 * cb21 + sa12 * sb12 * sb21,
                 cos(a1) * cos(a2) * sin(db))  # ll=start
    return x.unit(), (db, (a2 - a1))  # negated d
예제 #8
0
    def __mod__(self, arg, **unused):
        '''Regular C{%} operator.

           @arg arg: A C{scalar} value to be formatted (either
                     the C{scalar}, or a 1-tuple C{(scalar,)},
                     or 2-tuple C{(prec, scalar)}.

           @raise TypeError: Non-scalar B{C{arg}} value.

           @raise ValueError: Invalid B{C{arg}}.
        '''
        def _error(arg):
            n = _DOT_(Fstr.__name__, self.name or self)
            return _SPACE_(n, _PERCENT_, repr(arg))

        prec = 6  # default std %f and %F
        if isinstance(arg, (tuple, list)):
            n = len(arg)
            if n == 1:
                arg = arg[0]
            elif n == 2:
                prec, arg = arg
            else:
                raise _ValueError(_error(arg))

        if not isscalar(arg):
            raise _TypeError(_error(arg))
        return self(arg, prec=prec)
예제 #9
0
    def toStr(self,
              prec=3,
              sep=_SPACE_,
              radius=False,
              **unused):  # PYCHOK expected
        '''Return a string representation of this WM coordinate.

           @kwarg prec: Optional number of decimals, 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 radius: Optionally, include radius (C{bool} or C{scalar}).

           @return: This WM as "meter meter" (C{str}) plus " radius"
                    if B{C{radius}} is C{True} or C{scalar}.

           @raise WebMercatorError: Invalid B{C{radius}}.

           @example:

           >>> w = Wm(448251, 5411932.0001)
           >>> w.toStr(4)  # 448251.0 5411932.0001
           >>> w.toStr(sep=', ')  # 448251, 5411932
        '''
        fs = self._x, self._y
        if radius in (False, None):
            pass
        elif radius is True:
            fs += (self._radius, )
        elif isscalar(radius):
            fs += (radius, )
        else:
            raise WebMercatorError(radius=radius)
        t = strs(fs, prec=prec)
        return t if sep is None else sep.join(t)
예제 #10
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: Number of B{C{knots}} and B{C{weight}}s
                            don't match.

           @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(_item_sq(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
예제 #11
0
def _fraction(fraction, n):
    f = 1  # int, no fractional indices
    if fraction in (None, 1):
        pass
    elif not (isscalar(fraction) and EPS < fraction < EPS1 and
              (float(n) - fraction) < n):
        raise FrechetError(fraction=fraction)
    elif fraction < EPS1:
        f = float(fraction)
    return f
예제 #12
0
    def times(self, factor):
        '''Multiply this vector by a scalar.

           @arg factor: Scale factor (C{scalar}).

           @return: New, scaled vector (L{Vector3d}).

           @raise TypeError: Non-scalar B{C{factor}}.
        '''
        if not isscalar(factor):
            raise IsnotError('scalar', factor=factor)
        return self.classof(self.x * factor, self.y * factor, self.z * factor)
예제 #13
0
 def _gc3(self, start, end, namend, raiser=_points_):
     '''(INTERNAL) Return great circle, start and end Nvectors.
     '''
     s = start.toNvector()
     if isscalar(end):  # bearing
         gc = s.greatCircle(end)
         e = None
     else:
         self.others(end, name=namend)
         e = end.toNvector()
         gc = s.cross(e, raiser=raiser)  # XXX .unit()?
     return gc, s, e
예제 #14
0
def _to3zBhp(zone,
             band,
             hemipole=NN,
             Error=_ValueError):  # imported by .epsg, .ups, .utm, .utmups
    '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter.

       @arg zone: Zone with/-out Band (C{scalar} or C{str}).
       @kwarg band: Optional (longitudinal/polar) Band letter (C{str}).
       @kwarg hemipole: Optional hemisphere/pole letter (C{str}).
       @kwarg Error: Optional error to raise, overriding the default
                     C{ValueError}.

       @return: 3-Tuple (C{zone, Band, hemisphere/pole}) as (C{int,
                str, 'N'|'S'}) where C{zone} is C{0} for UPS or
                C{1..60} for UTM and C{Band} is C{'A'..'Z'} I{NOT}
                checked for valid UTM/UPS bands.

       @raise ValueError: Invalid B{C{zone}}, B{C{band}} or B{C{hemipole}}.
    '''
    try:
        B, z = band, _UTMUPS_ZONE_INVALID
        if isscalar(zone):
            z = int(zone)
        elif zone and isstr(zone):
            if zone.isdigit():
                z = int(zone)
            elif len(zone) > 1:
                B = zone[-1:]
                z = int(zone[:-1])
            elif zone in 'AaBbYyZz':  # single letter
                B = zone
                z = _UPS_ZONE

        if _UTMUPS_ZONE_MIN <= z <= _UTMUPS_ZONE_MAX:
            hp = hemipole[:1].upper()
            if hp in _NS_ or not hp:
                z = Zone(z)
                B = Band(B.upper())
                if B.isalpha():
                    return z, B, (hp or _NS_[B < _N_])
                elif not B:
                    return z, B, hp

        t = _invalid_
    except (AttributeError, IndexError, TypeError, ValueError) as x:
        t = str(x)  # no Python 3+ exception chaining
    raise Error(zone=zone, band=B, hemipole=hemipole, txt=t)
예제 #15
0
def fstr(floats, prec=6, fmt='F', ints=False, sep=', '):
    '''Convert one or more floats to string, optionally stripped of trailing zero decimals.

       @arg floats: Single or a list, sequence, tuple, etc. (C{scalar}s).
       @kwarg prec: The C{float} precision, number of decimal digits (0..9).
                    Trailing zero decimals are stripped if B{C{prec}} is
                    positive, but kept for negative B{C{prec}} values.
       @kwarg fmt: Optional, float format (C{str}).
       @kwarg ints: Optionally, remove the decimal dot (C{bool}).
       @kwarg sep: Separator joining the B{C{floats}} (C{str}).

       @return: The C{sep.join(strs(floats, ...)} joined (C{str}) or single
                C{strs((floats,), ...)} (C{str}) if B{C{floats}} is C{scalar}.
    '''
    if isscalar(floats):
        floats = (floats, )
    return sep.join(_streprs(prec, floats, fmt, ints, True, None))
예제 #16
0
    def dividedBy(self, factor):
        '''Divide this vector by a scalar.

           @arg factor: The divisor (C{scalar}).

           @return: New, scaled vector (L{Vector3d}).

           @raise TypeError: Non-scalar B{C{factor}}.

           @raise VectorError: Invalid or zero B{C{factor}}.
        '''
        if not isscalar(factor):
            raise _IsnotError(_scalar_, factor=factor)
        try:
            return self.times(_1_0 / factor)
        except (ValueError, ZeroDivisionError) as x:
            raise VectorError(factor=factor, txt=str(x))
예제 #17
0
    def __iadd__(self, other):
        '''Add a scalar or an other instance to this instance.

           @arg other: L{Fsum} instance or C{scalar}.

           @return: This instance, updated (L{Fsum}).

           @raise TypeError: Invalid B{C{other}} type.

           @see: Method L{Fsum.fadd}.
        '''
        if isscalar(other):
            self.fadd_(other)
        elif other is self:
            self.fmul(2)
        elif isinstance(other, Fsum):
            self.fadd(other._ps)
        else:
            raise _TypeError(_SPACE_(self, '+=', repr(other)))
        return self
예제 #18
0
    def __isub__(self, other):
        '''Subtract a scalar or an other instance from this instance.

           @arg other: L{Fsum} instance or C{scalar}.

           @return: This instance, updated (L{Fsum}).

           @raise TypeError: Invalid B{C{other}} type.

           @see: Method L{Fsum.fadd}.
        '''
        if isscalar(other):
            self.fadd_(-other)
        elif other is self:
            self._ps = []  # zero
            self._fsum2_ = None
        elif isinstance(other, Fsum):
            self.fadd(-p for p in other._ps)
        else:
            raise _TypeError(_SPACE_(self, '-=', repr(other)))
        return self
예제 #19
0
def _to3zBhp(zone, band, hemipole=''):  # imported by .epsg, .ups, .utm, .utmups
    '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter.

       @arg zone: Zone with/-out Band (C{scalar} or C{str}).
       @kwarg band: Optional (longitudinal/polar) Band letter (C{str}).
       @kwarg hemipole: Optional hemisphere/pole letter (C{str}).

       @return: 3-Tuple (C{zone, Band, hemisphere/pole}) as (C{int,
                str, 'N'|'S'}) where C{zone} is C{0} for UPS or
                C{1..60} for UTM and C{Band} is C{'A'..'Z'} I{NOT}
                checked for valid UTM/UPS bands.

       @raise ValueError: Invalid B{C{zone}}, B{C{band}} or B{C{hemipole}}.
    '''
    B = band
    try:
        z = _UTMUPS_ZONE_INVALID
        if isscalar(zone) or zone.isdigit():
            z = int(zone)
        elif zone and isstr(zone):
            if len(zone) > 1:
                B = zone[-1:]
                z = int(zone[:-1])
            elif zone in 'AaBbYyZz':  # single letter
                B = zone
                z = _UPS_ZONE

        if _UTMUPS_ZONE_MIN <= z <= _UTMUPS_ZONE_MAX:
            hp = hemipole[:1].upper()
            if hp in ('N', 'S') or not hp:
                B = B.upper()
                if B.isalpha():
                    return z, B, (hp or ('S' if B < 'N' else 'N'))
                elif not B:
                    return z, B, hp

    except (AttributeError, TypeError, ValueError):
        pass
    raise ValueError('%s invalid: %r' % (_or('zone', 'band', 'hemipole'),
                                             (zone,   B,      hemipole)))
예제 #20
0
    def fadd(self, iterable):
        '''Accumulate more values from an iterable.

           @arg iterable: Sequence, list, tuple, etc. (C{scalar}s).

           @raise OverflowError: Partial C{2sum} overflow.

           @raise TypeError: Non-scalar B{C{iterable}} value.

           @raise ValueError: Invalid or non-finite B{C{iterable}} value.
        '''
        if isscalar(iterable):  # for backward compatibility
            iterable = tuple(iterable)


#       def _iter():
#           for a in iterable:
#               if isinstance(a, Fsum):
#                   if a is self:
#                       self.fmul(2)
#                   else:
#                       for a in a._ps:
#                           yield a
#               else:
#                   yield a

        ps = self._ps
        for a in iterable:  # _iter()
            if not isfinite(a):
                raise ValueError('%s, not %s: %r' % (self, 'finite', a))
            i = 0
            for p in ps:
                a, p = _2sum(a, p)
                if p:
                    ps[i] = p
                    i += 1
            ps[i:] = [a]
            self._n += 1
        # assert self._ps is ps
        self._fsum2_ = None
예제 #21
0
def _spherical_datum(radius, name=NN, raiser=False):
    '''(INTERNAL) Create a L{Datum} from an L{Ellipsoid}, L{Ellipsoid2} or scalar earth C{radius}.
    '''
    try:
        d = _ellipsoidal_datum(radius, name=name)
    except TypeError:
        d = None
    if d is None:
        if not isscalar(radius):
            _xinstanceof(Datum,
                         Ellipsoid,
                         Ellipsoid2,
                         a_f2Tuple,
                         Scalar,
                         datum=radius)
        n = _UNDERSCORE_ + name
        r = Radius_(radius, Error=TypeError)
        E = Ellipsoid(r, r, name=n)
        d = Datum(E, transform=Transforms.Identity, name=n)
    elif raiser and not d.isSpherical:  # raiser if no spherical
        raise _IsnotError(_spherical_, datum=radius)
    return d
예제 #22
0
def fstr(floats, prec=6, fmt=Fmt.F, ints=False, sep=_COMMASPACE_, strepr=None):
    '''Convert one or more floats to string, optionally stripped of trailing zero decimals.

       @arg floats: Single or a list, sequence, tuple, etc. (C{scalar}s).
       @kwarg prec: The C{float} precision, number of decimal digits (0..9).
                    Trailing zero decimals are stripped if B{C{prec}} is
                    positive, but kept for negative B{C{prec}} values.  In
                    addition, trailing decimal zeros are stripped for U{alternate,
                    form '#'<https://docs.Python.org/3/library/stdtypes.html
                    #printf-style-string-formatting>}.
       @kwarg fmt: Optional, C{float} format (C{str}).
       @kwarg ints: Optionally, remove the decimal dot for C{int} values (C{bool}).
       @kwarg sep: Separator joining the B{C{floats}} (C{str}).
       @kwarg strepr: Optional callable to format non-C{floats} (typically
                      C{repr}, C{str}) or C{None} to raise a TypeError.

       @return: The C{sep.join(strs(floats, ...)} joined (C{str}) or single
                C{strs((floats,), ...)} (C{str}) if B{C{floats}} is C{scalar}.
    '''
    if isscalar(floats):  # see Fstr.__call__ above
        return next(_streprs(prec, (floats, ), fmt, ints, True, strepr))
    else:
        return sep.join(_streprs(prec, floats, fmt, ints, True, strepr))
예제 #23
0
def intersection(start1,
                 end1,
                 start2,
                 end2,
                 height=None,
                 wrap=False,
                 LatLon=LatLon,
                 **LatLon_kwds):
    '''Compute the intersection point of two paths both defined
       by two points or a start point and bearing from North.

       @arg start1: Start point of the first path (L{LatLon}).
       @arg end1: End point ofthe first path (L{LatLon}) or
                  the initial bearing at the first start point
                  (compass C{degrees360}).
       @arg start2: Start point of the second path (L{LatLon}).
       @arg end2: End point of the second path (L{LatLon}) or
                  the initial bearing at the second start point
                  (compass C{degrees360}).
       @kwarg height: Optional height for the intersection point,
                      overriding the mean height (C{meter}).
       @kwarg wrap: Wrap and unroll longitudes (C{bool}).
       @kwarg LatLon: Optional class to return the intersection
                      point (L{LatLon}) or C{None}.
       @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
                           arguments, ignored if B{C{LatLon=None}}.

       @return: The intersection point (B{C{LatLon}}) or a
                L{LatLon3Tuple}C{(lat, lon, height)} if B{C{LatLon}}
                is C{None}.  An alternate intersection point might
                be the L{antipode} to the returned result.

       @raise TypeError: A B{C{start}} or B{C{end}} point not L{LatLon}.

       @raise ValueError: Intersection is ambiguous or infinite or
                          the paths are parallel, coincident or null
                          or invalid B{C{height}}.

       @example:

       >>> p = LatLon(51.8853, 0.2545)
       >>> s = LatLon(49.0034, 2.5735)
       >>> i = intersection(p, 108.547, s, 32.435)  # '50.9078°N, 004.5084°E'
    '''
    _Trll.others(start1, name='start1')
    _Trll.others(start2, name='start2')

    hs = [start1.height, start2.height]

    a1, b1 = start1.philam
    a2, b2 = start2.philam

    db, b2 = unrollPI(b1, b2, wrap=wrap)
    r12 = haversine_(a2, a1, db)
    if abs(r12) < EPS:  # [nearly] coincident points
        a, b = favg(a1, a2), favg(b1, b2)

    # see <https://www.EdWilliams.org/avform.htm#Intersection>
    elif isscalar(end1) and isscalar(end2):  # both bearings
        sa1, ca1, sa2, ca2, sr12, cr12 = sincos2(a1, a2, r12)

        x1, x2 = (sr12 * ca1), (sr12 * ca2)
        if abs(x1) < EPS or abs(x2) < EPS:
            raise ValueError('intersection %s: %r vs %r' % ('parallel',
                                                            (start1, end1),
                                                            (start2, end2)))

        # handle domain error for equivalent longitudes,
        # see also functions asin_safe and acos_safe at
        # <https://www.EdWilliams.org/avform.htm#Math>
        t1, t2 = map1(acos1, (sa2 - sa1 * cr12) / x1, (sa1 - sa2 * cr12) / x2)
        if sin(db) > 0:
            t12, t21 = t1, PI2 - t2
        else:
            t12, t21 = PI2 - t1, t2

        t13, t23 = map1(radiansPI2, end1, end2)
        x1, x2 = map1(
            wrapPI,
            t13 - t12,  # angle 2-1-3
            t21 - t23)  # angle 1-2-3
        sx1, cx1, sx2, cx2 = sincos2(x1, x2)
        if sx1 == 0 and sx2 == 0:  # max(abs(sx1), abs(sx2)) < EPS
            raise ValueError('intersection %s: %r vs %r' % ('infinite',
                                                            (start1, end1),
                                                            (start2, end2)))
        sx3 = sx1 * sx2
        #       if sx3 < 0:
        #           raise ValueError('intersection %s: %r vs %r' % ('ambiguous',
        #                            (start1, end1), (start2, end2)))
        x3 = acos1(cr12 * sx3 - cx2 * cx1)
        r13 = atan2(sr12 * sx3, cx2 + cx1 * cos(x3))

        a, b = _destination2(a1, b1, r13, t13)
        # choose antipode for opposing bearings
        if _xb(a1, b1, end1, a, b, wrap) < 0 or \
           _xb(a2, b2, end2, a, b, wrap) < 0:
            a, b = antipode_(a, b)  # PYCHOK PhiLam2Tuple

    else:  # end point(s) or bearing(s)
        x1, d1 = _x3d2(start1, end1, wrap, '1', hs)
        x2, d2 = _x3d2(start2, end2, wrap, '2', hs)
        x = x1.cross(x2)
        if x.length < EPS:  # [nearly] colinear or parallel paths
            raise ValueError('intersection %s: %r vs %r' % ('colinear',
                                                            (start1, end1),
                                                            (start2, end2)))
        a, b = x.philam
        # choose intersection similar to sphericalNvector
        d1 = _xdot(d1, a1, b1, a, b, wrap)
        if d1:
            d2 = _xdot(d2, a2, b2, a, b, wrap)
            if (d2 < 0 and d1 > 0) or (d2 > 0 and d1 < 0):
                a, b = antipode_(a, b)  # PYCHOK PhiLam2Tuple

    h = fmean(hs) if height is None else Height(height)
    return _latlon3(degrees90(a), degrees180(b), h, intersection, LatLon,
                    **LatLon_kwds)
예제 #24
0
def _2epoch(epoch):  # imported by .ellipsoidalBase.py
    '''(INTERNAL) Validate an C{epoch}.
    '''
    if isscalar(epoch) and epoch > 0:  # XXX 1970?
        return _F(epoch)
    raise IsnotError('scalar', epoch=epoch)
예제 #25
0
파일: trf.py 프로젝트: itzmejawad/PyGeodesy
def _2epoch(epoch):  # imported by .ellipsoidalBase
    '''(INTERNAL) Validate an C{epoch}.
    '''
    if isscalar(epoch) and epoch > 0:  # XXX 1970?
        return _F(epoch)
    raise _TypeError(epoch=epoch, txt=_not_scalar_)