Beispiel #1
0
    def __new__(cls, cll, precision=3, name=''):
        '''New L{Georef} from an other L{Georef} instance or georef
           C{str} or from a C{LatLon} instance or lat-/longitude C{str}.

           @param cll: Cell or location (L{Georef} or C{str}, C{LatLon}
                       or C{str}).
           @keyword precision: Optional, the desired georef resolution
                               and length (C{int} 0..11), see function
                               L{wgrs.encode} for more details.
           @keyword name: Optional name (C{str}).

           @return: New L{Georef}.

           @raise RangeError: Invalid B{C{cll}} lat- or longitude.

           @raise TypeError: Invalid B{C{cll}}.

           @raise ValueError: INValid or non-alphanumeric B{C{cll}}.
        '''
        if isinstance(cll, Georef):
            g, p = _2geostr2(str(cll))
            self = str.__new__(cls, g)
            self._latlon = LatLon2Tuple(*cll._latlon)
            self._name = cll._name
            self._precision = p  # cll._precision

        elif isinstance(cll, _Strs):
            if ',' in cll:
                lat, lon, h = _2fllh(*parse3llh(cll, height=None))
                g = encode(lat, lon, precision=precision, height=h)  # PYCHOK false
                self = str.__new__(cls, g)
                self._latlon = LatLon2Tuple(lat, lon)
                self._precision = precision
                if h not in (None, _MISSING):
                    self._height = h
            else:
                self = str.__new__(cls, cll.upper())
                self._decode()

        else:  # assume LatLon
            try:
                lat, lon, h = _2fllh(cll.lat, cll.lon)
                h = getattr(cll, 'height', h)
            except AttributeError:
                raise TypeError('%s: %r' % (Georef.__name__, cll))
            g = encode(lat, lon, precision=precision, height=h)  # PYCHOK false
            self = str.__new__(cls, g)
            self._latlon = LatLon2Tuple(lat, lon)
            self._precision = precision
            if h not in (None, _MISSING):
                self._height = h

        if name:
            self.name = name
        return self
Beispiel #2
0
 def _decode(self):
     # cache all decoded attrs
     lat, lon, p = decode3(self)
     if self._latlon is None:
         self._latlon = LatLon2Tuple(lat, lon)
     if self._precision is None:
         self._precision = p
Beispiel #3
0
 def sizes(self):
     '''Get the lat- and longitudinal size of this cell as
        a L{LatLon2Tuple}C{(lat, lon)} with the latitudinal
        height and longitudinal width in (C{meter}).
     '''
     n = min(len(_Sizes) - 1, self.precision or 1)
     return LatLon2Tuple(*map2(float, _Sizes[n][:2]))
Beispiel #4
0
 def _reverse4(self):
     '''(INTERNAL) Convert to geodetic location.
     '''
     r = self.cs0.reverse4(self.easting, self.northing)
     self._latlon = LatLon2Tuple(r.lat, r.lon)
     self._azi, self._rk = r.azimuth, r.reciprocal
     return r  # LatLonAziRk4Tuple
Beispiel #5
0
 def _decode(self):
     # cache all decoded attrs
     lat, lon, p, h, r = decode5(self)  # PYCHOK LatLonPrec5Tuple
     if self._latlon is None:
         self._latlon = LatLon2Tuple(lat, lon)
     if self._precision is None:
         self._precision = p
     if self._height is _MISSING:
         self._height = h
     if self._radius is _MISSING:
         self._radius = r
Beispiel #6
0
def antipode(lat, lon):
    '''Return the antipode, the point diametrically opposite
       to a given point.

       @param lat: Latitude (C{degrees}).
       @param lon: Longitude (C{degrees}).

       @return: A L{LatLon2Tuple}C{(lat, lon)}.

       @see: U{Geosphere<https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
    '''
    return LatLon2Tuple(-wrap90(lat), wrap180(lon + 180))
