예제 #1
0
def csea(a=1, e=0):
    r"""
    Return a function object that wraps the ISEA projection and its inverse
    of an ellipsoid with major radius `a` and eccentricity `e`.
                
    OUTPUT:
    
    - A function object of the form f(u, v, radians=False, inverse=False).
    """
    R_A = auth_rad(a, e)
    def f(u, v, radians=False, inverse=False):
        if not inverse:
            lam, phi = u, v
            if not radians:
                # Convert to radians.
                lam, phi = deg2rad([lam, phi])
            return tuple(R_A*array(csea_ellipsoid(lam, phi, e=e)))
        else:
            # Scale down to R_A = 1.
            x, y = array((u, v))/R_A
            lam, phi = array(csea_ellipsoid_inverse(x, y, e=e))
            if not radians:
                # Convert to degrees.
                lam, phi = rad2deg([lam, phi])
            return lam, phi
    return f
예제 #2
0
    def test_rhealpix(self):
        inputs = [(-pi, pi/3), (0, pi/4), (pi/2, -pi/6)]

        # Should agree with rhealpix_ellipsoid and rhealpix_ellipsoid_inverse.
        e = 0.5
        a = 7
        R_A = auth_rad(a, e)
        f = pjr.rhealpix(a=a, e=e)
        for p in inputs:
            get = f(*p, radians=True)
            expect = tuple(R_A*array(pjr.rhealpix_ellipsoid(*p, e=e)))
            for i in range(len(expect)):
                self.assertAlmostEqual(get[i], expect[i])
            get = f(*get, radians=True, inverse=True)
            expect = tuple(array(expect)/R_A)
            expect = pjr.rhealpix_ellipsoid_inverse(*expect, e=e)
            for i in range(len(expect)):
                self.assertAlmostEqual(get[i], expect[i])
        
        # Should work in degrees mode.
        for p in inputs:
            get = f(*rad2deg(p), radians=False)
            expect = f(*p, radians=True)
            for i in range(len(expect)):
                self.assertAlmostEqual(get[i], expect[i])
예제 #3
0
def isea(a=1, e=0):
    r"""
    Return a function object that wraps the ISEA projection and its inverse
    of an ellipsoid with major radius `a` and eccentricity `e`.
    
    EXAMPLES::
    
        >>> f = isea(a=2, e=0)
        >>> print(my_round(f(0, pi/3, radians=True), 15))
        (-4.7097959155097699, 2.9195761776404252)
        >>> g = isea(a=2, e=0.1)
        >>> print(my_round(g(0, 60, radians=False), 15))
        (-4.6978889550868486, 2.9179977608222689)
        
    OUTPUT:
    
    - A function object of the form f(u, v, radians=False, inverse=False).
    """
    R_A = auth_rad(a, e)
    def f(u, v, radians=False, inverse=False):
        if not inverse:
            lam, phi = u, v
            if not radians:
                # Convert to radians.
                lam, phi = deg2rad([lam, phi])
            return tuple(R_A*array(isea_ellipsoid(lam, phi, e=e)))
        else:
            # Scale down to R_A = 1.
            x, y = array((u, v))/R_A
            lam, phi = array(isea_ellipsoid_inverse(x, y, e=e))
            if not radians:
                # Convert to degrees.
                lam, phi = rad2deg([lam, phi])
            return lam, phi
    return f
