Esempio n. 1
0
    def __init__(self, e, n, h=0, conic=Conics.WRF_Lb, name=''):
        '''New L{Lcc} Lamber conformal conic position.

           @param e: Easting (C{meter}).
           @param n: Northing (C{meter}).
           @keyword h: Optional height (C{meter}).
           @keyword conic: Optional, the conic projection (L{Conic}).
           @keyword name: Optional name (C{str}).

           @return: The Lambert location (L{Lcc}).

           @raise TypeError: If B{C{conic}} is not L{Conic}.

           @raise LCCError: Invalid or negative B{C{e}} or B{C{n}}.

           @example:

           >>> lb = Lcc(448251, 5411932.0001)
        '''
        _TypeError(Conic, conic=conic)
        self._conic = conic
        self._easting  = false2f(e, 'easting',  false=conic.E0 > 0, Error=LCCError)
        self._northing = false2f(n, 'northing', false=conic.N0 > 0, Error=LCCError)
        if h:
            self._height = float(h)
        if name:
            self.name = name
Esempio n. 2
0
    def __init__(self,
                 latlonh0=0,
                 lon0=0,
                 height0=0,
                 ecef=EcefKarney(Datums.WGS84),
                 name=''):
        '''New L{EcefCartesian} converter.

           @keyword latlonh0: Either a C{LatLon}, an L{Ecef9Tuple} or C{scalar}
                              latitude in C{degrees} of the cartesian origin.
           @keyword lon0: Optional C{scalar} longitude of the cartesian origin
                          in C{degrees} for C{scalar} B{C{latlonh0}}.
           @keyword height0: Optional height of the cartesian origin in C{meter},
                             vertically above (or below) the surface of the
                             ellipsoid.
           @keyword ecef: An EXEC converter (L{EcefKarney}).
           @keyword name: Optional name (C{str}).

           @raise EcefError: If B{C{latlonh0}} not C{LatLon}, L{Ecef9Tuple} or
                             C{scalar} or B{C{lon0}} not C{scalar} for C{scalar}
                             B{C{latlonh0}} or C{abs(B{lat0})} exceeds 90°.

           @raise TypeError: Invalid B{C{ecef}}, not L{EcefKarney}.
        '''
        _TypeError(EcefKarney, ecef=ecef)
        self._ecef = ecef
        self.reset(latlonh0, lon0, height0, name=name)
Esempio n. 3
0
    def convertDatum(self, datum2, datum):
        '''Convert this Cartesian point from one to an other datum.

           @param datum2: Datum to convert I{to} (L{Datum}).
           @param datum: Datum to convert I{from} (L{Datum}).

           @return: The converted Cartesian point (C{Cartesian}).

           @raise TypeError: B{C{datum2}} or B{C{datum}} not a
                             L{Datum}.
        '''
        _TypeError(Datum, datum2=datum2, datum=datum)

        if datum == datum2:
            return self.copy()

        elif datum == Datums.WGS84:
            # converting from WGS 84
            c, d, i = self, datum2, False

        elif datum2 == Datums.WGS84:
            # converting to WGS84, use inverse transform
            c, d, i = self, datum, True

        else:  # neither datum2 nor datum is WGS84, convert to WGS84 first
            c, d, i = self._applyHelmert(datum.transform, True), datum2, False

        return c._applyHelmert(d.transform, i)
Esempio n. 4
0
    def toUtmUps(self, pole=''):
        '''Convert this C{LatLon} point to a UTM or UPS coordinate.

           @keyword pole: Optional top/center of UPS (stereographic)
                          projection (C{str}, 'N[orth]' or 'S[outh]').

           @return: The UTM or UPS coordinate (L{Utm} or L{Ups}).

           @raise TypeError: Result in L{Utm} or L{Ups}.

           @see: Function L{toUtmUps}.
        '''
        if self._utm:
            u = self._utm
        elif self._ups and (self._utm.pole == pole or not pole):
            u = self._ups
        else:
            from pygeodesy.utmups import toUtmUps8, Utm, Ups  # PYCHOK recursive import
            u = toUtmUps8(self, datum=self.datum, Utm=Utm, Ups=Ups, pole=pole)
            if isinstance(u, Utm):
                self._utm = u
            elif isinstance(u, Ups):
                self._ups = u
            else:
                _TypeError(Utm, Ups, toUtmUps8=u)
        return u