Beispiel #7
0
    def to2ll(self):
        '''Convert this vector to (geodetic) lat- and longitude.

           @return: A L{LatLon2Tuple}C{(lat, lon)}.

           @example:

           >>> v = Vector3d(0.500, 0.500, 0.707)
           >>> a, b = v.to2ll()  # 44.99567, 45.0
        '''
        a, b = self.to2ab()
        r = LatLon2Tuple(degrees90(a), degrees180(b))
        return self._xnamed(r)
Beispiel #8
0
    def latlon2(self, ndigits=0):
        '''Return this point's lat- and longitude, rounded.

           @keyword ndigits: Number of decimal digits (C{int}).

           @return: A L{LatLon2Tuple}C{(lat, lon)}, both rounded
                    away from zero.

           @see: Built-in function C{round}.
        '''
        r = LatLon2Tuple(round(self.lat, ndigits),
                         round(self.lon, ndigits))
        return self._xnamed(r)
Beispiel #9
0
    def reset(self, lat0, lon0):
        '''Set the center point of this projection.

           @param lat0: Latitude of center point (C{degrees90}).
           @param lon0: Longitude of center point (C{degrees180}).
        '''
        g, M = self.datum.ellipsoid._geodesic2

        self._meridian = m = g.Line(lat0, lon0, 0.0,
                                    g.STANDARD | g.DISTANCE_IN)
        self._latlon0 = LatLon2Tuple(m.lat1, m.lon1)
        s, c = M.sincosd(m.lat1)  # == self.lat0 == self..LatitudeOrigin()
        self._sb0, self._cb0 = M.norm(s * (1.0 - g.f), c)
Beispiel #10
0
def toCss(latlon, cs0=_CassiniSoldner0, height=None, Css=Css, name=''):
    '''Convert an (ellipsoidal) geodetic point to a Cassini-Soldner location.

       @param latlon: Ellipsoidal point (C{LatLon}).
       @keyword cs0: Optional, the Cassini-Soldner projection to use
                     (L{CassiniSoldner}).
       @keyword height: Optional height for the point, overriding
                        the default height (C{meter}).
       @keyword Css: Optional (sub-)class to return the location
                     (L{Css}) or C{None}.
       @keyword name: Optional B{C{Css}} name (C{str}).

       @return: The Cassini-Soldner location (B{C{Css}}) or an
                L{EasNor3Tuple}C{(easting, northing, height)}
                if B{C{Css}} is C{None}.

       @raise ImportError: Package U{GeographicLib<https://PyPI.org/
                           project/geographiclib>} missing.

       @raise TypeError: If B{C{latlon}} is not ellipsoidal.
    '''
    if not isinstance(latlon, _LLEB):
        raise TypeError('%s not %s: %r' % ('latlon', 'ellipsoidal', latlon))

    cs = _CassiniSoldner(cs0)

    C, E = cs.datum.ellipsoid, latlon.datum.ellipsoid
    if C != E:
        raise ValueError('%s mistmatch: %r vs %r' % ('ellipsoidal', C, E))

    c = cs.forward4(latlon.lat, latlon.lon)
    h = latlon.height if height is None else height

    if Css is None:
        r = EasNor3Tuple(c.easting, c.northing, h)
    else:
        r = Css(c.easting, c.northing, h=h, cs0=cs)
        r._latlon = LatLon2Tuple(latlon.lat, latlon.lon)
        r._azi, r._rk = c.azimuth, c.reciprocal
    return _xnamed(r, name or nameof(latlon))
