Example #1
0
    def boundsOf(self, wide, high, radius=R_M):
        '''Return the SE and NW lat-/longitude of a great circle
           bounding box centered at this location.

           @arg wide: Longitudinal box width (C{meter}, same units as
                      B{C{radius}} or C{degrees} if B{C{radius}} is C{None}).
           @arg high: Latitudinal box height (C{meter}, same units as
                      B{C{radius}} or C{degrees} if B{C{radius}} is C{None}).
           @kwarg radius: Mean earth radius (C{meter}).

           @return: A L{Bounds2Tuple}C{(latlonSW, latlonNE)}, the
                    lower-left and upper-right corner (C{LatLon}).

           @see: U{https://www.Movable-Type.co.UK/scripts/latlong-db.html}
        '''
        w = Scalar_(wide, name='wide') * _0_5
        h = Scalar_(high, name='high') * _0_5
        if radius is not None:
            r = Radius_(radius)
            c = cos(self.phi)
            w = degrees(asin(w / r) / c) if c > EPS else _0_0  # XXX
            h = degrees(h / r)
        w, h = abs(w), abs(h)

        r = Bounds2Tuple(self.classof(self.lat - h, self.lon - w, height=self.height),
                         self.classof(self.lat + h, self.lon + w, height=self.height))
        return self._xnamed(r)
Example #2
0
    def isequalTo(self, other, eps=None):
        '''Compare this point with an other point, I{ignoring} height.

           @arg other: The other point (C{LatLon}).
           @kwarg eps: Tolerance for equality (C{degrees}).

           @return: C{True} if both points are identical,
                    I{ignoring} height, C{False} otherwise.

           @raise TypeError: The B{C{other}} point is not C{LatLon}
                             or mismatch of the B{C{other}} and
                             this C{class} or C{type}.

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

           @see: Method L{isequalTo3}.

           @example:

           >>> p = LatLon(52.205, 0.119)
           >>> q = LatLon(52.205, 0.119)
           >>> e = p.isequalTo(q)  # True
        '''
        self.others(other)

        e = _0_0 if eps in (None, 0, _0_0) else Scalar_(eps, name='eps')
        if e > 0:
            return max(map1(abs, self.lat - other.lat,
                                 self.lon - other.lon)) < e
        else:
            return self.lat == other.lat and \
                   self.lon == other.lon
Example #3
0
    def __init__(self,
                 latlon0,
                 par1,
                 par2=None,
                 E0=0,
                 N0=0,
                 k0=1,
                 opt3=0,
                 name='',
                 auth=''):
        '''New Lambert conformal conic projection.

           @arg latlon0: Origin with (ellipsoidal) datum (C{LatLon}).
           @arg par1: First standard parallel (C{degrees90}).
           @kwarg par2: Optional, second standard parallel (C{degrees90}).
           @kwarg E0: Optional, false easting (C{meter}).
           @kwarg N0: Optional, false northing (C{meter}).
           @kwarg k0: Optional scale factor (C{scalar}).
           @kwarg opt3: Optional meridian (C{degrees180}).
           @kwarg name: Optional name of the conic (C{str}).
           @kwarg auth: Optional authentication authority (C{str}).

           @return: A Lambert projection (L{Conic}).

           @raise TypeError: Non-ellipsoidal B{C{latlon0}}.

           @raise ValueError: Invalid B{C{par1}}, B{C{par2}},
                              B{C{E0}}, B{C{N0}}, B{C{k0}}
                              or B{C{opt3}}.

           @example:

           >>> from pygeodesy import Conic, Datums, ellipsoidalNvector
           >>> ll0 = ellipsoidalNvector.LatLon(23, -96, datum=Datums.NAD27)
           >>> Snyder = Conic(ll0, 33, 45, E0=0, N0=0, name='Snyder')
        '''
        if latlon0 is not None:
            _xinstanceof(_LLEB, latlon0=latlon0)
            self._phi0, self._lam0 = latlon0.philam

            self._par1 = Phi_(par1, name='par1')
            self._par2 = self._par1 if par2 is None else Phi_(par2,
                                                              name='par2')

            if k0 != 1:
                self._k0 = Scalar_(k0, name='k0')
            if E0:
                self._E0 = Northing(E0, name='E0', falsed=True)
            if N0:
                self._N0 = Easting(N0, name='N0', falsed=True)
            if opt3:
                self._opt3 = Lam_(opt3, name='opt3')

            self.toDatum(latlon0.datum)._dup2(self)
            self._register(Conics, name)
        elif name:
            self._name = name
        if auth:
            self._auth = auth