예제 #4
0
    def test_healpix(self):
        inputs = [(-pi, pi/3), (0, pi/4), (pi/2, -pi/6)]

        # Should agree with healpix_ellipsoid and healpix_ellipsoid_inverse.
        e = 0.5
        a = 7
        R_A = auth_rad(a, e)
        f = pjh.healpix(a=a, e=e)
        for p in inputs:
            get = f(*p, radians=True)
            expect = tuple(R_A*array(pjh.healpix_ellipsoid(*p, e=e)))
            for i in range(len(expect)):
                self.assertAlmostEqual(get[i], expect[i])
            get = f(*get, radians=True, inverse=True)
            expect = tuple(array(expect)/R_A)
            expect = pjh.healpix_ellipsoid_inverse(*expect, e=e)
            for i in range(len(expect)):
                self.assertAlmostEqual(get[i], expect[i])
        
        # Should work in degrees mode.
        for p in inputs:
            get = f(*rad2deg(p), radians=False)
            expect = f(*p, radians=True)
            for i in range(len(expect)):
                self.assertAlmostEqual(get[i], expect[i])
예제 #5
0
def csea(a=1, e=0):
    r"""
    Return a function object that wraps the ISEA projection and its inverse
    of an ellipsoid with major radius `a` and eccentricity `e`.
                
    OUTPUT:
    
    - A function object of the form f(u, v, radians=False, inverse=False).
    """
    R_A = auth_rad(a, e)

    def f(u, v, radians=False, inverse=False):
        if not inverse:
            lam, phi = u, v
            if not radians:
                # Convert to radians.
                lam, phi = deg2rad([lam, phi])
            return tuple(R_A * array(csea_ellipsoid(lam, phi, e=e)))
        else:
            # Scale down to R_A = 1.
            x, y = array((u, v)) / R_A
            lam, phi = array(csea_ellipsoid_inverse(x, y, e=e))
            if not radians:
                # Convert to degrees.
                lam, phi = rad2deg([lam, phi])
            return lam, phi

    return f
예제 #6
0
def rhealpix(a=1, e=0, north_square=0, south_square=0):
    r"""
    Return a function object that wraps the rHEALPix projection and its inverse
    of an ellipsoid with major radius `a` and eccentricity `e`.
    
    EXAMPLES::
    
        >>> f = rhealpix(a=2, e=0, north_square=1, south_square=2)
        >>> print(my_round(f(0, pi/3, radians=True), 15))
        (-0.57495135977821499, 2.1457476865731109)
        >>> p = (0, 60) 
        >>> q = f(*p, radians=False)
        >>> print(my_round(q, 15))
        (-0.57495135977821499, 2.1457476865731109)
        >>> print(my_round(f(*q, radians=False, inverse=True), 15))
        (5.9999999999999997e-15, 59.999999999999986)
        >>> print(my_round(p, 15))
        (0, 60)
        
    OUTPUT:
    
    - A function object of the form f(u, v, radians=False, inverse=False).
    """
    R_A = auth_rad(a, e)

    def f(u, v, radians=False, inverse=False):
        if not inverse:
            lam, phi = u, v
            if not radians:
                # Convert to radians.
                lam, phi = deg2rad([lam, phi])
            return tuple(R_A * array(
                rhealpix_ellipsoid(lam,
                                   phi,
                                   e=e,
                                   north_square=north_square,
                                   south_square=south_square)))
        else:
            # Scale down to R_A = 1.
            x, y = array((u, v)) / R_A
            lam, phi = array(
                rhealpix_ellipsoid_inverse(x,
                                           y,
                                           e=e,
                                           north_square=north_square,
                                           south_square=south_square))

            if not radians:
                # Convert to degrees.
                lam, phi = rad2deg([lam, phi])
            return lam, phi

    return f