Esempio n. 5
0
    def convertDatum(self, datum2, datum=None):
        '''Convert this cartesian point from one to an other datum.

           @param datum2: Datum to convert I{to} (L{Datum}).
           @keyword datum: Datum to convert I{from} (L{Datum}).

           @return: The converted point (C{Cartesian}).

           @raise TypeError: B{C{datum2}} or B{C{datum}} not a
                             L{Datum}.
        '''
        _TypeError(Datum, datum2=datum2)

        if datum and self.datum != datum:
            c = self.convertDatum(datum)
        else:
            c = self

        i, d = False, c.datum
        if d == datum2:
            return c.copy() if c is self else c

        elif d == Datums.WGS84:
            d = datum2  # convert from WGS84 to datum2

        elif datum2 == Datums.WGS84:
            i = True  # convert to WGS84 by inverse transform

        else:  # neither datum2 nor c.datum is WGS84, invert to WGS84 first
            c = c._applyHelmert(d.transform, True)
            d = datum2

        return c._applyHelmert(d.transform, i, datum=datum2)
Esempio n. 6
0
    def convertRefFrame(self, reframe2, reframe, epoch=None):
        '''Convert this Cartesian point from one to an other reference frame.

           @param reframe2: Reference frame to convert I{to} (L{RefFrame}).
           @param reframe: Reference frame to convert I{from} (L{RefFrame}).
           @keyword epoch: Optional epoch to observe for B{C{reframe}}, a
                           fractional calendar year (C{scalar}).

           @return: The converted Cartesian point (C{Cartesian}) or
                    this Cartesian point if conversion is C{nil}.

           @raise TRFError: No conversion available from
                                 B{C{reframe}} to B{C{reframe2}}.

           @raise TypeError: B{C{reframe2}} or B{C{reframe}} not a
                             L{RefFrame} or B{C{epoch}} not C{scalar}.
        '''
        _TypeError(RefFrame, reframe2=reframe2, reframe=reframe)

        c = self
        for t in _reframeTransforms(
                reframe2, reframe,
                reframe.epoch if epoch is None else _2epoch(epoch)):
            c = c._applyHelmert(t, False)
        return c
Esempio n. 7
0
    def toLatLon(self, datum=None, LatLon=None, **kwds):
        '''Convert this cartesian point to a geodetic point.

           @keyword datum: Optional datum (L{Datum}) or C{None}.
           @keyword LatLon: Optional (sub-)class to return the
                            geodetic point (C{LatLon}) or C{None}.
           @keyword kwds: Optional, additional B{C{LatLon}} keyword
                          arguments, ignored if C{B{LatLon}=None}.

           @return: The B{C{LatLon}} point or if C{B{LatLon}=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{kwds}}.
        '''
        c = self
        if datum is not None:
            _TypeError(Datum, datum=datum)
            if datum != self.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, height=r.height, datum=c.datum, **kwds)
        return self._xnamed(r)
    def latlon(self, latlonh):
        '''Set the lat- and longitude and optionally the height.

           @param latlonh: New lat-, longitude and height (2- or
                           3-tuple of C{degrees} and C{meter}).

           @raise TypeError: Height of B{C{latlonh}} not C{scalar} or
                             B{C{latlonh}} not C{list} or C{tuple}.

           @raise ValueError: Invalid B{C{latlonh}} or M{len(latlonh)}.

           @see: Function L{parse3llh} to parse a B{C{latlonh}} string
                 into a 3-tuple (lat, lon, h).
        '''
        _TypeError(list, tuple, latlonh=latlonh)

        if len(latlonh) == 3:
            h = scalar(latlonh[2], None, name='latlonh')
        elif len(latlonh) != 2:
            raise ValueError('%s invalid: %r' % ('latlonh', latlonh))
        else:
            h = self._height

        lat, lon = parseDMS2(latlonh[0], latlonh[1])
        self._update(lat != self._lat or lon != self._lon or h != self._height)
        self._lat, self._lon, self._height = lat, lon, h
    def convertRefFrame(self, reframe2):
        '''Convert this point to an other reference frame.

           @param reframe2: Reference frame to convert I{to} (L{RefFrame}).

           @return: The converted point (ellipsoidal C{LatLon}) or
                    this point if conversion is C{nil}.

           @raise TRFError: No B{C{.reframe}} or no conversion
                            available from B{C{.reframe}} to
                            B{C{reframe2}}.

           @raise TypeError: The B{C{reframe2}} is not a L{RefFrame}.

           @example:

           >>> p = LatLon(51.4778, -0.0016, reframe=RefFrames.ETRF2000)  # default Datums.WGS84
           >>> p.convertRefFrame(RefFrames.ITRF2014)  # 51.477803°N, 000.001597°W, +0.01m
        '''
        _TypeError(RefFrame, reframe2=reframe2)

        if not self.reframe:
            raise TRFError('no %r.%s' % (self, 'reframe'))

        ts = _reframeTransforms(reframe2, self.reframe, self.epoch)
        if ts:
            c = self.toCartesian()
            for t in ts:
                c = c._applyHelmert(t, False)
            ll = c.toLatLon(datum=self.datum, LatLon=self.classof,
                            epoch=self.epoch, reframe=reframe2)
            # ll.reframe, ll.epoch = reframe2, self.epoch
        else:
            ll = self
        return ll
