Example #1
0
    def __init__(self, x, y=None, z=None, h=0, ll=None, datum=None, name=''):
        '''New n-vector normal to the earth's surface.

           @param x: An C{Nvector}, L{Vector3Tuple}, L{Vector4Tuple} or
                     the C{X} coordinate (C{scalar}).
           @param y: The C{Y} coordinate (C{scalar}) if B{C{x}} C{scalar}.
           @param z: The C{Z} coordinate (C{scalar}) if B{C{x}} C{scalar}.
           @keyword h: Optional height above surface (C{meter}).
           @keyword ll: Optional, original latlon (C{LatLon}).
           @keyword datum: Optional, I{pass-thru} datum (C{Datum}).
           @keyword name: Optional name (C{str}).

           @raise TypeError: Non-scalar B{C{x}}, B{C{y}} or B{C{z}}
                             coordinate or B{C{x}} not an C{Nvector},
                             L{Vector3Tuple} or L{Vector4Tuple}.

           @example:

           >>> from pygeodesy.sphericalNvector import Nvector
           >>> v = Nvector(0.5, 0.5, 0.7071, 1)
           >>> v.toLatLon()  # 45.0°N, 045.0°E, +1.00m
        '''
        x, y, z, h, d, n = _xyzhdn6(x, y, z, h, datum, ll)
        Vector3d.__init__(self, x, y, z, ll=ll, name=name or n)
        if h:
            self.h = h
        if d:  # just pass-thru
            self._datum = d
Example #2
0
    def __init__(self, x, y=None, z=None, h=0, ll=None, datum=None, name=NN):
        '''New n-vector normal to the earth's surface.

           @arg x: An C{Nvector}, L{Vector3Tuple}, L{Vector4Tuple} or
                     the C{X} coordinate (C{scalar}).
           @arg y: The C{Y} coordinate (C{scalar}) if B{C{x}} C{scalar}.
           @arg z: The C{Z} coordinate (C{scalar}) if B{C{x}} C{scalar}.
           @kwarg h: Optional height above surface (C{meter}).
           @kwarg ll: Optional, original latlon (C{LatLon}).
           @kwarg datum: Optional, I{pass-thru} datum (L{Datum}).
           @kwarg name: Optional name (C{str}).

           @raise TypeError: Non-scalar B{C{x}}, B{C{y}} or B{C{z}}
                             coordinate or B{C{x}} not an C{Nvector},
                             L{Vector3Tuple} or L{Vector4Tuple} or
                             invalid B{C{datum}}.

           @example:

           >>> from pygeodesy.sphericalNvector import Nvector
           >>> v = Nvector(0.5, 0.5, 0.7071, 1)
           >>> v.toLatLon()  # 45.0°N, 045.0°E, +1.00m
        '''
        x, y, z, h, d, n = _xyzhdn6(x, y, z, h, datum, ll)
        Vector3d.__init__(self, x, y, z, ll=ll, name=name or n)
        if h:
            self.h = h
        if d not in (None, self._datum):
            _xinstanceof(Datum, datum=d)
            self._datum = d  # pass-thru
    def greatCircle(self, bearing):
        '''Compute the vector normal to great circle obtained by heading
           on the given initial bearing from this point.

           Direction of vector is such that initial bearing vector
           b = c × n, where n is an n-vector representing this point.

           @param bearing: Bearing from this point (compass C{degrees360}).

           @return: Vector representing great circle (L{Vector3d}).

           @example:

           >>> p = LatLon(53.3206, -1.7297)
           >>> g = p.greatCircle(96.0)
           >>> g.toStr()  # (-0.794, 0.129, 0.594)
        '''
        a, b = self.to2ab()
        t = radians(bearing)

        sa, ca, sb, cb, st, ct = sincos2(a, b, t)

        return Vector3d(sb * ct - cb * sa * st,
                       -cb * ct - sb * sa * st,
                        ca * st)  # XXX .unit()?