예제 #7
0
def healpix_diagram(a=1, e=0, shade_polar_region=True):
    r"""
    Return a Sage Graphics object diagramming the HEALPix projection
    boundary and polar triangles for the ellipsoid with major radius `a` 
    and eccentricity `e`.
    Inessential graphics method.
    Requires Sage graphics methods.
    """
    from sage.all import Graphics, line2d, point, polygon, text, RealNumber, Integer
    
    # Make Sage types compatible with Numpy.
    RealNumber = float
    Integer = int
    
    R = auth_rad(a, e)
    g = Graphics()
    color = 'black' # Boundary color.
    shade_color = 'blue'  # Polar triangles color.    
    dl = array((R*pi/2,0))
    lu = [(-R*pi, R*pi/4),(-R*3*pi/4, R*pi/2)]
    ld = [(-R*3*pi/4, R*pi/2),(-R*pi/2, R*pi/4)] 
    g += line2d([(-R*pi, -R*pi/4),(-R*pi, R*pi/4)], color=color) 
    g += line2d([(R*pi, R*pi/4),(R*pi, -R*pi/4)], linestyle = '--', 
                color=color)
    for k in range(4):
        g += line2d([array(p) + k*dl for p in lu], color=color) 
        g += line2d([array(p) + k*dl for p in ld], linestyle = '--', 
                    color=color)
        g += line2d([array(p) + array((k*R*pi/2 - R*pi/4, -R*3*pi/4)) 
                     for p in ld], color=color) 
        g += line2d([array(p) + array((k*R*pi/2 + R*pi/4, -R*3*pi/4)) 
                     for p in lu], linestyle = '--', color=color)
    pn = array((-R*3*pi/4, R*pi/2))
    ps = array((-R*3*pi/4, -R*pi/2))
    g += point([pn + k*dl for k in range(4)] +
               [ps + k*dl for k in range(4)], size=20, color=color)
    g += point([pn + k*dl for k in range(1, 4)] + 
               [ps + k*dl for k in range(1, 4)], color='white', size=10, 
               zorder=3)
    npp = [(-R*pi, R*pi/4), (-R*3*pi/4, R*pi/2), (-R*pi/2, R*pi/4)]
    spp = [(-R*pi, -R*pi/4), (-R*3*pi/4, -R*pi/2), (-R*pi/2, -R*pi/4)]

    if shade_polar_region:
        for k in range(4):
            g += polygon([array(p) + k*dl for p in npp], alpha=0.1, 
                         color=shade_color) 
            g += text(str(k), array((-R*3*pi/4, R*5*pi/16)) + k*dl, 
                      color='red', fontsize=20)
            g += polygon([array(p) + k*dl for p in spp], alpha=0.1, 
                         color=shade_color)
            g += text(str(k), array((-R*3*pi/4, -R*5*pi/16)) + k*dl,    
                      color='red', fontsize=20)    
    return g
