Exemplo n.º 1
0
    def _reverse(self, x, y, name, LatLon, LatLon_kwds, _c_t, lea):
        '''(INTERNAL) Azimuthal (spherical) reverse C{x, y} to C{lat, lon}.
        '''
        x = Scalar(x=x)
        y = Scalar(y=y)

        r = hypot(x, y)
        c, t = _c_t(r / self.radius)
        if t:
            s0, c0 = self._sc0
            sc, cc = sincos2(c)
            k = c / sc
            z = atan2b(x, y)  # (x, y) for azimuth from true North

            lat = degrees(asin1(s0 * cc + c0 * sc * (y / r)))
            if lea or abs(c0) > EPS:
                lon = atan2(x * sc, c0 * cc * r - s0 * sc * y)
            else:
                lon = atan2(x, (y if s0 < 0 else -y))
            lon = _norm180(self.lon0 + degrees(lon))
        else:
            k, z = _1_0, _0_0
            lat, lon = self.latlon0

        t = self._toLatLon(lat, lon, LatLon, LatLon_kwds) if LatLon else \
            Azimuthal7Tuple(x, y, lat, lon, z, k, self.datum)
        return self._xnamed(t, name=name)
Exemplo n.º 2
0
 def __new__(cls, z, h, e, n, B, d, c, s, Error=None):
     if Error is not None:
         e = Easting(e, Error=Error)
         n = Northing(n, Error=Error)
         c = Scalar(c, name=_convergence_, Error=Error)
         s = Scalar(s, name=_scale_, Error=Error)
     return _NamedTuple.__new__(cls, z, h, e, n, B, d, c, s)
Exemplo n.º 3
0
    def reverse(self, x, y, name=NN, LatLon=None, **LatLon_kwds):
        '''Convert an azimuthal equidistant location to (ellipsoidal) geodetic lat- and longitude.

           @arg x: Easting of the location (C{meter}).
           @arg y: Northing of the location (C{meter}).
           @kwarg name: Optional name for the location (C{str}).
           @kwarg LatLon: Class to use (C{LatLon}) or C{None}.
           @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
                               arguments, ignored if B{C{LatLon=None}}.

           @return: The geodetic (C{LatLon}) or if B{C{LatLon}} is C{None} an
                    L{Azimuthal7Tuple}C{(x, y, lat, lon, azimuth, scale, datum)}.

           @note: The C{lat} will be in the range C{[-90..90] degrees} and C{lon}
                  in the range C{[-180..180] degrees}.  The scale of the projection
                  is C{1} in I{radial} direction, C{azimuth} clockwise from true
                  North and is C{1 / reciprocal} in the direction perpendicular
                  to this.
        '''
        x = Scalar(x, name=_x_)
        y = Scalar(y, name=_y_)

        z = atan2d(x, y)  # (x, y) for azimuth from true North
        s = hypot(x, y)

        r = self.geodesic.Direct(self.lat0, self.lon0, z, s, self._mask)
        t = self._toLatLon(r.lat2, r.lon2, LatLon, LatLon_kwds) if LatLon else \
            Azimuthal7Tuple(x, y, r.lat2, r.lon2, r.azi2, self._1_rk(r), self.datum)
        return _xnamed(t, name or self.name)
Exemplo n.º 4
0
    def __init__(self, easting, northing, band='', datum=None, falsed=True,
                                          convergence=None, scale=None):
        '''(INTERNAL) New L{UtmUpsBase}.
        '''
        E = self._Error
        if not E:
            notOverloaded(self, '_Error')

        self._easting  = Easting(easting,   Error=E)
        self._northing = Northing(northing, Error=E)

        if band:
            _xinstanceof(str, band=band)
            self._band = band

        if datum:
            _xinstanceof(Datum, datum=datum)
            if datum != self._datum:
                self._datum = datum

        if not falsed:
            self._falsed = False

        if convergence is not self._convergence:
            self._convergence = Scalar(convergence, name='convergence', Error=E)
        if scale is not self._scale:
            self._scale = Scalar(scale, name='scale', Error=E)