Example #4
0
    def toLatLon(self, height=None, LatLon=None, datum=None, **kwds):
        '''Convert this n-vector to an C{Nvector}-based geodetic point.

           @keyword height: Optional height, overriding this n-vector's
                            height (C{meter}).
           @keyword LatLon: Optional (sub-)class to return the
                            point (L{LatLon}) or C{None}.
           @keyword datum: Optional, spherical datum (C{Datum}).
           @keyword kwds: Optional, additional C{name=value} pairs
                          for B{C{LatLon}} instance, provided
                          B{C{LatLon}} is not C{None}.

           @return: The B{C{LatLon}} point (L{LatLon}) or if
                    C{B{LatLon}=None} or a L{LatLon3Tuple}C{(lat,
                    lon, height)} if B{C{LatLon}} is C{None}.

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

           @example:

           >>> v = Nvector(0.5, 0.5, 0.7071)
           >>> p = v.toLatLon()  # 45.0°N, 45.0°E
        '''
        h = self.h if height is None else height
        d = datum or self.datum

        # XXX use self.Cartesian(Cartesian=None) if h == self.h
        # and d == self.datum, for better accuracy of the height
        r = self.Ecef(d).forward(Vector3d.to2ll(self), height=h, M=True)
        if LatLon is not None:  # class or .classof
            r = LatLon(r.lat, r.lon, r.height, datum=r.datum, **kwds)
        return self._xnamed(r)
    def toVector3d(self):
        '''Return this NED vector as a 3-d vector.

           @return: The vector(north, east, down) (L{Vector3d}).
        '''
        from pygeodesy.vector3d import Vector3d
        return Vector3d(*self.to3ned(), name=self.name)
