def _rsT(T): '''(INTERNAL) Helper for C{_RD}, C{_RF} and C{_RJ}. ''' s = map2(sqrt, T[1:]) r = fdot(s[:3], s[1], s[2], s[0]) T = tuple((t + r) * 0.25 for t in T) return r, s, T
def sizes(self): '''Get the lat- and longitudinal size of this cell as a L{LatLon2Tuple}C{(lat, lon)} with the latitudinal height and longitudinal width in (C{meter}). ''' n = min(len(_Sizes) - 1, self.precision or 1) return LatLon2Tuple(*map2(float, _Sizes[n][:2])) # XXX Height, Width
def __init__(self, knots, weight=None, name=NN): '''New L{HeightLSQBiSpline} interpolator. @arg knots: The points with known height (C{LatLon}s). @kwarg weight: Optional weight or weights for each B{C{knot}} (C{scalar} or C{scalar}s). @kwarg name: Optional name for this height interpolator (C{str}). @raise HeightError: Insufficient number of B{C{knots}} or an invalid B{C{knot}} or B{C{weight}}. @raise LenError: Number of B{C{knots}} and B{C{weight}}s don't match. @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) n = len(hs) w = weight if isscalar(w): w = float(w) if w <= 0: raise HeightError(weight=w) w = [w] * n elif w is not None: m, w = len2(w) if m != n: raise LenError(HeightLSQBiSpline, weight=m, knots=n) w = map2(float, w) m = min(w) if m <= 0: raise HeightError(_item_sq(weight=w.find(m)), m) 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 _DDDMMSS_(strDDDMMSS, suffix, sep, clip): S = suffix.upper() if isstr(strDDDMMSS): t = strDDDMMSS.strip() if sep: t = t.replace(sep, NN).strip() s = t[:1] # sign or digit P = t[-1:] # compass point, digit or dot t = t.lstrip(_PLUSMINUS_).rstrip(S).strip() f = t.split(_DOT_) d = len(f[0]) f = NN.join(f) if 1 < d < 8 and f.isdigit() and ( (P in S and s.isdigit()) or (P.isdigit() and s in '-0123456789+' # PYCHOK indent and S in ((_NS_, _EW_) + _WINDS))): # check [D]DDMMSS form and compass point X = _EW_ if (d & 1) else _NS_ if not (P in X or (S in X and (P.isdigit() or P == _DOT_))): t = 'DDDMMSS'[d & 1 ^ 1:d | 1], X[:1], X[1:] raise ParseError('form %s applies %s-%s' % t) f = 0 # fraction else: # try other forms return _DMS2deg(strDDDMMSS, S, sep, clip) else: # float or int to [D]DDMMSS[.fff] f = float(strDDDMMSS) s = _MINUS_ if f < 0 else NN P = _0_ # anything except _SW_ f, i = modf(abs(f)) t = Fmt.f(i, prec=0) # str(i) == 'i.0' d = len(t) # bump number of digits to match # the given, valid compass point if S in (_NS_ if (d & 1) else _EW_): t = _0_ + t d += 1 # P = S # elif d > 1: # P = (_EW_ if (d & 1) else _NS_)[0] if d < 4: # [D]DD[.ddd] if f: t = float(t) + f t = t, 0, 0 else: f += float(t[d - 2:]) if d < 6: # [D]DDMM[.mmm] t = t[:d - 2], f, 0 else: # [D]DDMMSS[.sss] t = t[:d - 4], t[d - 4:d - 2], f d = _dms2deg(s, P, *map2(float, t)) return clipDegrees(d, float(clip)) if clip else d
def _DMS2deg(strDMS, suffix, sep, clip): '''(INTERNAL) Helper for C{parseDDDMMSS} and C{parseDMS}. ''' try: d = float(strDMS) except (TypeError, ValueError): strDMS = strDMS.strip() t = strDMS.lstrip(_PLUSMINUS_).rstrip(suffix.upper()).strip() if sep: t = t.replace(sep, _SPACE_) for s in _S_ALL: t = t.replace(s, NN) else: for s in _S_ALL: t = t.replace(s, _SPACE_) t = map2(float, t.strip().split()) + (0, 0) d = _dms2deg(strDMS[:1], strDMS[-1:], *t[:3]) return clipDegrees(d, float(clip)) if clip else d
def __init__(self, AB, x, y): '''(INTERNAL) New Alpha or Beta Krüger series @arg AB: Krüger Alpha or Beta series coefficients (C{4-, 6- or 8-tuple}). @arg x: Eta angle (C{radians}). @arg 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 encode(lat, lon, precision=None): '''Encode a lat-/longitude as a C{geohash}, either to the specified precision or if not provided, to an automatically evaluated precision. @arg lat: Latitude (C{degrees}). @arg lon: Longitude (C{degrees}). @kwarg precision: Optional, the desired geohash length (C{int} 1..12). @return: The C{geohash} (C{str}). @raise GeohashError: Invalid B{C{lat}}, B{C{lon}} or B{C{precision}}. @example: >>> geohash.encode(52.205, 0.119, 7) # 'u120fxw' >>> geohash.encode(52.205, 0.119, 12) # 'u120fxwshvkg' >>> geohash.encode(52.205, 0.1188, 12) # 'u120fxws0jre' >>> geohash.encode(52.205, 0.1188) # 'u120fxw' >>> geohash.encode( 0, 0) # 's00000000000' ''' lat, lon = _2fll(lat, lon) if precision is None: # Infer precision by refining geohash until # it matches precision of supplied lat/lon. for p in range(1, _MaxPrec + 1): gh = encode(lat, lon, p) ll = map2(float, decode(gh)) if abs(lat - ll[0]) < EPS and \ abs(lon - ll[1]) < EPS: return gh p = _MaxPrec else: p = Precision_(precision, Error=GeohashError, low=1, high=_MaxPrec) s, w, n, e = _Bounds4 b = i = 0 d, gh = True, [] while len(gh) < p: i += i if d: # bisect longitude m = favg(e, w) if lon < m: e = m else: w = m i += 1 else: # bisect latitude m = favg(n, s) if lat < m: n = m else: s = m i += 1 d = not d b += 1 if b == 5: # 5 bits gives a character: # append it and start over gh.append(_GeohashBase32[i]) b = i = 0 return ''.join(gh)
def ab(self): '''Get the lat- and longitude of (the approximate center of) this geohash as a 2-tuple (lat, lon) in C{radians}. ''' return map2(radians, self.latlon)