Ejemplo n.º 1
0
    def forward(self, lat, lon, lon0=None):  # MCCABE 13
        '''Forward projection, from geographic to transverse Mercator.

           @arg lat: Latitude of point (C{degrees}).
           @arg lon: Longitude of point (C{degrees}).
           @kwarg lon0: Central meridian of the projection (C{degrees}).

           @return: L{EasNorExact4Tuple}C{(easting, northing,
                    convergence, scale)} in C{meter}, C{meter},
                    C{degrees} and C{scalar}.

           @see: C{void TMExact::Forward(real lon0, real lat, real lon,
                                         real &x, real &y,
                                         real &gamma, real &k)}.

           @raise EllipticError: No convergence.
        '''
        lat = _fix90(lat)
        lon, _ = _diff182((self._lon0 if lon0 is None else lon0), lon)
        # Explicitly enforce the parity
        backside = _lat = _lon = False
        if not self.extendp:
            if lat < 0:
                _lat, lat = True, -lat
            if lon < 0:
                _lon, lon = True, -lon
            if lon > 90:
                backside = True
                if lat == 0:
                    _lat = True
                lon = 180 - lon

        # u,v = coordinates for the Thompson TM, Lee 54
        if lat == 90:
            u, v = self._Eu.cK, 0
        elif lat == 0 and lon == self._1_e_90:
            u, v = 0, self._Ev.cK
        else:  # tau = tan(phi), taup = sinh(psi)
            tau, lam = tan(radians(lat)), radians(lon)
            u, v = self._zetaInv(self._E.es_taupf(tau), lam)

        sncndn6 = self._sncndn6(u, v)
        xi, eta, _ = self._sigma3(v, *sncndn6)
        if backside:
            xi = 2 * self._Eu.cE - xi
        y = xi  * self._k0_a
        x = eta * self._k0_a

        if lat == 90:
            g, k = lon, self._k0
        else:
            g, k = self._zetaScaled(sncndn6, ll=False)

        if backside:
            g = 180 - g
        if _lat:
            y, g = -y, -g
        if _lon:
            x, g = -x, -g
        return EasNorExact4Tuple(x, y, g, k)
Ejemplo n.º 2
0
    def forward(self, lat, lon, lon0=0, name=NN):
        '''Convert a geodetic location to east- and northing.

           @arg lat: Latitude of the location (C{degrees}).
           @arg lon: Longitude of the location (C{degrees}).
           @kwarg lon0: Optional central meridian longitude (C{degrees}).
           @kwarg name: Optional name for the location (C{str}).

           @return: 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 value of B{C{lat}}
                  should be in the range C{[-90..90] degrees}.  The returned
                  values C{x} and C{y} will be large but finite for points
                  projecting to infinity, i.e. one or both of the poles.
        '''
        E = self.datum.ellipsoid
        s = self._sign

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

        sa, ca = sincos2d(_Lat_(lat) * s)
        ca = max(_EPSX, ca)
        ta = sa / ca

        _, sxi, txi = self._cstxif3(ta)
        dq = self._qZ * _Dsn(txi, txi0, sxi, self._sxi0) * (txi - txi0)
        drho = -E.a * dq / (sqrt(self._m02 - n0 * dq) + self._m0)

        lon = _Lon_(lon)
        if lon0:
            lon, _ = _diff182(_Lon_(lon0, name=_lon0_), lon)
        b = radians(lon)

        th = self._k02n0 * b
        sth, cth = sincos2(th)  # XXX sin, cos
        if n0:
            x = sth / n0
            y = (1 - cth if cth < 0 else sth**2 / (1 + cth)) / n0
        else:
            x = self._k02 * b
            y = 0
        t = nrho0 + n0 * drho
        x = t * x / k0
        y = s * (nrho0 * y - drho * cth) / k0

        g = degrees360(s * th)
        if t:
            k0 *= t * hypot1(E.b_a * ta) / E.a
        t = Albers7Tuple(x, y, lat, lon, g, k0, self.datum)
        return _xnamed(t, name or self.name)