예제 #8
0
    def test_healpix_ellipsoid(self):
        # Ellipsoid parameters.
        a = 5
        e = 0.8
        R_A = auth_rad(a, e=e)
        # Expected output of healpix_ellipsoid() applied to inputs.
        healpix_ellipsoid_outputs = []
        g = Proj(proj='healpix', R=R_A)
        for p in inputs:
            lam, phi = p
            beta = auth_lat(phi, e=e, radians=RADIANS)
            q = g(lam, beta, radians=RADIANS)
            healpix_ellipsoid_outputs.append(q)

        # Forward projection should be correct on test points.
        f = Proj(proj='healpix', a=a, e=e)
        given = inputs
        get = [f(*p, radians=RADIANS) for p in given]
        expect = healpix_ellipsoid_outputs
        # Fuzz to allow for rounding errors:
        error = 1e-12
        print('=' * 80)
        print(
            'HEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s'
            % (a, e))
        print('input (radians) / expected output (meters) / received output')
        print('=' * 80)
        for i in range(len(get)):
            print(given[i], expect[i], get[i])
            self.assertTrue(rel_err(get[i], expect[i]) < error)

        # Inverse of projection of a point p should yield p.
        given = get
        get = [f(*q, radians=RADIANS, inverse=True) for q in given]
        expect = inputs
        # Fuzz for rounding errors based on the error of the approximation to
        # the inverse authalic latitude function:
        alpha = PI / 4
        alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS),
                          e,
                          radians=RADIANS,
                          inverse=True)
        error = 10 * rel_err(alpha_, alpha)
        print('=' * 80)
        print(
            'HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s'
            % (a, e))
        print('input (meters) / expected output (radians) / received output')
        print('=' * 80)
        for i in range(len(get)):
            print(given[i], expect[i], get[i])
            self.assertTrue(rel_err(get[i], expect[i]) < error)
 def test_rhealpix_ellipsoid(self):
     # Ellipsoid parameters.
     a = 5
     e = 0.8
     R_A = auth_rad(a, e=e) 
     # Forward projection should be correct on test points.
     print('='*80)
     print('rHEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e))
     print('input (radians) / expected output (meters) / received output')
     print('='*80)
     given = inputs
     # Fuzz to allow for rounding errors:
     error = 1e-12
     for (ns, ss) in product(list(range(4)), repeat=2):   
         print('_____ north_square = %s, south_square = %s' % (ns, ss))          
         expect = []
         g = Proj(proj='rhealpix', R=R_A,
                  north_square=ns, south_square=ss)
         for p in given:
             lam, phi = p
             beta = auth_lat(phi, e=e, radians=RADIANS)
             q = g(lam, beta, radians=RADIANS)
             expect.append(tuple(q))
         f = Proj(proj='rhealpix', a=a, e=e,
                  north_square=ns, south_square=ss)
         get = [f(*p, radians=RADIANS) for p in given]
         for i in range(len(given)):
             print(given[i], expect[i], get[i])
             self.assertTrue(rel_err(get[i], expect[i]) < error)
 
     # Inverse of projection of point a p should yield p.
     # Fuzz for rounding errors based on the error of the approximation to
     # the inverse authalic latitude function:
     alpha = PI/4
     alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS), e, radians=RADIANS, 
                       inverse=True)
     error = 10*rel_err(alpha_, alpha)        
     print('='*80)
     print('HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e))
     print('input (meters) / expected output (radians) / received output')
     print('='*80)
     # The inverse of the projection of a point p should yield p.
     for (ns, ss) in product(list(range(4)), repeat=2): 
         print('_____ north_square = %s, south_square = %s' % (ns, ss))
         f = Proj(proj='rhealpix', a=a, e=e, north_square=ns, 
                  south_square=ss)
         for p in inputs:
             expect = p
             q = f(*p, radians=RADIANS)
             get = f(*q, radians=RADIANS, inverse=True)   
             print(q, expect, get)             
             self.assertTrue(rel_err(get, expect) < error)
예제 #10
0
파일: ellipsoids.py 프로젝트: alex-ip/dggs
 def __init__(self,
              R=None,
              a=WGS84_A,
              b=None,
              e=None,
              f=WGS84_F,
              lon_0=0,
              lat_0=0,
              radians=False):
     self.lon_0 = lon_0
     self.lat_0 = lat_0
     self.radians = radians
     if R is not None:
         # The ellipsoid is a sphere.
         # Override the other geometric parameters.
         self.sphere = True
         self.R = R
         self.a = R
         self.b = R
         self.e = 0
         self.f = 0
         self.R_A = R
     else:
         self.sphere = False
         self.a = a
         if b is not None:
             # Derive the other geometric parameters from a and b.
             self.b = b
             self.e = sqrt(1 - (b / a)**2)
             self.f = (a - b) / a
         elif e is not None:
             # Derive the other geometric parameters from a and e.
             self.e = e
             self.b = a * sqrt(1 - e**2)
             self.f = 1 - sqrt(1 - e**2)
         else:
             self.f = f
             self.b = self.a * (1 - f)
             self.e = sqrt(f * (1 - f))
         self.R_A = auth_rad(self.a, self.e)
     self.phi_0 = auth_lat(arcsin(2.0 / 3),
                           e=self.e,
                           radians=True,
                           inverse=True)
     if not self.radians:
         # Convert to degrees.
         self.phi_0 = rad2deg(self.phi_0)
    def test_healpix_ellipsoid(self):
        # Ellipsoid parameters.
        a = 5
        e = 0.8
        R_A = auth_rad(a, e=e) 
        # Expected output of healpix_ellipsoid() applied to inputs.
        healpix_ellipsoid_outputs = []
        g = Proj(proj='healpix', R=R_A)
        for p in inputs:
            lam, phi = p
            beta = auth_lat(phi, e=e, radians=RADIANS)
            q = g(lam, beta, radians=RADIANS)
            healpix_ellipsoid_outputs.append(q)

        # Forward projection should be correct on test points.
        f = Proj(proj='healpix', a=a, e=e)
        given = inputs
        get = [f(*p, radians=RADIANS) for p in given]
        expect = healpix_ellipsoid_outputs
        # Fuzz to allow for rounding errors:
        error = 1e-12
        print('='*80)
        print('HEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e))
        print('input (radians) / expected output (meters) / received output')
        print('='*80)
        for i in range(len(get)):
            print(given[i], expect[i], get[i])
            self.assertTrue(rel_err(get[i], expect[i]) < error)
         
        # Inverse of projection of a point p should yield p.
        given = get
        get = [f(*q, radians=RADIANS, inverse=True) for q in given]
        expect = inputs
        # Fuzz for rounding errors based on the error of the approximation to
        # the inverse authalic latitude function:
        alpha = PI/4
        alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS), e, radians=RADIANS, 
                          inverse=True)
        error = 10*rel_err(alpha_, alpha)        
        print('='*80)
        print('HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s' % (a, e))
        print('input (meters) / expected output (radians) / received output')
        print('='*80)
        for i in range(len(get)):
            print(given[i], expect[i], get[i])
            self.assertTrue(rel_err(get[i], expect[i]) < error)