def _x3d2(start, end, wrap, n, hs):
    # see <https://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)
        hs.append(end.height)
        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

    sb21, cb21, sb12, cb12, \
    sa21,    _, sa12,    _ = sincos2(b21, b12, 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
Example #7
0
    def toVector3d(self):
        '''Convert this n-vector to a normalized 3-d vector,
           I{ignoring the height}.

           @return: Normalized vector (L{Vector3d}).
        '''
        u = self.unit()
        return Vector3d(u.x, u.y, u.z, name=self.name)
Example #8
0
    def toVector3d(self):
        '''Convert this point to a vector normal to earth's surface.

           @return: Vector representing this point (L{Vector3d}).
        '''
        if self._v3d is None:
            x, y, z = self.to3xyz()
            self._v3d = Vector3d(x, y, z)  # XXX .unit()
        return self._v3d
Example #9
0
    def __init__(self, xyz, y=None, z=None, datum=None, ll=None, name=NN):
        '''New C{Cartesian...}.

           @arg xyz: An L{Ecef9Tuple}, L{Vector3Tuple}, L{Vector4Tuple}
                     or the C{X} coordinate (C{scalar}).
           @arg y: The C{Y} coordinate (C{scalar}) if B{C{xyz}} C{scalar}.
           @arg z: The C{Z} coordinate (C{scalar}) if B{C{xyz}} C{scalar}.
           @kwarg datum: Optional datum (L{Datum}).
           @kwarg ll: Optional, original latlon (C{LatLon}).
           @kwarg name: Optional name (C{str}).

           @raise TypeError: Non-scalar B{C{xyz}}, B{C{y}} or B{C{z}}
                             coordinate or B{C{xyz}} not an L{Ecef9Tuple},
                             L{Vector3Tuple} or L{Vector4Tuple}.
        '''
        x, y, z, _, d, n = _xyzhdn6(xyz, y, z, None, datum, ll)
        Vector3d.__init__(self, x, y, z, ll=ll, name=name or n)
        if d:
            self.datum = d
Example #10
0
    def toStr(self, prec=3, fmt='[%s]', sep=', '):  # PYCHOK expected
        '''Return the string representation of this cartesian.

           @keyword prec: Optional number of decimals, unstripped (C{int}).
           @keyword fmt: Optional enclosing backets format (string).
           @keyword sep: Optional separator to join (string).

           @return: Cartesian represented as "[x, y, z]" (string).
        '''
        return Vector3d.toStr(self, prec=prec, fmt=fmt, sep=sep)
Example #11
0
    def __init__(self, x, y, z, h=0, ll=None, name=''):
        '''New n-vector normal to the earth's surface.

           @param x: X component (C{scalar}).
           @param y: Y component (C{scalar}).
           @param z: Z component (C{scalar}).
           @keyword h: Optional height above surface (C{meter}).
           @keyword ll: Optional, original latlon (C{LatLon}).
           @keyword name: Optional name (C{str}).

           @example:

           >>> from pygeodesy.sphericalNvector import Nvector
           >>> v = Nvector(0.5, 0.5, 0.7071, 1)
           >>> v.toLatLon()  # 45.0°N, 045.0°E, +1.00m
        '''
        Vector3d.__init__(self, x, y, z, ll=ll, name=name)
        if h:
            self._h = scalar(h, None, name='h')
Example #12
0
 def _to3LLh(self, LL, height, **kwds):
     '''(INTERNAL) Helper for C{subclass.toLatLon} and C{.to3llh}.
     '''
     h = self.h if height is None else height
     r = Vector3d.to2ll(self)  # LatLon2Tuple
     if LL is None:
         r = r._3Tuple(h)  # already ._xnamed
     else:
         r = self._xnamed(LL(r.lat, r.lon, height=h, **kwds))
     return r
Example #13
0
    def toVector3d(self, norm=True):
        '''Convert this n-vector to a 3-D vector, I{ignoring
           the height}.

           @kwarg norm: Normalize the 3-D vector (C{bool}).

           @return: The (normalized) vector (L{Vector3d}).
        '''
        u = self.unit()
        v = Vector3d(u.x, u.y, u.z, name=self.name)
        return v.unit() if norm else v
Example #14
0
    def unit(self, ll=None):
        '''Normalize this n-vector to unit length.

           @kwarg ll: Optional, original latlon (C{LatLon}).

           @return: Normalized vector (C{Nvector}).
        '''
        if self._united is None:
            u = Vector3d.unit(self, ll=ll)  # .copy()
            self._united = u._united = _xattrs(u, self, '_h')
        return self._united
Example #15
0
    def to3abh(self, height=None):
        '''Convert this n-vector to (geodetic) lat-, longitude
           in C{radians} and height.

           @keyword height: Optional height, overriding this
                            n-vector's height (C{meter}).

           @return: A L{PhiLam3Tuple}C{(phi, lam, height)}.
        '''
        h = self.h if height is None else height
        return Vector3d.to2ab(self)._3Tuple(h)
Example #16
0
    def toStr(self,
              prec=3,
              fmt=Fmt.SQUARE,
              sep=_COMMASPACE_):  # PYCHOK expected
        '''Return the string representation of this cartesian.

           @kwarg prec: Optional number of decimals, unstripped (C{int}).
           @kwarg fmt: Optional enclosing backets format (string).
           @kwarg sep: Optional separator to join (string).

           @return: Cartesian represented as "[x, y, z]" (string).
        '''
        return Vector3d.toStr(self, prec=prec, fmt=fmt, sep=sep)
Example #17
0
    def toStr(self, prec=5, fmt=_PARENTH_, sep=_COMMA_SPACE_):  # PYCHOK expected
        '''Return a string representation of this n-vector.

           Height component is only included if non-zero.

           @kwarg prec: Optional number of decimals, unstripped (C{int}).
           @kwarg fmt: Optional enclosing backets format (C{str}).
           @kwarg sep: Optional separator between components (C{str}).

           @return: Comma-separated C{"(x, y, z [, h])"} enclosed in
                    B{C{fmt}} brackets (C{str}).

           @example:

           >>> Nvector(0.5, 0.5, 0.7071).toStr()  # (0.5, 0.5, 0.7071)
           >>> Nvector(0.5, 0.5, 0.7071, 1).toStr(-3)  # (0.500, 0.500, 0.707, +1.00)
        '''
        t = Vector3d.toStr(self, prec=prec, fmt=NN, sep=sep)
        if self.h:
            t = sep.join((t, self.hStr()))
        return t if not fmt else (fmt % (t,))
Example #18
0
    def toStr(self, prec=5, fmt='(%s)', sep=', '):  # PYCHOK expected
        '''Return a string representation of this n-vector.

           Height component is only included if non-zero.

           @kwarg prec: Optional number of decimals, unstripped (C{int}).
           @kwarg fmt: Optional enclosing backets format (C{str}).
           @kwarg sep: Optional separator between components (C{str}).

           @return: Comma-separated C{"(x, y, z [, h])"} enclosed in
                    B{C{fmt}} brackets (C{str}).

           @example:

           >>> Nvector(0.5, 0.5, 0.7071).toStr()  # (0.5, 0.5, 0.7071)
           >>> Nvector(0.5, 0.5, 0.7071, 1).toStr(-3)  # (0.500, 0.500, 0.707, +1.00)
        '''
        t = Vector3d.toStr(self, prec=prec, fmt='%s', sep=sep)
        if self.h:
            t = '%s%s%s%+.2f' % (t, sep, self.H, self.h)
        return fmt % (t, )
Example #19
0
def _nearestOn(p,
               p1,
               p2,
               within=True,
               height=None,
               wrap=True,
               equidistant=None,
               tol=_TOL_M,
               LatLon=None,
               **LatLon_kwds):
    # (INTERNAL) Get closet point, like L{_intersects2} above,
    # separated to allow callers to embellish any exceptions

    from pygeodesy.sphericalNvector import LatLon as _LLS
    from pygeodesy.vector3d import _nearestOn as _vnOn, Vector3d

    def _v(t, h):
        return Vector3d(t.x, t.y, h)

    _ = p.ellipsoids(p1)
    E = p.ellipsoids(p2)

    if wrap:
        p1 = _unrollon(p, p1)
        p2 = _unrollon(p, p2)
        p2 = _unrollon(p1, p2)

    r = E.rocMean(fmean_(p.lat, p1.lat, p2.lat))
    e = max(m2degrees(tol, radius=r), EPS)

    # get the azimuthal equidistant projection
    A = _Equidistant2(equidistant, p.datum)

    # gu-/estimate initial nearestOn, spherically ... wrap=False
    t = _LLS(p.lat, p.lon, height=p.height).nearestOn(_LLS(p1.lat,
                                                           p1.lon,
                                                           height=p1.height),
                                                      _LLS(p2.lat,
                                                           p2.lon,
                                                           height=p2.height),
                                                      within=within,
                                                      height=height)
    n = t.name

    h = h1 = h2 = 0
    if height is False:  # use height as Z component
        h = t.height
        h1 = p1.height
        h2 = p2.height

    # ... and then iterate like Karney suggests to find
    # tri-points of median lines, @see: references under
    # method LatLonEllipsoidalBase.intersections2 above
    c = None  # force first d == c to False
    # closest to origin, .z to interpolate height
    p = Vector3d(0, 0, h)
    for i in range(1, _TRIPS):
        A.reset(t.lat, t.lon)  # gu-/estimate as origin
        # convert points to projection space
        t1 = A.forward(p1.lat, p1.lon)
        t2 = A.forward(p2.lat, p2.lon)
        # compute nearestOn in projection space
        v = _vnOn(p, _v(t1, h1), _v(t2, h2), within=within)
        # convert nearestOn back to geodetic
        r = A.reverse(v.x, v.y)
        d = euclid(r.lat - t.lat, r.lon - t.lon)
        # break if below tolerance or if unchanged
        t = r
        if d < e or d == c:
            t._iteration = i  # _NamedTuple._iteration
            if height is False:
                h = v.z  # nearest interpolated
            break
        c = d
    else:
        raise ValueError(_no_(Fmt.convergence(tol)))

    r = _LatLon4Tuple(t.lat, t.lon, h, t.datum, LatLon, LatLon_kwds)
    r._iteration = t.iteration  # ._iteration for tests
    return _xnamed(r, n)
Example #20
0
 def _update(self, updated):
     if updated:  # reset cached attrs
         self._e9t = self._v4t = None
         Vector3d._update(self, updated)
Example #21
0
 def _xcopy(self, *attrs):
     '''(INTERNAL) Make copy with add'l, subclass attributes.
     '''
     return Vector3d._xcopy(self, '_h', *attrs)
Example #22
0
 def _update(self, updated, *attrs):
     '''(INTERNAL) Zap cached attributes if updated.
     '''
     if updated:
         Vector3d._update(self, updated, '_latlon', '_philam', *attrs)
Example #23
0
 def _v(t, h):
     return Vector3d(t.x, t.y, h)
Example #24
0
 def _update(self, updated, *attrs):
     '''(INTERNAL) Zap cached attributes if updated.
     '''
     if updated:
         Vector3d._update(self, updated, '_e9t', '_v4t', *attrs)