Exemplo n.º 1
0
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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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()?
Exemplo n.º 4
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)
Exemplo n.º 5
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
Exemplo n.º 6
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
Exemplo n.º 7
0
 def _v(t, h):
     return Vector3d(t.x, t.y, h)
Exemplo n.º 8
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)