예제 #12
0
def rhealpix(a=1, e=0, north_square=0, south_square=0):
    r"""
    Return a function object that wraps the rHEALPix projection and its inverse
    of an ellipsoid with major radius `a` and eccentricity `e`.
    
    EXAMPLES::
    
        >>> f = rhealpix(a=2, e=0, north_square=1, south_square=2)
        >>> print(my_round(f(0, pi/3, radians=True), 15))
        (-0.57495135977821499, 2.1457476865731109)
        >>> p = (0, 60) 
        >>> q = f(*p, radians=False)
        >>> print(my_round(q, 15))
        (-0.57495135977821499, 2.1457476865731109)
        >>> print(my_round(f(*q, radians=False, inverse=True), 15))
        (5.9999999999999997e-15, 59.999999999999986)
        >>> print(my_round(p, 15))
        (0, 60)
        
    OUTPUT:
    
    - A function object of the form f(u, v, radians=False, inverse=False).
    """
    R_A = auth_rad(a, e)
    def f(u, v, radians=False, inverse=False):
        if not inverse:
            lam, phi = u, v
            if not radians:
                # Convert to radians.
                lam, phi = deg2rad([lam, phi])
            return tuple(R_A*array(rhealpix_ellipsoid(lam, phi, e=e,
                         north_square=north_square, 
                         south_square=south_square)))
        else:
            # Scale down to R_A = 1.
            x, y = array((u, v))/R_A
            lam, phi = array(rhealpix_ellipsoid_inverse(x, y, e=e,
                             north_square=north_square, 
                             south_square=south_square))
                             
            if not radians:
                # Convert to degrees.
                lam, phi = rad2deg([lam, phi])
            return lam, phi
    return f