Esempio n. 10
0
def nearestOn2(point, points, closed=False, radius=R_M, height=None):
    '''Locate the point on a polygon (with great circle arcs
       joining consecutive points) closest to an other point.

       If the given point is within the extent of any great circle
       arc, the closest point is on that arc.  Otherwise, the
       closest is the nearest of the arc's end points.

       @param point: The other, reference point (L{LatLon}).
       @param points: The polygon points (L{LatLon}[]).
       @keyword closed: Optionally, close the polygon (C{bool}).
       @keyword radius: Mean earth radius (C{meter}).
       @keyword height: Optional height, overriding the mean height
                        for a point within the arc (C{meter}).

       @return: 2-Tuple C{(closest, distance)} of the closest point
                (L{LatLon}) on the polygon and the C{distance} from
                the C{closest} to the other B{C{point}} in C{meter},
                same units as B{C{radius}}.

       @raise TypeError: Some B{C{points}} or B{C{point}} not C{LatLon}.

       @raise ValueError: No B{C{points}}.
    '''
    _TypeError(LatLon, point=point)

    return point.nearestOn2(points, closed=closed, radius=radius, height=height)
Esempio n. 11
0
    def __init__(self,
                 latlon0,
                 par1,
                 par2=None,
                 E0=0,
                 N0=0,
                 k0=1,
                 opt3=0,
                 name='',
                 auth=''):
        '''New Lambert conformal conic projection.

           @param latlon0: Origin with (ellipsoidal) datum (C{LatLon}).
           @param par1: First standard parallel (C{degrees90}).
           @keyword par2: Optional, second standard parallel (C{degrees90}).
           @keyword E0: Optional, false easting (C{meter}).
           @keyword N0: Optional, false northing (C{meter}).
           @keyword k0: Optional scale factor (C{scalar}).
           @keyword opt3: Optional meridian (C{degrees180}).
           @keyword name: Optional name of the conic (C{str}).
           @keyword auth: Optional authentication authority (C{str}).

           @return: A Lambert projection (L{Conic}).

           @raise TypeError: Non-ellipsoidal B{C{latlon0}}.

           @example:

           >>> from pygeodesy import Conic, Datums, ellipsoidalNvector
           >>> ll0 = ellipsoidalNvector.LatLon(23, -96, datum=Datums.NAD27)
           >>> Snyder = Conic(ll0, 33, 45, E0=0, N0=0, name='Snyder')
        '''
        if latlon0 is not None:
            _TypeError(_LLEB, latlon0=latlon0)

            self._lat0, self._lon0 = latlon0.to2ab()
            self._par1 = radians(par1)
            if par2 is None:
                self._par2 = self._par1
            else:
                self._par2 = radians(par2)
            self._opt3 = radians(opt3)

            if k0 != 1:
                self._k0 = float(k0)
            if N0:
                self._N0 = float(N0)
            if E0:
                self._E0 = float(E0)

            self.toDatum(latlon0.datum)._dup2(self)
            self._register(Conics, name)
        elif name:
            self._name = name
        if auth:
            self._auth = auth
Esempio n. 12
0
    def exactTM(self, exactTM):
        '''Set the ETM projection (L{ExactTransverseMercator}).
        '''
        _TypeError(ExactTransverseMercator, exactTM=exactTM)

        E = self.datum.ellipsoid
        if exactTM._E != E or exactTM.majoradius != E.a \
                           or exactTM.flattening != E.f:
            raise ETMError('%r vs %r' % (exactTM, E))
        self._exactTM = exactTM
        self._scale0  = exactTM.k0
Esempio n. 13
0
def _CassiniSoldner(cs0):
    '''(INTERNAL) Get/set default projection.
    '''
    if cs0 is None:
        global _CassiniSoldner0
        if _CassiniSoldner0 is None:
            _CassiniSoldner0 = CassiniSoldner(0, 0, name='Default')
        cs0 = _CassiniSoldner0
    else:
        _TypeError(CassiniSoldner, cs0=cs0)
    return cs0