Example #4
0
    def k0(self, k0):
        '''Set the central scale factor (C{float}), aka I{C{scale0}}.

           @raise ETMError: Invalid B{C{k0}}.
        '''
        self._k0 = Scalar_(k0, name=_k0_, Error=ETMError, low=_TOL_10, high=1.0)
        # if not self._k0 > 0:
        #     raise Scalar_.Error_(Scalar_, k0, name=_k0_, Error=ETMError)
        self._k0_a = self._k0 * self._a
    def epsilon(self, eps):
        '''Set the convergence epsilon.

           @arg eps: New epsilon (C{scalar}).

           @raise TypeError: Non-scalar B{C{eps}}.

           @raise ValueError: Out of bounds B{C{eps}}.
        '''
        self._epsilon = Scalar_(eps, name='epsilon')
Example #6
0
def precision(res1, res2=None):
    '''Determine the L{Geohash} precisions to meet a given (geographic)
       resolutions.

       @arg res1: The required, primary (longitudinal) resolution (C{degrees}).
       @kwarg res2: Optional, required, secondary (latitudinal resolution (C{degrees}).

       @return: The L{Geohash} precision or length (C{int} 1..12).

       @raise ValueError: Invalid B{C{res1}} or B{C{res2}}.

       @see: C++ class U{Geohash
             <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1Geohash.html>}.
    '''
    r1 = Scalar_(res1, name='res1')
    r2 = r1 if res2 is None else Scalar_(res2, name='res2')
    for p in range(1, _MaxPrec):
        if resolution2(p, None if res2 is None else p) <= (r1, r2):
            return p
    return _MaxPrec
Example #7
0
def precision(res):
    '''Determine the L{Georef} precision to meet a required (geographic)
       resolution.

       @arg res: The required resolution (C{degrees}).

       @return: The L{Georef} precision (C{int} 0..11).

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

       @see: Function L{wgrs.encode} for more C{precision} details.
    '''
    r = Scalar_(res=res)
    for p in range(_MaxPrec):
        if resolution(p) <= r:
            return p
    return _MaxPrec