예제 #13
0
 def __init__(self, R=None, a=WGS84_A, b=None, e=None, f=WGS84_F, 
              lon_0=0, lat_0=0, radians=False):
     self.lon_0 = lon_0
     self.lat_0 = lat_0
     self.radians = radians
     if R is not None:
         # The ellipsoid is a sphere. 
         # Override the other geometric parameters.
         self.sphere = True
         self.R = R
         self.a = R
         self.b = R
         self.e = 0
         self.f = 0
         self.R_A = R
     else:
         self.sphere = False
         self.a = a
         if b is not None:
             # Derive the other geometric parameters from a and b.
             self.b = b
             self.e = sqrt(1 - (b/a)**2)
             self.f = (a - b)/a
         elif e is not None:
             # Derive the other geometric parameters from a and e.
             self.e = e
             self.b = a*sqrt(1 - e**2)
             self.f = 1 - sqrt(1 - e**2)
         else:
             self.f = f
             self.b = self.a*(1 - f)
             self.e = sqrt(f*(1 - f))
         self.R_A = auth_rad(self.a, self.e) 
     self.phi_0 = auth_lat(arcsin(2.0/3), e=self.e, radians=True, 
                           inverse=True)
     if not self.radians:
         # Convert to degrees.
         self.phi_0 = rad2deg(self.phi_0)
예제 #14
0
def rhealpix_diagram(a=1,
                     e=0,
                     north_square=0,
                     south_square=0,
                     shade_polar_region=True):
    r"""
    Return a Sage Graphics object diagramming the rHEALPix projection
    boundary and polar triangles for the ellipsoid with major radius `a` 
    and eccentricity `e`.
    Inessential graphics method.
    Requires Sage graphics methods.
    """
    from sage.all import Graphics, line2d, point, polygon, text, RealNumber, Integer
    # Make Sage types compatible with Numpy.
    RealNumber = float
    Integer = int

    R = auth_rad(a, e)
    g = Graphics()
    color = 'black'  # Boundary color.
    shade_color = 'blue'  # Polar triangles color.
    north = north_square
    south = south_square
    south_sq = [(-R * pi + R * south * pi / 2, -R * pi / 4),
                (-R * pi + R * south * pi / 2, -R * 3 * pi / 4),
                (-R * pi + R * (south + 1) * pi / 2, -R * 3 * pi / 4),
                (-R * pi + R * (south + 1) * pi / 2, -R * pi / 4)]
    north_sq = [(-R * pi + R * north * pi / 2, R * pi / 4),
                (-R * pi + R * north * pi / 2, R * 3 * pi / 4),
                (-R * pi + R * (north + 1) * pi / 2, R * 3 * pi / 4),
                (-R * pi + R * (north + 1) * pi / 2, R * pi / 4)]
    # Outline.
    g += line2d(south_sq, linestyle='--', color=color)
    g += line2d(north_sq, linestyle='--', color=color)
    g += line2d([(R * pi, -R * pi / 4), (R * pi, R * pi / 4)],
                linestyle='--',
                color=color)
    g += line2d([
        north_sq[0], (-R * pi, R * pi / 4), (-R * pi, -R * pi / 4), south_sq[0]
    ],
                color=color)
    g += line2d([south_sq[3], (R * pi, -R * pi / 4)], color=color)
    g += line2d([north_sq[3], (R * pi, R * pi / 4)], color=color)
    g += point([south_sq[0], south_sq[3]], size=20, zorder=3, color=color)
    g += point([north_sq[0], north_sq[3]], size=20, zorder=3, color=color)
    g += point([(R * pi, -R * pi / 4), (R * pi, R * pi / 4)],
               size=20,
               zorder=3,
               color=color)
    g += point([(R * pi, -R * pi / 4), (R * pi, R * pi / 4)],
               size=10,
               color='white',
               zorder=3)
    if shade_polar_region:
        # Shade.
        g += polygon(south_sq, alpha=0.1, color=shade_color)
        g += polygon(north_sq, alpha=0.1, color=shade_color)

    # Slice square into polar triangles.
    g += line2d([south_sq[0], south_sq[2]], color='lightgray')
    g += line2d([south_sq[1], south_sq[3]], color='lightgray')
    g += line2d([north_sq[0], north_sq[2]], color='lightgray')
    g += line2d([north_sq[1], north_sq[3]], color='lightgray')

    # Label polar triangles.
    sp = south_sq[0] + R * array((pi / 4, -pi / 4))
    np = north_sq[0] + R * array((pi / 4, pi / 4))
    shift = R * 3 * pi / 16
    g += text(str(south), sp + array((0, shift)), color='red', fontsize=20)
    g += text(str((south + 1) % 4),
              sp + array((shift, 0)),
              color='red',
              rotation=90,
              fontsize=20)
    g += text(str((south + 2) % 4),
              sp + array((0, -shift)),
              color='red',
              rotation=180,
              fontsize=20)
    g += text(str((south + 3) % 4),
              sp + array((-shift, 0)),
              color='red',
              rotation=270,
              fontsize=20)
    g += text(str(north), np + array((0, -shift)), color='red', fontsize=20)
    g += text(str((north + 1) % 4),
              np + array((shift, 0)),
              color='red',
              rotation=90,
              fontsize=20)
    g += text(str((north + 2) % 4),
              np + array((0, shift)),
              color='red',
              rotation=180,
              fontsize=20)
    g += text(str((north + 3) % 4),
              np + array((-shift, 0)),
              color='red',
              rotation=270,
              fontsize=20)
    return g
