Beispiel #1
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)
Beispiel #2
0
    def toStr(self, prec=3, sep=' ', radius=False):  # PYCHOK expected
        '''Return a string representation of this WM coordinate.

           @keyword prec: Optional number of decimals, unstripped (C{int}).
           @keyword sep: Optional separator to join (C{str}).
           @keyword radius: Optionally, include radius (C{bool} or C{scalar}).

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

           @raise ValueError: Invalid I{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 ValueError('% invalid: %r' % ('radius', radius))
        return fStr(fs, prec=prec, sep=sep)
Beispiel #3
0
def _toZBlat3(zone, band, mgrs=False):  # used by mgrs.Mgrs
    '''(INTERNAL) Check and return zone, Band and band latitude.

       @param zone: Zone number or string.
       @param band: Band letter.
       @param mgrs: Optionally, raise UTMError (C{bool}).

       @return: 3-Tuple (zone, Band, latitude).
    '''
    try:
        if isscalar(zone) or zone.isdigit():
            z, B, x = int(zone), str(band), band
        else:
            z, B, x = int(zone[:-1] or 0), zone[-1:], zone

        if 1 > z or z > 60:
            raise ValueError

    except (AttributeError, TypeError, ValueError):
        raise UTMError('%s invalid: %r' % ('zone', zone))

    b = None
    if B:
        b = _Bands.find(B)
        if b < 0:
            raise UTMError('%s invalid: %r' % ('band', x))
        b = (b << 3) - 80
    elif mgrs:
        raise UTMError('%s missing' % ('band', ))

    return z, B, b
Beispiel #4
0
def _x3d2(start, end, wrap, n):
    # see <http://www.EdWilliams.org/intersect.htm> (5) ff
    a1, b1 = start.to2ab()

    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)
        a2, b2 = end.to2ab()

    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

    cb21, cb12 = map1(cos, b21, b12)
    sb21, sb12 = map1(sin, b21, b12)
    sa21, sa12 = map1(sin, a1 - a2, a1 + a2)

    x = Vector3d(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
Beispiel #5
0
    def __init__(self, knots, weight=None):
        '''New L{HeightLSQBiSpline} interpolator.

           @param knots: The points with known height (C{LatLon}s).
           @keyword weight: Optional weight or weights for each I{knot}
                            (C{scalar} or C{scalar}s).

           @raise HeightError: Insufficient number of I{knots} or
                               I{weight}s or invalid I{knot} or I{weight}.

           @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)
        m = len(hs)

        if not weight:
            w = None  # default
        elif isscalar(weight):
            w = float(weight)
            if w <= 0:
                raise HeightError('invalid %s: %.6f' % ('weight', w))
        else:
            n, w = len2(weight)
            if n != m:
                raise HeightError('invalid %s: %s, not %s' %
                                  ('number of weights', n, m))
            w = np.array(map(float, w))
            for i in range(m):
                if w[i] <= 0:
                    raise HeightError('invalid %s[%s]: %.6f' %
                                      ('weight', i, w[i]))

        T = 1.0e-4  # like SciPy example
        ps = np.array(_ordedup(xs, T, PI2 - T))
        ts = np.array(_ordedup(ys, T, PI - T))

        try:
            self._ev = spi.LSQSphereBivariateSpline(ys,
                                                    xs,
                                                    hs,
                                                    ts,
                                                    ps,
                                                    eps=EPS,
                                                    w=w).ev
        except Exception as x:
            raise _SciPyIssue(x)
Beispiel #6
0
    def times(self, factor):
        '''Multiply this vector by a scalar.

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

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

           @raise TypeError: Non-scalar I{factor}.
        '''
        if not isscalar(factor):
            raise TypeError('%s not scalar: %r' % ('factor', factor))
        return self.classof(self.x * factor, self.y * factor, self.z * factor)
Beispiel #7
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
Beispiel #8
0
    def dividedBy(self, factor):
        '''Divide this vector by a scalar.

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

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

           @raise TypeError: Non-scalar I{factor}.

           @raise ValueError: Invalid or zero I{factor}.
        '''
        if not isscalar(factor):
            raise TypeError('%s not scalar: %r' % ('factor', factor))
        try:
            return self.times(1.0 / factor)
        except (ValueError, ZeroDivisionError):
            raise ValueError('%s invalid: %r' % ('factor', factor))
Beispiel #9
0
def _to3zBhp(zone,
             band,
             hemipole=''):  # imported by .epsg, .ups, .utm, .utmups
    '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter.

       @param zone: Zone with/-out Band (C{scalar} or C{str}).
       @keyword band: Optional (longitudinal/polar) Band letter (C{str}).
       @keyword 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 isinstance(zone, _Strs):
            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, %s or %s invalid: %r' % ('zone', 'band', 'hemipole',
                                                   (zone, B, hemipole)))
Beispiel #10
0
def intersection(start1,
                 end1,
                 start2,
                 end2,
                 height=None,
                 wrap=False,
                 LatLon=LatLon):
    '''Compute the intersection point of two paths both defined
       by two points or a start point and bearing from North.

       @param start1: Start point of the first path (L{LatLon}).
       @param end1: End point ofthe first path (L{LatLon}) or
                    the initial bearing at the first start point
                    (compass C{degrees360}).
       @param start2: Start point of the second path (L{LatLon}).
       @param end2: End point of the second path (L{LatLon}) or
                    the initial bearing at the second start point
                    (compass C{degrees360}).
       @keyword height: Optional height for the intersection point,
                        overriding the mean height (C{meter}).
       @keyword wrap: Wrap and unroll longitudes (C{bool}).
       @keyword LatLon: Optional (sub-)class for the intersection point
                        (L{LatLon}) or C{None}.

       @return: The intersection point (I{LatLon}) or 3-tuple
                (C{degrees90}, C{degrees180}, height) if I{LatLon}
                is C{None}.  An alternate intersection point might
                be the L{antipode} to the returned result.

       @raise TypeError: Start or end point(s) not L{LatLon}.

       @raise ValueError: Intersection is ambiguous or infinite or
                          the paths are parallel, coincident or null.

       @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')

    a1, b1 = start1.to2ab()
    a2, b2 = start2.to2ab()

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

    # see <http://www.EdWilliams.org/avform.htm#Intersection>
    elif isscalar(end1) and isscalar(end2):  # both bearings
        ca1, ca2, cr12 = map1(cos, a1, a2, r12)
        sa1, sa2, sr12 = map1(sin, 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
        # <http://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, sx2 = map1(sin, 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)))
        cx1, cx2 = map1(cos, x1, x2)

        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)

    else:  # end point(s) or bearing(s)
        x1, d1 = _x3d2(start1, end1, wrap, '1')
        x2, d2 = _x3d2(start2, end2, wrap, '2')
        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.to2ll()
        # choose intersection similar to sphericalNvector
        d1 = _xdot(d1, a1, b1, a, b, wrap)
        d2 = _xdot(d2, a2, b2, a, b, wrap)
        if (d1 < 0 and d2 > 0) or (d1 > 0 and d2 < 0):
            a, b = antipode(a, b)

    h = start1._havg(start2) if height is None else height
    return (a, b, h) if LatLon is None else LatLon(a, b, height=h)
Beispiel #11
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 TypeError('%s not %s: %r' % ('epoch', 'scalar', epoch))