Esempio n. 14
0
    def reframe(self, reframe):
        '''Set or clear this point's reference frame.

           @param reframe: Reference frame (L{RefFrame}) or C{None}.

           @raise TypeError: The B{C{reframe}} is not a L{RefFrame}.
        '''
        if isinstance(reframe, RefFrame):
            self._reframe = reframe
        elif reframe is not None:
            _TypeError(RefFrame, reframe=reframe)
        elif self.reframe is not None:
            self._reframe = None
Esempio n. 15
0
    def datum(self, datum):
        '''Set this point's datum I{without conversion}.

           @param datum: New datum (L{Datum}).

           @raise TypeError: The B{C{datum}} is not a L{Datum}
                             or not ellipsoidal.
        '''
        _TypeError(Datum, datum=datum)
        if not datum.isEllipsoidal:
            raise _IsNotError('ellipsoidal', datum=datum)
        self._update(datum != self._datum)
        self._datum = datum
Esempio n. 16
0
def _to4lldn(latlon, lon, datum, name):
    '''(INTERNAL) Return 4-tuple (C{lat, lon, datum, name}).
    '''
    try:
        # if lon is not None:
        #     raise AttributeError
        lat, lon = latlon.lat, latlon.lon
        _TypeError(_LLEB, LatLonDatum5Tuple, latlon=latlon)
        d = datum or latlon.datum
    except AttributeError:
        lat, lon = parseDMS2(latlon, lon)
        d = datum or Datums.WGS84
    return lat, lon, d, (name or nameof(latlon))
Esempio n. 17
0
    def datum(self, datum):
        '''Set this point's datum without conversion.

           @param datum: New datum (L{Datum}).

           @raise TypeError: If B{C{datum}} is not a L{Datum}.

           @raise ValueError: If B{C{datum}} is not spherical.
        '''
        _TypeError(Datum, datum=datum)
        if not datum.isSpherical:
            raise ValueError('%r not %s: %r' % ('datum', 'spherical', datum))
        self._update(datum != self._datum)
        self._datum = datum
Esempio n. 18
0
    def datum(self, datum):
        '''Set this geocentric point's C{datum} I{without conversion}.

           @param datum: New datum (L{Datum}).

           @raise TypeError: The B{C{datum}} is not a L{Datum}.
        '''
        _TypeError(Datum, datum=datum)
        d = self.datum
        if d is not None:
            if d.isEllipsoidal and not datum.isEllipsoidal:
                raise _IsNotError('ellipsoidal', datum=datum)
            elif d.isSpherical and not datum.isSpherical:
                raise _IsNotError('spherical', datum=datum)
        self._update(datum != d)
        self._datum = datum
Esempio n. 19
0
    def multiply(self, other):
        '''Matrix multiply M{M0' ⋅ M} this matrix transposed with
           an other matrix.

           @param other: The other matrix (L{EcefMatrix}).

           @return: The matrix product (L{EcefMatrix}).

           @raise TypeError: If B{C{other}} is not L{EcefMatrix}.
        '''
        _TypeError(EcefMatrix, other=other)

        # like LocalCartesian.MatrixMultiply, transposed(self) x other
        # <https://GeographicLib.SourceForge.io/html/LocalCartesian_8cpp_source.html>
        M = (fdot(self[r::3], *other[c::3]) for r in range(3) for c in range(3))
        return EcefMatrix(*M)
Esempio n. 20
0
    def datum(self, datum):
        '''Set the datum and ellipsoid (L{Datum}).

           @raise EllipticError: No convergence.

           @raise TypeError: Invalid B{C{datum}}.
        '''
        _TypeError(Datum, datum=datum)

        E = datum.ellipsoid
        self._reset(E.e, E.e2)
        self._a = E.a
        self._f = E.f  # flattening = (a - b) / a

        self._datum = datum
        self._E     = E
Esempio n. 21
0
    def __init__(self, epoch, ellipsoid, name=''):
        '''New L{RefFrame}.

           @param epoch: Epoch, a fractional calendar year (C{scalar}).
           @param ellipsoid: The ellipsoid (L{Ellipsoid}).
           @keyword name: Optional, unique name (C{str}).

           @raise NameError: A L{RefFrame} with that B{C{name}}
                             already exists.

           @raise TypeError: If B{C{epoch}} is not C{scalar} or
                             B{C{ellipsoid}} is not an L{Ellipsoid}.
        '''
        _TypeError(Ellipsoid, ellipsoid=ellipsoid)
        self._ellipsoid = ellipsoid
        self._epoch = _2epoch(epoch)
        self._register(RefFrames, name)
