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