1
2# -*- coding: utf-8 -*-
3
4# Test Albers Equal-Area projection.
5
6__all__ = ('Tests',)
7__version__ = '21.01.28'
8
9from base import TestsBase  # RandomLatLon
10
11from pygeodesy import albers, AlbersError, AlbersEqualArea, \
12                      AlbersEqualArea2, AlbersEqualArea4, \
13                      AlbersEqualAreaCylindrical, \
14                      AlbersEqualAreaNorth, AlbersEqualAreaSouth, \
15                      Datums, fstr, sincos2d
16
17_NAD27 = Datums.NAD27  # Clarke1866
18_WGS84 = Datums.WGS84
19
20
21class Tests(TestsBase):
22
23    def testAlbers2(self):
24
25        A = AlbersEqualArea2(40 + 58/60.0, 39 + 56/60.0, name='Karney_example')  # WGS84
26        self.test('name',      A.named,                 A.named)
27        self.test('datum',     A.datum.name,           _WGS84.name)
28        self.test('ellipsoid', A.datum.ellipsoid.name, _WGS84.ellipsoid.name)
29        for n, x in (('lat0',        '40.451991337063'),
30                     ('scale0',      '0.999959500363'),
31                     ('equatoradius', A.datum.ellipsoid.a),
32                     ('flattening',   A.datum.ellipsoid.f),
33                     ('_sign',       '1.000000000000'),
34                     ('_m02',        '0.580681094922'),
35                     ('_n0',         '0.648810669236'),
36                     ('_txi0',       '0.848822476849')):
37            self.test(n, getattr(A, n), x, fmt='%.12f')
38        self.test('iteration', A.iteration, 3, known=A.iteration > 0)
39        self.test('ispolar', A.ispolar, False)
40
41        for lon0, x in ((0,     '-5675721.76113534, 2516917.91242155, 39.95, -75.17, 311.23285234, 0.99999745'),
42                        (-77.5, '199089.12574012, -53115.52801838, 39.95, 2.33, 1.51160641, 0.99999745')):
43            f = A.forward(39.95, -75.17, lon0=lon0)
44            self.test('forward', fstr(f[:6], prec=8), x, known=round(f.x, 7) == -5675721.7611353)
45            r = A.reverse(f.x, f.y, lon0=lon0)
46            self.test('reverse', fstr(r[:6], prec=8), x, known=round(r.lon, 2) == -75.17)
47
48        for lon0, x in ((0,     '220000.0, -53000.0, 39.94581132, 2.57463362, 1.67031446, 0.99999808'),
49                        (-77.5, '220000.0, -53000.0, 39.94581132, -74.92536638, 1.67031446, 0.99999808')):
50            r = A.reverse(220e3, -53e3,  lon0=lon0)
51            self.test('reverse', fstr(r[:6], prec=8), x)
52            f = A.forward(r.lat, r.lon, lon0=lon0)
53            self.test('forward', fstr(f[:6], prec=8), x, known=round(f.lon, 8) == 2.57463362)
54
55        self.subtitle(albers, 'Page292')
56        A = AlbersEqualArea2(29.5, 45.5, datum=_NAD27, name='Snyder_p292')
57        self.test('name',      A.named,                A.named)
58        self.test('datum',     A.datum.name,           _NAD27.name)
59        self.test('ellipsoid', A.datum.ellipsoid.name, _NAD27.ellipsoid.name)
60        for n, x in (('lat0',        '37.934543880726'),
61                     ('scale0',       '0.990309187872'),
62                     ('equatoradius',  A.datum.ellipsoid.a),
63                     ('flattening',    A.datum.ellipsoid.f),
64                     ('_sign',        '1.000000000000'),
65                     ('_m02',         '0.623664507732'),
66                     ('_n0',          '0.614760830736'),
67#                    ('_nrho0', '5037024.736824393272'),
68                     ('_txi0',        '0.775925617021')):
69            self.test(n, getattr(A, n), x, fmt='%.12f')
70        self.test('iteration', A.iteration, 4, known=A.iteration > 0)
71        self.test('ispolar', A.ispolar, False)
72
73        for lon0, x in ((0,   '-6105839.22928148, 2214046.74930274, 35.0, -75.0, 314.78223745, 0.99155461'),
74                        (-96, '1885472.72581347, -119505.66687766, 35.0, 21.0, 12.66097351, 0.99155461')):
75            f = A.forward(35, -75, lon0=lon0)
76            self.test('forward', fstr(f[:6], prec=8), x, known=round(f.x, 7) == -6105839.2292815 or
77                                                               round(f.y, 7) ==  -119505.6668777)
78            r = A.reverse(f.x, f.y, lon0=lon0)
79            self.test('reverse', fstr(r[:6], prec=8), x, known=round(r.lon, 1) == -75.0)
80
81        for lon0, x in ((0,   '1885427.7, 1535925.0, 49.40436665, 25.93001383, 15.63329611, 1.01436109'),
82                        (-96, '1885427.7, 1535925.0, 49.40436665, -70.06998617, 15.63329611, 1.01436109')):
83            r = A.reverse(1885427.7, 1535925, lon0=lon0)
84            self.test('reverse', fstr(r[:6], prec=8), x)
85            f = A.forward(r.lat, r.lon, lon0=lon0)
86            self.test('forward', fstr(f[:6], prec=8), x, known=round(f.lon, 8) == 25.93001383)
87
88        self.subtitle(albers, 'Table15')
89        A = AlbersEqualArea2(29.5, 45.5, datum=Datums.NAD27, name='Snyder_p103')
90        for lat, k in ((52,   1.02863),
91                       (50,   1.01727),
92                       (45.5, 1.00000),
93                       (45,   0.99869),
94                       (40,   0.99097),
95                       (35,   0.99155),
96                       (30,   0.99893),
97                       (29.5, 1.00000),
98                       (25,   1.01222),
99                       (22,   1.02283)):
100            t = A.forward(lat, 0)
101            self.test(str(lat) + ' k', t.scale, k, fmt='%.5f')
102
103    def testLats(self):
104        self.subtitle(albers, 'Lats')
105        s, c = sincos2d(30)
106        for lat, A in (( 45, AlbersEqualArea(45)),
107                       ( 40, AlbersEqualArea2(40, 40)),
108                       ( 30, AlbersEqualArea4( s, c,  s, c)),
109                       (-30, AlbersEqualArea4(-s, c, -s, c)),
110                       (  0, AlbersEqualAreaCylindrical()),
111                       ( 90, AlbersEqualAreaNorth()),
112                       (-90, AlbersEqualAreaSouth())):
113            self.test(A.named + '.lat0', A.lat0, lat, fmt='%.1f')
114            self.test(A.named + '.lat1', A.lat1, lat, fmt='%.1f')
115            self.test(A.named + '.lat2', A.lat2, lat, fmt='%.1f')
116
117        try:
118            self.test('error', AlbersEqualArea4(s, -c, 0, c), AlbersError.__name__)
119        except Exception as x:
120            self.test('error', str(x), 'lat1 (150.0): above 90 limit')
121        try:
122            self.test('error', AlbersEqualArea4(-0.5, c, 0.5, c), AlbersError.__name__)
123        except Exception as x:
124            self.test('error', str(x), 'slat1 (-0.5) or slat2 (0.5): invalid')
125
126
127if __name__ == '__main__':
128
129    t = Tests(__file__, __version__, albers)
130    t.testAlbers2()
131    t.testLats()
132    t.results()
133    t.exit()
134