Exemplo n.º 5
0
    def __init__(self,
                 easting,
                 northing,
                 band=NN,
                 datum=None,
                 falsed=True,
                 convergence=None,
                 scale=None):
        '''(INTERNAL) New L{UtmUpsBase}.
        '''
        E = self._Error
        if not E:
            notOverloaded(self, '_Error')

        self._easting = Easting(easting, Error=E)
        self._northing = Northing(northing, Error=E)

        if band:
            _xinstanceof(str, band=band)
            self._band = band

        if datum not in (None, self._datum):
            self._datum = _ellipsoidal_datum(datum)  # XXX name=band

        if not falsed:
            self._falsed = False

        if convergence is not self._convergence:
            self._convergence = Scalar(convergence,
                                       name=_convergence_,
                                       Error=E)
        if scale is not self._scale:
            self._scale = Scalar(scale, name=_scale_, Error=E)
Exemplo n.º 6
0
    def reverse(self, x, y, name=NN, LatLon=None, **LatLon_kwds):
        '''Convert an azimuthal gnomonic location to (ellipsoidal) geodetic lat- and longitude.

           @arg x: Easting of the location (C{meter}).
           @arg y: Northing of the location (C{meter}).
           @kwarg name: Optional name for the location (C{str}).
           @kwarg LatLon: Class to use (C{LatLon}) or C{None}.
           @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
                               arguments, ignored if C{B{LatLon}=None}.

           @return: The geodetic (C{LatLon}) or if B{C{LatLon}} is C{None} an
                    L{Azimuthal7Tuple}C{(x, y, lat, lon, azimuth, scale, datum)}.

           @raise AzimuthalError: No convergence.

           @note: The C{lat} will be in the range C{[-90..90] degrees} and C{lon}
                  in the range C{[-180..180] degrees}.  The C{azimuth} is clockwise
                  from true North.  The scale is C{1 / reciprocal**2} in C{radial}
                  direction and C{1 / reciprocal} in the direction perpendicular
                  to this.
        '''
        x = Scalar(x=x)
        y = Scalar(y=y)

        z = atan2d(x, y)  # (x, y) for azimuth from true North
        q = hypot(x, y)

        d = e = self.equatoradius
        s = e * atan(q / e)
        if q > e:

            def _d(r, q):
                return (r.M12 - q * r.m12) * r.m12  # negated

            q = 1 / q
        else:  # little == True

            def _d(r, q):  # PYCHOK _d
                return (q * r.M12 - r.m12) * r.M12  # negated

        e *= _Karney_eps

        S = Fsum(s)
        g = self.geodesic.Line(self.lat0, self.lon0, z, self._mask)
        for self._iteration in range(1, _TRIPS):
            r = g.Position(s, self._mask)
            if abs(d) < e:
                break
            s, d = S.fsum2_(_d(r, q))
        else:
            raise AzimuthalError(x=x, y=y, txt=_no_(Fmt.convergence(e)))

        t = self._7Tuple(x, y, r, r.M12) if LatLon is None else \
            self._toLatLon(r.lat2, r.lon2, LatLon, LatLon_kwds)

        t._iteration = self._iteration
        return self._xnamed(t, name=name)
Exemplo n.º 7
0
 def __new__(cls, x, y, lat, lon, azi, s, datum):
     return _NamedTuple.__new__(
         cls,
         Scalar(x, name=_x_, Error=AzimuthalError),
         Scalar(y, name=_y_, Error=AzimuthalError),  # PYCHOK indent
         Lat_(lat, Error=AzimuthalError),
         Lon_(lon, Error=AzimuthalError),
         Bearing(azi, name=_azimuth_, Error=AzimuthalError),
         Scalar(s, name=_scale_, Error=AzimuthalError),
         datum)
Exemplo n.º 8
0
 def __new__(cls, z, h, e, n, B, d, c, s, Error=None):
     if Error is not None:
         e = Easting(e, Error=Error)
         n = Northing(n, Error=Error)
         c = Degrees(convergence=c, Error=Error)
         s = Scalar(scale=s, Error=Error)
     return _NamedTuple.__new__(cls, z, h, e, n, B, d, c, s)