예제 #15
0
def rhealpix_diagram(a=1, e=0, north_square=0, south_square=0,
                     shade_polar_region=True):
    r"""
    Return a Sage Graphics object diagramming the rHEALPix projection
    boundary and polar triangles for the ellipsoid with major radius `a` 
    and eccentricity `e`.
    Inessential graphics method.
    Requires Sage graphics methods.
    """
    from sage.all import Graphics, line2d, point, polygon, text, RealNumber, Integer
    # Make Sage types compatible with Numpy.
    RealNumber = float
    Integer = int

    R = auth_rad(a, e)
    g = Graphics()
    color = 'black' # Boundary color.
    shade_color = 'blue'  # Polar triangles color.    
    north = north_square
    south = south_square
    south_sq = [(-R*pi + R*south*pi/2, -R*pi/4), 
                (-R*pi + R*south*pi/2, -R*3*pi/4), 
                (-R*pi + R*(south + 1)*pi/2, -R*3*pi/4), 
                (-R*pi + R*(south + 1)*pi/2, -R*pi/4)]
    north_sq = [(-R*pi + R*north*pi/2, R*pi/4), 
                (-R*pi + R*north*pi/2, R*3*pi/4), 
                (-R*pi + R*(north + 1)*pi/2, R*3*pi/4), 
                (-R*pi + R*(north + 1)*pi/2, R*pi/4)]
    # Outline.
    g += line2d(south_sq, linestyle = '--', color=color)
    g += line2d(north_sq, linestyle = '--', color=color)
    g += line2d([(R*pi, -R*pi/4), (R*pi, R*pi/4)], linestyle='--',
               color=color)
    g += line2d([north_sq[0], (-R*pi, R*pi/4), (-R*pi, -R*pi/4), 
                south_sq[0]], color=color) 
    g += line2d([south_sq[3], (R*pi, -R*pi/4)], color=color)
    g += line2d([north_sq[3],(R*pi, R*pi/4)], color=color) 
    g += point([south_sq[0], south_sq[3]], size=20, zorder=3, color=color)         
    g += point([north_sq[0], north_sq[3]], size=20, zorder=3, color=color)    
    g += point([(R*pi, -R*pi/4), (R*pi, R*pi/4)], size=20, zorder=3, 
               color=color) 
    g += point([(R*pi, -R*pi/4), (R*pi, R*pi/4)], size=10, color='white', 
               zorder=3)
    if shade_polar_region:
        # Shade.
        g += polygon(south_sq, alpha=0.1, color=shade_color)
        g += polygon(north_sq, alpha=0.1, color=shade_color)

    # Slice square into polar triangles.
    g += line2d([south_sq[0], south_sq[2]], color='lightgray')
    g += line2d([south_sq[1], south_sq[3]], color='lightgray')
    g += line2d([north_sq[0], north_sq[2]], color='lightgray')
    g += line2d([north_sq[1], north_sq[3]], color='lightgray')

    # Label polar triangles.
    sp = south_sq[0] + R*array((pi/4, -pi/4))
    np = north_sq[0] + R*array((pi/4, pi/4))
    shift = R*3*pi/16
    g += text(str(south), sp + array((0, shift)), color='red', 
              fontsize=20)
    g += text(str((south + 1) % 4), sp + array((shift, 0)), 
              color='red', rotation=90, fontsize=20)
    g += text(str((south + 2) % 4), sp + array((0, -shift)), 
              color='red', rotation=180, fontsize=20)
    g += text(str((south + 3) % 4), sp + array((-shift, 0)), 
              color='red', rotation=270, fontsize=20)
    g += text(str(north), np + array((0, -shift)), color='red',
              fontsize=20)
    g += text(str((north + 1) % 4), np + array((shift, 0)), 
              color='red', rotation=90, fontsize=20)
    g += text(str((north + 2) % 4), np + array((0, shift)), 
              color='red', rotation=180, fontsize=20)
    g += text(str((north + 3) % 4), np + array((-shift, 0)), 
              color='red', rotation=270, fontsize=20)
    return g