Esempio n. 22
0
def toMgrs(utm, Mgrs=Mgrs, name=''):
    '''Convert a UTM coordinate to an MGRS grid reference.

       @param utm: A UTM coordinate (L{Utm} or L{Etm}).
       @keyword Mgrs: Optional (sub-)class to return the MGRS
                      grid reference (L{Mgrs}) or C{None}.
       @keyword name: Optional B{C{Mgrs}} name (C{str}).

       @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
    '''
    _TypeError(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 = Mgrs6Tuple(utm.zone, en, e, n, utm.band, utm.datum)
    else:
        r = Mgrs(utm.zone, en, e, n, band=utm.band, datum=utm.datum)
    return _xnamed(r, name or utm.name)
Esempio n. 23
0
    def __new__(cls, eisu):
        '''New L{Epsg} European Petroleum Survey Group (EPSG) code from
           a UTM/USP coordinate or other EPSG code.

           @param eisu: Other (L{Epsg}, C{int}, C{str}, L{Utm} or L{Ups}).

           @return: New L{Epsg}.

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

           @raise EPSGError: Invalid B{C{eisu}}.
        '''
        if isinstance(eisu, Epsg):
            self = int.__new__(cls, int(eisu))
            self._band = eisu.band
            self._epsg = self  # XXX eisu
            self._hemisphere = eisu.hemisphere
            self._utmups = eisu.utmups
            self._zone = eisu.zone
            if eisu.name:
                self.name = eisu.name

        elif isinstance(eisu, _Ints):
            self = int.__new__(cls, eisu)
            self._epsg = eisu
            self._zone, self._hemisphere = decode2(eisu)  # PYCHOK UtmUps2Tuple

        elif isinstance(eisu, _Strs):
            self = encode(eisu)

        else:
            u = eisu
            _TypeError(Utm, Ups, eisu=u)
            self = encode(u.zone, hemipole=u.hemisphere,
                          band=u.band)  # PYCHOK **kwds
            self._utmups = u
            if u.name:
                self.name = u.name

        return self
Esempio n. 24
0
    def destinationNed(self, delta):
        '''Calculate the destination point using the supplied NED delta
           from this point.

           @param delta: Delta from this to the other point in the
                         local tangent plane (LTP) of this point (L{Ned}).

           @return: Destination point (L{Cartesian}).

           @raise TypeError: If {delta} is not L{Ned}.

           @example:

           >>> a = LatLon(49.66618, 3.45063)
           >>> delta = toNed(116807.681, 222.493, -0.5245)  # [N:-86126, E:-78900, D:1069]
           >>> b = a.destinationNed(delta)  # 48.88667°N, 002.37472°E

           @JSname: I{destinationPoint}.
        '''
        _TypeError(Ned, delta=delta)

        n, e, d = self._rotation3()
        # convert NED delta to standard Vector3d in coordinate frame of n-vector
        dn = delta.toVector3d().to3xyz()
        # rotate dn to get delta in cartesian (ECEF) coordinate
        # reference frame using the rotation matrix column vectors
        dc = Cartesian(fdot(dn, n.x, e.x, d.x), fdot(dn, n.y, e.y, d.y),
                       fdot(dn, n.z, e.z, d.z))

        # apply (cartesian) delta to this Cartesian to
        # obtain destination point as cartesian
        v = self.toCartesian().plus(dc)  # the plus() gives a plain vector

        return v.toLatLon(
            datum=self.datum,
            LatLon=self.classof)  # Cartesian(v.x, v.y, v.z).toLatLon(...)
Esempio n. 25
0
    def __init__(self, x, y, z, h=0, datum=None, ll=None, name=''):
        '''New n-vector normal to the earth's surface.

           @param x: X component (C{meter}).
           @param y: Y component (C{meter}).
           @param z: Z component (C{meter}).
           @keyword h: Optional height above model surface (C{meter}).
           @keyword datum: Optional datum this n-vector is defined
                           within (L{Datum}).
           @keyword ll: Optional, original latlon (C{LatLon}).
           @keyword name: Optional name (C{str}).

           @raise TypeError: If B{C{datum}} is not a L{Datum}.

           @example:

           >>> from ellipsoidalNvector import Nvector
           >>> v = Nvector(0.5, 0.5, 0.7071, 1)
           >>> v.toLatLon()  # 45.0°N, 045.0°E, +1.00m
        '''
        NvectorBase.__init__(self, x, y, z, h=h, ll=ll, name=name)
        if datum:
            _TypeError(Datum, datum=datum)
            self._datum = datum