Exemplo n.º 9
0
    def intermediateChordTo(self, other, fraction, height=None):
        '''Locate the point projected from the point at given fraction
           on a straight line (chord) between this and an other point.

           @arg other: The other point (L{LatLon}).
           @arg fraction: Fraction between both points (float, between
                          0.0 for this and 1.0 for the other point).
           @kwarg height: Optional height at the intermediate point,
                          overriding the fractional height (C{meter}).

           @return: Intermediate point (L{LatLon}).

           @raise TypeError: The B{C{other}} point is not L{LatLon}.

           @example:

           >>> p = LatLon(52.205, 0.119)
           >>> q = LatLon(48.857, 2.351)
           >>> i = p.intermediateChordTo(q, 0.25)  # 51.3723°N, 000.7072°E

           @JSname: I{intermediatePointOnChordTo}, I{intermediatePointDirectlyTo}.
        '''
        self.others(other)

        f = Scalar(fraction=fraction)
        i = other.toNvector().times(f).plus(
             self.toNvector().times(1 - f))
#       i = other.toNvector() * f + \
#            self.toNvector() * (1 - f))

        h = self._havg(other, f=f) if height is None else Height(height)
        return i.toLatLon(height=h, LatLon=self.classof)  # Nvector(i.x, i.y, i.z).toLatLon(...)
Exemplo n.º 10
0
def _intermediateTo(p1, p2, fraction, height, wrap):
    # (INTERNAL) Helper for C{ellipsoidalKarney.LatLon.intermediateTo}
    # and C{ellipsoidalVincenty.LatLon.intermediateTo}.
    t = p1.distanceTo3(p2, wrap=wrap)
    f = Scalar(fraction=fraction)
    h = p1._havg(p2, f=f) if height is None else Height(height)
    return p1.destination(t.distance * f, t.initial, height=h)
Exemplo n.º 11
0
    def intermediateTo(self, other, fraction, height=None, wrap=False):
        '''Locate the point at given fraction between this and an
           other point.

           @arg other: The other point (L{LatLon}).
           @arg fraction: Fraction between both points (float, between
                          0.0 for this and 1.0 for the other point).
           @kwarg height: Optional height, overriding the fractional
                          height (C{meter}).
           @kwarg wrap: Wrap and unroll longitudes (C{bool}).

           @return: Intermediate point (L{LatLon}).

           @raise TypeError: The B{C{other}} point is not L{LatLon}.

           @raise ValueError: Invalid B{C{fraction}} or B{C{height}}.

           @example:

           >>> p1 = LatLon(52.205, 0.119)
           >>> p2 = LatLon(48.857, 2.351)
           >>> p = p1.intermediateTo(p2, 0.25)  # 51.3721°N, 000.7073°E

           @JSname: I{intermediatePointTo}.
        '''
        self.others(other)

        f = Scalar(fraction, name='fraction')

        a1, b1 = self.philam
        a2, b2 = other.philam

        db, b2 = unrollPI(b1, b2, wrap=wrap)
        r = haversine_(a2, a1, db)
        sr = sin(r)
        if abs(sr) > EPS:
            sa1, ca1, sa2, ca2, \
            sb1, cb1, sb2, cb2 = sincos2(a1, a2, b1, b2)

            A = sin((1 - f) * r) / sr
            B = sin(f * r) / sr

            x = A * ca1 * cb1 + B * ca2 * cb2
            y = A * ca1 * sb1 + B * ca2 * sb2
            z = A * sa1 + B * sa2

            a = atan2(z, hypot(x, y))
            b = atan2(y, x)

        else:  # points too close
            a = favg(a1, a2, f=f)
            b = favg(b1, b2, f=f)

        if height is None:
            h = self._havg(other, f=f)
        else:
            h = Height(height)
        return self.classof(degrees90(a), degrees180(b), height=h)