예제 #16
0
    def test_rhealpix_ellipsoid(self):
        # Ellipsoid parameters.
        a = 5
        e = 0.8
        R_A = auth_rad(a, e=e)
        # Forward projection should be correct on test points.
        print('=' * 80)
        print(
            'rHEALPix forward projection, ellipsoid with major radius a = %s and eccentricity e = %s'
            % (a, e))
        print('input (radians) / expected output (meters) / received output')
        print('=' * 80)
        given = inputs
        # Fuzz to allow for rounding errors:
        error = 1e-12
        for (ns, ss) in product(list(range(4)), repeat=2):
            print('_____ north_square = %s, south_square = %s' % (ns, ss))
            expect = []
            g = Proj(proj='rhealpix', R=R_A, north_square=ns, south_square=ss)
            for p in given:
                lam, phi = p
                beta = auth_lat(phi, e=e, radians=RADIANS)
                q = g(lam, beta, radians=RADIANS)
                expect.append(tuple(q))
            f = Proj(proj='rhealpix',
                     a=a,
                     e=e,
                     north_square=ns,
                     south_square=ss)
            get = [f(*p, radians=RADIANS) for p in given]
            for i in range(len(given)):
                print(given[i], expect[i], get[i])
                self.assertTrue(rel_err(get[i], expect[i]) < error)

        # Inverse of projection of point a p should yield p.
        # Fuzz for rounding errors based on the error of the approximation to
        # the inverse authalic latitude function:
        alpha = PI / 4
        alpha_ = auth_lat(auth_lat(alpha, e, radians=RADIANS),
                          e,
                          radians=RADIANS,
                          inverse=True)
        error = 10 * rel_err(alpha_, alpha)
        print('=' * 80)
        print(
            'HEALPix inverse projection, ellipsoid with major radius a = %s and eccentricity e = %s'
            % (a, e))
        print('input (meters) / expected output (radians) / received output')
        print('=' * 80)
        # The inverse of the projection of a point p should yield p.
        for (ns, ss) in product(list(range(4)), repeat=2):
            print('_____ north_square = %s, south_square = %s' % (ns, ss))
            f = Proj(proj='rhealpix',
                     a=a,
                     e=e,
                     north_square=ns,
                     south_square=ss)
            for p in inputs:
                expect = p
                q = f(*p, radians=RADIANS)
                get = f(*q, radians=RADIANS, inverse=True)
                print(q, expect, get)
                self.assertTrue(rel_err(get, expect) < error)