Exemplo n.º 1
0
 def _hIDW(self, x, y):
     # interpolate height at (x, y) radians or degrees
     try:
         ds = self._distances(x, y)
         return fidw(self._hs, ds, beta=self._beta)
     except (TypeError, ValueError) as x:
         raise HeightError(str(x))
Exemplo n.º 2
0
 def _hIDW(self, lli):  # PYCHOK expected
     # interpolate height at point lli
     try:
         kwds = self._distanceTo_kwds
         ds = (k.distanceTo(lli, **kwds) for k in self._ks)
         return fidw(self._hs, ds, beta=self._beta)
     except (TypeError, ValueError) as x:
         raise HeightError(str(x))
Exemplo n.º 3
0
def trilaterate(point1,
                distance1,
                point2,
                distance2,
                point3,
                distance3,
                radius=R_M,
                height=None,
                LatLon=LatLon,
                useZ=False):
    '''Locate a point at given distances from three other points.
       See also U{Trilateration<https://WikiPedia.org/wiki/Trilateration>}.

       @param point1: First point (L{LatLon}).
       @param distance1: Distance to the first point (C{meter}, same units
                         as B{C{radius}}).
       @param point2: Second point (L{LatLon}).
       @param distance2: Distance to the second point (C{meter}, same units
                         as B{C{radius}}).
       @param point3: Third point (L{LatLon}).
       @param distance3: Distance to the third point (C{meter}, same units
                         as B{C{radius}}).
       @keyword radius: Optional, mean earth radius (C{meter}).
       @keyword height: Optional height at the trilaterated point, overriding
                        the IDW height (C{meter}, same units as B{C{radius}}).
       @keyword LatLon: Optional (sub-)class to return the trilaterated
                        point (L{LatLon}).
       @keyword useZ: Include Z component iff non-NaN, non-zero (C{bool}).

       @return: Trilaterated point (B{C{LatLon}}).

       @raise TypeError: If B{C{point1}}, B{C{point2}} or B{C{point3}}
                         is not L{LatLon}.

       @raise ValueError: Invalid B{C{radius}}, some B{C{distances}} exceed
                          trilateration or some B{C{points}} coincide.
    '''
    def _nd2(p, d, name, *qs):
        # return Nvector and radial distance squared
        _Nvll.others(p, name=name)
        for q in qs:
            if p.isequalTo(q, EPS):
                raise ValueError('%s %s: %r' % ('coincident', 'points', p))
        return p.toNvector(), (float(d) / radius)**2

    if float(radius or 0) < EPS:
        raise ValueError('%s %s: %r' % ('radius', 'invalid', radius))

    n1, d12 = _nd2(point1, distance1, 'point1')
    n2, d22 = _nd2(point2, distance2, 'point2', point1)
    n3, d32 = _nd2(point3, distance3, 'point3', 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)

    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_(d12, -d22, d**2) / (2 * d)  # n1->intersection x- and ...
            y = fsum_(d12, -d32, i**2, j**2) / (2 * j) - (x * i / j
                                                          )  # ... y-component

            n = n1.plus(X.times(x)).plus(Y.times(y))  # .plus(Z.times(z))
            if useZ:  # include non-NaN, non-zero Z component
                z = fsum_(d12, -(x**2), -(y**2))
                if z > EPS:
                    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
            return n.toLatLon(
                height=h,
                LatLon=LatLon)  # Nvector(n.x, n.y, n.z).toLatLon(...)

    # no intersection, d < EPS_2 or j < EPS_2
    raise ValueError('no %s for %r, %r, %r at %r, %r, %r' %
                     ('trilaterate', point1, point2, point3, distance1,
                      distance2, distance3))
Exemplo n.º 4
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))