Exemplo n.º 12
0
def elevation2(lat, lon, timeout=2.0):
    '''Get the geoid elevation at an C{NAD83} to C{NAVD88} location.

       @arg lat: Latitude (C{degrees}).
       @arg lon: Longitude (C{degrees}).
       @kwarg timeout: Optional, query timeout (seconds).

       @return: An L{Elevation2Tuple}C{(elevation, data_source)}
                or (C{None, "error"}) in case of errors.

       @raise ValueError: Invalid B{C{timeout}}.

       @note: The returned C{elevation} is C{None} if B{C{lat}} or B{C{lon}}
              is invalid or outside the C{Conterminous US (CONUS)},
              if conversion failed or if the query timed out.  The
              C{error} is the C{HTTP-, IO-, SSL-, Type-, URL-} or
              C{ValueError} as a string (C{str}).

       @see: U{USGS National Map<https://NationalMap.gov/epqs>},
             the U{FAQ<https://www.USGS.gov/faqs/what-are-projection-
             horizontal-and-vertical-datum-units-and-resolution-3dep-standard-dems>},
             U{geoid.py<https://Gist.GitHub.com/pyRobShrk>}, module
             L{geoids}, classes L{GeoidG2012B}, L{GeoidKarney} and
             L{GeoidPGM}.
    '''
    try:
        x = _qURL(
            'https://NED.USGS.gov/epqs/pqs.php',  # 'https://NationalMap.gov/epqs/pqs.php'
            (
                '%s=%.6F' % (_x_, Lon(lon)),
                '%s=%.6F' % (_y_, Lat(lat)),
                '%s=%s' % (_units_, 'Meters'),  # 'Feet', capitalized
                'output=xml'),  # json, case_sensitive
            timeout=Scalar(timeout, name=_timeout_))
        if x[:6] == '<?xml ':
            e = _xml('Elevation', x)
            try:
                e = float(e)
                if -1000000 < e < 1000000:
                    return Elevation2Tuple(e, _xml('Data_Source', x))
                e = 'non-CONUS %.2F' % (e, )
            except (TypeError, ValueError):
                pass
        else:
            e = 'no %s "%s"' % (
                _XML_,
                clips(x, limit=128, white=_SPACE_),
            )
    except (HTTPError, IOError, TypeError, ValueError) as x:
        e = repr(x)
    e = _error(elevation2, lat, lon, e)
    return Elevation2Tuple(None, e)
Exemplo n.º 13
0
    def __init__(self, north, east, down, name=NN):
        '''New North-East-Down vector.

           @arg north: North component (C{meter}).
           @arg east: East component (C{meter}).
           @arg down: Down component, normal to the surface of
                      the ellipsoid (C{meter}).
           @kwarg name: Optional name (C{str}).

           @raise ValueError: Invalid B{C{north}}, B{C{east}}
                              or B{C{down}}.
           @example:

           >>> from ellipsiodalNvector import Ned
           >>> delta = Ned(110569, 111297, 1936)
           >>> delta.toStr(prec=0)  #  [N:110569, E:111297, D:1936]
        '''
        self._north = Scalar(north=north or 0)
        self._east = Scalar(east=east or 0)
        self._down = Scalar(down=down or 0)
        if name:
            self.name = name
Exemplo n.º 14
0
def geoidHeight2(lat, lon, model=0, timeout=2.0):
    '''Get the C{NAVD88} geoid height at an C{NAD83} location.

       @arg lat: Latitude (C{degrees}).
       @arg lon: Longitude (C{degrees}).
       @kwarg model: Optional, geoid model ID (C{int}).
       @kwarg timeout: Optional, query timeout (seconds).

       @return: An L{GeoidHeight2Tuple}C{(height, model_name)}
                or C{(None, "error"}) in case of errors.

       @raise ValueError: Invalid B{C{timeout}}.

       @note: The returned C{height} is C{None} if B{C{lat}} or B{C{lon}} is
              invalid or outside the C{Conterminous US (CONUS)}, if the
              B{C{model}} was invalid, if conversion failed or if the
              query timed out.  The C{error} is the C{HTTP-, IO-, SSL-,
              Type-, URL-} or C{ValueError} as a string (C{str}).

       @see: U{NOAA National Geodetic Survey
             <https://www.NGS.NOAA.gov/INFO/geodesy.shtml>},
             U{Geoid<https://www.NGS.NOAA.gov/web_services/geoid.shtml>},
             U{USGS10mElev.py<https://Gist.GitHub.com/pyRobShrk>}, module
             L{geoids}, classes L{GeoidG2012B}, L{GeoidKarney} and
             L{GeoidPGM}.
    '''
    try:
        j = _qURL('https://Geodesy.NOAA.gov/api/geoid/ght',
                  ('lat=%.6F' % (Lat(lat), ), 'lon=%.6F' %
                   (Lon(lon), ), 'model=%s' % (model, ) if model else ''),
                  timeout=Scalar(timeout, name='timeout'))  # PYCHOK 5
        if j[:1] == '{' and j[-1:] == '}' and j.find('"error":') > 0:
            d = _json(j)
            if isinstance(d.get('error', 'N/A'), float):
                h = d.get('geoidHeight', None)
                if h is not None:
                    m = _str(d.get('geoidModel', 'N/A'))
                    return GeoidHeight2Tuple(h, m)
            e = 'geoidHeight'
        else:
            e = 'JSON'
        e = 'no %s "%s"' % (e, clips(j, limit=256, white=' '))
    except (HTTPError, IOError, TypeError, ValueError) as x:
        e = repr(x)
    e = _error(geoidHeight2, lat, lon, e)
    return GeoidHeight2Tuple(None, e)
