Exemplo n.º 1
0
    def forward(self, lat, lon, name=NN):
        '''Convert an (ellipsoidal) geodetic location to azimuthal equidistant east- and northing.

           @arg lat: Latitude of the location (C{degrees90}).
           @arg lon: Longitude of the location (C{degrees180}).
           @kwarg name: Optional name for the location (C{str}).

           @return: An L{Azimuthal7Tuple}C{(x, y, lat, lon, azimuth, scale, datum)}
                    with C{x} and C{y} in C{meter} and C{lat} and C{lon} in
                    C{degrees}.  The C{scale} of the projection is C{1} in I{radial}
                    direction, C{azimuth} clockwise from true North and is C{1 /
                    reciprocal} in the direction perpendicular to this.

           @see: Method L{EquidistantKarney.reverse}.  A call to C{.forward}
                 followed by a call to C{.reverse} will return the original
                 C{lat, lon} to within roundoff.

            @raise AzimuthalError: Invalid B{C{lat}} or B{C{lon}}.
       '''
        r = self.geodesic.Inverse(self.lat0, self.lon0, Lat_(lat), Lon_(lon),
                                  self._mask)
        x, y = sincos2d(r.azi1)
        t = Azimuthal7Tuple(x * r.s12, y * r.s12, r.lat2, r.lon2, r.azi2,
                            self._1_rk(r), self.datum)
        return _xnamed(t, name or self.name)
Exemplo n.º 2
0
 def __new__(cls, x, y, lat, lon, azi, s, datum):
     return _NamedTuple.__new__(
         cls,
         Scalar(x, name=_x_, Error=AzimuthalError),
         Scalar(y, name=_y_, Error=AzimuthalError),  # PYCHOK indent
         Lat_(lat, Error=AzimuthalError),
         Lon_(lon, Error=AzimuthalError),
         Bearing(azi, name=_azimuth_, Error=AzimuthalError),
         Scalar(s, name=_scale_, Error=AzimuthalError),
         datum)
Exemplo n.º 3
0
    def reset(self, lat0, lon0):
        '''Set or reset the center point of this azimuthal projection.

           @arg lat0: Center point latitude (C{degrees90}).
           @arg lon0: Center point longitude (C{degrees180}).

           @raise AzimuthalError: Invalid B{C{lat0}} or B{C{lon0}}.
        '''
        self._latlon0 = LatLon2Tuple(Lat_(lat0=lat0, Error=AzimuthalError),
                                     Lon_(lon0=lon0, Error=AzimuthalError))
        self._sc0 = tuple(sincos2d(self.lat0))
        self._radius = None
Exemplo n.º 4
0
    def reset(self, lat0, lon0):
        '''Set or reset the center point of this Cassini-Soldner projection.

           @arg lat0: Center point latitude (C{degrees90}).
           @arg lon0: Center point longitude (C{degrees180}).

           @raise CSSError: Invalid B{C{lat0}} or B{C{lon0}}.
        '''
        g, M = self.datum.ellipsoid._geodesic_Math2

        self._meridian = m = g.Line(Lat_(lat0, name=_lat0_, Error=CSSError),
                                    Lon_(lon0, name=_lon0_, Error=CSSError),
                                    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)
Exemplo n.º 5
0
    def _forward(self, lat, lon, name, _k_t):
        '''(INTERNAL) Azimuthal (spherical) forward C{lat, lon} to C{x, y}.
        '''
        sa, ca, sb, cb = sincos2d(Lat_(lat), Lon_(lon) - self.lon0)
        s0, c0 = self._sc0

        k, t = _k_t(s0 * sa + c0 * ca * cb)
        if t:
            r = k * self.radius
            x = r * ca * sb
            y = r * (c0 * sa - s0 * ca * cb)
            z = atan2b(x, y)  # (x, y) for azimuth from true North
        else:  # 0 or 180
            x = y = z = 0

        t = Azimuthal7Tuple(x, y, lat, lon, z, k, self.datum)
        return self._xnamed(t, name=name)
