def falsed2(self): '''Get the easting and northing falsing (L{EasNor2Tuple}C{(easting, northing)}). ''' e = n = 0 if self.falsed: e = _FalseEasting # relative to central meridian if self.hemisphere == _S_: # relative to equator n = _FalseNorthing return EasNor2Tuple(e, n)
def forward(self, lat, lon): '''Convert an (ellipsoidal) geodetic location Cassini-Soldner easting and northing. @param lat: Latitude of the location (C{degrees90}). @param lon: Longitude of the location (C{degrees180}). @return: An L{EasNor2Tuple}C{(easting, northing)}. ''' r = EasNor2Tuple(*self.forward4(lat, lon)[:2]) return self._xnamed(r)
def forward(self, lat, lon): '''Convert an (ellipsoidal) geodetic location to Cassini-Soldner easting and northing. @arg lat: Latitude of the location (C{degrees90}). @arg lon: Longitude of the location (C{degrees180}). @return: An L{EasNor2Tuple}C{(easting, northing)}. @see: Methods L{CassiniSoldner.forward4}, L{CassiniSoldner.reverse} and L{CassiniSoldner.reverse4}. ''' r = EasNor2Tuple(*self.forward4(lat, lon)[:2]) return self._xnamed(r)
def to2en(self, falsed=True): '''Return easting and northing, falsed or unfalsed. @keyword falsed: Return easting and northing falsed (C{bool}), otherwise unfalsed. @return: An L{EasNor2Tuple}C{(easting, northing)}. ''' e, n = self.falsed2 if self.falsed and not falsed: e, n = -e, -n elif falsed and not self.falsed: pass else: e = n = 0 return EasNor2Tuple(e + self.easting, n + self.northing)
def eastingnorthing2(self, falsed=True): '''Return easting and northing, falsed or unfalsed. @kwarg falsed: Return easting and northing falsed (C{bool}), otherwise unfalsed. @return: An L{EasNor2Tuple}C{(easting, northing)} in C{meter}s. ''' e, n = self.falsed2 if self.falsed and not falsed: e, n = -e, -n elif falsed and not self.falsed: pass else: e = n = 0 return EasNor2Tuple(Easting(e + self.easting, Error=self._Error), Northing(n + self.northing, Error=self._Error))
def forward(self, lat, lon): '''Convert an (ellipsoidal) geodetic location to Cassini-Soldner easting and northing. @arg lat: Latitude of the location (C{degrees90}). @arg lon: Longitude of the location (C{degrees180}). @return: An L{EasNor2Tuple}C{(easting, northing)}. @see: Methods L{CassiniSoldner.forward4}, L{CassiniSoldner.reverse} and L{CassiniSoldner.reverse4}. @raise CSSError: Invalid B{C{lat}} or B{C{lon}}. ''' t = self.forward4(lat, lon) r = EasNor2Tuple(t.easting, t.northing) return self._xnamed(r)
def _EasNor2Tuple(e, n): '''(INTERNAL) Helper for L{parseOSGR} and L{toOsgr}. ''' return EasNor2Tuple(Easting(e, Error=OSGRError), Northing(n, Error=OSGRError))
def falsed2(self): '''Get the easting and northing falsing (L{EasNor2Tuple}C{(easting, northing)}). ''' f = _Falsing if self.falsed else 0 return EasNor2Tuple(f, f)
def toOsgr(latlon, lon=None, datum=Datums.WGS84, Osgr=Osgr, name=''): '''Convert a lat-/longitude point to an OSGR coordinate. @param latlon: Latitude (C{degrees}) or an (ellipsoidal) geodetic C{LatLon} point. @keyword lon: Optional longitude in degrees (scalar or C{None}). @keyword datum: Optional datum to convert (C{Datum}). @keyword Osgr: Optional (sub-)class to return the OSGR coordinate (L{Osgr}) or C{None}. @keyword name: Optional B{C{Osgr}} name (C{str}). @return: The OSGR coordinate (B{C{Osgr}}) or an L{EasNor2Tuple}C{(easting, northing)} if B{C{Osgr}} is C{None}. @raise TypeError: Non-ellipsoidal B{C{latlon}} or B{C{datum}} conversion failed. @raise OSGRError: Invalid B{C{latlon}} or B{C{lon}}. @example: >>> p = LatLon(52.65798, 1.71605) >>> r = toOsgr(p) # TG 51409 13177 >>> # for conversion of (historical) OSGB36 lat-/longitude: >>> r = toOsgr(52.65757, 1.71791, datum=Datums.OSGB36) ''' if not isinstance(latlon, _LLEB): # XXX fix failing _LLEB.convertDatum() latlon = _LLEB(*parseDMS2(latlon, lon), datum=datum) elif lon is not None: raise OSGRError('%s not %s: %r' % ('lon', None, lon)) elif not name: # use latlon.name name = nameof(latlon) E = _OSGB36.ellipsoid ll = _ll2datum(latlon, _OSGB36, 'latlon') a, b = map1(radians, ll.lat, ll.lon) sa, ca = sincos2(a) s = E.e2s2(sa) # v, r = E.roc2_(sa, _F0); r = v / r v = E.a * _F0 / sqrt(s) # nu r = s / E.e12 # nu / rho == v / (v * E.e12 / s) x2 = r - 1 # η2 ta = tan(a) ca3, ca5 = fpowers(ca, 5, 3) # PYCHOK false! ta2, ta4 = fpowers(ta, 4, 2) # PYCHOK false! vsa = v * sa I4 = (E.b * _F0 * _M(E.Mabcd, a) + _N0, (vsa / 2) * ca, (vsa / 24) * ca3 * fsum_(5, -ta2, 9 * x2), (vsa / 720) * ca5 * fsum_(61, ta4, -58 * ta2)) V4 = (_E0, (v * ca), (v / 6) * ca3 * (r - ta2), (v / 120) * ca5 * fdot((-18, 1, 14, -58), ta2, 5 + ta4, x2, ta2 * x2)) d, d2, d3, d4, d5, d6 = fpowers(b - _B0, 6) # PYCHOK false! n = fdot(I4, 1, d2, d4, d6) e = fdot(V4, 1, d, d3, d5) if Osgr is None: r = EasNor2Tuple(e, n) else: r = Osgr(e, n) if lon is None and isinstance(latlon, _LLEB): r._latlon = latlon # XXX weakref(latlon)? return _xnamed(r, name)
def parseOSGR(strOSGR, Osgr=Osgr, name=''): '''Parse an OSGR coordinate string to an Osgr instance. Accepts standard OS Grid References like 'SU 387 148', with or without whitespace separators, from 2- up to 10-digit references (1 m × 1 m square), or fully numeric, comma-separated references in metres, for example '438700,114800'. @param strOSGR: An OSGR coordinate (C{str}). @keyword Osgr: Optional (sub-)class to return the OSGR coordinate (L{Osgr}) or C{None}. @keyword name: Optional B{C{Osgr}} name (C{str}). @return: The OSGR coordinate (B{C{Osgr}}) or an L{EasNor2Tuple}C{(easting, northing)} if B{C{Osgr}} is C{None}. @raise OSGRError: Invalid B{C{strOSGR}}. @example: >>> g = parseOSGR('TG 51409 13177') >>> str(g) # TG 51409 13177 >>> g = parseOSGR('TG5140913177') >>> str(g) # TG 51409 13177 >>> g = parseOSGR('TG51409 13177') >>> str(g) # TG 51409 13177 >>> g = parseOSGR('651409,313177') >>> str(g) # TG 51409 13177 >>> g.toStr(prec=0) # 651409,313177 ''' def _c2i(G): g = ord(G.upper()) - ord('A') if g > 7: g -= 1 return g def _s2f(g): return float(g.strip()) def _s2i(G, g): g += '00000' # std to meter return int(str(G) + g[:5]) s = strOSGR.strip() try: g = s.split(',') if len(g) == 2: # "easting,northing" if len(s) < 13: raise ValueError # caught below e, n = map(_s2f, g) else: # "GR easting northing" g, s = s[:2], s[2:].strip() e, n = map(_c2i, g) n, m = divmod(n, 5) E = ((e - 2) % 5) * 5 + m N = 19 - (e // 5) * 5 - n if 0 > E or E > 6 or \ 0 > N or N > 12: raise ValueError # caught below g = s.split() if len(g) == 1: # no whitespace e, n = halfs2(s) elif len(g) == 2: e, n = g else: raise ValueError # caught below e = _s2i(E, e) n = _s2i(N, n) except ValueError: raise OSGRError('%s invalid: %r' % ('strOSGR', strOSGR)) r = EasNor2Tuple(e, n) if Osgr is None else Osgr(e, n) return _xnamed(r, name)
def eastingnorthing(self): '''Get easting and northing (L{EasNor2Tuple}C{(easting, northing)}) in C{meter}s. ''' return EasNor2Tuple(self.easting, self.northing)