Exemplo n.º 15
0
    def rescale0(self, lat, scale0=_K0):
        '''Set the central scale factor for this UPS projection.

           @arg lat: Northern latitude (C{degrees}).
           @arg scale0: UPS k0 scale at B{C{lat}} latitude (C{scalar}).

           @raise RangeError: If B{C{lat}} outside the valid range
                              and L{rangerrors} set to C{True}.

           @raise UPSError: Invalid B{C{scale}}.
        '''
        s0 = Scalar_(scale0, Error=UPSError, name='scale0', low=EPS)  # <= 1.003 or 1.0016?
        u  = toUps8(abs(Lat(lat)), 0, datum=self.datum, Ups=_UpsK1)
        k  = s0 / u.scale
        if self.scale0 != k:
            self._band = NN  # force re-compute
            self._latlon = self._epsg = self._mgrs = self._utm = None
            self._scale0 = Scalar(k)
Exemplo n.º 16
0
    def intermediateTo(self, other, fraction, height=None):
        '''Locate the point at a given fraction between this and an
           other point.

           @arg other: The other point (L{LatLon}).
           @arg fraction: Fraction between both points (float, between
                          0.0 for this and 1.0 for the other point).
           @kwarg height: Optional height at the intermediate point,
                          overriding the fractional height (C{meter}).

           @return: Intermediate point (L{LatLon}).

           @raise TypeError: The B{C{other}} point is not L{LatLon}.

           @raise Valuerror: Points coincide or invalid B{C{height}}.

           @example:

           >>> p = LatLon(52.205, 0.119)
           >>> q = LatLon(48.857, 2.351)
           >>> i = p.intermediateTo(q, 0.25)  # 51.3721°N, 000.7074°E

           @JSname: I{intermediatePointTo}.
        '''
        q = self.others(other).toNvector()
        p = self.toNvector()
        f = Scalar(fraction=fraction)

        x = p.cross(q, raiser=_points_)
        d = x.unit().cross(p)  # unit(p × q) × p
        # angular distance α, tan(α) = |p × q| / p ⋅ q
        s, c = sincos2(atan2(x.length, p.dot(q)) * f)  # interpolated
        i = p.times(c).plus(d.times(s))  # p * cosα + d * sinα

        h = self._havg(other, f=f) if height is None else Height(height)
        return i.toLatLon(height=h, LatLon=self.classof)  # Nvector(i.x, i.y, i.z).toLatLon(...)
Exemplo n.º 17
0
from pygeodesy.units import Meter, Lat, Scalar, Scalar_
from pygeodesy.utily import degrees90, degrees180, sincos2d
from pygeodesy.utmupsBase import _LLEB, _hemi, _parseUTMUPS5, \
                                 _to4lldn, _to3zBhp, _to3zll, \
                                 _UPS_LAT_MAX, _UPS_LAT_MIN, _UPS_ZONE, \
                                 _UPS_ZONE_STR, UtmUpsBase

from math import atan, atan2, radians, sqrt, tan

__all__ = _ALL_LAZY.ups
__version__ = '20.11.04'