Exemplo n.º 6
0
    def forward4(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{EasNorAziRk4Tuple}C{(easting, northing,
                    azimuth, reciprocal)}.

           @see: Method L{CassiniSoldner.forward}, L{CassiniSoldner.reverse}
                 and L{CassiniSoldner.reverse4}.

           @raise CSSError: Invalid B{C{lat}} or B{C{lon}}.
        '''
        g, M = self.datum.ellipsoid._geodesic_Math2

        lat = Lat_(lat, Error=CSSError)
        d = M.AngDiff(self.lon0, Lon_(lon, Error=CSSError))[0]  # _2sum
        r = g.Inverse(lat, -abs(d), lat, abs(d))
        z1, a = r.azi1, (r.a12 * 0.5)
        z2, s = r.azi2, (r.s12 * 0.5)
        if s == 0:
            z = M.AngDiff(z1, z2)[0] * 0.5  # _2sum
            c = -90 if abs(d) > 90 else 90
            z1, z2 = c - z, c + z
        if d < 0:
            a, s, z2 = -a, -s, z1

        # z: azimuth of easting direction
        e, z = s, M.AngNormalize(z2)
        p = g.Line(lat, d, z, g.DISTANCE | g.GEODESICSCALE)
        # rk: reciprocal of azimuthal northing scale
        rk = p.ArcPosition(-a, g.GEODESICSCALE).M21
        # rk = p._GenPosition(True, -a, g.DISTANCE)[7]

        # s, c = M.sincosd(p.EquatorialAzimuth())
        s, c = M.sincosd(M.atan2d(p._salp0, p._calp0))
        sb1 = -c if lat < 0 else c
        cb1 = -abs(s) if abs(d) > 90 else abs(s)  # copysign(s, 90 - abs(d))
        d = M.atan2d(sb1 * self._cb0 - cb1 * self._sb0,
                     cb1 * self._cb0 + sb1 * self._sb0)
        n = self._meridian.ArcPosition(d, g.DISTANCE).s12
        # n = self._meridian._GenPosition(True, d, g.DISTANCE)[4]
        r = EasNorAziRk4Tuple(e, n, z, rk)
        return self._xnamed(r)
Exemplo n.º 7
0
    def forward(self, lat, lon, name=NN, raiser=True):
        '''Convert an (ellipsoidal) geodetic location to azimuthal gnomonic east- and northing.

           @arg lat: Latitude of the location (C{degrees90}).
           @arg lon: Longitude of the location (C{degrees180}).
           @kwarg name: Optional name for the location (C{str}).
           @kwarg raiser: Do or don't throw an error (C{bool}) if
                          the location lies over the horizon.

           @return: An L{Azimuthal7Tuple}C{(x, y, lat, lon, azimuth, scale, datum)}
                    with C{x} and C{y} in C{meter} and C{lat} and C{lon} in C{degrees}
                    and C{azimuth} clockwise from true North.  The C{scale} of the
                    projection is C{1 / reciprocal**2} in I{radial} direction and
                    C{1 / reciprocal} in the direction perpendicular to this.  Both
                    C{x} and C{y} will be C{NAN} if the geodetic location lies over
                    the horizon and B{C{raiser}} is C{False}.

           @raise AzimuthalError: Invalid B{C{lat}}, B{C{lon}} or the geodetic location
                                  lies over the horizon and B{C{raiser}} is C{True}.
        '''
        self._iteration = 0

        r = self.geodesic.Inverse(self.lat0, self.lon0, Lat_(lat), Lon_(lon),
                                  self._mask)
        if r.M21 < EPS:
            if raiser:
                raise AzimuthalError(lat=lat, lon=lon, txt=_over_horizon_)
            x = y = NAN
        else:
            q = r.m12 / r.M21  # .M12
            x, y = sincos2d(r.azi1)
            x *= q
            y *= q

        t = self._7Tuple(x, y, r, r.M21)
        t._iteraton = self._iteration  # = 0
        return self._xnamed(t, name=name)
Exemplo n.º 8
0
def _Lat(**name_lat):
    '''(INTERNAL) Latitude C{-90 <= B{lat} <= 90}.
    '''
    return Lat_(Error=AlbersError, **name_lat)
Exemplo n.º 9
0
 def _Lat_s_c3(name, s, c):
     L = Lat_(atan2d(s, c), name=name, Error=AlbersError)
     r = _1_0 / Float_(hypot(s, c), name=name, Error=AlbersError)
     return L, s * r, c * r
Exemplo n.º 10
0
def _Lat_(lat, name=_lat_):
    '''(INTERNAL) Latitude C{-90 <= B{lat} <= 90}.
    '''
    return Lat_(lat, name=name, Error=AlbersError)
Exemplo n.º 11
0
 def __new__(cls, lat, lon, azi, rk):
     return _NamedTuple.__new__(cls, Lat_(lat, Error=CSSError),
                                Lon_(lon, Error=CSSError),
                                Bearing(azi, Error=CSSError),
                                Scalar(rk, Error=CSSError))