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)
def __init__(self, knots, datum=None, beta=2, wrap=False, name=''): '''New L{HeightIDWhaversine} interpolator. @param knots: The points with known height (C{LatLon}s). @keyword datum: Optional datum (L{Datum} to use, overriding the default C{B{knots}[0].datum} @keyword beta: Inverse distance power (C{int} 1, 2, or 3). @keyword wrap: Wrap and L{unroll180} longitudes (C{bool}). @keyword name: Optional height interpolator name (C{str}). @raise HeightError: Insufficient number of B{C{knots}} or invalid B{C{knot}}, B{C{datum}} or B{C{beta}}. @raise ImportError: Package U{GeographicLib <https://PyPI.org/project/geographiclib>} missing. @raise TypeError: Invalid B{C{datum}}. ''' n, self._lls = len2(knots) if n < self._kmin: raise HeightError('insufficient %s: %s, need %s' % ('knots', n, self._kmin)) try: self._datum = self._lls[0].datum if datum is None else datum if not isinstance(self.datum, Datum): raise TypeError except (AttributeError, TypeError): raise TypeError('%s invalid: %r' % ('datum', self.datum or datum)) self._geodesic = self.datum.ellipsoid.geodesic self.beta = beta if wrap: self._warp = True if name: self.name = name
def __init__(self, points, tolerance, radius, shortest, indices, **options): '''New C{Simplify} state. ''' n, self.pts = len2(points) if n > 0: self.n = n self.r = {0: True, n-1: True} # dict to avoid duplicates if indices: self.indices = True if radius: self.radius = float(radius) if self.radius < self.eps: raise ValueError('%s too small: %.6e' % ('radius', radius)) if options: self.options = options # tolerance converted to degrees squared self.s2 = degrees(tolerance / self.radius)**2 if min(self.s2, tolerance) < self.eps: raise ValueError('%s too small: %.6e' % ('tolerance', tolerance)) self.s2e = self.s2 + 1 # sentinel # compute either the shortest or perpendicular distance self.d2i = self.d2iS if shortest else self.d2iP # PYCHOK false
def sumOf(nvectors, Vector=None, h=None, **kwds): '''Return the vectorial sum of two or more n-vectors. @param nvectors: Vectors to be added (C{Nvector}[]). @keyword Vector: Optional class for the vectorial sum (C{Nvector}) or C{None}. @keyword h: Optional height, overriding the mean height (C{meter}). @keyword kwds: Optional, additional B{C{Vector}} keyword arguments, ignored if C{B{Vector}=None}. @return: Vectorial sum (B{C{Vector}}) or a L{Vector4Tuple}C{(x, y, z, h)} if C{B{Vector}=None}. @raise VectorError: No B{C{nvectors}}. ''' n, nvectors = len2(nvectors) if n < 1: raise VectorError('no nvectors: %r' & (n, )) if h is None: h = fsum(v.h for v in nvectors) / float(n) if Vector is None: r = _sumOf(nvectors, Vector=Vector3Tuple)._4Tuple(h) else: r = _sumOf(nvectors, Vector=Vector, h=h, **kwds) return r
def __init__(self, knots, weight=None, name=''): '''New L{HeightLSQBiSpline} interpolator. @param knots: The points with known height (C{LatLon}s). @keyword weight: Optional weight or weights for each B{C{knot}} (C{scalar} or C{scalar}s). @keyword name: Optional height interpolator name (C{str}). @raise HeightError: Insufficient number of B{C{knots}} or B{C{weight}}s or invalid B{C{knot}} or B{C{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])) try: T = 1.0e-4 # like SciPy example ps = np.array(_ordedup(xs, T, PI2 - T)) ts = np.array(_ordedup(ys, T, PI - T)) self._ev = spi.LSQSphereBivariateSpline(ys, xs, hs, ts, ps, eps=EPS, w=w).ev except Exception as x: raise _SciPyIssue(x) if name: self.name = name
def clip(self, points, inull, closed): # MCCABE 19, clip points np, self._points = len2(points) if np > 0: # initial points, opened p = self._points[0] while np > 1 and _eq(self._points[np - 1], p): np -= 1 if np < 3: raise ValueError('too few %s: %s' % ('points', np)) no = ni = True # all out- or inside? for e in self.clips(): # clip the points, closed d2, p2 = self.dot2(np - 1) for i in range(np): d1, p1 = d2, p2 d2, p2 = self.dot2(i) if d1 < 0: # p1 inside, ... # self.append(p1, False, e) if d2 < 0: # ... p2 inside self.append(p2, inull) else: # ... p2 outside p = self.intersect(p1, p2, e) self.append(p, inull) if d2 > 0: no = False elif d2 < 0: # p1 out-, p2 inside p = self.intersect(p1, p2, e) self.append(p, inull) self.append(p2, inull) if d1 > 0: no = ni = False elif d1 > 0: ni = False if self._clipped: # replace points self._points = self._clipped self._clipped = [] np = len(self._points) # no is True iff all points are on or at one # side (left or right) of each clip edge, # ni is True iff all points are on or on the # right side (i.e. inside) of all clip edges if no and not ni: self._points = () np = 0 elif np > 1: p = self._points[0] if closed: # close clipped polygon if _neq(self._points[np - 1], p): self._points.append(p) np += 1 elif not inull: # open clipped polygon while np > 0 and _eq(self._points[np - 1], p): np -= 1 return np
def __init__(self, corners): n = '' try: n, cs = len2(corners) if n == 2: # make a box b, l, t, r = boundsOf(cs, wrap=False) cs = LL_(b, l), LL_(t, l), LL_(t, r), LL_(b, r) n, cs = points2(cs, closed=True) self._corners = cs = cs[:n] self._nc = n self._cw = 1 if isclockwise(cs, adjust=False, wrap=False) else -1 if self._cw != isconvex_(cs, adjust=False, wrap=False): raise ValueError except ValueError: raise ValueError('%s[%s] invalid: %r' % ('corners', n, corners)) self._clipped = self._points = []
def sumOf(vectors, Vector=Vector3d, **kwds): '''Compute the vectorial sum of several vectors. @param vectors: Vectors to be added (L{Vector3d}[]). @keyword Vector: Optional class for the vectorial sum (L{Vector3d}). @keyword kwds: Optional, additional B{C{Vector}} keyword arguments. @return: Vectorial sum (B{C{Vector}}). @raise VectorError: No B{C{vectors}}. ''' n, vectors = len2(vectors) if n < 1: raise VectorError('no vectors: %r' & (n, )) return Vector(fsum(v.x for v in vectors), fsum(v.y for v in vectors), fsum(v.z for v in vectors), **kwds)
def sumOf(nvectors, Vector=Nvector, h=None, **kwds): '''Return the vectorial sum of two or more n-vectors. @param nvectors: Vectors to be added (L{Nvector}[]). @keyword Vector: Optional class for the vectorial sum (L{Nvector}). @keyword kwds: Optional, additional B{C{Vector}} keyword arguments. @keyword h: Optional height, overriding the mean height (C{meter}). @return: Vectorial sum (B{C{Vector}}). @raise VectorError: No B{C{nvectors}}. ''' n, nvectors = len2(nvectors) if n < 1: raise VectorError('no nvectors: %r' & (n, )) if h is None: h = fsum(v.h for v in nvectors) / float(n) return _sumOf(nvectors, Vector=Vector, h=h, **kwds)
def _allis2(llis, m=1, Error=HeightError): # imported by .geoids # dtermine return type and convert lli C{LatLon}s to list if not isinstance(llis, tuple): # llis are *args raise AssertionError('type(%s): %r' % ('*llis', llis)) n = len(llis) if n == 1: # convert single lli to 1-item list llis = llis[0] try: n, llis = len2(llis) _as = _alist # return list of interpolated heights except TypeError: # single lli n, llis = 1, [llis] _as = _ascalar # return single interpolated heights else: # of 0, 2 or more llis _as = _atuple # return tuple of interpolated heights if n < m: raise Error('insufficient %s: %s, need %s' % ('llis', n, m)) return _as, llis
def sumOf(vectors, Vector=Vector3d, **kwds): '''Compute the vectorial sum of several vectors. @param vectors: Vectors to be added (L{Vector3d}[]). @keyword Vector: Optional class for the vectorial sum (L{Vector3d}). @keyword kwds: Optional, additional B{C{Vector}} keyword arguments, ignored if C{B{Vector}=None}. @return: Vectorial sum (B{C{Vector}}). @raise VectorError: No B{C{vectors}}. ''' n, vectors = len2(vectors) if n < 1: raise VectorError('no vectors: %r' & (n, )) r = Vector3Tuple(fsum(v.x for v in vectors), fsum(v.y for v in vectors), fsum(v.z for v in vectors)) if Vector is not None: r = Vector(r.x, r.y, r.z, **kwds) # PYCHOK x, y, z return r
def __init__(self, AB, x, y): '''(INTERNAL) New Alpha or Beta Krüger series @param AB: Krüger Alpha or Beta series coefficients (C{4-, 6- or 8-tuple}). @param x: Eta angle (C{radians}). @param y: Ksi angle (C{radians}). ''' n, j2 = len2(range(2, len(AB) * 2 + 1, 2)) self._ab = AB self._pq = map2(mul, j2, self._ab) # assert len(self._ab) == len(self._pq) == n x2 = map2(mul, j2, (x, ) * n) self._chx = map2(cosh, x2) self._shx = map2(sinh, x2) # assert len(x2) == len(self._chx) == len(self._shx) == n y2 = map2(mul, j2, (y, ) * n) self._cy = map2(cos, y2) self._sy = map2(sin, y2)
def points2(points, closed=True, base=None, Error=ValueError): '''Check a polygon represented by points. @param points: The polygon points (C{LatLon}[]) @keyword closed: Optionally, consider the polygon closed, ignoring any duplicate or closing final B{C{points}} (C{bool}). @keyword base: Optionally, check the B{C{points}} against this base class C{None}. @keyword Error: Exception for raise (C{ValueError}). @return: 2-Tuple (n, points) with the number (C{int}) of points and the points C{list} or C{tuple}. @raise TypeError: Some B{C{points}} are not C{LatLon}. @raise Error: Insufficient number of B{C{points}}. ''' n, points = len2(points) if closed: # remove duplicate or closing final points while n > 1 and (points[n - 1] == points[0] or points[n - 1] == points[n - 2]): n -= 1 # XXX following line is unneeded if points # are always indexed as ... i in range(n) points = points[:n] # XXX numpy.array slice is a view! if n < (3 if closed else 1): raise Error('too few %s: %s' % ('points', n)) if base and not (isNumpy2(points) or isTuple2(points)): for i in range(n): base.others(points[i], name='%s[%s]' % ('points', i)) return n, points