_Bands = _A_, 'B', 'Y', 'Z'  # polar bands
_EPS__2 = EPS**2
_Falsing = Meter(2000e3)  # false easting and northing (C{meter})
_K0 = Scalar(0.994)  # central UPS scale factor
_K1 = Scalar(_1_0)  # rescale point scale factor


class UPSError(_ValueError):
    '''Universal Polar Stereographic (UPS) parse or other L{Ups} issue.
    '''
    pass


def _Band(a, b):
    # determine the polar band letter
    return _Bands[(0 if a < 0 else 2) + (0 if b < 0 else 1)]


def _scale(E, rho, tau):
Exemplo n.º 18
0
from pygeodesy.units import Meter, Lat, Scalar, Scalar_
from pygeodesy.utily import degrees90, degrees180, sincos2d
from pygeodesy.utmupsBase import _LLEB, _hemi, _parseUTMUPS5, \
                                 _to4lldn, _to3zBhp, _to3zll, \
                                 _UPS_LAT_MAX, _UPS_LAT_MIN, _UPS_ZONE, \
                                 _UPS_ZONE_STR, UtmUpsBase, UtmUps5Tuple, \
                                  UtmUps8Tuple, UtmUpsLatLon5Tuple  # PYCHOK indent

from math import atan, atan2, radians, sqrt, tan

__all__ = _ALL_LAZY.ups
__version__ = '20.09.01'

_Bands   = 'A', 'B', 'Y', 'Z'    #: (INTERNAL) Polar bands.
_Falsing = Meter(2000e3)  #: (INTERNAL) False easting and northing (C{meter}).
_K0      = Scalar(0.994)  #: (INTERNAL) Central UPS scale factor.
_K1      = Scalar(1.0)    #: (INTERNAL) Rescale point scale factor.


class UPSError(_ValueError):
    '''Universal Polar Stereographic (UPS) parse or other L{Ups} issue.
    '''
    pass


def _Band(a, b):
    # determine the polar band letter
    return _Bands[(0 if a < 0 else 2) + (0 if b < 0 else 1)]


def _scale(E, rho, tau):
Exemplo n.º 19
0
 def __new__(cls, e, n, azi, rk):
     return _NamedTuple.__new__(cls, Easting(e, Error=CSSError),
                                Northing(n, Error=CSSError),
                                Bearing(azi, Error=CSSError),
                                Scalar(rk, Error=CSSError))
Exemplo n.º 20
0
 def __new__(cls, lat, lon, azi, rk):
     return _NamedTuple.__new__(cls, Lat(lat, Error=CSSError),
                                Lon(lon, Error=CSSError),
                                Bearing(azi, Error=CSSError),
                                Scalar(rk, Error=CSSError))
Exemplo n.º 21
0
 def __new__(cls, x, y, lat, lon, g, k, datum):
     return _NamedTuple.__new__(cls, Scalar(x, name=_x_, Error=AlbersError),
                                Scalar(y, name=_y_, Error=AlbersError),
                                _Lat_(lat), _Lon_(lon),
                                Degrees(g, name=_gamma_, Error=AlbersError),
                                _Ks(k, _scale_), datum)