Beispiel #11
0
def parseDMS2(strLat, strLon, sep=S_SEP, clipLat=90, clipLon=180):
    '''Parse lat- and longitude representions.

       @param strLat: Latitude in any of several forms (C{str} or C{degrees}).
       @param strLon: Longitude in any of several forms (C{str} or C{degrees}).
       @keyword sep: Optional separator between deg°, min′ and sec″ ('').
       @keyword clipLat: Keep latitude in B{C{-clipLat..+clipLat}} range (C{degrees}).
       @keyword clipLon: Keep longitude in B{C{-clipLon..+clipLon}} range (C{degrees}).

       @return: A L{LatLon2Tuple}C{(lat, lon)} in C{degrees}.

       @raise RangeError: Value of B{C{strLat}} or B{C{strLon}} outside the
                          valid range and L{rangerrors} set to C{True}.

       @raise ValueError: Invalid B{C{strLat}} or B{C{strLon}}.

       @see: Function L{parse3llh} to parse a string with lat-,
             longitude and height values and function L{parseDMS}
             to parse individual lat- or longitudes.
    '''
    return LatLon2Tuple(parseDMS(strLat, suffix='NS', sep=sep, clip=clipLat),
                        parseDMS(strLon, suffix='EW', sep=sep, clip=clipLon))
Beispiel #12
0
def decode_error(geohash):
    '''Return the relative lat-/longitude decoding errors for
       this geohash.

       @param geohash: To be decoded (L{Geohash}).

       @return: A L{LatLon2Tuple}C{(lat, lon)} with the lat- and
                longitudinal errors in (C{degrees}).

       @raise TypeError: The B{C{geohash}} is not a L{Geohash},
                         C{LatLon} or C{str}.

       @raise ValueError: Invalid or null B{C{geohash}}.

       @example:

       >>> geohash.decode_error('u120fxw')  # 0.00068665, 0.00068665
       >>> geohash.decode_error('fur')  # 0.703125, 0.703125
       >>> geohash.decode_error('fu')  # 2.8125, 5.625
       >>> geohash.decode_error('f')  # 22.5, 22.5
    '''
    s, w, n, e = bounds(geohash)
    return LatLon2Tuple((n - s) * 0.5, (e - w) * 0.5)
Beispiel #13
0
    def reverse(self, easting, northing, LatLon=None):
        '''Convert a Cassini-Soldner location to (ellipsoidal) geodetic
           lat- and longitude.

           @param easting: Easting of the location (C{meter}).
           @param northing: Northing of the location (C{meter}).
           @keyword LatLon: Optional, ellipsoidal (sub-)class to return
                            the location as (C{LatLon}) or C{None}.

           @return: Geodetic location B{C{LatLon}} or a
                    L{LatLon2Tuple}C{(lat, lon)} if
                    B{C{LatLon}} is C{None}.

           @raise TypeError: If B{C{LatLon}} is not ellipsoidal.
        '''
        a, b = self.reverse4(easting, northing)[:2]
        if LatLon is None:
            r = LatLon2Tuple(a, b)
        elif issubclassof(LatLon, _LLEB):
            r = LatLon(a, b, datum=self.datum)
        else:
            raise TypeError('%s not ellipsoidal: %r' % ('LatLon', LatLon))
        return self._xnamed(r)
Beispiel #14
0
    def to2ll(self, datum=None):
        '''Convert this WM coordinate to a geodetic lat- and longitude.

           @keyword datum: Optional datum (C{Datum}).

           @return: A L{LatLon2Tuple}C{(lat, lon)}.

           @raise TypeError: Non-ellipsoidal B{C{datum}}.
        '''
        r = self.radius
        x = self._x / r
        y = 2 * atan(exp(self._y / r)) - PI_2
        if datum:
            E = datum.ellipsoid
            if not E.isEllipsoidal:
                raise TypeError('%s not %s: %r' % ('datum', 'ellipsoidal', datum))
            # <https://Earth-Info.NGA.mil/GandG/wgs84/web_mercator/
            #       %28U%29%20NGA_SIG_0011_1.0.0_WEBMERC.pdf>
            y = y / r
            if E.e:
                y -= E.e * atanh(E.e * tanh(y))
            y *= E.a
            x *= E.a / r
        return self._xnamed(LatLon2Tuple(degrees90(y), degrees180(x)))
Beispiel #15
0
 def latlon(self):
     '''Get the lat- and longitude (L{LatLon2Tuple}).
     '''
     if self._latlon is None:
         self._latlon = LatLon2Tuple(self._lat, self._lon)
     return self._xrenamed(self._latlon)