def register(self, item): '''Registed a new item. @arg item: The item (any C{type}). @return: The item name (C{str}). @raise NameError: An B{C{item}} already registered with that name or the B{C{item}} has no, an empty or an invalid name. @raise TypeError: The B{C{item}} type invalid. ''' if not (self._item_classes and isinstance(item, self._item_classes)): raise TypeError('%s: %r' % (_dot_('item', 'type'), item)) try: n = item.name if not (n and n.replace('_', '').isalnum() and isstr(n)): raise ValueError except (AttributeError, ValueError): raise NameError('%s %s: %r' % (_dot_('item', 'name'), 'invalid', item)) if n in self: raise NameError('%s %s: %r' % (self._dot_(n), 'exists', item)) self[n] = item
def _xUnit(units, Base): # in .frechet, .hausdorff '''(INTERNAL) Get C{Unit} from C{Unit} or C{name}, ortherwise C{Base}. ''' if not issubclassof(Base, _NamedUnit): raise _IsnotError(_NamedUnit.__name__, Base=Base) U = globals().get(units.capitalize(), Base) if isstr(units) else ( units if issubclassof(units, Base) else Base) return U if issubclassof(U, Base) else Base
def __new__(cls, cll, precision=3, name=NN): '''New L{Georef} from an other L{Georef} instance or georef C{str} or from a C{LatLon} instance or lat-/longitude C{str}. @arg cll: Cell or location (L{Georef} or C{str}, C{LatLon} or C{str}). @kwarg precision: Optional, the desired georef resolution and length (C{int} 0..11), see function L{wgrs.encode} for more details. @kwarg name: Optional name (C{str}). @return: New L{Georef}. @raise RangeError: Invalid B{C{cll}} lat- or longitude. @raise TypeError: Invalid B{C{cll}}. @raise WGRSError: INValid or non-alphanumeric B{C{cll}}. ''' h = None if isinstance(cll, Georef): g, p = _2geostr2(str(cll)) self = Str.__new__(cls, g) self._latlon = LatLon2Tuple(*cll._latlon) self._precision = p # cll._precision if cll._name: self._name = cll._name elif isstr(cll): if ',' in cll: lat, lon, h = _2fllh(*parse3llh(cll, height=None)) g = encode(lat, lon, precision=precision, height=h) # PYCHOK false self = Str.__new__(cls, g) self._latlon = LatLon2Tuple(lat, lon) else: self = Str.__new__(cls, cll.upper()) self._decode() else: # assume LatLon try: lat, lon, h = _2fllh(cll.lat, cll.lon) h = getattr(cll, _height_, h) except AttributeError: raise _xStrError(Georef, cll=cll) # Error=WGRSError g = encode(lat, lon, precision=precision, height=h) # PYCHOK false self = Str.__new__(cls, g) self._latlon = LatLon2Tuple(lat, lon) if h not in (None, MISSING): self._height = Height(h) if self._precision is None: self._precision = _2Precision(precision) if name: self.name = name return self
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 __new__(cls, cll, precision=1, name=NN): '''New L{Garef} from an other L{Garef} instance or garef C{str} or from a C{LatLon} instance or lat-/longitude C{str}. @arg cll: Cell or location (L{Garef} or C{str}, C{LatLon} or C{str}). @kwarg precision: Optional, the desired garef resolution and length (C{int} 0..2), see function L{gars.encode} for more details. @kwarg name: Optional name (C{str}). @return: New L{Garef}. @raise RangeError: Invalid B{C{cll}} lat- or longitude. @raise TypeError: Invalid B{C{cll}}. @raise GARSError: INValid or non-alphanumeric B{C{cll}}. ''' if isinstance(cll, Garef): g, p = _2garstr2(str(cll)) self = Str.__new__(cls, g) self._latlon = LatLon2Tuple(*cll._latlon) self._name = cll._name self._precision = p # cll._precision elif isstr(cll): if ',' in cll: lat, lon = _2fll(*parse3llh(cll)) cll = encode(lat, lon, precision=precision) # PYCHOK false self = Str.__new__(cls, cll) self._latlon = LatLon2Tuple(lat, lon) else: self = Str.__new__(cls, cll.upper()) self._decode() else: # assume LatLon try: lat, lon = _2fll(cll.lat, cll.lon) except AttributeError: raise _xStrError(Garef, cll=cll) # Error=GARSError cll = encode(lat, lon, precision=precision) # PYCHOK false self = Str.__new__(cls, cll) self._latlon = LatLon2Tuple(lat, lon) if self._precision is None: self._precision = _2Precision(precision) if name: self.name = name return self
def _xUnits(units, Base=_NamedUnit): # in .frechet, .hausdorff '''(INTERNAL) Set property C{units} as C{Unit} or C{Str}. ''' if not issubclassof(Base, _NamedUnit): raise _IsnotError(_NamedUnit.__name__, Base=Base) elif issubclassof(units, Base): return units elif isstr(units): return Str( units, name=_units_) # XXX Str to _Pass and for backward compatibility else: raise _IsnotError(Base.__name__, Str.__name__, str.__name__, units=units)
def _to3zBhp(zone, band, hemipole=NN, Error=_ValueError): # imported by .epsg, .ups, .utm, .utmups '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter. @arg zone: Zone with/-out Band (C{scalar} or C{str}). @kwarg band: Optional (longitudinal/polar) Band letter (C{str}). @kwarg hemipole: Optional hemisphere/pole letter (C{str}). @kwarg Error: Optional error to raise, overriding the default C{ValueError}. @return: 3-Tuple (C{zone, Band, hemisphere/pole}) as (C{int, str, 'N'|'S'}) where C{zone} is C{0} for UPS or C{1..60} for UTM and C{Band} is C{'A'..'Z'} I{NOT} checked for valid UTM/UPS bands. @raise ValueError: Invalid B{C{zone}}, B{C{band}} or B{C{hemipole}}. ''' try: B, z = band, _UTMUPS_ZONE_INVALID if isscalar(zone): z = int(zone) elif zone and isstr(zone): if zone.isdigit(): z = int(zone) elif len(zone) > 1: B = zone[-1:] z = int(zone[:-1]) elif zone in 'AaBbYyZz': # single letter B = zone z = _UPS_ZONE if _UTMUPS_ZONE_MIN <= z <= _UTMUPS_ZONE_MAX: hp = hemipole[:1].upper() if hp in _NS_ or not hp: z = Zone(z) B = Band(B.upper()) if B.isalpha(): return z, B, (hp or _NS_[B < _N_]) elif not B: return z, B, hp t = _invalid_ except (AttributeError, IndexError, TypeError, ValueError) as x: t = str(x) # no Python 3+ exception chaining raise Error(zone=zone, band=B, hemipole=hemipole, txt=t)
def __new__(cls, cll, precision=None, name=NN): '''New L{Geohash} from an other L{Geohash} instance or C{str} or from a C{LatLon} instance or C{str}. @arg cll: Cell or location (L{Geohash} or C{str}, C{LatLon} or C{str}). @kwarg precision: Optional, the desired geohash length (C{int} 1..12), see function L{geohash.encode} for some examples. @kwarg name: Optional name (C{str}). @return: New L{Geohash}. @raise TypeError: Invalid B{C{cll}}. @raise GeohashError: INValid or non-alphanumeric B{C{cll}}. ''' if isinstance(cll, Geohash): gh = _2geostr(str(cll)) self = Str.__new__(cls, gh) elif isstr(cll): if ',' in cll: lat, lon = _2fll(*parse3llh(cll)) gh = encode(lat, lon, precision=precision) self = Str.__new__(cls, gh) self._latlon = lat, lon else: gh = _2geostr(cll) self = Str.__new__(cls, gh) else: # assume LatLon try: lat, lon = _2fll(cll.lat, cll.lon) except AttributeError: raise _xStrError(Geohash, cll=cll) # Error=GeohashError gh = encode(lat, lon, precision=precision) self = Str.__new__(cls, gh) self._latlon = lat, lon if name: self.name = name return self
def __new__(cls, eisu, name=NN): '''New L{Epsg} (I{European Petroleum Survey Group}) code from a UTM/USP coordinate or other EPSG code. @arg eisu: Other code (L{Epsg}, C{int}, C{str}, L{Utm} or L{Ups}). @return: New L{Epsg}. @raise TypeError: Invalid B{C{eisu}}. @raise EPSGError: Invalid B{C{eisu}}. ''' if isinstance(eisu, Epsg): self = int.__new__(cls, int(eisu)) self._band = eisu.band self._epsg = self # XXX eisu self._hemisphere = eisu.hemisphere self._utmups = eisu.utmups self._zone = eisu.zone if eisu.name: self.name = eisu.name elif isint(eisu): self = int.__new__(cls, eisu) self._epsg = eisu self._zone, self._hemisphere = decode2(eisu) # PYCHOK UtmUps2Tuple elif isstr(eisu): self = encode(eisu) else: u = eisu _xinstanceof(Utm, Ups, eisu=u) self = encode(u.zone, hemipole=u.hemisphere, band=u.band) # PYCHOK **kwds self._utmups = u if u.name: self.name = u.name if name: self.name = name return self
def _to3zBhp(zone, band, hemipole=''): # imported by .epsg, .ups, .utm, .utmups '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter. @arg zone: Zone with/-out Band (C{scalar} or C{str}). @kwarg band: Optional (longitudinal/polar) Band letter (C{str}). @kwarg hemipole: Optional hemisphere/pole letter (C{str}). @return: 3-Tuple (C{zone, Band, hemisphere/pole}) as (C{int, str, 'N'|'S'}) where C{zone} is C{0} for UPS or C{1..60} for UTM and C{Band} is C{'A'..'Z'} I{NOT} checked for valid UTM/UPS bands. @raise ValueError: Invalid B{C{zone}}, B{C{band}} or B{C{hemipole}}. ''' B = band try: z = _UTMUPS_ZONE_INVALID if isscalar(zone) or zone.isdigit(): z = int(zone) elif zone and isstr(zone): if len(zone) > 1: B = zone[-1:] z = int(zone[:-1]) elif zone in 'AaBbYyZz': # single letter B = zone z = _UPS_ZONE if _UTMUPS_ZONE_MIN <= z <= _UTMUPS_ZONE_MAX: hp = hemipole[:1].upper() if hp in ('N', 'S') or not hp: B = B.upper() if B.isalpha(): return z, B, (hp or ('S' if B < 'N' else 'N')) elif not B: return z, B, hp except (AttributeError, TypeError, ValueError): pass raise ValueError('%s invalid: %r' % (_or('zone', 'band', 'hemipole'), (zone, B, hemipole)))
def unregister(self, name_or_item): '''Remove a registered item. @arg name_or_item: Name (C{str}) of or the item (any C{type}). @return: The unregistered item. @raise NameError: No item with that B{C{name}}. @raise ValueError: No such item. ''' name = self.find(name_or_item) if name is None: if not isstr(name_or_item): raise _ValueError(name_or_item=name_or_item) name = name_or_item try: item = dict.pop(self, name) except KeyError: raise _NameError(item=self._dot_(name), txt=_doesn_t_exist_) item._enum = None return item
def register(self, item): '''Registed a new item. @arg item: The item (any C{type}). @return: The item name (C{str}). @raise NameError: An B{C{item}} already registered with that name or the B{C{item}} has no, an empty or an invalid name. @raise TypeError: The B{C{item}} type invalid. ''' try: n = item.name if not (n and n.replace(_UNDERSCORE_, NN).isalnum() and isstr(n)): raise ValueError except (AttributeError, ValueError, TypeError) as x: raise _NameError(_dot_('item', _name_), item, txt=str(x)) if n in self: raise _NameError(self._dot_(n), item, txt='exists') if not (self._item_Classes and isinstance(item, self._item_Classes)): raise _TypesError(self._dot_(n), item, *self._item_Classes) self[n] = item
def register(self, item): '''Registed a new item. @arg item: The item (any C{type}). @return: The item name (C{str}). @raise NameError: An B{C{item}} already registered with that name or the B{C{item}} has no, an empty or an invalid name. @raise TypeError: The B{C{item}} type invalid. ''' try: n = item.name if not (n and isstr(n) and isidentifier(n)): raise ValueError except (AttributeError, ValueError, TypeError) as x: raise _NameError(_DOT_(_item_, _name_), item, txt=str(x)) if n in self: raise _NameError(self._DOT_(n), item, txt=_exists_) if not (self._item_Classes and isinstance(item, self._item_Classes)): raise _TypesError(self._DOT_(n), item, *self._item_Classes) self[n] = item
def _xvalid(name, _OK=False): '''(INTERNAL) Check valid attribute name C{name}. ''' return True if (name and isstr(name) and name != _name_ and (_OK or not name.startswith(_UNDER_)) and (not iskeyword(name)) and isidentifier(name)) else False