Exemplo n.º 22
0
    def reverse(self, x, y, lon0=0, name=NN, LatLon=None, **LatLon_kwds):
        '''Convert an east- and northing location to geodetic lat- and longitude.

           @arg x: Easting of the location (C{meter}).
           @arg y: Northing of the location (C{meter}).
           @kwarg lon0: Optional central meridian longitude (C{degrees}).
           @kwarg name: Optional name for the location (C{str}).
           @kwarg LatLon: Class to use (C{LatLon}) or C{None}.
           @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
                               arguments, ignored if B{C{LatLon=None}}.

           @return: The geodetic (C{LatLon}) or if B{C{LatLon}} is C{None} an
                    L{Albers7Tuple}C{(x, y, lat, lon, gamma, scale, datum)}.

           @note: The origin latitude is returned by C{property lat0}.  No
                  false easting or northing is added.  The returned value of
                  C{lon} is in the range C{[-180..180] degrees} and C{lat}
                  is in the range C{[-90..90] degrees}.  If the given
                  B{C{x}} or B{C{y}} point is outside the valid projected
                  space the nearest pole is returned.
        '''
        x = Scalar(x, name=_x_)
        y = Scalar(y, name=_y_)
        E = self.datum.ellipsoid

        k0 = self._k0
        n0 = self._n0
        k0n0 = self._k0n0
        nrho0 = self._nrho0
        txi0 = self._txi0

        y_ = self._sign * y
        nx = k0n0 * x
        ny = k0n0 * y_
        y1 = nrho0 - ny

        drho = den = nrho0 + hypot(nx,
                                   y1)  # 0 implies origin with polar aspect
        if den:
            drho = fsum_(x * nx, -2 * y_ * nrho0, y_ * ny) * k0 / den
        # dsxia = scxi0 * dsxi
        dsxia = -self._scxi0 * (2 * nrho0 + n0 * drho) * drho / self._qZa2
        t = 1 - dsxia * (2 * txi0 + dsxia)
        txi = (txi0 + dsxia) / (sqrt(t) if t > _EPSX2 else _EPSX)

        ta = self._tanf(txi)
        lat = degrees(atan(ta * self._sign))

        b = atan2(nx, y1)
        lon = degrees(b / self._k02n0 if n0 else x / (y1 * k0))
        if lon0:
            lon += _norm180(_Lon_(lon0, name=_lon0_))
        lon = _norm180(lon)

        if LatLon is None:
            g = degrees360(self._sign * b)
            if den:
                k0 *= (nrho0 + n0 * drho) * hypot1(E.b_a * ta) / E.a
            r = Albers7Tuple(x, y, lat, lon, g, k0, self.datum)
        else:
            kwds = _xkwds(LatLon_kwds, datum=self.datum)
            r = LatLon(lat, lon, **kwds)
        return _xnamed(r, name or self.name)
Exemplo n.º 23
0
 def _nd2(p, d, r, _i_, *qs):  # .toNvector and angular distance squared
     for q in qs:
         if p.isequalTo(q, EPS):
             raise _ValueError(points=p, txt=_coincident_)
     return p.toNvector(), (Scalar(d, name=_distance_ + _i_) / r)**2
Exemplo n.º 24
0
def _scale(E, rho, tau):
    # compute the point scale factor, ala Karney
    t = hypot1(tau)
    return Scalar((rho / E.a) * t * sqrt(E.e12 + E.e2 / t**2))
Exemplo n.º 25
0
from pygeodesy.units import Easting, Lam_, Northing, Phi_, Scalar
from pygeodesy.utily import degrees90, degrees180, sincos2

from math import cos, radians, sin, sqrt, tan

__all__ = _ALL_LAZY.osgr
__version__ = '20.09.01'

_10um = 1e-5  #: (INTERNAL) 0.01 millimeter (C{meter})
_100km = 100000  #: (INTERNAL) 100 km (int meter)

_A0 = Phi_(49)  #: (INTERNAL) NatGrid true origin latitude, 49°N.
_B0 = Lam_(-2)  #: (INTERNAL) NatGrid true origin longitude, 2°W.
_E0 = Easting(400e3)  #: (INTERNAL) Easting of true origin (C{meter}).
_N0 = Northing(-100e3)  #: (INTERNAL) Northing of true origin (C{meter}).
_F0 = Scalar(
    0.9996012717)  #: (INTERNAL) NatGrid scale of central meridian (C{float}).

_Datums_OSGB36 = Datums.OSGB36  #: (INTERNAL) Airy130 ellipsoid
_latlon_ = 'latlon'
_no_convertDatum_ = 'no .convertDatum'
_ord_A = ord('A')
_TRIPS = 33  #: (INTERNAL) .toLatLon convergence


def _ll2datum(ll, datum, name):
    '''(INTERNAL) Convert datum if needed.
    '''
    if datum not in (None, ll.datum):
        try:
            ll = ll.convertDatum(datum)
        except AttributeError:
Exemplo n.º 26
0
 def __new__(cls, lat, lon, d, c, s):
     return _NamedTuple.__new__(cls, Lat(lat), Lon(lon), d,
                                Scalar(c, name=_convergence_),
                                Scalar(s, name=_scale_))