Example #1
0
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
Example #2
0
    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)
Example #3
0
    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
Example #4
0
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
Example #5
0
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
Example #6
0
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)
Example #7
0
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
Example #8
0
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
Example #9
0
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