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)
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)