def _to3zBlat(zone, band, Error=UTMError): # imported by .mgrs.py '''(INTERNAL) Check and return zone, Band and band latitude. @param zone: Zone number or string. @param band: Band letter. @param Error: Exception to raise (L{UTMError}). @return: 3-Tuple (zone, Band, latitude). ''' try: z, B, _ = _to3zBhp(zone, band=band) # in .ellipsoidalBase if _UTM_ZONE_MIN > z or z > _UTM_ZONE_MAX: raise ValueError except ValueError: raise Error('%s invalid: %r' % ('zone', zone)) b = None if B: b = _Bands.find(B) if b < 0: raise Error('%s invalid: %r' % ('band', band or B)) b = (b << 3) - 80 elif Error is not UTMError: raise Error('%s missing: %r' % ('band', band)) return z, B, b
def __init__( self, zone, pole, easting, northing, band=NN, # PYCHOK expected datum=Datums.WGS84, falsed=True, convergence=None, scale=None, name=NN): '''New L{Ups} UPS coordinate. @arg zone: UPS zone (C{int}, zero) or zone with/-out Band letter (C{str}, '00', '00A', '00B', '00Y' or '00Z'). @arg pole: Top/center of (stereographic) projection (C{str}, C{'N[orth]'} or C{'S[outh]'}). @arg easting: Easting, see B{C{falsed}} (C{meter}). @arg northing: Northing, see B{C{falsed}} (C{meter}). @kwarg band: Optional, polar Band (C{str}, 'A'|'B'|'Y'|'Z'). @kwarg datum: Optional, this coordinate's datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}). @kwarg falsed: Both B{C{easting}} and B{C{northing}} are falsed (C{bool}). @kwarg convergence: Optional, meridian convergence gamma to save (C{degrees}). @kwarg scale: Optional, computed scale factor k to save (C{scalar}). @kwarg name: Optional name (C{str}). @raise TypeError: Invalid B{C{datum}}. @raise UPSError: Invalid B{C{zone}}, B{C{pole}}, B{C{easting}}, B{C{northing}}, B{C{band}}, B{C{convergence}} or B{C{scale}}. ''' if name: self.name = name try: z, B, p = _to3zBhp(zone, band, hemipole=pole) if z != _UPS_ZONE or (B and B not in _Bands): raise ValueError except (TypeError, ValueError) as x: raise UPSError(zone=zone, pole=pole, band=band, txt=str(x)) self._pole = p UtmUpsBase.__init__(self, easting, northing, band=B, datum=datum, falsed=falsed, convergence=convergence, scale=scale)
def __init__( self, zone, pole, easting, northing, band='', # PYCHOK expected datum=Datums.WGS84, falsed=True, convergence=None, scale=None, name=''): '''New L{Ups} UPS coordinate. @param zone: UPS zone (C{int}, zero) or zone with/-out Band letter (C{str}, '00', '00A', '00B', '00Y' or '00Z'). @param pole: Top/center of (stereographic) projection (C{str}, C{'N[orth]'} or C{'S[outh]'}). @param easting: Easting, see B{C{falsed}} (C{meter}). @param northing: Northing, see B{C{falsed}} (C{meter}). @keyword band: Optional, polar Band (C{str}, 'A'|'B'|'Y'|'Z'). @keyword datum: Optional, this coordinate's datum (L{Datum}). @keyword falsed: Both B{C{easting}} and B{C{northing}} are falsed (C{bool}). @keyword convergence: Optional, meridian convergence gamma to save (C{degrees}). @keyword scale: Optional, computed scale factor k to save (C{scalar}). @keyword name: Optional name (C{str}). @raise UPSError: Invalid B{C{zone}}, B{C{pole}} or B{C{band}}. ''' if name: self.name = name try: z, B, p = _to3zBhp(zone, band=band, hemipole=pole) if z != _UPS_ZONE or (B and B not in _Bands): raise ValueError except ValueError: raise UPSError('%s, %s or %s invalid: %r' % ('zone', 'pole', 'band', (zone, pole, band))) self._band = B self._convergence = convergence self._easting = float(easting) self._falsed = falsed self._northing = float(northing) self._pole = p self._datum = datum self._scale = scale
def _to7zBlldfn(latlon, lon, datum, falsed, name, zone, Error, **cmoff): '''(INTERNAL) Determine 7-tuple (zone, band, lat, lon, datum, falsed, name) for L{toEtm8} and L{toUtm8}. ''' f = falsed and _xkwds_get(cmoff, cmoff=True) # DEPRECATED lat, lon, d, name = _to4lldn(latlon, lon, datum, name) z, B, lat, lon = _to3zBll(lat, lon, cmoff=f) if zone: # re-zone for ETM/UTM r, _, _ = _to3zBhp(zone, B) if r != z: if not _UTM_ZONE_MIN <= r <= _UTM_ZONE_MAX: raise Error(zone=zone) if f: # re-offset from central meridian lon += _cmlon(z) - _cmlon(r) z = r return z, B, lat, lon, d, f, name
def encode(zone, hemipole='', band=''): '''Determine the U{EPSG<https://www.EPSG-Registry.org>} code for a given UTM/UPS zone number, hemisphere/pole and/or Band. @arg zone: The (longitudinal) UTM zone (C{int}, 1..60) or UPS zone (C{int}, 0) or UTM zone with/-out (latitudinal) Band letter (C{str}, '01C'..'60X') or UPS zone with/-out (polar) Band letter (C{str}, '00A', '00B', '00Y' or '00Z'). @kwarg hemipole: UTM/UPS hemisphere or UPS projection top/center pole (C{str}, C{'N[orth]'} or C{'S[outh]'}). @kwarg band: Optional (latitudinal) UTM or (polar) UPS Band letter (C{str}). @return: C{EPSG} code (L{Epsg}). @raise EPSGError: Invalid B{C{zone}}, B{C{hemipole}} or B{C{band}}. @note: Coverage of UPS as zone C{0} follows Karney's function U{UTMUPS::EncodeEPSG <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1UTMUPS.html>}. ''' try: z, B, hp = _to3zBhp(zone, band, hemipole=hemipole) # in .ellipsoidalBase if hp not in ('N', 'S'): raise ValueError except ValueError: raise InvalidError(zone=zone, hemipole=hemipole, band=band, Error=EPSGError) if _UTM_ZONE_MIN <= z <= _UTM_ZONE_MAX: e = z - _UTM_ZONE_MIN + (_EPSG_N_01 if hp == 'N' else _EPSG_S_01) elif z == _UPS_ZONE: e = _EPSG_N if hp == 'N' else _EPSG_S else: raise InvalidError(zone=zone, Error=EPSGError) e = Epsg(e) e._band = B # e._hemisphere = hp return e
def UtmUps(zone, hemipole, easting, northing, band=NN, datum=Datums.WGS84, falsed=True, name=NN): '''Class-like function to create a UTM/UPS coordinate. @kwarg zone: The UTM (longitudinal) zone with/-out Band letter for UTM or for UPS zone C{"00"} or C{0} (C{str} or C{int}). @kwarg hemipole: UTM hemisphere or UPS top/center of projection (C{str}, C{'N[orth]'} or C{'S[outh]'}). @arg easting: Easting, see B{C{falsed}} (C{meter}). @arg northing: Northing, see B{C{falsed}} (C{meter}). @kwarg band: Optional, UTM (latitudinal) Band letter C{'C'|'D'..'W'|'X'} or UPS (polar) Band letter C{'A'|'B'|'Y'|'Z'} (C{str}). @kwarg datum: Optional, the coordinate's datum (L{Datum}). @kwarg falsed: Both B{C{easting}} and B{C{northing}} are falsed (C{bool}). @kwarg name: Optional name (C{str}). @return: New UTM or UPS instance (L{Utm} or L{Ups}). @raise TypeError: Invalid B({C{datum}}. @raise UTMUPSError: UTM or UPS validation failed. @see: Classes L{Utm} and L{Ups} and I{Karney}'s U{UTMUPS <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1UTMUPS.html>}. ''' z, B, hp = _to3zBhp(zone, band, hemipole=hemipole) U = Ups if z in (_UPS_ZONE, _UPS_ZONE_STR) else Utm return U(z, hp, easting, northing, band=B, datum=datum, falsed=falsed, name=name)
def _to3zBlat(zone, band, Error=UTMError): # imported by .mgrs '''(INTERNAL) Check and return zone, Band and band latitude. @arg zone: Zone number or string. @arg band: Band letter. @arg Error: Exception to raise (L{UTMError}). @return: 3-Tuple (zone, Band, latitude). ''' z, B, _ = _to3zBhp(zone, band, Error=Error) if _UTM_ZONE_MIN > z or z > _UTM_ZONE_MAX: raise Error(zone=zone) b = None if B: b = _Bands.find(B) if b < 0: raise Error(band=band or B) b = Int((b << 3) - 80, name='bandLat') B = Band(B) elif Error is not UTMError: raise Error(band=band, txt=_Missing) return Zone(z), B, b
def utmupsValidate(coord, falsed=False, MGRS=False): '''Check a UTM or UPS coordinate. @arg coord: The UTM or UPS coordinate (L{Utm}, L{Ups} or C{5+Tuple}). @kwarg falsed: C{5+Tuple} easting and northing are falsed (C{bool}). @kwarg MGRS: Increase easting and northing ranges (C{bool}). @return: C{None} if validation passed. @raise UTMUPSError: Validation failed. @see: Function L{utmupsValidateOK}. ''' def _en(en, lo, hi, ename): try: if lo <= float(en) <= hi: return except (TypeError, ValueError): pass t = '%s range [%.0F, %.0F]' % (U, lo, hi) raise UTMUPSError('%s outside %s: %g' % (ename, t, en)) if isinstance(coord, (Ups, Utm)): zone = coord.zone hemi = coord.hemisphere e, n = coord.easting, coord.northing band = coord.band enMM = coord.falsed elif isinstance(coord, (UtmUps5Tuple, UtmUps8Tuple)): zone = coord.zone hemi = coord.hemipole e, n = coord.easting, coord.northing band = coord.band enMM = falsed else: raise InvalidError(coord=coord, Error=UTMUPSError) z, B, h = _to3zBhp(zone, band, hemipole=hemi) if z == _UPS_ZONE: # UPS import pygeodesy.ups as u # PYCHOK expected U, M = 'UPS', _UpsMinMax else: # UTM import pygeodesy.utm as u # PYCHOK expected U, M = 'UTM', _UtmMinMax if MGRS: U, s = 'MGRS', _MGRS_TILE else: s = 0 i = 'SN'.find(h) if i < 0 or z < _UTMUPS_ZONE_MIN \ or z > _UTMUPS_ZONE_MAX \ or B not in u._Bands: raise InvalidError(zone=zone, hemisphere=hemi, band=band, coord='%s(%s%s %s)' % (U, z, B, h), Error=UTMUPSError) if enMM: _en(e, M.eMin[i] - s, M.eMax[i] + s, 'easting') # PYCHOK .eMax .eMin _en(n, M.nMin[i] - s, M.nMax[i] + s, 'northing') # PYCHOK .nMax .nMin
def utmupsValidate(coord, falsed=False, MGRS=False, Error=UTMUPSError): '''Check a UTM or UPS coordinate. @arg coord: The UTM or UPS coordinate (L{Utm}, L{Ups} or C{5+Tuple}). @kwarg falsed: C{5+Tuple} easting and northing are falsed (C{bool}). @kwarg MGRS: Increase easting and northing ranges (C{bool}). @kwarg Error: Optional error to raise, overriding the default (L{UTMUPSError}). @return: C{None} if validation passed. @raise Error: Validation failed. @see: Function L{utmupsValidateOK}. ''' def _en(en, lo, hi, ename): # U, Error try: if lo <= float(en) <= hi: return except (TypeError, ValueError): pass t = _SPACE_.join( (_outside_, U, _range_, '[%.0F' % (lo, ), '%.0F]' % (hi, ))) raise Error(ename, en, txt=t) if isinstance(coord, (Ups, Utm)): hemi = coord.hemisphere enMM = coord.falsed elif isinstance(coord, (UtmUps5Tuple, UtmUps8Tuple)): hemi = coord.hemipole enMM = falsed else: raise _IsnotError(Error=Error, coord=coord, *map1(modulename, Utm, Ups, UtmUps5Tuple, UtmUps8Tuple)) band = coord.band zone = coord.zone z, B, h = _to3zBhp(zone, band, hemipole=hemi) if z == _UPS_ZONE: # UPS import pygeodesy.ups as u # PYCHOK expected U, M = _UPS_, _UpsMinMax else: # UTM import pygeodesy.utm as u # PYCHOK expected U, M = _UTM_, _UtmMinMax if MGRS: U, s = _MGRS_, _MGRS_TILE else: s = 0 i = _NS_.find(h) if i < 0 or z < _UTMUPS_ZONE_MIN \ or z > _UTMUPS_ZONE_MAX \ or B not in u._Bands: t = '%s(%s%s %s)' % (U, z, B, h) raise Error(coord=t, zone=zone, band=band, hemisphere=hemi) if enMM: _en(coord.easting, M.eMin[i] - s, M.eMax[i] + s, _easting_) # PYCHOK .eMax .eMin _en(coord.northing, M.nMin[i] - s, M.nMax[i] + s, _northing_) # PYCHOK .nMax .nMin