def toCartesian(self, **Cartesian_h_datum_kwds): # PYCHOK Cartesian=Cartesian '''Convert this n-vector to C{Nvector}-based cartesian (ECEF) coordinates. @kwarg Cartesian_h_datum_kwds: Optional L{Cartesian}, B{C{h}}, B{C{datum}} and other keyword arguments, ignored if B{C{Cartesian=None}}. Use B{C{Cartesian=...}} to override this L{Cartesian} class or specify B{C{Cartesian=None}}. @return: The cartesian point (L{Cartesian}) or if B{C{Cartesian}} is C{None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M} if available. @raise TypeError: Invalid B{C{Cartesian}}, B{C{h}}, B{C{datum}} or other B{C{Cartesian_h_datum_kwds}}. @example: >>> v = Nvector(0.5, 0.5, 0.7071) >>> c = v.toCartesian() # [3194434, 3194434, 4487327] >>> p = c.toLatLon() # 45.0°N, 45.0°E ''' kwds = _xkwds(Cartesian_h_datum_kwds, h=self.h, Cartesian=Cartesian, datum=self.datum) return NvectorBase.toCartesian(self, **kwds) # class or .classof
def meanOf(points, datum=Datums.WGS84, height=None, LatLon=LatLon, **LatLon_kwds): '''Compute the geographic mean of several points. @arg points: Points to be averaged (L{LatLon}[]). @kwarg datum: Optional datum to use (L{Datum}). @kwarg height: Optional height at mean point, overriding the mean height (C{meter}). @kwarg LatLon: Optional class to return the mean point (L{LatLon}) or C{None}. @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments, ignored if B{C{LatLon=None}}. @return: Geographic mean point and mean height (B{C{LatLon}}) or a L{LatLon3Tuple}C{(lat, lon, height)} if B{C{LatLon}} is C{None}. @raise ValueError: Insufficient number of B{C{points}}. ''' _, points = _Nvll.points2(points, closed=False) # geographic mean m = sumOf(p._N_vector for p in points) lat, lon, h = m._N_vector.latlonheight if height is not None: h = height if LatLon is None: r = LatLon3Tuple(lat, lon, h) else: kwds = _xkwds(LatLon_kwds, height=h, datum=datum) r = LatLon(lat, lon, **kwds) return _xnamed(r, meanOf.__name__)
def toLatLon(self, LatLon=None, **LatLon_height_datum_kwds): '''Return the geodetic C{(lat, lon, height[, datum])} coordinates. @kwarg LatLon: Optional class to return C{(lat, lon, height[, datum])} or C{None}. @kwarg LatLon_height_datum_kwds: Optional B{C{LatLon}}, B{C{height}}, B{C{datum}} and other keyword arguments. @return: An instance of C{LatLon}C{(lat, lon, **_height_datum_kwds)} or if B{C{LatLon}} is C{None}, a L{LatLon3Tuple}C{(lat, lon, height)} respectively L{LatLon4Tuple}C{(lat, lon, height, datum)} whether C{datum} is un-/available. @raise TypeError: Invalid B{C{LatLon}} or B{C{LatLon_height_datum_kwds}}. ''' kwds = _xkwds(LatLon_height_datum_kwds, height=self.height, datum=self.datum) # PYCHOK Ecef9Tuple d = kwds['datum'] if LatLon is None: r = LatLon3Tuple(self.lat, self.lon, kwds['height']) # PYCHOK Ecef9Tuple if d: r = r.to4Tuple(d) # checks type(d) else: if d is None: d = kwds.pop['datum'] r = LatLon(self.lat, self.lon, **kwds) # PYCHOK Ecef9Tuple return self._xnamed(r)
def toNvector(self, **Nvector_datum_kwds): # PYCHOK Datums.WGS84 '''Convert this cartesian to L{Nvector} components, I{including height}. @kwarg Nvector_datum_kwds: Optional L{Nvector}, B{C{datum}} and other keyword arguments, ignored if B{C{Nvector=None}}. Use B{C{Nvector=...}} to override this L{Nvector} class or specify B{C{Nvector=None}}. @return: The C{n-vector} components (L{Nvector}) or a L{Vector4Tuple}C{(x, y, z, h)} if B{C{Nvector=None}}. @raise TypeError: Invalid B{C{Nvector}}, B{C{datum}} or other B{C{Nvector_datum_kwds}}. @example: >>> from ellipsoidalNvector import LatLon >>> c = Cartesian(3980581, 97, 4966825) >>> n = c.toNvector() # (0.62282, 0.000002, 0.78237, +0.24) ''' kwds = _xkwds(Nvector_datum_kwds, Nvector=Nvector, datum=self.datum) return CartesianEllipsoidalBase.toNvector(self, **kwds)
def toLatLon(self, datum=None, LatLon=None, **LatLon_kwds): '''Convert this cartesian to a geodetic (lat-/longitude) point. @kwarg datum: Optional datum (L{Datum}) or C{None}. @kwarg LatLon: Optional class to return the geodetic point (C{LatLon}) or C{None}. @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments, ignored if B{C{LatLon=None}}. @return: The geodetic point (B{C{LatLon}}) or if B{C{LatLon}} is C{None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M} if available. @raise TypeError: Invalid B{C{datum}} or B{C{LatLon_kwds}}. ''' if datum in (None, self.datum): r = self.toEcef() else: _xinstanceof(Datum, datum=datum) c = self.convertDatum(datum) r = c.Ecef(c.datum).reverse(c, M=True) if LatLon is not None: # class or .classof r = LatLon(r.lat, r.lon, **_xkwds(LatLon_kwds, datum=r.datum, height=r.height)) _datum_datum(r.datum, datum or self.datum) return self._xnamed(r)
def toLatLon( self, **LatLon_height_datum_kwds): # PYCHOK height=None, LatLon=LatLon '''Convert this n-vector to an C{Nvector}-based geodetic point. @kwarg LatLon_height_datum_kwds: Optional L{LatLon}, B{C{height}}, B{C{datum}} and other keyword arguments, ignored if B{C{LatLon=None}}. Use B{C{LatLon=...}} to override this L{LatLon} class or set B{C{LatLon=None}}. @return: The geodetic point (L{LatLon}) or a L{LatLon3Tuple}C{(lat, lon, height)} if B{C{LatLon}} is C{None}. @raise TypeError: Invalid B{C{LatLon}}, B{C{height}}, B{C{datum}} or other B{C{LatLon_height_datum_kwds}}. @example: >>> v = Nvector(0.5, 0.5, 0.7071) >>> p = v.toLatLon() # 45.0°N, 45.0°E ''' kwds = _xkwds(LatLon_height_datum_kwds, height=self.h, LatLon=LatLon, datum=self.datum) return NvectorBase.toLatLon(self, **kwds) # class or .classof
def toNvector(self, **Nvector_datum_kwds): # PYCHOK signature '''Convert this point to L{Nvector} components, I{including height}. @kwarg Nvector_datum_kwds: Optional L{Nvector}, B{C{datum}} or other keyword arguments, ignored if B{C{Nvector=None}}. Use B{C{Nvector=...}} to override this L{Nvector} class or specify B{C{Nvector=None}}. @return: The C{n-vector} components (L{Nvector}) or a L{Vector4Tuple}C{(x, y, z, h)} if B{C{Nvector}} is C{None}. @raise TypeError: Invalid B{C{Nvector}}, B{C{datum}} or other B{C{Nvector_datum_kwds}}. @example: >>> p = LatLon(45, 45) >>> n = p.toNvector() >>> n.toStr() # [0.50, 0.50, 0.70710] ''' kwds = _xkwds(Nvector_datum_kwds, Nvector=Nvector, datum=self.datum) return LatLonNvectorBase.toNvector(self, **kwds)
def reverse(self, easting, northing, LatLon=None, **LatLon_kwds): '''Convert a Cassini-Soldner location to (ellipsoidal) geodetic lat- and longitude. @arg easting: Easting of the location (C{meter}). @arg northing: Northing of the location (C{meter}). @kwarg LatLon: Optional, ellipsoidal class to return the geodetic location as (C{LatLon}) or C{None}. @kwarg LatLon_kwds: Optional (C{LatLon}) keyword arguments, ignored if B{C{LatLon=None}}. @return: Geodetic location B{C{LatLon}} or if B{C{LatLon}} is C{None}, a L{LatLon2Tuple}C{(lat, lon)}. @raise CSSError: Ellipsoidal mismatch of B{C{LatLon}} and this projection. @raise TypeError: Invalid B{C{LatLon}} or B{C{LatLon_kwds}}. @see: Method L{CassiniSoldner.reverse4}, L{CassiniSoldner.forward} and L{CassiniSoldner.forward4}. ''' r = self.reverse4(easting, northing) if LatLon is None: r = LatLon2Tuple(r.lat, r.lon) # PYCHOK expected else: _xsubclassof(_LLEB, LatLon=LatLon) kwds = _xkwds(LatLon_kwds, datum=self.datum) r = LatLon(r.lat, r.lon, **kwds) # PYCHOK expected self._datumatch(r) return self._xnamed(r)
def toLatLon(self, LatLon, datum=None, **LatLon_kwds): '''Convert this WM coordinate to a geodetic point. @arg LatLon: Ellipsoidal class to return the geodetic point (C{LatLon}). @kwarg datum: Optional datum for ellipsoidal or C{None} for spherical B{C{LatLon}} (C{Datum}). @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments. @return: Point of this WM coordinate (B{C{LatLon}}). @raise TypeError: If B{C{LatLon}} and B{C{datum}} are incompatible or if B{C{datum}} is not ellipsoidal. @example: >>> w = Wm(448251.795, 5411932.678) >>> from pygeodesy import sphericalTrigonometry as sT >>> ll = w.toLatLon(sT.LatLon) # 43°39′11.58″N, 004°01′36.17″E ''' e = issubclassof(LatLon, _LLEB) if e and datum: kwds = _xkwds(LatLon_kwds, datum=datum) elif not (e or datum): # and LatLon kwds = LatLon_kwds datum = None else: raise _TypeError(LatLon=LatLon, datum=datum) r = self.latlon2(datum=datum) r = LatLon(r.lat, r.lon, **kwds) return self._xnamed(r)
def _Vector(x, y, z): n = intersections2.__name__ if Vector is None: v = Vector3d(x, y, z, name=n) else: kwds = _xkwds(Vector_kwds, name=n) v = Vector(x, y, z, **kwds) return v
def _latlon4(t, h, n): if LatLon is None: r = LatLon4Tuple(t.lat, t.lon, h, t.datum) else: kwds = _xkwds(LatLon_kwds, datum=t.datum, height=h) r = LatLon(t.lat, t.lon, **kwds) r._iteration = t.iteration # ._iteration for tests return _xnamed(r, n)
def _toLatLon(self, lat, lon, LatLon, LatLon_kwds): '''(INTERNAL) Check B{C{LatLon}} and return an instance. ''' kwds = _xkwds(LatLon_kwds, datum=self.datum) r = LatLon(lat, lon, **kwds) # handle .classof B = _LLEB if self.datum.isEllipsoidal else _LLB _xinstanceof(B, LatLon=r) return r
def __init__(self, *args, **kwds): if args: # args override kwds if len(args) != 1: t = unstr(self.classname, *args, **kwds) raise _ValueError(args=len(args), txt=t) kwds = _xkwds(dict(args[0]), **kwds) if _name_ in kwds: _Named.name.fset(self, kwds.pop(_name_)) # see _Named.name dict.__init__(self, kwds)
def _latlon3(lat, lon, height, func, LatLon, **LatLon_kwds): '''(INTERNAL) Helper for L{intersection} and L{meanof}. ''' if LatLon is None: r = LatLon3Tuple(lat, lon, height) else: kwds = _xkwds(LatLon_kwds, height=height) r = LatLon(lat, lon, **kwds) return _xnamed(r, func.__name__)
def toWm(latlon, lon=None, radius=R_MA, Wm=Wm, name='', **Wm_kwds): '''Convert a lat-/longitude point to a WM coordinate. @arg latlon: Latitude (C{degrees}) or an (ellipsoidal or spherical) geodetic C{LatLon} point. @kwarg lon: Optional longitude (C{degrees} or C{None}). @kwarg radius: Optional earth radius (C{meter}). @kwarg Wm: Optional class to return the WM coordinate (L{Wm}) or C{None}. @kwarg name: Optional name (C{str}). @kwarg Wm_kwds: Optional, additional B{C{Wm}} keyword arguments, ignored if B{C{Wm=None}}. @return: The WM coordinate (B{C{Wm}}) or an L{EasNorRadius3Tuple}C{(easting, northing, radius)} if B{C{Wm}} is C{None}. @raise ValueError: If B{C{lon}} value is missing, if B{C{latlon}} is not scalar, if B{C{latlon}} is beyond the valid WM range and L{rangerrors} is set to C{True} or if B{C{radius}} is invalid. @example: >>> p = LatLon(48.8582, 2.2945) # 448251.8 5411932.7 >>> w = toWm(p) # 448252 5411933 >>> p = LatLon(13.4125, 103.8667) # 377302.4 1483034.8 >>> w = toWm(p) # 377302 1483035 ''' e, r = None, Radius(radius) try: lat, lon = latlon.lat, latlon.lon if isinstance(latlon, _LLEB): r = latlon.datum.ellipsoid.a e = latlon.datum.ellipsoid.e if not name: # use latlon.name name = nameof(latlon) lat = clipDegrees(lat, _LatLimit) except AttributeError: lat, lon = parseDMS2(latlon, lon, clipLat=_LatLimit) s = sin(radians(lat)) y = atanh(s) # == log(tan((90 + lat) / 2)) == log(tanPI_2_2(radians(lat))) if e: y -= e * atanh(e * s) e, n = r * radians(lon), r * y if Wm is None: r = EasNorRadius3Tuple(e, n, r) else: kwds = _xkwds(Wm_kwds, radius=r) r = Wm(e, n, **kwds) return _xnamed(r, name)
def _latlon5(self, LatLon, **LatLon_kwds): '''(INTERNAL) Convert cached LatLon ''' ll = self._latlon if LatLon is None: r = LatLonDatum5Tuple(ll.lat, ll.lon, ll.datum, ll.convergence, ll.scale) else: _xsubclassof(_LLEB, LatLon=LatLon) kwds = _xkwds(LatLon_kwds, datum=ll.datum) r = _xattrs(LatLon(ll.lat, ll.lon, **kwds), ll, '_convergence', '_scale') return _xnamed(r, ll.name)
def toMgrs(utm, Mgrs=Mgrs, name=NN, **Mgrs_kwds): '''Convert a UTM coordinate to an MGRS grid reference. @arg utm: A UTM coordinate (L{Utm} or L{Etm}). @kwarg Mgrs: Optional class to return the MGRS grid reference (L{Mgrs}) or C{None}. @kwarg name: Optional B{C{Mgrs}} name (C{str}). @kwarg Mgrs_kwds: Optional, additional B{C{Mgrs}} keyword arguments, ignored if B{C{Mgrs=None}}. @return: The MGRS grid reference (B{L{Mgrs}}) or an L{Mgrs6Tuple}C{(zone, digraph, easting, northing, band, datum)} if B{L{Mgrs}} is C{None}. @raise TypeError: If B{C{utm}} is not L{Utm} nor L{Etm}. @raise MGRSError: Invalid B{C{utm}}. @example: >>> u = Utm(31, 'N', 448251, 5411932) >>> m = u.toMgrs() # 31U DQ 48251 11932 ''' _xinstanceof(Utm, utm=utm) # Utm, Etm e, n = utm.to2en(falsed=True) # truncate east-/northing to within 100 km grid square # XXX add rounding to nm precision? E, e = divmod(e, _100km) N, n = divmod(n, _100km) # columns in zone 1 are A-H, zone 2 J-R, zone 3 S-Z, then # repeating every 3rd zone (note -1 because eastings start # at 166e3 due to 500km false origin) z = utm.zone - 1 en = ( _Le100k[z % 3][int(E) - 1] + # rows in even zones are A-V, in odd zones are F-E _Ln100k[z % 2][int(N) % len(_Ln100k[0])]) if Mgrs is None: r = Mgrs4Tuple(utm.zone, en, e, n).to6Tuple(utm.band, utm.datum) else: kwds = _xkwds(Mgrs_kwds, band=utm.band, datum=utm.datum) r = Mgrs(utm.zone, en, e, n, **kwds) return _xnamed(r, name or utm.name)
def toLatLon(self, **LatLon_datum_kwds): # PYCHOK LatLon=LatLon '''Convert this cartesian point to an C{Nvector}-based geodetic point. @kwarg LatLon_datum_kwds: Optional L{LatLon}, B{C{datum}} and other keyword arguments, ignored if B{C{LatLon=None}}. Use B{C{LatLon=...}} to override this L{LatLon} class or specify B{C{LatLon=None}}. @return: The geodetic point (L{LatLon}) or if B{C{LatLon}} is C{None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M} if available. @raise TypeError: Invalid B{C{LatLon_datum_kwds}}. ''' kwds = _xkwds(LatLon_datum_kwds, LatLon=LatLon, datum=self.datum) return CartesianSphericalBase.toLatLon(self, **kwds)
def toCartesian(self, **Cartesian_datum_kwds): # PYCHOK Cartesian=Cartesian, datum=None '''Convert this point to C{Karney}-based cartesian (ECEF) coordinates. @kwarg Cartesian_datum_kwds: Optional L{Cartesian}, B{C{datum}} and other keyword arguments, ignored if B{C{Cartesian=None}}. Use B{C{Cartesian=...}} to override this L{Cartesian} class or specify B{C{Cartesian=None}}. @return: The cartesian point (L{Cartesian}) or if B{C{Cartesian}} is C{None}, an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with C{C} and C{M} if available. @raise TypeError: Invalid B{C{Cartesian_datum_kwds}}. ''' kwds = _xkwds(Cartesian_datum_kwds, Cartesian=Cartesian, datum=self.datum) return LatLonSphericalBase.toCartesian(self, **kwds)
def __init__(self, **kwds): # PYCHOK no *args kwds = _xkwds(kwds, **_Neighbors8Defaults) _NamedDict.__init__(self, **kwds) # name=...
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)