Example #8
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)
Example #9
0
    def reset(self, k2=0, alpha2=0, kp2=None, alphap2=None):  # MCCABE 13
        '''Reset the modulus and parameter.

           @kwarg k2: modulus squared (C{float}, 0 <= k^2<= 1).
           @kwarg alpha2: parameter (C{float}, 0 <= α^2 <= 1).
           @kwarg kp2: complementary modulus squared (C{float}, k'^2 >= 0).
           @kwarg alphap2: complementary parameter squared (C{float}, α'^2 >= 0).

           @raise EllipticError: Invalid B{C{k2}}, B{C{alpha2}}, B{C{kp2}}
                                 or B{C{alphap2}} or no convergence.

           @note: The arguments must satisfy I{B{C{k2}} + B{C{kp2}} = 1}
                  and I{B{C{alpha2}} + B{C{alphap2}} = 1}.  No checking
                  is done that these conditions are met to enable
                  accuracy to be maintained, e.g., when C{k} is very
                  close to unity.
        '''
        self._k2 = k2 = Scalar_(k2, name='k2', Error=EllipticError, high=1.0)

        self._alpha2 = alpha2 = Scalar_(alpha2, name='alpha2', Error=EllipticError, high=1.0)

        self._kp2 = kp2 = Scalar_(((1 - k2) if kp2 is None else kp2),
                                  name='kp2', Error=EllipticError)

        self._alphap2 = alphap2 = Scalar_(((1 - alpha2) if alphap2 is None else alphap2),
                                          name='alphap2', Error=EllipticError)

        # Values of complete elliptic integrals for k = 0,1 and alpha = 0,1
        #         K     E     D
        # k = 0:  pi/2  pi/2  pi/4
        # k = 1:  inf   1     inf
        #                    Pi    G     H
        # k = 0, alpha = 0:  pi/2  pi/2  pi/4
        # k = 1, alpha = 0:  inf   1     1
        # k = 0, alpha = 1:  inf   inf   pi/2
        # k = 1, alpha = 1:  inf   inf   inf
        #
        # G(0, k) = Pi(0, k) = H(1, k) = E(k)
        # H(0, k) = K(k) - D(k)
        # Pi(alpha2, 0) = G(alpha2, 0) = pi / (2 * sqrt(1 - alpha2))
        # H( alpha2, 0) = pi / (2 * (sqrt(1 - alpha2) + 1))
        # Pi(alpha2, 1) = inf
        # G( alpha2, 1) = H(alpha2, 1) = RC(1, alphap2)
        if k2:
            if kp2:
                self._eps = k2 / (sqrt(kp2) + 1)**2
                # D(k) = (K(k) - E(k))/k2, Carlson eq.4.3
                # <https://DLMF.NIST.gov/19.25.E1>
                self._cD = _RD_3(0, kp2, 1)
                self._cKE = k2 * self.cD
                # Complete elliptic integral E(k), Carlson eq. 4.2
                # <https://DLMF.NIST.gov/19.25.E1>
                self._cE = _RG_(kp2, 1) * 2
                # Complete elliptic integral K(k), Carlson eq. 4.1
                # <https://DLMF.NIST.gov/19.25.E1>
                self._cK = _RF_(kp2, 1)
            else:
                self._eps = k2
                self._cD  = self._cK = self._cKE = INF
                self._cE  = 1.0
        else:
            self._eps = EPS  # delattr(self, '_eps')
            self._cD  = PI_4
            self._cE  = self._cK = PI_2
            self._cKE = 0.0  # k2 * self._cD

        if alpha2:
            if alphap2:
                # <https://DLMF.NIST.gov/19.25.E2>
                if kp2:
                    rj_3 = _RJ_3(0, kp2, 1, alphap2)
                    # G(alpha2, k)
                    self._cG = self.cK + (alpha2 - k2) * rj_3
                    # H(alpha2, k)
                    self._cH = self.cK - alphap2 * rj_3
                    # Pi(alpha2, k)
                    self._cPi = self.cK + alpha2 * rj_3
                else:
                    self._cG = self._cH = _RC(1, alphap2)
                    self._cPi = INF  # XXX or NAN?
            else:
                self._cG = self._cH = self._cPi = INF  # XXX or NAN?
        else:
            self._cG  = self.cE
            self._cPi = self.cK
            # cH = cK - cD but this involves large cancellations
            # if k2 is close to 1.  So write (for alpha2 = 0)
            #   cH = int(cos(phi)**2/sqrt(1-k2*sin(phi)**2),phi,0,pi/2)
            #      = 1/sqrt(1-k2) * int(sin(phi)**2/sqrt(1-k2/kp2*sin(phi)**2,...)
            #      = 1/kp * D(i*k/kp)
            # and use D(k) = RD(0, kp2, 1) / 3
            # so cH = 1/kp * RD(0, 1/kp2, 1) / 3
            #       = kp2 * RD(0, 1, kp2) / 3
            # using <https://DLMF.NIST.gov/19.20.E18>
            # Equivalently
            #   RF(x, 1) - RD(0, x, 1)/3 = x * RD(0, 1, x)/3 for x > 0
            # For k2 = 1 and alpha2 = 0, we have
            #   cH = int(cos(phi),...) = 1
            self._cH = kp2 * _RD_3(0, 1, kp2) if kp2 else 1.0
Example #10
0
 def _option(name, m, m2_, K):
     f = Scalar_(m, name=name, Error=WGRSError)
     return NN(name[0].upper(), int(m2_(f * K) + _0_5))
Example #11
0
def _Ks(**name_k):
    '''(INTERNAL) Scale C{B{k} >= EPS}.
    '''
    return Scalar_(Error=AlbersError, low=EPS, **name_k)  # > 0
Example #12
0
 def k0(self, factor):
     '''Set the central scale factor (C{scalar}).
     '''
     n = Stereographic.k0.fget.__name__
     self._k0 = Scalar_(factor, name=n, low=EPS,
                        high=2)  # XXX high=1, 2, other?
Example #13
0
def _Ks(k, name):
    '''(INTERNAL) Scale C{B{k} >= EPS}.
    '''
    return Scalar_(k, name=name, Error=AlbersError, low=EPS)  # > 0
Example #14
0
 def _option(name, m, m2_, K):
     f = Scalar_(m, name=name, Error=WGRSError)
     return '%s%d' % (name[0].upper(), int(m2_(f * K) + 0.5))