def testSnyder(self, lat, lon, As, *xys): ll = lat, lon t = str(ll) for A, xy in zip(As, xys): n = A.__class__.__name__ + t f = A.forward(lat, lon) self.test(n, fstr(f[:2], prec=5), fstr(xy, prec=5)) r = A.reverse(f.x, f.y) self.test(n, fstr(r[2:4], prec=5), fstr(ll, prec=5))
def testEcefCartesian(self): self.test(EcefCartesian.__name__, '...', '...', nl=1) # <https://GeographicLib.SourceForge.io/html/CartConvert.1.html> c = EcefCartesian(33, 44, 20, name='Test') self.test('name', c.name, 'Test') t = c.toStr2() self.test('toStr', t, c.classname, known=True) self.testCopy(c) t = c.forward(33.3, 44.4, 6000) self.test('forward', fstr(t[3:6], prec=1), '33.3, 44.4, 6000.0') self.test('forward', fstr(t[0:3], prec=2), '37288.97, 33374.29, 5783.65') # 5783.64 self.test('name', c.name, 'Test') t = c.reverse(37288.97, 33374.29, 5783.65) self.test('reverse', fstr(t[3:6], prec=2), '33.3, 44.4, 6000.0') self.test('name', c.name, 'Test') # <https://SourceForge.net/p/geographiclib/code/ci/release/tree/examples/example-LocalCartesian.cpp> c.reset(48 + 50 / 60.0, 2 + 20 / 60.0, name='Paris') self.test('name', c.name, 'Paris') self.test(c.name, fstr((c.lat0, c.lon0, c.height0), prec=3), '48.833, 2.333, 0.0') t = c.forward(LatLon_(50.9, 1.8, name='Calais')) self.test('forward', fstr(t[3:6], prec=1), '50.9, 1.8, 0.0') self.test('forward', fstr(t[0:3], prec=2), '-37518.64, 229949.65, -4260.43') self.test('name', t.name, 'Calais') t = c.reverse(-37518.64, 229949.65, -4260.43) self.test('reverse', fstr(t[3:6], prec=2), '50.9, 1.8, -0.0', know=True) self.test('name', t.name, 'Paris') t = c.reverse(-38e3, 230e3, -4e3) self.test('reverse', fstr(t[0:3], prec=1), '4028834.2, 126130.9, 4926765.2') self.test('reverse', fstr(t[3:6], prec=2), '50.9, 1.79, 264.92') t = c.forward(50.9, 1.79, 264.92) self.test('forward', fstr(t[0:3], prec=1), '-38000.0, 230000.0, -4000.0', known=True)
def testKarneyPython(self, module): self.subtitle(module, 'KarneyPython') ll1 = module.LatLon(-41.32, 174.81) # <https://GeographicLib.SourceForge.io/html/python> d = ll1.geodesic.Inverse(-41.32, 174.81, 40.96, -5.50) self.test('.lat1', d.lat1, -41.320, fmt='%.3f') self.test('.lon1', d.lon1, 174.810, fmt='%.3f') self.test('.azi1', d.azi1, 161.067669986160, fmt='%.12f', known=abs(d.azi1 - 161.067669986160) < 1e-11) self.test('.lat2', d.lat2, 40.960, fmt='%.3f') self.test('.lon2', d.lon2, -5.500, fmt='%.3f') self.test('.azi2', d.azi2, 18.825195123247, fmt='%.12f') self.test('.s12', d.s12, 19959679.267353821546, fmt='%.12f', known=True) d3 = ll1.distanceTo3(module.LatLon(40.96, -5.50)) self.test('distanceTo3', fstr(d3, prec=12), '19959679.267353821546, 161.06766998616, 18.825195123247', known=True) ll2, d2 = ll1.destination2(19959679.26735382, 161.067669986160) self.test('destination2', fstr((ll2.lat, ll2.lon, d2), prec=12), '40.96, -5.5, 18.825195123247') # <https://GeographicLib.SourceForge.io/scripts/geod-calc.html> LL = module.LatLon p = LL(-63.1, -58), LL(-72.9, -74), LL(-71.9, -102), \ LL(-74.9, -102), LL(-74.3, -131), LL(-77.5, -163), \ LL(-77.4, 163), LL(-71.7, 172), LL(-65.9, 140), \ LL(-65.7, 113), LL(-66.6, 88), LL(-66.9, 59), \ LL(-69.8, 25), LL(-70.0, -4), LL(-71.0, -14), \ LL(-77.3, -33), LL(-77.9, -46), LL(-74.7, -61) # on/around south pole! self.test('areaOf', module.areaOf(p), '1.366270368e+13', fmt='%.9e') # 1.366270368002013e+13' self.test('perimeterOf', module.perimeterOf(p, closed=True), '1.683106789e+07', fmt='%.9e') # 1.683106789279071e+07 self.test('isclockwise', module.isclockwise(p), True) # polar self.test('isclockwise', module.isclockwise(reversed(p)), False) # polar
def testGars(self, LL): # Karney's geographiclib/1.49/examples/example-GARS.cpp # <https://SourceForge.net/p/geographiclib/code/ci/release/tree/examples/example-GARS.cpp> g = Garef('57.64911, 10.40744', precision=2) self.test('Garef', g, '381NH45') self.test('Garef', g.toStr(), '381NH45') self.test('Garef', g.toRepr(), "Garef('381NH45')") self.test('Garef', g.toRepr(std=True), "'381NH45'") self.test_('Garef', repr(g), "Garef('381NH45')", "'381NH45'") # PYGEODESY_NAMEDSTR_REPR self.test('Garef.precision', g.precision, 2) self.testCopy(g) self.test('Garef.latlon', fstr(g.latlon, prec=5), '57.64911, 10.40744') t = g.toLatLon(LL) self.test('Garef.toLatLon', repr(t), 'LatLon(57°38′56.8″N, 010°24′26.78″E)') self.testCodec3(g, '57.625, 10.375, 2.0', prec=4) t = Garef(t, precision=2, name='self') self.test('Garef(LatLon)', t, g) self.testCopy(t) for t in range(-1, 4): r = gars.resolution(t) p = gars.precision(r) self.test('precision', t, p, known=t < 0 or t > 2) b = degDMS(r, prec=0, s_D='', s_S='') # only S_MIN x = ('30' + S_MIN) if p < 1 else ( ('15' + S_MIN) if p < 2 else ('5' + S_MIN)) self.test('resolution', b, x) # also to test degDMS
def testLatLonEcef(self, module): self.test(module.__name__, 'LatLon', 'LatLon', nl=1) ll = module.LatLon(48.833, 2.333, name='Paris') t = ll.toEcef() self.test('forward', fstr(t[3:6], prec=3), '48.833, 2.333, 0.0') self.test( 'forward', fstr(t[0:3], prec=2), '4202946.8, 171232.47, 4778354.17' if ll.isEllipsoidal else '4190278.55, 170716.35, 4796058.21') self.test('name', t.name, 'Paris') e = ll.datum.ecef().reverse(t) self.test('reverse', fstr(e[3:6], prec=3), '48.833, 2.333, 0.0') self.test('name', e.name, 'Paris') ll = e.toLatLon(module.LatLon) self.test( 'toLatLon', repr(ll), 'LatLon(48°49′58.8″N, 002°19′58.8″E, +0.00m)' if ll.isEllipsoidal else 'LatLon(48°49′58.8″N, 002°19′58.8″E)') self.test('name', ll.name, 'Paris') t = e.toLatLon(LatLon=None) self.test('to4Tuple', t.classname, 'LatLon4Tuple') self.test( 'to4Tuple', repr(t), 'Paris(lat=48.833, lon=2.333, height=0.0, datum=%r)' % (t.datum, )) t = e.toLatLon(LatLon=None, datum=None) self.test('to3Tuple', t.classname, 'LatLon3Tuple') self.test('to3Tuple', repr(t), 'Paris(lat=48.833, lon=2.333, height=0.0)') v = e.toVector(getattr(module, 'Nvector', nvector.Nvector)) # XXX missing Nvector? self.test( 'toVector', str(v), '(4202946.79528, 171232.46613, 4778354.17)' if ll.isEllipsoidal else '(4190278.55277, 170716.34863, 4796058.20898)') self.test('name', v.name, 'Paris') c = e.toCartesian(module.Cartesian) self.test( 'forward', c.toStr(prec=2), '[4202946.8, 171232.47, 4778354.17]' if ll.isEllipsoidal else '[4190278.55, 170716.35, 4796058.21]')
def testAzimuthal(self, Azimuthal, *xs): P = Azimuthal(48 + 50 / 60.0, 2 + 20 / 60.0, name='Paris') self.test(repr(P), P, P) f = P.forward(50.9, 1.8, name='Calais') self.test('forward', fstr(f[:6], prec=6), xs[0]) r = P.reverse(f.x, f.y, name='Calais') self.test('reverse', fstr(r[:6], prec=6), xs[1]) self.test('iteration', P.iteration, P.iteration) self.testCopy(P) r = P.reverse(-38e3, 230e3, name='Calais') self.test('reverse', fstr(r[:6], prec=6), xs[2]) f = P.forward(r.lat, r.lon, name='Calais') self.test('forward', fstr(f[:6], prec=6), xs[3]) for m in (ellipsoidalKarney, ellipsoidalNvector, ellipsoidalVincenty): r = P.reverse(-38e3, 230e3, LatLon=m.LatLon) self.test('reverse', repr(r), xs[4]) G = Azimuthal(51.4934, 0.0098, name='Greenwich') self.test(repr(G), G, G) f = G.forward(P.lat0, P.lon0, P.name) self.test('forward', fstr(f[:6], prec=6), xs[5]) r = G.reverse(f.x, f.y) self.test('reverse', fstr(r[:6], prec=6), xs[6]) self.test('iteration', G.iteration, G.iteration) h = hypot(f.x, f.y) # easting + norting ~= distance d = vincentys(G.lat0, G.lon0, r.lat, r.lon) # haversine self.test('hypot', h, d, fmt='%.3f', known=abs(d - h) < 1000, nt=1)
def testEcefMatrix(self): self.test(EcefMatrix.__name__, '...', '...', nl=1) # index order in .multiply t = tuple(r * 3 + c for r in range(3) for c in range(3)) self.test('index', t, '(0, 1, 2, 3, 4, 5, 6, 7, 8)') M = EcefMatrix(*t) self.test('matrix', fstr(M, prec=0), '0, 1, 2, 3, 4, 5, 6, 7, 8') t = M.multiply(M) self.test('multiply', fstr(t, prec=0), '45, 54, 63, 54, 66, 78, 63, 78, 93') self.testCopy(M) I = [0] * 9 # PYCHOK I I[0] = I[4] = I[8] = 1 I = EcefMatrix(*I) # PYCHOK I self.test('matrix', fstr(I, prec=0), '1, 0, 0, 0, 1, 0, 0, 0, 1') t = I.multiply(I) self.test('multiply', fstr(t, prec=0), '1, 0, 0, 0, 1, 0, 0, 0, 1') self.testCopy(I)
def testStreprs(self): self.test('anstr', anstr('a-b?_'), 'a-b__') self.test('fstr', fstr(0.123, prec=-6), '0.123000') self.test('fstr', fstr(0.123, prec=+6), '0.123') self.test('fstr', fstr((0.123, 456.789), prec=+6), '0.123, 456.789') self.test('fstr', fstr(0.123, prec=-5, fmt='%.*e'), '1.23000e-01') self.test('fstr', fstr(0.123, prec=+5, fmt='%.*e'), '1.23e-01') try: # coverage self.test('fstr', fstr(1, fmt='X'), ValueError.__name__) except ValueError as x: from pygeodesy.streprs import _Fspec_ self.test('fstr', str(x), "fmt ('X'): not %r" % (_Fspec_, )) for f, x in ( (1, '1.0'), (1.0, '1.0'), (-1, '-1.0'), # (1e300, '10000<290>40160.'), (1e1234, 'INF'), # == INF (INF, 'INF'), (NAN, 'NAN'), (NEG0, '-0.0'), (0.0, '0.0')): self.test('fstr(%F)' % (f, ), fstr(f), x) for f, x in (('0.0', '0.0'), ('0.00', '0.0'), ('0.000', '0.0'), ('00.0', '00.0'), ('000.00', '000.0'), ('0.000', '0.0'), ('0.010', '0.01'), ('0.0200', '0.02'), ('0.0e+01', '0.0e+01'), ('0.00e+02', '0.0e+02'), ('0.000e+03', '0.0e+03'), ('00.0e+00', '00.0e+00'), ('000.00e+01', '000.0e+01'), ('0.000e+02', '0.0e+02'), ('0.010e+03', '0.01e+03'), ('0.0200e+00', '0.02e+00')): self.test('fstrzs(%s)' % (f, ), fstrzs(f), x) for f, x in (('0', '0.0'), ('0.0', '0.0'), ('0.', '0.'), ('1e10', '1.0e10'), ('2E+2', '2.0E+2'), ('3.E3', '3.E3')): self.test('fstrzs(%s, ap1z=True)' % (f, ), fstrzs(f, ap1z=True), x) ll = LatLon_(45, 90, height=1.2) self.test('instr', ll.toStr2(), 'LatLon_(45.0°N, 090.0°E, +1.20)') self.test('instr', instr(ll, 45, 90, h=1.2), 'LatLon_(45, 90, h=1.2)') self.test('unstr', unstr('f', 1.1, 2.2), 'f(1.1, 2.2)') self.test('unstr', unstr('f', y=2.2, x=1.1), 'f(x=1.1, y=2.2)')
def testGeohash(self, LL): cn = classname(LL(0, 0)) g = Geohash('geek') self.test('Geohash', str(g), 'geek') self.test('Geohash', g.toStr(), 'geek') self.test('Geohash', repr(g), "'geek'") # std_repr self.test('Geohash', g.toRepr(), "Geohash('geek')") self.test('Geohash', Geohash(g), 'geek') self.test( 'bounds', g.bounds(LL), '(%s(65°23′26.25″N, 017°55′46.88″W), %s(65°33′59.06″N, 017°34′41.25″W))' % (cn, cn)) self.test('toLatLon', g.toLatLon(LL), '65.478516°N, 017.753906°W') self.test('latlon', fstr(g.latlon, prec=7), '65.4785156, -17.7539062') self.test('philam', fstr(g.philam, prec=7), '1.1428157, -0.3098641') self.testCopy(g) g = Geohash(LL(65.390625, -17.929689), precision=9) self.test('Geohash', g, 'geehpbpbp') self.test('toLatLon', g.toLatLon(LL), '65.390625°N, 017.929689°W') self.test('latlon', fstr(g.latlon, prec=8), '65.390625, -17.929689') self.test('ab', fstr(g.ab, prec=7), '1.1412817, -0.3129321') self.test('decode', geohash.decode(g), "('65.390646', '-17.929709')") self.test('decode2', geohash.decode2(g), '(65.390646, -17.929709)') self.test('decode_error', fstr(geohash.decode_error(g), fmt='%.*e'), '2.145767e-05, 2.145767e-05') self.test('distance1To', g.distance1To('geehpb'), '2758.887', prec=3) self.test('distance2To', g.distance2To('geehpb'), '682.760', prec=3) self.test('distance3To', g.distance3To('geehpb'), '397.404', prec=3) self.test('sizes', fstr(g.sizes, prec=1), '4.8, 4.8') self.testCopy(g) for d in (g.neighbors, geohash.neighbors(g)): self.test('N', d.N, g.N) self.test('NE', d.NE, g.NE) self.test('E', d.E, g.E) self.test('SE', d.SE, g.SE) self.test('S', d.S, g.S) self.test('SW', d.SW, g.SW) self.test('W', d.W, g.W) self.test('NW', d.NW, g.NW) self.test('N', d['N'], g.N) self.test('NE', d['NE'], g.NE) self.test('E', d['E'], g.E) self.test('SE', d['SE'], g.SE) self.test('S', d['S'], g.S) self.test('SW', d['SW'], g.SW) self.test('W', d['W'], g.W) self.test('NW', d['NW'], g.NW) b = geohash.bounds('u120fxw') self.test('bounds', fstr(b, prec=8), '52.20428467, 0.11810303, 52.20565796, 0.11947632') d = geohash.decode('u120fxw') self.test('decode', fstr(d, prec=4), '52.205, 0.1188') for g in ('u120fxw', 'geek', 'fur', 'geehpbpbp', 'u4pruydqqvj8', 'bgr96qxvpd46', '0123456789', 'zzzzzz'): self.test('encode-decode', geohash.encode(*geohash.decode(g)), g) for p in range(8, 13): g = Geohash(LL(57.64911, 10.40744), precision=p) # Jutland, Denamrk self.test( 'Geohash', g, 'u4pruydqqvj8'[:p], ) self.test('N.E.S.W', g.N.E.S.W == g, 'True') self.test('E.S.W.N', g.E.S.W.N == g, 'True') self.test('S.W.N.E', g.S.W.N.E == g, 'True') self.test('W.N.E.S', g.W.N.E.S == g, 'True') self.test('N.E.S.S.W.W.N.N.E.S', g.N.E.S.S.W.W.N.N.E.S == g, True) # MCCABE Law of Demeter self.test('encode', geohash.encode(52.205, 0.1188), 'u120fxw') self.test('decode', geohash.decode('u120fxw'), "('52.205', '0.1188')") self.test('decode2', geohash.decode2('u120fxw'), '(52.205, 0.1188)') self.test('decode_error', fstr(geohash.decode_error('u120fxw'), fmt='%.*e'), '6.866455e-04, 6.866455e-04') self.test('distance1', geohash.distance1('u120fxw', 'u120fxws0'), '486.710', prec=3) self.test('distance2', geohash.distance2('u120fxw', 'u120fxws0'), '3.374', prec=3) self.test('distance3', geohash.distance3('u120fxw', 'u120fxws0'), '2.798', prec=3) self.test('sizes', fstr(geohash.sizes('u120fxw'), prec=1), '153.0, 153.0') g = Geohash('52.5009, 13.354') self.test('Geohash', g, 'u336xv') e = geohash.encode(52.5009, 13.354) self.test('encode', e, 'u336xv') self.test('equal', g == e, True) self.test('sizes', fstr(geohash.sizes(g), prec=1), '610.0, 1220.0') self.test('encode', geohash.encode(69.6, -45.7), 'fur') self.test('decode', geohash.decode('fur'), "('69.6', '-45.7')") self.test('decode', geohash.decode('fu'), "('70.3', '-51')") self.test('decode', geohash.decode('f'), "('68', '-68')") self.test('decode_error', geohash.decode_error('fur'), '(0.703125, 0.703125)') self.test('decode_error', geohash.decode_error('fu'), '(2.8125, 5.625)') self.test('decode_error', geohash.decode_error('f'), '(22.5, 22.5)') # <https://PyPI.org/project/pygeohash/> self.test('encode', geohash.encode(42.6, -5.6), 'ezs42e44yx96') self.test('decode', geohash.decode('ezs42e44yx96'), "('42.60000003', '-5.59999997')", known=True) self.test('encode', geohash.encode(42.6, -5.6, precision=5), 'ezs42') self.test('decode', geohash.decode('ezs42'), "('42.605', '-5.603')") self.test('distance1', geohash.distance1('bcd3u', 'bc83n'), '503442.4', prec=1) # 625441. self.test('distance2', geohash.distance2('bcd3u', 'bc83n'), '303317.6', prec=1) self.test('distance3', geohash.distance3('bcd3u', 'bc83n'), '179940.1', prec=1) for t in range(0, 14): r = geohash.resolution2(t, t) p = geohash.precision(*r) self.test('precision', t, p, known=t in (0, 13)) b = fstr(r, prec=t + 1) self.test('resolution', b, b) # just to show
def test3(self, LatLon): self.subtitle(points, LatLon=LatLon) p = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1) self.test('areaOf', areaOf(p, radius=R_MA), '8.811228e+09', fmt='%.6e') self.test( 'centroidOf', fstr(centroidOf(p), prec=6), '45.5, 1.5', ) self.test('perimeterOf', perimeterOf(p, radius=R_MA), '2.673633e+05', fmt='%.6e') self.test('isclockwise', isclockwise(p), False) p = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1) self.test('areaOf', areaOf(p, radius=R_MA), '7.086883e+09', fmt='%.6e') self.test('perimeterOf', perimeterOf(p, radius=R_MA), '2.687460e+05', fmt='%.6e') self.test( 'centroidOf', fstr(centroidOf(p), prec=6), '0.333333, 0.333333', ) self.test('isclockwise', isclockwise(p), True) p = LatLon(0, 1), LatLon(1, 2), LatLon(2, 1), LatLon(1, 0) self.test('areaOf', areaOf(p, radius=R_M), '2.827856e+10', fmt='%.6e') self.test('perimeterOf', perimeterOf(p, radius=R_M), '4.717039e+05', fmt='%.6e') self.test( 'centroidOf', fstr(centroidOf(p), prec=6), '1.0, 1.0', ) self.test('isclockwise', isclockwise(p), False) p = LatLon(45, -70), LatLon(60, 0), LatLon(20, 110), LatLon(80, 170) self.test('areaOf', areaOf(p, radius=R_M), '1.047657e+12', fmt='%.6e') self.test('perimeterOf', perimeterOf(p, radius=R_M), '2.332643e+07', fmt='%.6e') self.test( 'centroidOf', fstr(centroidOf(p), prec=3), '22.536, -164.928', ) self.test('isclockwise', isclockwise(p), True) p = LatLon(0, 0), LatLon(0, 3), LatLon(3, 3), LatLon(3, 2), \ LatLon(1, 2), LatLon(1, 1), LatLon(2, 1), LatLon(2, 0) self.test('areaOf', areaOf(p, radius=R_M), '8.482014e+10', fmt='%.6e') self.test('perimeterOf', perimeterOf(p, radius=R_M), '1.334104e+06', fmt='%.6e') self.test( 'centroidOf', fstr(centroidOf(p), prec=3), '1.167, 1.667', ) self.test('isclockwise', isclockwise(p), False) p = LatLon(-20, -180), LatLon(5, -160), LatLon(0, -60), LatLon(-60, -160) self.test('areaOf', areaOf(p, radius=R_M), '5.151974e+13', fmt='%.6e') self.test('perimeterOf', perimeterOf(p, radius=R_M), '2.638608e+07', fmt='%.6e') self.test( 'centroidOf', fstr(centroidOf(p), prec=3), '-19.444, -133.333', ) self.test('isclockwise', isclockwise(p), True) # <https://GeographicLib.SourceForge.io/scripts/geod-calc.html> p = LatLon(-63.1, -58), LatLon(-72.9, -74), LatLon(-71.9, -102), \ LatLon(-74.9, -102), LatLon(-74.3, -131), LatLon(-77.5, -163), \ LatLon(-77.4, 163), LatLon(-71.7, 172), LatLon(-65.9, 140), \ LatLon(-65.7, 113), LatLon(-66.6, 88), LatLon(-66.9, 59), \ LatLon(-69.8, 25), LatLon(-70.0, -4), LatLon(-71.0, -14), \ LatLon(-77.3, -33), LatLon(-77.9, -46), LatLon(-74.7, -61) # on/around south pole! self.test('areaOf', areaOf(p, radius=R_M), '1.366270e+13', fmt='%.6e', known=True) # 1.366270368002013e+13' self.test('perimeterOf', perimeterOf(p, radius=R_M), '1.366270e+13', fmt='%.6e', known=True) # 1.366270368002013e+13 self.test( 'centroidOf', fstr(centroidOf(p), prec=3), '-72.112, 92.032', ) self.test('isclockwise', isclockwise(p), False) self.test('points2', p[0].points2(p)[0], len(p)) p = LatLon('66.6S', '88W') self.test('latlon', fstr(p.latlon, prec=6), '-66.6, -88.0') self.test('philam', fstr(p.philam, prec=6), '-1.162389, -1.53589') self.test('to2ab', fstr(p.to2ab(), prec=6), '-1.162389, -1.53589') if LatLon is LatLon_: self.test('toStr', p.toStr(prec=6, kwds='test'), "66.6°S, 088.0°W, kwds='test'") q = p.classof(p.lat, p.lon, name='test') self.test('__ne__', q != p, False) self.test('latlonheight', fstr(p.latlonheight, prec=6), '-66.6, -88.0, 0.0') self.test('philamheight', fstr(p.philamheight, prec=6), '-1.162389, -1.53589, 0.0') self.test('_N_vector', p._N_vector, '(0.01386, -0.39691, -0.91775)') self.test('toNvector', p.toNvector().toStr(prec=5), '(0.01386, -0.39691, -0.91775)') self.test('toNvector', p.toNvector(Nvector=None), '(0.01386, -0.396906, -0.917755)', known=True) q = p.classof(-66.6, -88) self.test('classof', q, p) try: t = p.others(q) except Exception as x: t = str(x) self.test('others', t, None) self.testCopy(p)
def testKarneyVincenty(self, module, LatLon, d): self.subtitle(module, 'KarneyVincenty', datum=d.name) p = LatLon(-37.95103342, 144.42486789, datum=d) t = p.distanceTo(p) self.test('coincident', t, '0.0') t = p.distanceTo3(p) self.test('coincident', fstr(t), '0.0, 0.0, 0.0') q = p.destination(54972.271, 306.86816) t = q.toStr(F_D, prec=4) self.test('destination', t, '37.6528°S, 143.9265°E') self.test('destination', isinstance(q, LatLon), True) q, f = p.destination2(54972.271, 306.86816) t = q.toStr(F_D) + ', ' + compassDMS(f, prec=4) self.test('destination2', t, '37.652821°S, 143.926496°E, 307.1736°NW') self.test('destination2', isinstance(q, LatLon), True) f = p.finalBearingOn(54972.271, 306.86816) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingOn', t, '307.1736°, 307°10′25.07″NW') # <https://GitHub.com/chrisveness/geodesy/blob/master/test/latlon-ellipsoidal-vincenty-tests.js> # ... Test case (UK), using WGS-84 p = LatLon(50.06632, -5.71475, datum=d) q = LatLon(58.64402, -3.07009, datum=d) m = p.distanceTo(q) self.test('distanceTo', m, '969954.166', fmt='%.3f') t = p.distanceTo3(q) t = fstr(t, prec=6) self.test('distanceTo3', t, '969954.166314, 9.141877, 11.29722') t = p.distanceTo2(q) t = fstr(t, prec=5) self.test('distanceTo2', t, '972708.16174, 11.22502') b = p.initialBearingTo(q) t = bearingDMS(b, prec=4) + ', ' + compassDMS(b, form=F_DMS, prec=2) self.test('initialBearingTo', t, '9.1419°, 9°08′30.76″N') t = p.destination(m, b) self.test('destination', t.toStr(form=F_D, prec=5), '58.64402°N, 003.07009°W') f = p.finalBearingTo(q) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingTo', t, '11.2972°, 11°17′49.99″NNE') f = p.finalBearingOn(m, b) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingOn', t, '11.2972°, 11°17′49.99″NNE') p = LatLon(52.205, 0.119) q = LatLon(48.857, 2.351) m = p.distanceTo(q) self.test('distanceTo', m, '404607.806', fmt='%.3f') t = p.distanceTo3(q) t = fstr(t, prec=6) self.test('distanceTo3', t, '404607.805988, 156.11064, 157.8345') t = p.distanceTo2(q) t = fstr(t, prec=6) self.test('distanceTo2', t, '402574.597287, 157.726344') b = p.initialBearingTo(q) t = bearingDMS(b, prec=4) + ', ' + compassDMS(b, form=F_DMS, prec=2) self.test('initialBearingTo', t, '156.1106°, 156°06′38.31″SSE') t = p.destination(m, b) self.test('destination', t.toStr(form=F_D, prec=5), '48.857°N, 002.351°E') f = p.finalBearingTo(q) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingTo', t, '157.8345°, 157°50′04.2″SSE') # 157.9 f = p.finalBearingOn(m, b) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingOn', t, '157.8345°, 157°50′04.2″SSE') p = LatLon(37.95103, 144.42487, datum=d) q = LatLon(37.65280, 143.9265, datum=d) m = p.distanceTo(q) self.test('distanceTo', m, '54973.295', fmt='%.3f') t = p.distanceTo3(q) t = fstr(t, prec=5) self.test('distanceTo3', t, '54973.29527, 233.13008, 232.82461') t = p.distanceTo2(q) t = fstr(t, prec=5) self.test('distanceTo2', t, '54903.41209, 232.9209') b = p.initialBearingTo(q) t = bearingDMS(b, prec=4) + ', ' + compassDMS(b, form=F_DMS, prec=2) self.test('initialBearingTo', t, '233.1301°, 233°07′48.28″SW') t = p.destination(m, b) self.test('destination', t.toStr(form=F_D, prec=5), '37.6528°N, 143.9265°E') f = p.finalBearingTo(q) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingTo', t, '232.8246°, 232°49′28.59″SW') f = p.finalBearingOn(m, b) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingOn', t, '232.8246°, 232°49′28.59″SW') # <https://GitHub.com/maurycyp/vincenty> Maurycy Pietrzak Boston = LatLon(42.3541165, -71.0693514, datum=d) NewYork = LatLon(40.7791472, -73.9680804, datum=d) m = Boston.distanceTo(NewYork) self.test('distanceToMP', m, '298396.057', fmt='%.3f') self.test('distanceToSM', m2SM(m), 185.414, fmt='%.3f') p = LatLon(0, 0, datum=d) q = LatLon(0, 1, datum=d) m = p.distanceTo(q) self.test('distanceToMP', m, '111319.491', fmt='%.3f') q = LatLon(1, 0, datum=d) m = p.distanceTo(q) self.test('distanceToMP', m, '110574.389', fmt='%.3f') # <https://PyPI.org/project/pygc> Kyle Wilcox p = LatLon(0, 50, datum=d) q = LatLon(0, 52, datum=d) m = p.distanceTo(q) self.test('distanceToKW', m, '222638.982', fmt='%.3f') q = LatLon(0, 49, datum=d) m = p.distanceTo(q) self.test('distanceToKW', m, '111319.491', fmt='%.3f') # <https://www.Movable-Type.co.UK/scripts/latlong-vincenty.html> # ... Test case (from Geoscience Australia), using WGS-84 FindersPeak = LatLon('37°57′03.72030″S', '144°25′29.52440″E') Buninyong = LatLon('37°39′10.15610″S', '143°55′35.38390″E') m, b, f = FindersPeak.distanceTo3(Buninyong) self.test('distanceTo3', m, '54972.271', fmt='%.3f') self.test('distanceTo3', bearingDMS(b, F_DMS), '306°52′05.37″') self.test('distanceTo3', bearingDMS(f, F_DMS), '307°10′25.07″') m, b = FindersPeak.distanceTo2(Buninyong) self.test('distanceTo2', m, '54902.390', fmt='%.3f') self.test('distanceTo2', bearingDMS(b, F_DMS), '307°04′38.41″')
def _fstr(floats): fmt = '[%s]' if isinstance(floats, list) else \ '(%s,)' if isinstance(floats, tuple) else '%s' return fmt % (fstr(floats, prec=9), )
def testEcef(self, Ecef): self.test(Ecef.__name__, '...', '...', nl=1) Karney = Ecef is EcefKarney Sudano = Ecef is EcefSudano g = Ecef(Datums.WGS84, name='Test') self.test('name', g.name, 'Test') t = g.toStr2() self.test('toStr', t, g.classname, known=True) t = Ecef(g.a, g.f, name=g.name) # coverage self.test('a, f', t, t.classname, known=True) self.testCopy(g) # <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1Geocentric.html> t = g.forward(27.99, 86.93, 8820) # Mt Everest self.test('forward', fstr(t[3:6], prec=2), '27.99, 86.93, 8820.0') self.test('forward', fstr(t[0:3], prec=1), '302271.4, 5635928.4, 2979666.1') self.test('name', t.name, 'Test') t = g.reverse(302271.4, 5635928.4, 2979666.1) self.test('reverse', fstr(t[0:3], prec=1), '302271.4, 5635928.4, 2979666.1') self.test('reverse', fstr(t[3:6], prec=2), '27.99, 86.93, 8820.01', known=Sudano and _known(t, 27.99, 8820)) self.test('case', t.C, 2 if Karney else (5 if Sudano else 1)) self.test('iteration', t.iteration, t.iteration) self.test('name', t.name, 'Test') # <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1Geocentric.html> t = g.reverse(302e3, 5636e3, 2980e3) self.test('reverse', fstr(t[0:3], prec=1), '302000.0, 5636000.0, 2980000.0') self.test('reverse', fstr(t[3:6], prec=2), '27.99, 86.93, 9027.03', known=Sudano and _known(t, 27.99, 9027)) self.test('case', t.C, 2 if Karney else (5 if Sudano else 1)) self.test('iteration', t.iteration, t.iteration) t = g.forward(27.99, 86.93, 8820.0) self.test('forward', fstr(t[3:6], prec=2), '27.99, 86.93, 8820.0') self.test('forward', fstr(t[0:3], prec=2), '302271.43, 5635928.37, 2979666.13') # <https://GeographicLib.SourceForge.io/html/CartConvert.1.html> t = g.forward(33.3, 44.4, 6000) self.test('forward', fstr(t[3:6], prec=2), '33.3, 44.4, 6000.0') self.test('forward', fstr(t[0:3], prec=2), '3816209.6, 3737108.55, 3485109.57') t = g.reverse(3816209.6, 3737108.55, 3485109.57) self.test('reverse', fstr(t[0:3], prec=2), '3816209.6, 3737108.55, 3485109.57') self.test('reverse', fstr(t[3:6], prec=3), '33.3, 44.4, 5999.996', known=Sudano and _known(t, 33.3, 5999)) self.test('case', t.C, 2 if Karney else (5 if Sudano else 1)) self.test('iteration', t.iteration, t.iteration) # <https://GeographicLib.SourceForge.io/html/CartConvert.1.html> t = g.reverse(30000, 30000, 0) self.test('reverse', fstr(t[0:3], prec=1), '30000.0, 30000.0, 0.0') self.test('reverse', fstr(t[3:6], prec=3), '6.483, 45.0, -6335709.726', known=not Karney) self.test('case', t.C, 3 if Karney else (0 if Sudano else 1)) self.test('iteration', t.iteration, t.iteration) t = g.forward(6.483, 45.0, -6335709.726) self.test('forward', fstr(t[3:6], prec=3), '6.483, 45.0, -6335709.726') self.test('forward', fstr(t[0:3], prec=1), '30000.0, 30000.0, -0.0', known=True) # Rey-Jer You <https://www.ResearchGate.net/publication/240359424> for i, (x, y, z, h) in enumerate( ((-2259148.993, 3912960.837, 4488055.516, 1e3), (-2259502.546, 3913573.210, 4488762.622, 2e3), (-2259856.100, 3914185.582, 4489469.729, 3e3), (-2260209.653, 3914797.955, 4490176.836, 4e3), (-2262330.973, 3918472.189, 4494419.477, 1e4), (-2265866.507, 3924595.914, 4501490.544, 2e4), (-2294150.778, 3973585.709, 4558059.087, 1e5), (-2541638.152, 4402246.414, 5053033.834, 8e5), (-2612348.830, 4524720.901, 5194455.190, 1e6))): i = '-%d' % (i + 1, ) r = '45.0, 120.0, %.1f' % (h, ) # Zero and First order columns t = g.reverse(x, y, z) k = Sudano and _known(t, 45, h) self.test('reverse' + i, fstr(t[3:6], prec=3), r, known=k) f = g.forward(t.lat, t.lon, t.height) self.test('forward' + i, fstr(f[0:3], prec=1), fstr((x, y, z), prec=1), known=k) self.test('xyzh' + i, fstr(f.xyzh, prec=1), fstr((x, y, z, h), prec=1), known=k) f = f.phi, f.lam t = radians(t.lat), radians(t.lon) self.test('philam' + i, fstr(f, prec=4), fstr(t, prec=4)) # <https://www.researchgate.net/publication/3709199_An_exact_conversion_from_an_Earth-centered_coordinate_system_to_latitude_longitude_and_altitude> t = g.reverse(4588301.55696757, 0, 4558059.086984613) self.test('sudano', fstr(t[3:6], prec=3), '45.0, 0.0, 100000.0', known=Sudano) # <https://www.OrdnanceSurvey.co.UK/documents/resources/guide-coordinate-systems-great-britain.pdf> pp 47 g = Ecef(Ellipsoids.GRS80, name='OS-UK') self.test('name', g.name, 'OS-UK') t = g.forward( parse3llh('''53°36′43.1653"N, 001°39′51.9920"W, 299.800''')) self.test('forward', fstr(t[3:6], prec=8), '53.61199036, -1.66444222, 299.8') self.test('forward', fstr(t[0:3], prec=2), '3790644.9, -110149.21, 5111482.97') t = g.reverse(3790644.9, -110149.21, 5111482.97) self.test('reverse', fstr(t[0:3], prec=2), '3790644.9, -110149.21, 5111482.97') self.test('reverse', fstr(t[3:5], prec=8), '53.61199036, -1.66444223', known=Sudano) self.test('reverse.lat', latDMS(t.lat, prec=4), '53°36′43.1653″N', known=Sudano) self.test('reverse.lon', lonDMS(t.lon, prec=4), '001°39′51.992″W') self.test('reverse.height', fstr(t.height, prec=-3), '299.800', known=Sudano) self.test('case', t.C, 2 if Karney else (6 if Sudano else 1)) self.test('iteration', t.iteration, t.iteration) # coverage self.test(EcefError.__name__, g.reverse(0, 0, 0), '(0.0, 0.0, ...)', known=True) try: self.test(EcefError.__name__, g.forward(None, None, None), EcefError.__name__) except Exception as x: self.test(EcefError.__name__, str(x).split(':')[0], 'lat (None), lon (None) ...', known=True) try: self.test(Ecef.__name__, Ecef(None), EcefError.__name__) except Exception as x: self.test(Ecef.__name__, str(x), Ecef.__name__, known=True)
def testDms(self): # MCCABE 14 for t in ('0.0°', '0°', '''000°00'00"''', '''000°00'00.0"''', '''000° 00'00"''', '''000°00 ' 00.0"''', '''000° 00' 00.0'''): self.test("parseDMS('%s')" % (t, ), parseDMS(t), '0.0') t = '000°-00′-00.0"' self.test("parseDMS('%s')" % (t, ), parseDMS(t, sep='-'), '0.0') _X = '' for t, X, x in ((1, '1.0', _X), (12, '12.0', _X), (123, '123.0', _X), (1234, '12.567', '1234.0'), (12345, '123.75', '12345.0'), (123456, '12.582', '123456.0'), (1234567, '123.769', '1234567.0'), (12345678, '1234.955', '12345678.0'), (.1, 0.1, _X), (1.2, 1.2, _X), (12.3, 12.3, _X), (123.4, 123.4, _X), (1234.5, 12.575, 1234.5), (12345.6, 123.76, 12345.6), (123456.7, 12.582, 123456.7), ('1N', '1.0', _X), ('12S', '-12.0', _X), ('012.3W', '-12.3', _X), ('123E', '123.0', _X), ('1234N', '12.567', '1234.0'), ('12345E', '123.75', '12345.0'), ('1234.5S', '-12.575', '-1234.5'), ('12345.6E', '123.76', '12345.6'), ('123456.7S', '-12.582', '-123456.7'), ('1234567.8W', '-123.769', '-1234567.8'), ('12345678E', '12345678.0', _X)): self.test('parseDDDMMSS(%r)' % (t, ), fstr(parseDDDMMSS(t), prec=3), X) self.test('parseDMS(%r)' % (t, ), fstr(parseDMS(t), prec=3), x or X) t = 345.0 self.test('parseDDDMMSS(%r, NS)' % (t, ), fstr(parseDDDMMSS(t, suffix='NS'), prec=3), '3.75') self.test('parseDDDMMSS(%r, EW)' % (t, ), fstr(parseDDDMMSS(t, suffix='EW'), prec=3), '345.0') t = 5430.0 self.test('parseDDDMMSS(%r, NS)' % (t, ), fstr(parseDDDMMSS(t, suffix='NS'), prec=3), '54.5') self.test('parseDDDMMSS(%r, EW)' % (t, ), fstr(parseDDDMMSS(t, suffix='EW'), prec=3), '54.5') for t, x in (('12E', '12.0'), ('012.3S', '-12.3'), ('123N', '123.0'), ('1234E', '1234.0'), ('12345N', '12345.0'), ('1234.5W', '-1234.5'), ('123456E', '123456.0'), ('1234567S', '-1234567.0')): try: self.test('parseDDDMMSS(%r)' % (t, ), parseDDDMMSS(t), ParseError.__name__) except ParseError as X: self.test('parseDDDMMSS(%r)' % (t, ), repr(X), repr(X)) self.test('parseDMS(%r)' % (t, ), fstr(parseDMS(t), prec=5), x) r = rangerrors(True) try: self.test('parseDMS', parseDMS(181, clip=180), RangeError.__name__) except RangeError as x: self.test('parseDMS', str(x), str(x)) rangerrors(False) try: self.test('parseDMS', parseDMS(-91, clip=90), RangeError.__name__) except RangeError as x: self.test('parseDMS', str(x), str(x)) rangerrors(r) x = parse3llh('000° 00′ 05.31″W, 51° 28′ 40.12″ N') self.test('parse3llh', fstr(x, prec=6), '51.477811, -0.001475, 0.0') t = 'toDMS(%s)' % ('', ) self.test(t, toDMS(45.99999, F_DM, prec=1), '46°00.0′') # not 45°60.0′ self.test(t, toDMS(45.99999, F_DM, prec=2), '46°00.0′') self.test(t, toDMS(45.9999, F_DM, prec=2), '45°59.99′') self.test(t, toDMS(45.99999, F_DM, prec=3), '45°59.999′') self.test(t, toDMS(45.99999, F_DMS, prec=1), '46°00′00.0″') self.test(t, toDMS(45.99999, F_DMS, prec=2), '45°59′59.96″') self.test(t, toDMS(45.99999, F_DMS, prec=3), '45°59′59.964″') self.test(t, toDMS(45.76260), '45°45′45.36″') for F, p, x in ((F_D, None, '45.7626°'), (F_DM, None, "45°45.756'"), (F_DMS, None, '''45°45'45.36"'''), (F_DEG, None, '45.7626'), (F_MIN, None, '4545.756'), (F_SEC, None, '454545.36'), (F_RAD, None, '0.79871'), (F_D, 6, '45.7626°'), (F_DM, -4, "45°45.7560'"), (F_DMS, 2, '''45°45'45.36"'''), (F_DEG, -6, '45.762600'), (F_MIN, -5, '4545.75600'), (F_SEC, -3, '454545.360'), (F_RAD, -6, '0.798708'), (F_D_, 6, '45.7626°'), (F_DM_, -4, "45°45.7560'"), (F_DMS_, 2, '''45°45'45.36"'''), (F_DEG_, -6, '45.762600'), (F_MIN_, -5, '4545.75600'), (F_SEC_, -3, '454545.360'), (F_RAD_, -6, '0.798708')): t = 'toDMS(%s)' % (F, ) self.test(t, toDMS(45.76260, F, prec=p), x) self.test(t, toDMS(-45.76260, F, prec=p), '-' + x) for F, p, x in ((F_D__, 6, '45.7626°'), (F_DM__, -4, "45°45.7560'"), (F_DMS__, 2, '''45°45'45.36"'''), (F_DEG__, -6, '45.762600'), (F_MIN__, -5, '4545.75600'), (F_SEC__, -3, '454545.360'), (F_RAD__, -6, '0.798708')): t = 'toDMS(%s)' % (F, ) self.test(t, toDMS(45.76260, F, prec=p), '+' + x) self.test(t, toDMS(-45.76260, F, prec=p), '-' + x) # <https://GitHub.com/chrisveness/geodesy/blob/master/test/dms-tests.js> for a, x in ( ((1, ), 'N'), ((0, ), 'N'), ((-1, ), 'N'), ((359, ), 'N'), ((24, ), 'NNE'), ((24, 1), 'N'), ((24, 2), 'NE'), ((24, 3), 'NNE'), ((226, ), 'SW'), ((226, 1), 'W'), ((226, 2), 'SW'), ((226, 3), 'SW'), ((237, ), 'WSW'), ((237, 1), 'W'), ((237, 2), 'SW'), ((237, 3), 'WSW'), # Martin Schultz ((11.25, ), 'NNE'), ((11.249, ), 'N'), ((-11.25, ), 'N'), ((348.749, ), 'NNW'), ((45, 1), 'E'), ((44.99, 1), 'N'), ((45, 2), 'NE'), ((44.99, 2), 'NE'), ((45, 3), 'NE'), ((44.99, 3), 'NE'), ((45, 4), 'NE'), ((44.99, 4), 'NE'), # XXX ((22.5, 1), 'N'), ((22.49, 1), 'N'), ((22.5, 2), 'NE'), ((22.49, 2), 'N'), ((22.5, 3), 'NNE'), ((22.49, 3), 'NNE'), ((22.5, 4), 'NNE'), ((22.49, 4), 'NNE'), # XXX ((11.25, 1), 'N'), ((11.249, 1), 'N'), ((11.25, 2), 'N'), ((11.249, 2), 'N'), ((11.25, 3), 'NNE'), ((11.249, 3), 'N'), ((11.25, 4), 'NbE'), ((11.249, 4), 'NbE'), # XXX # examples ((24, 1), 'N'), ((24, 2), 'NE'), ((24, 3), 'NNE'), ((24, ), 'NNE'), ((18, 3), 'NNE'), ((11, 4), 'NbE'), ((30, 4), 'NEbN')): self.test('compassPoint%s' % (a, ), compassPoint(*a), x) for a, x in enumerate( ('NbE', 'NEbN', 'NEbE', 'EbN', 'EbS', 'SEbE', 'SEbS', 'SbE', 'SbW', 'SWbS', 'SWbW', 'WbS', 'WbN', 'NWbW', 'NWbN', 'NbW')): a = 11.25 + a * 22.5 self.test('compassPoint(%s)' % (a, ), compassPoint(a, 4), x) t = degDMS(1.0101, prec=5, s_D='', pos='+') # coverage self.test('_DEG', t, '+1.0101') t = degDMS(0.0101, prec=5, s_S='', pos='+') self.test('_MIN', t, "+0.606'") t = degDMS(0.0101, prec=5, s_M='', pos='+') self.test('_SEC', t, '+36.36"')
def _tstr(t): s = list(t[:5]) s[0] = fstr(t.fd, prec=p) return '(%s)' % (', '.join(map(str, s)), )
def testTrilaterate3d(self, module, Vector): self.subtitle(module, Vector.__name__) try: # numpy # <https://GISPoint.de/artikelarchiv/avn/2008/avn-ausgabe-12008/ # 2303-direkte-loesung-des-raeumlichen-bogenschnitts-mit-methoden-der-linearen-algebra.html> c1, r1 = Vector(50.0, 150.0, 13.0), 74.760 c2, r2 = Vector(100.0, 50.0, 11.0), 84.623 c3, r3 = Vector(200.0, 120.0, 12.0), 82.608 t = c1.trilaterate3d2(r1, c2, r2, c3, r3) k = numpy_version < 1.12 # numpy too old? n = joined_(c1.named3, Vector.trilaterate3d2.__name__, sep='.') self.test(n, len(t), 2) self.test(t[0].named3, fstr(t[0].xyz, prec=4), '119.8958, 130.6508, -5.1451', known=k) self.test(t[1].named3, fstr(t[1].xyz, prec=4), '119.9999, 129.9999, 30.0019', known=k) # <https://www.ResearchGate.net/publication/ # 275027725_An_Algebraic_Solution_to_the_Multilateration_Problem> c1, r1 = Vector(27.297, -4.953, 1.470), 3.851 # 3.857 c2, r2 = Vector(25.475, -6.124, 2.360), 3.875 # 3.988 c3, r3 = Vector(22.590, 0.524, 1.200), 3.514 # 3.497 for C, V in ((vector3d, dict(Vector=Vector)), (Vector, {})): # method f = C.trilaterate3d2 t = f(c1, r1, c2, r2, c3, r3, **V) n = joined_(C.__name__, f.__name__, sep='.') self.test(n, len(t), 2) self.test(t[0].named3, fstr(t[0].xyz, prec=5), '24.31229, -2.52045, 1.53649', known=k) self.test(t[1].named3, fstr(t[1].xyz, prec=5), '24.35062, -2.48109, 1.66673', known=k) try: # concentric t = f(c3, r1, c2, r2, c3, r3, **V) self.test(n, t, IntersectionError.__name__) except IntersectionError as x: t = str(x) self.test(n, t, t) try: # too distant t = f(c1, r1 * 0.1, c2, r2 * 0.1, c3, r3, **V) self.test(n, t, IntersectionError.__name__) except IntersectionError as x: t = str(x) self.test(n, t, t) try: # colinear t = f(Vector(0, 0, 0), 10, Vector(0, 9, 0), 10, Vector(0, -9, 0), 10) self.test(n, t, IntersectionError.__name__) except IntersectionError as x: t = str(x) self.test(n, t, t) except ImportError as x: self.skip(str(x), n=14)
def testNvectorBase(self, module, **kwds): try: Nvector = module.Nvector c = Nvector.__name__ except AttributeError: Nvector = module.NvectorBase c = 'Vector4Tuple' self.subtitle(module, Nvector.__name__) v = Nvector(0.500, 0.500, 0.707, **kwds) s = module.sumOf((v, v), h=0, name='sumOf') self.test('sumOf', s.__class__.__name__, c) p = v.toLatLon(LatLon=None) c = v.toCartesian(Cartesian=None) self.test('ecef.x, .y, .z', fstr(p[:3], prec=5), fstr(c[:3], prec=5)) self.test('ecef.lat, .lon', fstr(p[3:5], prec=6), fstr(c[3:5], prec=6)) self.test('ecef.height', fstr(p.height, prec=6), fstr(c.height, prec=6), known=True) if c.M is not None: self.test('ecef.M', fstr(p.M, prec=9), fstr(c.M, prec=9)) if coverage: from pygeodesy.namedTuples import LatLon2Tuple, LatLon3Tuple, \ PhiLam2Tuple, PhiLam3Tuple self.test('.isEllipsoidal', v.isEllipsoidal, not v.isSpherical) self.test('.isSpherical', v.isSpherical, not v.isEllipsoidal) self.test('.latlon', v.latlon, LatLon2Tuple(v.lat, v.lon)) self.test('.philam', v.philam, PhiLam2Tuple(v.phi, v.lam)) self.test('.latlonheight', v.latlonheight, LatLon3Tuple(v.lat, v.lon, v.h), known=v.h in (0, 0.0, NEG0)) self.test('.philamheight', v.philamheight, PhiLam3Tuple(v.phi, v.lam, v.h), known=v.h in (0, 0.0, NEG0)) t = v.parse('0.5, 0.5, 0.707') self.test('parse', t, v) self.test('cmp', t.cmp(v), 0) self.test('eq', t == v, True) self.test('ge', t >= v, True) self.test('gt', t > v, False) self.test('le', t <= v, True) self.test('lt', t < v, False) self.test('ne', t != v, False) m = t * 2 self.test('*', m, '(1.0, 1.0, 1.414)') self.test('+', t + v, m) self.test('/', m / 2, t) self.test('-', m - t, t) m = v.__matmul__(t) self.test('@', m, '(0.0, 0.0, 0.0)') r = t.__rmatmul__(m) self.test('@', r, m) r = v.rotate(m, 45) self.test('rotate', r, '(0.26268, 0.26268, 0.37143)') r.crosserrors = True self.test('crosserrors', r.crosserrors, True) try: self.test('0', v.dividedBy(0), VectorError.__name__) except Exception as x: self.test('0', str(x), 'factor (0): float division by zero') t = vector3d.intersections2(Nvector(0, 0, 0), 500, Nvector(1000, 0, 0), 500, sphere=False) self.test('intersections2', t[0], t[1]) # abutting p1, p2 = Nvector(-100, -100, -100), Nvector(100, 100, 100) t = vector3d.nearestOn(Nvector(0, 0, 0), p1, p2) self.test('nearestOn', t, Nvector(0, 0, 0)) t = vector3d.nearestOn(Nvector(-200, -200, 0), p1, p2) self.test('nearestOn', t is p1, True) t = vector3d.nearestOn(Nvector(200, 200, 0), p1, p2) self.test('nearestOn', t, p2) self.test('nearestOn', t is p2, True) t = vector3d.iscolinearWith(Nvector(200, 200, 0), p1, p2) self.test('iscolinearWith', t, False) t = vector3d.iscolinearWith(Nvector(0, 0, 0), p1, p2) self.test('iscolinearWith', t, True)
def testOSgr(self, module): self.subtitle(module) LatLon = module.LatLon # check convertDatum and back p = LatLon(51.4778, -0.0016) # datum=Datums.WGS84) self.test('WGS84', p, '51.4778°N, 000.0016°W') r = p.convertDatum(Datums.OSGB36) self.test('OSGB36', r.toStr(form=F_D, m=None), '51.477284°N, 000.00002°E') r = r.convertDatum(Datums.WGS84) self.test('WGS84', r.toStr(form=F_D, m=None), '51.4778°N, 000.0016°W', known=True) g = osgr.Osgr(651409.903, 313177.270) self.test('OSgr1', g, 'TG 51409 13177') self.test('OSgr1', repr(g), '[G:TG, E:51409, N:13177]') self.test('iteration', g.iteration, g.iteration) # coverage p = g.toLatLon(LatLon) self.test('toLatLon1', p.toStr(F_DMS, m=None), '52°39′28.72″N, 001°42′57.74″E', known=True) self.test('toLatLon1', p, '52.657977°N, 001.716038°E', known=True) self.test('iteration', p.iteration, g.iteration) # coverage r = p.toOsgr() self.test('toOsgr1', r.toStr(prec=-3), '651409.903,313177.270', known=True) p = g.toLatLon(LatLon, datum=Datums.OSGB36) self.test('toLatLon2', p.toStr(F_DMS), '52°39′27.25″N, 001°43′04.47″E', known=True) self.test('toLatLon2', p, '52.657568°N, 001.717908°E', known=True) self.test('iteration', p.iteration, g.iteration) # coverage r = osgr.toOsgr(p) self.test('toOsgr2', r.toStr(0), '651409,313177', known=True) p = LatLon(52.65798, 1.71605) r = osgr.toOsgr(p) # TG 51409 13177 self.test('toOsgr3', r, 'TG 51409 13177') r = osgr.toOsgr(52.65757, 1.71791, datum=Datums.OSGB36) self.test('toOsgr4', r, 'TG 51409 13177') g = osgr.parseOSGR('TG 48251 11932') self.test('OSGR1', g, 'TG 48251 11932') self.test('OSGR1', repr(g), '[G:TG, E:48251, N:11932]') g = osgr.parseOSGR('TG51409 13177') self.test('OSGR2', g, 'TG 51409 13177') self.test('OSGR2', repr(g), '[G:TG, E:51409, N:13177]') g = osgr.parseOSGR('TG5140913177') self.test('OSGR3', g, 'TG 51409 13177') self.test('OSGR3', repr(g), '[G:TG, E:51409, N:13177]') g = osgr.parseOSGR('651409,313177') self.test('OSGR4', g, 'TG 51409 13177') self.test('OSGR4', repr(g), '[G:TG, E:51409, N:13177]') self.test('OSGR5', g.toStr(prec=0), '651409,313177') self.test('OSGR5', g.toRepr(prec=-3), '[OSGR:651409.000,313177.000]') self.test('OSGR5', g.toRepr(prec=-3), '[OSGR:651409.000,313177.000]') r = osgr.parseOSGR(g.toStr(prec=-3)) self.test('OSGR6', r.toStr(prec=0), '651409,313177') r = osgr.parseOSGR('651409,313177', Osgr=None) # coverage self.test('OSGR6', r.toStr(prec=0), '(651409, 313177)') r = g.parse('651409, 313177') # coverage self.test('OSGR6', r.toStr(prec=0), '651409,313177') self.test('issue', 38, 38) # courtesy jaluebbe <https://GitHub.com/mrJean1/PyGeodesy/issues/38>, with expected # results from <https://www.Movable-Type.co.UK/scripts/latlong-os-gridref.html> p = LatLon(52, -0.12, datum=Datums.WGS84) g = osgr.toOsgr(p) self.test('toOsgr', g.toRepr(), '[G:TL, E:29158, N:35174]') self.test('toOsgr', fstr((g.easting, g.northing), prec=3), '529158.072, 235174.785') self.test('toOsgr', g.datum.name, 'OSGB36') r = g.toLatLon(LatLon, datum=Datums.OSGB36) self.test('toLatLonOSGB36', r.toStr(m=None), '51°59′58.37″N, 000°07′06.14″W') self.test('toLatLonOSGB36', r.datum.name, 'OSGB36') p = g.toLatLon(LatLon, datum=Datums.WGS84) self.test('toLatLonWGS84 ', p.toStr(m=None), '52°00′00.0″N, 000°07′12.0″W') self.test('toLatLonWGS84 ', p.datum.name, 'WGS84') # courtesy jaluebbe <https://GitHub.com/mrJean1/PyGeodesy/issues/38>, with expected # results from <https://www.Movable-Type.co.UK/scripts/latlong-os-gridref.html> g = osgr.Osgr(532014, 123971) self.test('Osgr', g.toRepr(), '[G:TQ, E:32014, N:23971]') self.test('Osgr', fstr((g.easting, g.northing), prec=1), '532014.0, 123971.0') self.test('Osgr', g.datum.name, 'OSGB36') r = g.toLatLon(LatLon, datum=Datums.OSGB36) self.test('toLatLonOSGB36', r.toStr(form=F_DEG, m=None), '50.999425N, 000.118417W', known=True) self.test('toLatLonOSGB36', r.datum.name, 'OSGB36') p = g.toLatLon(LatLon, datum=Datums.WGS84) self.test('toLatLonWGS84 ', p.toStr(form=F_DEG, m=None), '50.999995N, 000.120004W', known=True) self.test('toLatLonWGS84 ', p.datum.name, 'WGS84') g = osgr.parseOSGR('TQ3201423971') self.test('parseOSGR', g.toRepr(), '[G:TQ, E:32014, N:23971]') self.test('parseOSGR', fstr((g.easting, g.northing), prec=1), '532014.0, 123971.0') self.test('parseOSGR', g.datum.name, 'OSGB36') r = g.toLatLon(LatLon, datum=Datums.OSGB36) self.test('toLatLonOSGB36', r.toStr(form=F_DEG, m=None), '50.999425N, 000.118417W', known=True) self.test('toLatLonOSGB36', r.datum.name, 'OSGB36') p = g.toLatLon(LatLon, datum=Datums.WGS84) self.test('toLatLonWGS84', p.toStr(form=F_DEG, m=None), '50.999995N, 000.120004W', known=True) self.test('toLatLonWGS84', p.datum.name, 'WGS84') # courtesy jaluebbe <https://GitHub.com/mrJean1/PyGeodesy/issues/38>, with expected # results from <https://www.Movable-Type.co.UK/scripts/latlong-os-gridref.html> g = osgr.toOsgr(LatLon(50.999995, -0.120004, datum=Datums.WGS84)) self.test('toOsgr', g.toRepr(), '[G:TQ, E:32013, N:23971]') self.test('toOsgr', fstr((g.easting, g.northing), prec=3), '532013.969, 123971.046') self.test('toOsgr', g.datum.name, 'OSGB36') r = g.toLatLon(LatLon, datum=Datums.OSGB36) self.test('toLatLonOSGB36', r.toStr(form=F_DEG, m=None), '50.999426N, 000.118417W') self.test('toLatLonOSGB36', r.datum.name, 'OSGB36') p = g.toLatLon(LatLon, datum=Datums.WGS84) self.test('toLatLonWGS84 ', p.toStr(form=F_DEG, m=None), '50.999995N, 000.120004W') self.test('toLatLonWGS84 ', p.datum.name, 'WGS84') # courtesy jaluebbe <https://GitHub.com/mrJean1/PyGeodesy/issues/38>, with expected # results from <https://www.Movable-Type.co.UK/scripts/latlong-os-gridref.html> g = osgr.toOsgr(LatLon(50.999995, +0.120004, datum=Datums.WGS84)) self.test('toOsgr', g.toRepr(), '[G:TQ, E:48853, N:24427]') self.test('toOsgr', fstr((g.easting, g.northing), prec=3), '548853.602, 124427.985') self.test('toOsgr', g.datum.name, 'OSGB36') r = g.toLatLon(LatLon, datum=Datums.OSGB36) self.test('toLatLonOSGB36', r.toStr(form=F_DEG, m=None), '50.999422N, 000.121618E') self.test('toLatLonOSGB36', r.datum.name, 'OSGB36') p = g.toLatLon(LatLon, datum=Datums.WGS84) self.test('toLatLonWGS84 ', p.toStr(form=F_DEG, m=None), '50.999995N, 000.120004E') self.test('toLatLonWGS84 ', p.datum.name, 'WGS84') for d in (Datums.WGS84, Datums.OSGB36): p = LatLon(52, -0.12, datum=d) g = osgr.toOsgr(p) r = g.toLatLon(LatLon, datum=d) t = r.toStr(form=F_DEG, m=None) # '52.0N, 000.12W' self.test('toLatLon', r.toStr(form=F_DEG, m=None), t) for _ in range(3): g = g.copy() r = g.toLatLon(LatLon, datum=d) self.test('toLatLon', r.toStr(form=F_DEG, m=None), t) # courtesy jaluebbe <https://GitHub.com/mrJean1/PyGeodesy/issues/38>, with expected # results from <https://www.Movable-Type.co.UK/scripts/latlong-os-gridref.html> p = LatLon(49.926244, -6.297934) self.test('LatLon', p, '49.926244°N, 006.297934°W') self.test('datum', p.datum.name, 'WGS84') g = p.toOsgr() self.test('datum', g.datum.name, 'OSGB36') self.test('toOsgr', g.toRepr(), '[G:SV, E:91645, N:11753]') g = osgr.Osgr(g.easting, g.northing) self.test('datum', g.datum.name, 'OSGB36') q = g.toLatLon(LatLon=LatLon) t = q.distanceTo(p) k = abs(t) < 0.005 self.test('LatLon', q.toStr(form=F_D, m=None), '49.926244°N, 006.297934°W', known=k) self.test('datum', q.datum.name, 'WGS84') self.test('distanceTo', t, 0.005, fmt='%.4f', known=k)
def testUtily(self): # Python 2.6.9 on Travis Ubuntu 14.04 produces -0.0 self.test('degrees90(PI_2)', degrees90(PI_2), 90.0) self.test('degrees90(PI)', degrees90(PI), -180.0) # XXX self.test('degrees90(PI2)', degrees90(PI2), 0.0) self.test('degrees90(-PI_2)', degrees90(-PI_2), -90.0) self.test('degrees90(-PI)', degrees90(-PI), -180.0) # XXX self.test('degrees90(-PI2)', abs(degrees90(-PI2)), 0.0) # -0.0 self.test('degrees180(PI_2)', degrees180(PI_2), 90.0) self.test('degrees180(PI)', degrees180(PI), 180.0) # XXX self.test('degrees180(PI2)', degrees180(PI2), 0.0) self.test('degrees180(-PI_2)', degrees180(-PI_2), -90.0) self.test('degrees180(-PI)', degrees180(-PI), -180.0) # XXX self.test('degrees180(-PI2)', abs(degrees180(-PI2)), 0.0) # -0.0 self.test('degrees360(PI_2)', degrees360(PI_2), 90.0) self.test('degrees360(PI)', degrees360(PI), 180.0) # XXX self.test('degrees360(PI2)', degrees360(PI2), 0.0) self.test('degrees360(-PI_2)', degrees360(-PI_2), 270.0) self.test('degrees360(-PI)', degrees360(-PI), 180.0) # XXX self.test('degrees360(-PI2)', abs(degrees360(-PI2)), 0.0) # -0.0 self.test('radiansPI_2(90)', radiansPI_2(90), PI_2) self.test('radiansPI_2(180)', radiansPI_2(180), -PI) self.test('radiansPI_2(360)', radiansPI_2(360), 0.0) self.test('radiansPI_2(-90)', radiansPI_2(-90), -PI_2) self.test('radiansPI_2(-180)', radiansPI_2(-180), -PI) self.test('radiansPI_2(-360)', abs(radiansPI_2(-360)), 0.0) # -0.0 self.test('radiansPI(90)', radiansPI(90), PI_2) self.test('radiansPI(180)', radiansPI(180), PI) self.test('radiansPI(360)', radiansPI(360), 0.0) self.test('radiansPI(-90)', radiansPI(-90), -PI_2) self.test('radiansPI(-180)', radiansPI(-180), -PI) self.test('radiansPI(-360)', abs(radiansPI(-360)), 0.0) # -0.0 self.test('radiansPI2(90)', radiansPI2(90), PI_2) self.test('radiansPI2(180)', radiansPI2(180), PI) self.test('radiansPI2(360)', radiansPI2(360), 0.0) self.test('radiansPI2(-90)', radiansPI2(-90), PI_2 + PI) self.test('radiansPI2(-180)', radiansPI2(-180), PI) self.test('radiansPI2(-360)', abs(radiansPI2(-360)), 0.0) # -0.0 self.test('wrap90(90)', wrap90(90), 90) self.test('wrap90(180)', wrap90(180), -180) self.test('wrap90(360)', wrap90(360), 0) self.test('wrap90(-90)', wrap90(-90), -90) self.test('wrap90(-180)', wrap90(-180), -180) self.test('wrap90(-360)', wrap90(-360), 0) self.test('wrap180(90)', wrap180(90), 90) self.test('wrap180(180)', wrap180(180), 180) self.test('wrap180(360)', wrap180(360), 0) self.test('wrap180(-90)', wrap180(-90), -90) self.test('wrap180(-180)', wrap180(-180), -180) self.test('wrap180(-360)', wrap180(-360), 0) self.test('wrap360(90)', wrap360(90), 90) self.test('wrap360(180)', wrap360(180), 180) self.test('wrap360(360)', wrap360(360), 0) self.test('wrap360(-90)', wrap360(-90), 270) self.test('wrap360(-180)', wrap360(-180), 180) self.test('wrap360(-360)', wrap360(-360), 0) self.test('wrapPI_2(PI_2)', wrapPI_2(PI_2), PI_2) self.test('wrapPI_2(PI)', wrapPI_2(PI), -PI) # XXX self.test('wrapPI_2(PI2)', wrapPI_2(PI2), 0.0) self.test('wrapPI_2(-PI_2)', wrapPI_2(-PI_2), -PI_2) self.test('wrapPI_2(-PI)', wrapPI_2(-PI), -PI) # XXX self.test('wrapPI_2(-PI2)', abs(wrapPI_2(-PI2)), 0.0) self.test('wrapPI(PI_2)', wrapPI(PI_2), PI_2) self.test('wrapPI(PI)', wrapPI(PI), PI) # XXX self.test('wrapPI(PI2)', wrapPI(PI2), 0.0) self.test('wrapPI(-PI_2)', wrapPI(-PI_2), -PI_2) self.test('wrapPI(-PI)', wrapPI(-PI), -PI) # XXX self.test('wrapPI(-PI2)', abs(wrapPI(-PI2)), 0.0) # -0.0 self.test('wrapPI2(PI_2)', wrapPI2(PI_2), PI_2) self.test('wrapPI2(PI)', wrapPI2(PI), PI) # XXX self.test('wrapPI2(PI2)', wrapPI2(PI2), 0.0) self.test('wrapPI2(-PI_2)', wrapPI2(-PI_2), PI_2 + PI) self.test('wrapPI2(-PI)', wrapPI2(-PI), PI) # XXX self.test('wrapPI2(-PI2)', abs(wrapPI2(-PI2)), 0.0) # -0.0 self.test('unroll180', fstr(unroll180(-90, 110, wrap=True)), '-160.0, -250.0') self.test('unroll180', fstr(unroll180(-90, 110, wrap=False)), '200.0, 110.0') self.test('unroll180', fstr(unroll180(-90, 830, wrap=True)), '-160.0, -250.0') self.test('unroll180', fstr(unroll180(-90, 830, wrap=False)), '920.0, 830.0') self.test('unroll180', fstr(unroll180(-110, 90, wrap=True)), '-160.0, -270.0') self.test('unroll180', fstr(unroll180(-110, 90, wrap=False)), '200.0, 90.0') self.test('unroll180', fstr(unroll180(-830, 90, wrap=True)), '-160.0, -990.0') self.test('unroll180', fstr(unroll180(-830, 90, wrap=False)), '920.0, 90.0') e = d = g = f = 0 for a in range(-1000, 1000): a *= 0.47 r = radians(a) sr, cr = sin(r), cos(r) s, c = sincos2(r) e = max(e, abs(sr - s), abs(cr - c)) sd, cd = sincos2d(a) d = max(d, abs(sr - sd), abs(cr - cd)) if sincosd: # compare with geographiclib s, c = sincosd(a) g = max(g, abs(sr - s), abs(cr - c)) f = max(f, abs(sd - s), abs(cd - c)) EPS_ = EPS * 8 self.test('sincos2', e, EPS, known=e < EPS_) self.test('sincos2d', d, EPS, known=d < EPS_) if sincosd: self.test('sincosd ', g, EPS, known=g < EPS_) self.test('sincos*d', f, EPS, known=f < EPS_) # <https://www.CivilGeo.com/when-a-foot-isnt-really-a-foot/> self.test('iFt2m', ft2m(614963.91), 187441, fmt='%.0f') self.test('iFt2m', ft2m(2483759.84), 757050, fmt='%.0f') self.test('sFt2m', ft2m(614962.68, usurvey=True), 187441, fmt='%.0f') self.test('sFt2m', ft2m(2483754.87, usurvey=True), 757050, fmt='%.0f') self.test('m2iFt', m2ft(187441), 614963.91, fmt='%.0f') self.test('m2iFt', m2ft(757050), 2483759.84, fmt='%.0f') self.test('m2sFt', m2ft(187441, usurvey=True), 614962.68, fmt='%.0f') self.test('m2sFt', m2ft(757050, usurvey=True), 2483754.87, fmt='%.0f') self.test('degrees2m', fstr(degrees2m(90), prec=4), '10007557.1761') self.test('degrees2m', fstr(degrees2m(90, lat=30), prec=4), '8666798.7443') self.test('m2degrees', fstr(m2degrees(degrees2m(90)), prec=1), '90.0') self.test('degrees2m', fstr(degrees2m(180), prec=4), '20015114.3522') self.test('degrees2m', fstr(degrees2m(180, lat=3 - 0), prec=4), '19987684.3336') self.test('m2degrees', fstr(m2degrees(degrees2m(180)), prec=1), '180.0') for a in range(0, 90, 7): d = m2degrees(degrees2m(45, lat=a), lat=a) self.test('m2-degrees-2m(%s, lat=%s)' % (45, a), d, '45.00', fmt='%.2f') self.test('isPoints2', isPoints2(None), False)
def testElliptic(self): RC = elliptic._RC RD = elliptic._RD RF = elliptic._RF RG = elliptic._RG RJ = elliptic._RJ eps4 = EPS * 4 self.test('eps4', eps4, eps4, fmt='%.9e') y = 0.1 for x in range(2, 100): x *= 0.01 rc = RC(x, y) rf = RF(x, y, y) k = abs(rc - rf) < eps4 t = 'RC, RF(%.3f, ...)' % (x, ) self.test(t, rc, rf, fmt='%.12f', known=k) y = x for kp2 in range(1, 100): kp2 *= 0.01 rd = RD(0, kp2, 1) rj = RJ(0, kp2, 1, 1) k = abs(rd - rj) < eps4 t = 'RD, RJ(%.3f, ...)' % (kp2, ) self.test(t, rd, rj, fmt='%.12f', known=k) self.test('eps4', eps4, eps4, fmt='%.9e', nl=1) # <https://GeographicLib.SourceForge.io/html/classGeographicLib_1_1EllipticFunction.html> e = elliptic.Elliptic(0.1) self.test('cK', e.cK, '1.612441349', fmt='%.9f') self.test('cE', e.cE, '1.530757637', fmt='%.9f') self.test('eps', e.eps, '0.0263340', fmt='%.7f') phi = radians(20) sn, cn = sincos2(phi) self.test('fE(phi)', e.fE(phi), '0.348372822', fmt='%.9f') dn = e.fDelta(sn, cn) self.test('fDelta(sn, cn)', dn, '0.994133906', fmt='%.9f') self.test('fD(sn, cn, dn)', e.fD(sn, cn, dn), '0.013885234', fmt='%.9f') self.test('fE(sn, cn, dn)', e.fE(sn, cn, dn), '0.348372822', fmt='%.9f') self.test('fEd(PI_2)', e.fEd(PI_2), '0.027415224', fmt='%.9f') self.test('fEinv(PI_2)', e.fEinv(PI_2), '1.612999420', fmt='%.9f') self.test('fF(sn, cn, dn)', e.fF(sn, cn, dn), '0.349761345', fmt='%.9f') self.test('fG(sn, cn, dn)', e.fG(sn, cn, dn), '0.348372822', fmt='%.9f') self.test('fH(sn, cn, dn)', e.fH(sn, cn, dn), '0.363646580', fmt='%.9f') self.test('fPi(sn, cn, dn)', e.fPi(sn, cn, dn), '0.349761345', fmt='%.9f') try: t = e.fPi(0, None, 1) except EllipticError as x: t = str(x) self.test('fPi(sn, None, dn)', t, 'invokation Elliptic.fPi(0, None, 1): invalid') try: t = e.fPi(0, 1, None) except EllipticError as x: t = str(x) self.test('fPi(sn, dn, None)', t, 'invokation Elliptic.fPi(0, 1, None): invalid') self.test('deltaD(sn, cn, dn)', e.deltaD(sn, cn, dn), '-0.3223642', fmt='%.7f', nl=1) self.test('deltaE(sn, cn, dn)', e.deltaE(sn, cn, dn), '0.0084191', fmt='%.7f') self.test('deltaEinv(sn, cn)', e.deltaEinv(sn, cn), '-0.0082518', fmt='%.7f') self.test('deltaF(sn, cn, dn)', e.deltaF(sn, cn, dn), '-0.0083379', fmt='%.7f') self.test('deltaG(sn, cn, dn)', e.deltaG(sn, cn, dn), '0.0084191', fmt='%.7f') self.test('deltaH(sn, cn, dn)', e.deltaH(sn, cn, dn), '0.3688975', fmt='%.7f') self.test('deltaPi(sn, cn, dn)', e.deltaPi(sn, cn, dn), '-0.0083379', fmt='%.7f') try: t = e.deltaPi(0, None, 1) except EllipticError as x: t = str(x) self.test('deltaPi(sn, None, dn)', t, 'invokation Elliptic.deltaPi(0, None, 1): invalid') try: t = e.deltaPi(0, 1, None) except EllipticError as x: t = str(x) self.test('deltaPi(sn, dn, None)', t, 'invokation Elliptic.deltaPi(0, 1, None): invalid') # U{Carlson<https://ArXiv.org/pdf/math/9409227.pdf>} 3 Numerical checks self.test('RF(1, 2, 0)', RF(1, 2, 0), '1.3110287771461', fmt='%.13f', nl=1) self.test('RF(2, 3, 4)', RF(2, 3, 4), '0.58408284167715', fmt='%.14f') self.test('RC(0, 1/4)', RC(0, 0.25), '3.1415926535898', fmt='%.13f') # PI self.test('RC(9/4, 2)', RC(2.25, 2), '0.69314718055995', fmt='%.14f') # ln(2) self.test('RJ(0, 1, 2, 3)', RJ(0, 1, 2, 3), '0.77688623778582', fmt='%.14f') self.test('RJ(2, 3, 4, 5)', RJ(2, 3, 4, 5), '0.14297579667157', fmt='%.14f') self.test('RD(0, 2, 1)', RD(0, 2, 1), '1.7972103521034', fmt='%.13f') self.test('RD(2, 3, 4)', RD(2, 3, 4), '0.16510527294261', fmt='%.14f') self.test('RG(0, 16, 16)', RG(0, 16, 16), '3.1415926535898', fmt='%.13f') # PI self.test('RG(2, 3, 4)', RG(2, 3, 4), '1.7255030280692', fmt='%.13f') self.test('RG(0, 0.0796, 4)', RG(0, 0.0796, 4), '1.0284758090288', fmt='%.13f') e.reset(0, 0) self.test('sncndn(x)', fstr(e.sncndn(0), prec=9), '0.0, 1.0, 1.0', nl=1) self.test('sncndn(x)', fstr(e.sncndn(PI_2), prec=9), '1.0, -0.0, 1.0', known=True) e.reset(1, 1) self.test('sncndn(x)', fstr(e.sncndn(0), prec=9), '0.0, 1.0, 1.0') self.test('sncndn(x)', fstr(e.sncndn(PI_2), prec=9), '0.917152336, 0.398536815, 0.398536815') self.test('sncndn(x)', type(e.sncndn(PI_4)), elliptic.Elliptic3Tuple) self.testCopy(e) for f in range(4): # coverage t = (f / 4.0, ) * 4 e = elliptic.Elliptic(*t) s = 'k2 alpha2 kp2 alphap2' e = tuple(getattr(e, a) for a in s.split()) t = tuple(Scalar(f, name=n) for n, f in zip(s.split(), t)) self.test(s, e, t)
def testAlbers2(self): A = AlbersEqualArea2(40 + 58 / 60.0, 39 + 56 / 60.0, name='Karney_example') # WGS84 self.test('name', A.named, A.named) self.test('datum', A.datum.name, _WGS84.name) self.test('ellipsoid', A.datum.ellipsoid.name, _WGS84.ellipsoid.name) for n, x in (('lat0', '40.451991337063'), ('scale0', '0.999959500363'), ('equatoradius', A.datum.ellipsoid.a), ('flattening', A.datum.ellipsoid.f), ('_sign', '1.000000000000'), ('_m02', '0.580681094922'), ('_n0', '0.648810669236'), ('_txi0', '0.848822476849')): self.test(n, getattr(A, n), x, fmt='%.12f') self.test('iteration', A.iteration, 3, known=A.iteration > 0) self.test('ispolar', A.ispolar, False) for lon0, x in ( (0, '-5675721.76113534, 2516917.91242155, 39.95, -75.17, 311.23285234, 0.99999745' ), (-77.5, '199089.12574012, -53115.52801838, 39.95, 2.33, 1.51160641, 0.99999745' )): f = A.forward(39.95, -75.17, lon0=lon0) self.test('forward', fstr(f[:6], prec=8), x, known=round(f.x, 7) == -5675721.7611353) r = A.reverse(f.x, f.y, lon0=lon0) self.test('reverse', fstr(r[:6], prec=8), x, known=round(r.lon, 2) == -75.17) for lon0, x in ( (0, '220000.0, -53000.0, 39.94581132, 2.57463362, 1.67031446, 0.99999808' ), (-77.5, '220000.0, -53000.0, 39.94581132, -74.92536638, 1.67031446, 0.99999808' )): r = A.reverse(220e3, -53e3, lon0=lon0) self.test('reverse', fstr(r[:6], prec=8), x) f = A.forward(r.lat, r.lon, lon0=lon0) self.test('forward', fstr(f[:6], prec=8), x, known=round(f.lon, 8) == 2.57463362) self.subtitle(albers, 'Page292') A = AlbersEqualArea2(29.5, 45.5, datum=_NAD27, name='Snyder_p292') self.test('name', A.named, A.named) self.test('datum', A.datum.name, _NAD27.name) self.test('ellipsoid', A.datum.ellipsoid.name, _NAD27.ellipsoid.name) for n, x in ( ('lat0', '37.934543880726'), ('scale0', '0.990309187872'), ('equatoradius', A.datum.ellipsoid.a), ('flattening', A.datum.ellipsoid.f), ('_sign', '1.000000000000'), ('_m02', '0.623664507732'), ('_n0', '0.614760830736'), # ('_nrho0', '5037024.736824393272'), ('_txi0', '0.775925617021')): self.test(n, getattr(A, n), x, fmt='%.12f') self.test('iteration', A.iteration, 4, known=A.iteration > 0) self.test('ispolar', A.ispolar, False) for lon0, x in ( (0, '-6105839.22928148, 2214046.74930274, 35.0, -75.0, 314.78223745, 0.99155461' ), (-96, '1885472.72581347, -119505.66687766, 35.0, 21.0, 12.66097351, 0.99155461' )): f = A.forward(35, -75, lon0=lon0) self.test('forward', fstr(f[:6], prec=8), x, known=round(f.x, 7) == -6105839.2292815 or round(f.y, 7) == -119505.6668777) r = A.reverse(f.x, f.y, lon0=lon0) self.test('reverse', fstr(r[:6], prec=8), x, known=round(r.lon, 1) == -75.0) for lon0, x in ( (0, '1885427.7, 1535925.0, 49.40436665, 25.93001383, 15.63329611, 1.01436109' ), (-96, '1885427.7, 1535925.0, 49.40436665, -70.06998617, 15.63329611, 1.01436109' )): r = A.reverse(1885427.7, 1535925, lon0=lon0) self.test('reverse', fstr(r[:6], prec=8), x) f = A.forward(r.lat, r.lon, lon0=lon0) self.test('forward', fstr(f[:6], prec=8), x, known=round(f.lon, 8) == 25.93001383) self.subtitle(albers, 'Table15') A = AlbersEqualArea2(29.5, 45.5, datum=Datums.NAD27, name='Snyder_p103') for lat, k in ((52, 1.02863), (50, 1.01727), (45.5, 1.00000), (45, 0.99869), (40, 0.99097), (35, 0.99155), (30, 0.99893), (29.5, 1.00000), (25, 1.01222), (22, 1.02283)): t = A.forward(lat, 0) self.test(str(lat) + ' k', t.scale, k, fmt='%.5f')
def _AB(E, K, A, B): E.KsOrder = K self.test('WGS84.AlphaKs', fstr(E.AlphaKs, prec=12, fmt='%.*e', ints=True), A) self.test('WGS84.BetaKs ', fstr(E.BetaKs, prec=12, fmt='%.*e', ints=True), B)
def testUtily(self): # Python 2.6.9 on Travis Ubuntu 14.04 produces -0.0 self.test('degrees90(PI_2)', degrees90(PI_2), 90.0) self.test('degrees90(PI)', degrees90(PI), -180.0) # XXX self.test('degrees90(PI2)', degrees90(PI2), 0.0) self.test('degrees90(-PI_2)', degrees90(-PI_2), -90.0) self.test('degrees90(-PI)', degrees90(-PI), -180.0) # XXX self.test('degrees90(-PI2)', abs(degrees90(-PI2)), 0.0) # -0.0 self.test('degrees180(PI_2)', degrees180(PI_2), 90.0) self.test('degrees180(PI)', degrees180(PI), 180.0) # XXX self.test('degrees180(PI2)', degrees180(PI2), 0.0) self.test('degrees180(-PI_2)', degrees180(-PI_2), -90.0) self.test('degrees180(-PI)', degrees180(-PI), -180.0) # XXX self.test('degrees180(-PI2)', abs(degrees180(-PI2)), 0.0) # -0.0 self.test('degrees360(PI_2)', degrees360(PI_2), 90.0) self.test('degrees360(PI)', degrees360(PI), 180.0) # XXX self.test('degrees360(PI2)', degrees360(PI2), 0.0) self.test('degrees360(-PI_2)', degrees360(-PI_2), 270.0) self.test('degrees360(-PI)', degrees360(-PI), 180.0) # XXX self.test('degrees360(-PI2)', abs(degrees360(-PI2)), 0.0) # -0.0 self.test('radiansPI_2(90)', radiansPI_2(90), PI_2) self.test('radiansPI_2(180)', radiansPI_2(180), -PI) self.test('radiansPI_2(360)', radiansPI_2(360), 0.0) self.test('radiansPI_2(-90)', radiansPI_2(-90), -PI_2) self.test('radiansPI_2(-180)', radiansPI_2(-180), -PI) self.test('radiansPI_2(-360)', abs(radiansPI_2(-360)), 0.0) # -0.0 self.test('radiansPI(90)', radiansPI(90), PI_2) self.test('radiansPI(180)', radiansPI(180), PI) self.test('radiansPI(360)', radiansPI(360), 0.0) self.test('radiansPI(-90)', radiansPI(-90), -PI_2) self.test('radiansPI(-180)', radiansPI(-180), -PI) self.test('radiansPI(-360)', abs(radiansPI(-360)), 0.0) # -0.0 self.test('radiansPI2(90)', radiansPI2(90), PI_2) self.test('radiansPI2(180)', radiansPI2(180), PI) self.test('radiansPI2(360)', radiansPI2(360), 0.0) self.test('radiansPI2(-90)', radiansPI2(-90), PI_2 + PI) self.test('radiansPI2(-180)', radiansPI2(-180), PI) self.test('radiansPI2(-360)', abs(radiansPI2(-360)), 0.0) # -0.0 self.test('wrap90(90)', wrap90(90), 90.0) self.test('wrap90(180)', wrap90(180), -180.0) self.test('wrap90(360)', wrap90(360), 0.0) self.test('wrap90(-90)', wrap90(-90), -90.0) self.test('wrap90(-180)', wrap90(-180), -180.0) self.test('wrap90(-360)', wrap90(-360), 0.0) self.test('wrap180(90)', wrap180(90), 90.0) self.test('wrap180(180)', wrap180(180), 180.0) self.test('wrap180(360)', wrap180(360), 0.0) self.test('wrap180(-90)', wrap180(-90), -90.0) self.test('wrap180(-180)', wrap180(-180), -180.0) self.test('wrap180(-360)', wrap180(-360), 0.0) self.test('wrap360(90)', wrap360(90), 90.0) self.test('wrap360(180)', wrap360(180), 180.0) self.test('wrap360(360)', wrap360(360), 0.0) self.test('wrap360(-90)', wrap360(-90), 270.0) self.test('wrap360(-180)', wrap360(-180), 180.0) self.test('wrap360(-360)', wrap360(-360), 0.0) self.test('wrapPI_2(PI_2)', wrapPI_2(PI_2), PI_2) self.test('wrapPI_2(PI)', wrapPI_2(PI), -PI) # XXX self.test('wrapPI_2(PI2)', wrapPI_2(PI2), 0.0) self.test('wrapPI_2(-PI_2)', wrapPI_2(-PI_2), -PI_2) self.test('wrapPI_2(-PI)', wrapPI_2(-PI), -PI) # XXX self.test('wrapPI_2(-PI2)', abs(wrapPI_2(-PI2)), 0.0) self.test('wrapPI(PI_2)', wrapPI(PI_2), PI_2) self.test('wrapPI(PI)', wrapPI(PI), PI) # XXX self.test('wrapPI(PI2)', wrapPI(PI2), 0.0) self.test('wrapPI(-PI_2)', wrapPI(-PI_2), -PI_2) self.test('wrapPI(-PI)', wrapPI(-PI), -PI) # XXX self.test('wrapPI(-PI2)', abs(wrapPI(-PI2)), 0.0) # -0.0 self.test('wrapPI2(PI_2)', wrapPI2(PI_2), PI_2) self.test('wrapPI2(PI)', wrapPI2(PI), PI) # XXX self.test('wrapPI2(PI2)', wrapPI2(PI2), 0.0) self.test('wrapPI2(-PI_2)', wrapPI2(-PI_2), PI_2 + PI) self.test('wrapPI2(-PI)', wrapPI2(-PI), PI) # XXX self.test('wrapPI2(-PI2)', abs(wrapPI2(-PI2)), 0.0) # -0.0 self.test('unroll180', fstr(unroll180(-90, 110, wrap=True)), '-160.0, -250.0') self.test('unroll180', fstr(unroll180(-90, 110, wrap=False)), '200.0, 110.0') self.test('unroll180', fstr(unroll180(-90, 830, wrap=True)), '-160.0, -250.0') self.test('unroll180', fstr(unroll180(-90, 830, wrap=False)), '920.0, 830.0') self.test('unroll180', fstr(unroll180(-110, 90, wrap=True)), '-160.0, -270.0') self.test('unroll180', fstr(unroll180(-110, 90, wrap=False)), '200.0, 90.0') self.test('unroll180', fstr(unroll180(-830, 90, wrap=True)), '-160.0, -990.0') self.test('unroll180', fstr(unroll180(-830, 90, wrap=False)), '920.0, 90.0') e = d = g = f = t = 0 for a in range(-1000, 1000, 2): a *= 0.47 r = radians(a) sr, cr = sin(r), cos(r) s, c = sincos2(r) e = max(e, abs(sr - s), abs(cr - c)) sd, cd = sincos2d(a) d = max(d, abs(sr - sd), abs(cr - cd)) if Math: # compare with geographiclib t = max(t, abs(atan2d(sr, cr) - atand(sr, cr))) s, c = sincosd(a) g = max(g, abs(sr - s), abs(cr - c)) f = max(f, abs(sd - s), abs(cd - c)) EPS_ = EPS * 8 self.test('sincos2', e, EPS_, known=e < EPS_) self.test('sincos2d', d, EPS_, known=d < EPS_) if Math: self.test('atand', t, EPS, known=t < EPS) self.test('sincosd ', g, EPS_, known=g < EPS_) self.test('sincos*d', f, EPS_, known=f < EPS_) # <https://www.CivilGeo.com/when-a-foot-isnt-really-a-foot/> self.test('iFt2m', ft2m(614963.91), 187441, fmt='%.0f') self.test('iFt2m', ft2m(2483759.84), 757050, fmt='%.0f') self.test('sFt2m', ft2m(614962.68, usurvey=True), 187441, fmt='%.0f') self.test('sFt2m', ft2m(2483754.87, usurvey=True), 757050, fmt='%.0f') self.test('m2iFt', m2ft(187441), 614963.91, prec=2) self.test('m2iFt', m2ft(757050), 2483759.84, prec=2) self.test('m2sFt', m2ft(187441, usurvey=True), 614962.68, prec=2) self.test('m2sFt', m2ft(757050, usurvey=True), 2483754.87, prec=2) for f, m in ((m2yard, '1.093613'), (acre2ha, '0.404686'), (acre2m2, '4046.856422'), (chain2m, '20.116800'), (fathom2m, '1.828800'), (furlong2m, '201.168000'), (yard2m, '0.914400')): self.test(f.__name__, f(1), m, prec=6) self.test('degrees2m', fstr(degrees2m(90), prec=4), '10007557.1761') self.test('degrees2m', fstr(degrees2m(90, lat=30), prec=4), '8666798.7443') self.test('m2degrees', fstr(m2degrees(degrees2m(90)), prec=1), '90.0') self.test('degrees2m', fstr(degrees2m(180), prec=4), '20015114.3522') self.test('degrees2m', fstr(degrees2m(180, lat=3 - 0), prec=4), '19987684.3336') self.test('m2degrees', fstr(m2degrees(degrees2m(180)), prec=1), '180.0') t = 'm2degrees2m(%s, lat=%s)' for a in range(0, 90, 7): d = m2degrees(degrees2m(45, lat=a), lat=a) self.test(t % (45, a), d, '45.00', prec=2) self.test('isPoints2', isPoints2(None), False)
def testWebMercator(self, LatLon, LatLonE): # <https://AlastairA.WordPress.com/2011/01/23/ # the-google-maps-bing-maps-spherical-mercator-projection> lat = 52.4827802220782 w = toWm(lat, -5.625) self.test('toWm1', w.toStr(prec=8), '-626172.13571216 6887893.4928338') y = R_MA * log(tan(radians((90 + lat) * 0.5))) self.test('Wm1.y', y, '6887893.49283380', fmt='%.8f') self.testCopy(w) w = Wm(448251.795, 5411932.678) self.test('Wm2', w, '448251.795 5411932.678') self.test('Wm2', w.toStr(prec=0), '448252 5411933') self.test('Wm2', w.toStr(prec=1), '448251.8 5411932.7') self.testCopy(w) ll = w.to2ll(None) # 2-tuple self.test('Wm2.to2ll', fstr(ll, prec=8), '43.65321741, 4.02671439') ll = w.toLatLon(LatLon) self.test('Wm2.toLatLon', ll, '43.653217°N, 004.026714°E') self.test('Wm2.toLatLon', ll.toStr(form=F_DMS), '43°39′11.58″N, 004°01′36.17″E') w = ll.toWm() # 448251.795205746 5411932.67761691 self.test('toWm1', w, '448251.795 5411932.678') self.test('toWm2', w.toStr(prec=0), '448252 5411933') self.test('toWm3', w.toRepr(prec=0, radius=True), '[x:448252, y:5411933, radius:6378137]') self.test('toWm3', w.toStr2(prec=0, radius=True), '[x:448252, y:5411933, radius:6378137]') t = w.copy() self.test('copy', t, w) t = w.parseWM(w.toStr(prec=3)) self.test('parseWM', t, w) t = w.parseWM(w.toStr(prec=3, radius=True)) self.test('parseWM', t, w) t = w.parseWM(w.toStr(prec=3, radius=0)) self.test('parseWM', t.toStr2(radius=True), w.toStr2(radius=True)) ll = LatLon(13.4125, 103.8667) w = toWm(ll) self.test('toWm4', w.toStr(prec=0), '11562388 1506899') self.test('toWm4', w.toStr(prec=6), '11562388.154378 1506899.04498') ll = LatLonE(13.4125, 103.8667) w = toWm(ll) self.test('toWm4E', w.toStr(prec=0), '11562388 1496994') self.test('toWm4E', w.toStr(prec=6), '11562388.154378 1496993.698095') # <https://www.EPSG.org/Portals/0/373-07-02.pdf> page 42 ll = LatLon('''24°22'54.433"N''', '''100°20'0"W''') w = ll.toWm() self.test('toWm5', w.toStr(prec=0), '-11169056 2800000') self.test('toWm5', w.toStr(prec=6), '-11169055.576258 2800000.003136') ll = LatLonE('''24°22'54.433"N''', '''100°20'00.0"W''') w = ll.toWm() self.test('toWm5E', w.toStr(prec=0), '-11169056 2782367') self.test('toWm5E', w.toStr(prec=6), '-11169055.576258 2782367.05923') w = Wm(-11169055.58, 2810000) ll = w.toLatLon(LatLon) self.test('Wm6.toLatLon', ll, '24.46358°N, 100.333333°W') self.test('Wm6.toLatLon', ll.toStr(form=F_DMS), '24°27′48.89″N, 100°20′00.0″W') ll = w.toLatLon(LatLonE, datum=Datums.WGS84) self.test('Wm6.toLatLonE', ll, '24.299812°N, 100.333333°W') self.test('Wm6.toLatLonE', ll.toStr(form=F_DMS), '24°17′59.32″N, 100°20′00.0″W') w = Wm(-11169055.58, 2800000) ll = w.toLatLon(LatLon) self.test('Wm7.toLatLon', ll, '24.381787°N, 100.333333°W') self.test('Wm7.toLatLon', ll.toStr(form=F_DMS), '24°22′54.43″N, 100°20′00.0″W') ll = w.toLatLon(LatLonE, datum=Datums.WGS84) self.test('Wm7.toLatLonE', ll, '24.218566°N, 100.333333°W') self.test('Wm7.toLatLonE', ll.toStr(form=F_DMS), '24°13′06.84″N, 100°20′00.0″W') # <https://AlastairA.WordPress.com/2011/01/23/ # the-google-maps-bing-maps-spherical-mercator-projection> w = toWm(51.4085960537841, -0.304339270784791, Wm=None) self.test('Wm8.toWm', fstr(w, prec=3), '-33878.893, 6693890.382, 6378137.0') w = toWm(51.4085960537841, -0.304339270784791) self.test('Wm8.toWm', w.toRepr(), '[x:-33878.893, y:6693890.382]') self.test('Wm8.toWm', w.toStr2(), '[x:-33878.893, y:6693890.382]') self.test('Wm8.toWm', w.toStr(radius=R_M), '-33878.893 6693890.382 6371008.771') self.test('Wm8.toWm.x', w.x, '-33878.893', fmt='%.3f') self.test('Wm8.toWm.y', w.y, '6693890.382', fmt='%.3f') self.test('Wm8.toWm.latlon', fstr(w.latlon, prec=6), '51.408596, -0.304339') self.test('Wm8.toWm.philam', fstr(w.philam, prec=6), '0.897249, -0.005312') ll = w.toLatLon(LatLon) self.test('Wm8.toLatLon', ll.toStr(form=F_D, prec=12), '51.408596053784°N, 000.304339270785°W') self.test('Wm8.toLatLon', ll.toStr(form=F_DMS, prec=6), '51°24′30.945794″N, 000°18′15.621375″W') for LL, datum in ((LatLon, Datums.WGS84), (LatLon_, Datums.WGS84), (LatLonE, None), (None, Datums.WGS84), (None, None)): try: ll = w.toLatLon(LL, datum=datum) except TypeError: ll = 'TypeError' self.test('Wm9.toLatLon', ll, 'TypeError') # <https://Earth-Info.NGA.mil/GandG/wgs84/web_mercator/ # %28U%29%20NGA_SIG_0011_1.0.0_WEBMERC.pdf> self._TableA1(LatLon, '', 0, '1118889.97', '2273030.93', '3503549.84', '4865942.28', '6446275.84', '8399737.89') self._TableA1(LatLon, '', 1.0 / 3600, '1118921.37', '2273063.83', '3503585.55', '4865982.65', '6446323.95', '8399799.73') self._TableA1(LatLonE, 'E', 0, '1111475.10', '2258423.65', '3482189.09', '4838471.40', '6413524.59', '8362698.55') self._TableA1(LatLonE, 'E', 1.0 / 3600, '1111506.30', '2258456.36', '3482224.61', '4838511.61', '6413572.57', '8362760.29')
def testDatum(self): # datum module tests E = Ellipsoid(1000, 1000, 0, name='TestEllipsiod') self.test('ellipsoid', E is Ellipsoids.TestEllipsiod, True) # print(Ellipsoid()) T = Transform(name='TestTransform') self.test('transform', T is Transforms.TestTransform, True) # print(Transform()) D = Datum(E, T, name='TestDatum') self.test('datum', D is Datums.TestDatum, True) # print(Datum()) e = Ellipsoids.unregister('TestEllipsiod') self.test(e.name, e, E) t = Transforms.unregister('TestTransform') self.test(t.name, t, T) d = Datums.unregister('TestDatum') self.test(d.name, d, D) T = Transforms.ED50 t = T.inverse().inverse("ED50_") self.test('ED50.inverse().inverse()', t == T, True) # to show WGS84 and NAD83 are identical up to 3 decimals for E in (Ellipsoids.WGS84, Ellipsoids.GRS80): # NAD83 self.test('R1', E.R1, R_M, fmt='%.4f') self.test('R2', E.R2, '6371007.2', fmt='%.1f') self.test('R3', E.R3, '6371000.8', fmt='%.1f') self.test('Rr', E.Rr, '6367449.1', fmt='%.1f') # 6367445.0 self.test('Rs', E.Rs, '6367435.7', fmt='%.1f') self.test('Rgeocentric', E.Rgeocentric(0), '6378137.000', fmt='%.3f') self.test('Rgeocentric', E.Rgeocentric(45), '6367489.544', fmt='%.3f') self.test('Rgeocentric', E.Rgeocentric(90), '6356752.314', fmt='%.3f') self.test('Rlat', E.Rlat(0), '6378137.000', fmt='%.3f') self.test('Rlat', E.Rlat(45), '6367444.657', fmt='%.3f') self.test('Rlat', E.Rlat(90), '6356752.314', fmt='%.3f') self.test('distance2', fstr(E.distance2(0, 0, 1, 1), prec=3), '156903.472, 45.192') self.test('distance2', fstr(E.distance2(0, 0, 10, 10), prec=3), '1569034.719, 45.192') self.test('distance2', fstr(E.distance2(40, 40, 50, 50), prec=3), '1400742.676, 37.563') self.test('distance2', fstr(E.distance2(70, 70, 80, 80), prec=3), '1179164.848, 18.896') self.test('roc2', fstr(E.roc2(0), prec=3), '6335439.327, 6378137.0') self.test('roc2', fstr(E.roc2(45), prec=3), '6367381.816, 6388838.29') self.test('roc2', fstr(E.roc2(90), prec=3), '6399593.626, 6399593.626') self.test('rocBearing', E.rocBearing(0, 0), '6335439.327', fmt='%.3f') self.test('rocBearing', E.rocBearing(45, 45), '6378092.008', fmt='%.3f') self.test('rocBearing', E.rocBearing(90, 0), '6399593.626', fmt='%.3f') self.test('rocGauss', E.rocGauss(0), '6356752.314', fmt='%.3f') self.test('rocGauss', E.rocGauss(45), '6378101.030', fmt='%.3f') self.test('rocGauss', E.rocGauss(90), '6399593.626', fmt='%.3f') self.test('rocMean', E.rocMean(0), '6356716.465', fmt='%.3f') self.test('rocMean', E.rocMean(45), '6378092.008', fmt='%.3f') self.test('rocMean', E.rocMean(90), '6399593.626', fmt='%.3f') self.test('rocMeridional', fstr(E.rocMeridional(0), prec=3), '6335439.327') self.test('rocMeridional', fstr(E.rocMeridional(45), prec=3), '6367381.816') self.test('rocMeridional', fstr(E.rocMeridional(90), prec=3), '6399593.626') self.test('rocPrimeVertical', fstr(E.rocPrimeVertical(0), prec=3), '6378137.0') self.test('rocPrimeVertical', fstr(E.rocPrimeVertical(45), prec=3), '6388838.29') self.test('rocPrimeVertical', fstr(E.rocPrimeVertical(90), prec=3), '6399593.626') self.test('a, b, None', Ellipsoid(1000, 500, None).f_, 2.0) # coverage self.test('a, None, f_', Ellipsoid(1000, None, 2).b, 500.0) # coverage E = Ellipsoids.WGS84.copy() # coverage self.test('WGS84.copy', E is not Ellipsoids.WGS84, True) self.test('WGS84.copy', E == Ellipsoids.WGS84, True) self.test('WGS84.find', Ellipsoids.find(E), None) self.test('WGS84.a2_b', E.a2_b, E.a2 / E.b, fmt='%.6f') self.test('WGS84.b2_a', E.b2_a, E.b2 / E.a, fmt='%.6f') self.test('WGS84.c', E.c, E.R2, fmt='%.6f') self.test('WGS84.es', E.es, E.e, fmt='%.6f') self.test('WGS84.f2', E.f2, (E.a - E.b) / E.b, fmt='%.6f') self.test('WGS84.m2degrees', int(E.m2degrees(E.a * PI_2)), 90) self.test('WGS84.area', E.area, '5.101e+14', fmt='%.3e') self.test('WGS84.volume', E.volume, '1.083e+21', fmt='%.3e') self.test('WGS84.ecef', E.ecef().__class__, EcefKarney) self.test('WGS84.ecef', E.ecef().name, E.name) t = E.toStr(prec=10) self.test( 'WGS84', t, "name='WGS84', a=6378137, b=6356752.3142499998, f_=298.257223563, f=0.0033528107, e=0.0818191908, e2=0.00669438, e12=0.99330562, e22=0.0067394967, n=0.0016792204, R1=6371008.7714166669, R2=6371007.180920884, R3=6371000.7900107643, Rr=6367449.1458250275, Rs=6367435.6797186071" ) e = (E.a - E.b) / (E.a + E.b) - E.n t = 'A=%.10f, e=%.10f, f_=%.10f, n=%.10f(%.10e)' % (E.A, E.e, E.f_, E.n, e) self.test( 'WGS84.', t, "A=6367449.1458234144, e=0.0818191908, f_=298.2572235630, n=0.0016792204(-3.7914875232e-13)" ) def _AB(E, K, A, B): E.KsOrder = K self.test('WGS84.AlphaKs', fstr(E.AlphaKs, prec=12, fmt='%.*e', ints=True), A) self.test('WGS84.BetaKs ', fstr(E.BetaKs, prec=12, fmt='%.*e', ints=True), B) _AB( E, 8, '8.377318206245e-04, 7.608527773572e-07, 1.197645503242e-09, 2.429170680397e-12, 5.711818370428e-15, 1.47999793138e-17, 4.107624109371e-20, 1.210785038923e-22', '8.377321640579e-04, 5.90587015222e-08, 1.673482665344e-10, 2.164798110491e-13, 3.787930968626e-16, 7.236769021816e-19, 1.493479824778e-21, 3.259522545838e-24' ) _AB( E, 6, '8.377318206245e-04, 7.608527773572e-07, 1.197645503329e-09, 2.429170607201e-12, 5.711757677866e-15, 1.491117731258e-17', '8.377321640579e-04, 5.90587015222e-08, 1.673482665284e-10, 2.164798040063e-13, 3.787978046169e-16, 7.248748890694e-19' ) _AB( E, 4, '8.377318206304e-04, 7.608527714249e-07, 1.197638001561e-09, 2.443376194522e-12', '8.377321640601e-04, 5.905869567934e-08, 1.673488880355e-10, 2.167737763022e-13' )
def testEllipsoidal(self, module, Cartesian, Nvector): # ellipsoidal modules tests self.subtitle(module, 'Ellipsoidal') LatLon = module.LatLon p = LatLon(51.4778, -0.0016, 0, Datums.WGS84) self.test('isEllipsoidal', p.isEllipsoidal, True) self.test('isSpherical', p.isSpherical, False) d = p.convertDatum(Datums.OSGB36) self.test('isEllipsoidal', d.isEllipsoidal, True) self.test('isSpherical', d.isSpherical, False) self.test('convertDatum', d, '51.477284°N, 000.00002°E, -45.91m' ) # 51.4773°N, 000.0000°E, -45.91m self.test('convertDatum', d.toStr(F_D, prec=4), '51.4773°N, 000.0°E, -45.91m') self.test('convertDatum', p.convertDatum(p.datum), p) # i.e. p.copy() if coverage: # coverage self.test('parse', p.parse(d.toStr(F_D__)), d) p.reframe = None self.test('reframe', p.reframe, None) c = p.toCartesian() self.test('toCartesian', c, '[3980581.21, -111.159, 4966824.522]') t = fstr(c.toEcef()[:3], 3) self.test('toEcef', t, '3980581.21, -111.159, 4966824.522') self.test('toEtm', p.toEtm(), '30 N 916396 5720041') self.test('toLcc', p.toLcc(), '5639901 4612638') self.test('toOsgr', p.toOsgr(), 'TQ 38876 77320') self.test('toUtmUps', p.toUtmUps(), '30 N 708207 5707224') self.test('toUtm', p.toUtm(), '30 N 708207 5707224') self.test('toWm', p.toWm(), '-178.111 6672799.209') self.test('elevation2', p.elevation2(timeout=0.1)[0], None) self.test('geoidHeight2', p.geoidHeight2(timeout=0.1)[0], None) p._update(True) # zap cached attrs self.test('toUtmUps', p.toUtmUps(), '30 N 708207 5707224') self.test('toUtmUps', p.toUtmUps(), '30 N 708207 5707224') p = p.copy() self.test('toUtm', p.toUtm(), '30 N 708207 5707224') self.test('toUtm', p.toUtm(), '30 N 708207 5707224') p = LatLon(84, 0) self.test('toUtmUps', p.toUtmUps(), '00 N 2000000 1333272') self.test('toUtmUps', p.toUtmUps(), '00 N 2000000 1333272') p = p.copy() self.test('toUps', p.toUps(), '00 N 2000000 1333272') self.test('toUps', p.toUps(), '00 N 2000000 1333272') p.lat = 86 self.test('toUps', p.toUps(), '00 N 2000000 1555732') p.lat = 83 self.test('toUtm', p.toUtm(), '31 N 459200 9217519') if Cartesian and Nvector: c = Cartesian(3980581, 97, 4966825) n = c.toNvector( ) # {x: 0.6228, y: 0.0000, z: 0.7824, h: 0.0000} # XXX height self.test('toNVector', n.toStr(4), '(0.6228, 0.0, 0.7824, +0.24)') self.test('toNvector', isinstance(n, Nvector), True) c = n.toCartesian() self.test('toCartesian', c.toStr(0), '[3980581, 97, 4966825]') self.test('toCartesian', isinstance(c, Cartesian), True) v = n.toVector3d() self.test('toVector3D', v.toStr(4), '(0.6228, 0.0, 0.7824)') n = Nvector(0.5, 0.5, 0.7071) self.test('Nvector', n, '(0.5, 0.5, 0.7071)') v = n.toVector3d() self.test('toVector3D', v.toStr(4), '(0.5, 0.5, 0.7071)') t = n.to3abh() # DEPRECATED self.test('to3abh', fstr(t, 4), '0.7854, 0.7854, 0.0') t = n.to3llh() # DEPRECATED self.test('to3llh', fstr(t, 3), '45.0, 45.0, 0.0') t = n.to4xyzh() # DEPRECATED self.test('to4xyzh', fstr(t, 1), '0.5, 0.5, 0.7, 0.0') n.H = '' # for test coverage c = n.toCartesian() # [3194434, 3194434, 4487327] self.test('toCartesian', c, '[3194434.411, 3194434.411, 4487326.82]') self.test('toCartesian', isinstance(c, Cartesian), True) p = c.toLatLon() # 45.0°N, 45.0°E self.test('toLatLon', p.toStr('d', 2), '45.0°N, 045.0°E, +0.00m') # 45.0°N, 45.0°E self.test('toLatLon', isinstance(p, LatLon), True) n = Nvector(0.51, 0.512, 0.7071, 1).toStr(3) self.test('Nvector', n, '(0.51, 0.512, 0.707, +1.00)') # <https://GitHub.com/DieuwerH/AE3537/blob/master/PyGeodesyTesting.py> s = Cartesian(3145.5036885, 5387.14337206, 3208.93193301).toLatLon() # WGS84 XXX m, Km, other? self.test( 'sat', s, '82.545852°N, 059.719736°E, -6353121.71m' if Nvector or module is V else '82.219069°N, 059.719736°E, -6353120.97m') # XXX neg height? d = LatLon(51.99888889, 4.37333333, height=134.64, name='DopTrackStation') self.test('dop', d, '51.998889°N, 004.373333°E, +134.64m') self.test('distance', d.distanceTo(s), '3806542.94364687' if Nvector else ('3817991.07401530' if module is V else '3802238.50498862'), fmt='%.8f')
def testUtm(self, LL): u = utm.Utm(3, 'N', 448251, 5411932.0001) self.test('Utm1', u.toStr(4), '03 N 448251.0 5411932.0001') u = utm.Utm(31, 'N', 448251.795, 5411932.678) self.test('Utm2', u, '31 N 448252 5411933') self.test('Utm2', u.toStr(prec=3), '31 N 448251.795 5411932.678') self.test('Utm2', u.toStr(prec=1, cs=True), '31 N 448251.8 5411932.7 n/a n/a') ll = u.toLatLon(LL) # 48.85820000°N, 002.29450000°E self.test('Utm.toLatLon1', ll, '48.8582°N, 002.2945°E') self.test('Utm.toLatLon1', ll.toStr(form=F_DMS), '48°51′29.52″N, 002°17′40.2″E') u = ll.toUtm( ) # 31U N 448251.795205746 5411932.67761691 -000.53131221° 0.9996329 self.test('toUtm1', u, '31 N 448252 5411933') self.test('toUtm1', u.toStr(prec=3), '31 N 448251.795 5411932.678') self.test( 'toUtm2', u.toRepr(B=True, cs=True), '[Z:31U, H:N, E:448252, N:5411933, C:-31.87873265′, S:0.9996329]') self.test( 'toUtm2', u.toStr2(B=True, cs=True), '[Z:31U, H:N, E:448252, N:5411933, C:-31.87873265′, S:0.9996329]') ll = LL(13.4125, 103.8667) u = toUtm8( ll ) # 48P N 377302.354182663 1483034.77706381 -000.26291348° 0.999786229 self.test('toUtm4', u, '48 N 377302 1483035') self.test( 'toUtm5', u.toStr(prec=6, B=True, cs=True), '48P N 377302.354183 1483034.777084 -15.77480856′ 0.99978623') ll = LL(-13.4125, -103.8667) u = ll.toUtm( ) # 13L S 622697.645817337 8516965.22293619 -000.26291348° 0.999786229 self.test('toUtm6', u, '13 S 622698 8516965') self.test( 'toUtm7', u.toStr(prec=6, B=True, cs=True), '13L S 622697.645817 8516965.222916 -15.77480856′ 0.99978623') t = u.toEtm() self.test('toEtm', t, '13 S 622698 8516965') m = u.toMgrs() self.test('toMgrs1', m, '13L FF 22697 16965') m = Utm('31U', 'N', 448251, 5411932).toMgrs() self.test('toMgrs2', m, '31U DQ 48251 11932') t = u.toUps(pole=u.pole) self.test('toUps', t, '00 S -7702368 -395110') # XXX invalid? t = u.toUtm(14) self.test('toUtm14', t, '14 S -27436 8512042') # XXX invalid? u = parseUTM5('18 N 516620 4574500') # Milford, PA self.test('Utm8', u, '18 N 516620 4574500') ll = u.toLatLon(LL) self.test('Utm8.toLatLon', ll, '41.321801°N, 074.801413°W') self.test('Utm8.toLatLon', ll.toStr(F_DEG), '41.321801N, 074.801413W') for lat, lon, x in ( (61.44, 25.4, '35V N 414668 6812845' ), # 35V N 414668.257431168 6812844.72764648 (-47.04, -73.48, '18G S 615472 4789270' ), # 18G S 615471.65815765 4789269.76738578 (40.4, -74.7, '18T N 525458 4472198' ), # 18T N 525457.882388688 4472198.04072697 (44.5, -88.5, '16T N 380753 4928503' ), # 16T N 380753.114847639 4928503.38224615 (50.8694, -115.6508, '11U N 594937 5636169' ), # 11U N 594936.575444796 5636168.98481247 (0.0, 0.0, '31N N 166021 0'), # 31N N 166021.443080537 0 (0.13, -0.2324, '30N N 808084 14386' ), # 30N N 808084.436750719 14385.7989105346 (-45.6456, 23.3545, '34G S 683474 4942631' ), # 34G S 683473.746903862 4942631.26945221 (-12.765, -33.8765, '25L S 404859 8588691' ), # 25L S 404859.139809849 8588691.00770755 (-80.5434, -170.654, '02A S 506346 1057743'), # outside 02C? S 506346 1057743 (90.0, 177.0, '60Z N 500000 9997965'), # outside (-90.0, -177.0, '01A S 500000 2035'), # outside (90.0, 3.0, '31Z N 500000 9997965'), # outside (23.4578, -135.4545, '08Q N 453580 2594273'), # 08Q N 453580 2594273 (77.345, 156.9876, '57X N 450794 8586116' ), # 57X N 450793.553276976 8586116.22730171 (-89.3454, -48.9306, '22A S 502639 75073'), # outside (60.0, 1.0, '31V N 388456 6653097'), # southern Norway (60.0, 3.0, '32V N 165640 6666594'), (60.0, 6.0, '32V N 332705 6655205'), (60.0, 9.0, '32V N 500000 6651411'), (60.0, 12.0, '33V N 332705 6655205'), (76.0, 1.0, '31X N 446000 8436100'), # Svalbard (76.0, 7.0, '31X N 607943 8438843'), (76.0, 13.0, '33X N 446000 8436100'), (76.0, 19.0, '33X N 607943 8438843'), (76.0, 25.0, '35X N 446000 8436100'), (76.0, 31.0, '35X N 607943 8438843'), (76.0, 37.0, '37X N 446000 8436100'), # copied from <https://GitHub.com/Turbo87/utm> (50.77535, 6.08389, '32U N 294409 5628898'), # Aachen (40.71435, -74.00597, '18T N 583960 4507523'), # New York (-41.28646, 174.77624, '60G S 313784 5427057'), # Wellington, New Zealand (-33.92487, 18.42406, '34H S 261878 6243186'), # Capetown, South Africa (-32.89018, -68.84405, '19H S 514586 6360877'), # Mendoza, Argentina (64.83778, -147.71639, '06W N 466013 7190568'), # Fairbanks, Alaska (56.79680, -5.00601, '30V N 377486 6296562'), # Ben Nevis, Scotland (84.0, -5.00601, '30X N 476594 9328501')): # Lat 84 >= _UTM_LAT_MAX p = LL(lat, lon) try: u = p.toUtm().toStr(prec=0, B=True) except ValueError as e: u = str(e) if x[2] in 'ABXYZ': # X only for Lat 84 x = u self.test('toUtm(%s)' % (p, ), u, x) # <https://WikiPedia.org/wiki/Easting_and_northing> m = toUtm8('50°52′10″N', '115°39′03″W', name='Mt Assiniboine') self.test('toUtm(%r)' % (m.name, ), repr(m), '[Z:11U, H:N, E:594934, N:5636174]') # Utm.toLatLon should converge, for any eps, # but eps = max(eps, EPS) and cached as EPS _EPSs = tuple(EPS * 10**(4 - e) for e in range(9)) # courtesy of sumnamazu <https://GitHub.com/mrJean1/PyGeodesy/issues/26> u = Utm(55, 'S', 321441.0425108216, 5810117.133231169) self.test('Utm9', u, '55 S 321441 5810117') for eps in _EPSs: # u._latlon = None # XXX hack to zap cache ll = fstr(u.toLatLon(eps=eps)[:2], prec=8) self.test('Utm9.toLatLon(eps=%.4e)' % (eps, ), ll, '-37.83891644, 144.97077387') u = Utm(31, 'N', 400000, 5000000) self.test('Utm10', u, '31 N 400000 5000000') for eps in _EPSs: # u._latlon = None # XXX hack to zap cache ll = fstr(u.toLatLon(eps=eps)[:2], prec=8) self.test('Utm10.toLatLon(eps=%.4e)' % (eps, ), ll, '45.14639288, 1.72796704') # TMcoords.dat line 111: 70.542985267281 40.282054589142 1399093.4917923557236 8314607.120342236932 ... u = toUtm8(70.542985267281, 40.282054589142, falsed=False, name='TMcoords.dat.110') self.test('Utm111', u, '37 N 1399093 8314607') for eps in _EPSs: # u._latlon = None # XXX hack to zap cache ll = fstr(u.toLatLon(eps=eps)[:2], prec=8) self.test('Utm111.toLatLon(eps=%.4e)' % (eps, ), ll, '70.54298527, 40.28205459')
def testCss(self, *LatLons): P = CassiniSoldner(48 + 50 / 60.0, 2 + 20 / 60.0, name='Paris') self.test(repr(P), P, P) f = P.forward(50.9, 1.8) # Calais self.test('forward', fstr(f, prec=6), '-37518.854545, 230003.561828') r = P.reverse(*f) self.test('reverse', fstr(r, prec=6), '50.9, 1.8') f = P.forward4(50.9, 1.8) # Calais self.test('forward4', fstr(f, prec=6), '-37518.854545, 230003.561828, 89.586104, 0.999983') self.testCopy(P) r = P.reverse(-38e3, 230e3) self.test('reverse', fstr(r, prec=6), '50.899937, 1.793161') f = P.forward(*r) self.test('forward', fstr(f, prec=6), '-38000.0, 230000.0') r = P.reverse4(-38e3, 230e3) self.test('reverse4', fstr(r, prec=6), '50.899937, 1.793161, 89.580797, 0.999982') for LL in LatLons: r = P.reverse(-38e3, 230e3, LatLon=LL) self.test('reverse', repr(r), 'LatLon(50°53′59.77″N, 001°47′35.38″E)') G = CassiniSoldner(51.4934, 0.0098, name='Greenwich') self.test(repr(G), G, G) f = G.forward(48 + 50 / 60.0, 2 + 20 / 60.0) # Paris self.test('forward', fstr(f, prec=6), '170557.151692, -293280.6051') r = G.reverse(*f) self.test('reverse', fstr(r, prec=6), '48.833333, 2.333333') h = hypot(*f) # easting + norting ~= distance d = haversine(*(G.latlon0 + r)) self.test('hypot', h, d, fmt='%.3f', known=abs(d - h) < 1000) C = toCss(LL(50.9, 1.8, height=1), cs0=P, name='Calais') self.test('toCss', C, '-37518.854545 230003.561828 +1.00m') self.test( 'toCss', C.toRepr(C=True), "[E:-37518.854545, N:230003.561828, H:+1.00m, name:'Calais', C:CassiniSoldner(48.833333, 2.333333, name='Paris')]" ) for a, f, x in ( ('easting', '%.6f', '-37518.854545'), ('northing', '%.6f', '230003.561828'), # ('latlon', '%r', '(50.9, 1.8)'), # Python 2.6 Ubuntu (50.899999999999999, 1.8) ('height', '%.1f', '1.0'), ('azi', '%.9f', '89.586103815'), ('rk', '%.9f', '0.999982722'), ('name', '%s', 'Calais'), ('cs0', '%s', '48.833333 2.333333')): v = getattr(C, a) self.test('Css.' + a, v, x, fmt=f) r = C.toLatLon(LatLon=LL) self.test('Css.' + 'toLatLon', repr(r), 'LatLon(50°54′00.0″N, 001°48′00.0″E, +1.00m)') self.test('Css.' + 'toLatLon.height', r.height, '1.0') # Height self.test('Css.' + 'toLatLon.name', r.name, 'Calais') self.test('Css.' + 'toLatLon.datum.name', r.datum.name, 'WGS84') self.test_('Css.' + 'toLatLon.height', repr(r.height), '1.0', 'height(1.0)') # Height self.testCopy(C) self.test('cs0.name', C.cs0.name, 'Paris') c = Css(C.easting, C.northing) # coverage css._CassiniSoldner self.test('cs0.name', c.cs0.name, 'Default') self.test('cs0.flattening', c.cs0.flattening, 0.00335281066475, fmt='%.9f') self.test('cs0.lat0', c.cs0.lat0, 0.0) # Lat self.test('cs0.majoradius', c.cs0.majoradius, '6378137.0') self.test_('cs0.lat0', repr(c.cs0.lat0), '0.0', 'lat0(0.0)') # Lat c = C.classof(C.easting, C.northing, h=C.height, cs0=C.cs0) # coverage Css._reverse4 for a, f, x in (('height', '%.1f', '1.0'), ('azi', '%.9f', '89.586103815'), ('rk', '%.9f', '0.999982722'), ('name', '%s', 'Calais'), ('cs0', '%s', '48.833333 2.333333')): v = getattr(c, a) self.test('classof.' + a, v, x, fmt=f) ll0 = c.cs0.latlon0 self.test('cs0.latlon0', ll0, '(48.833333, 2.333333)') c.cs0.latlon0 = ll0 self.test('cs0.latlon0', ll0, '(48.833333, 2.333333)') try: c.cs0.latlon0 = None self.test('cs0.latlon0', c.cs0.latlon0, TypeError.__name__) except TypeError as x: self.test('cs0.latlon0', str(x), str(x))
def testEllipsoids(self): # datum module tests E = Ellipsoid(1000, 1000, 0, name='TestEllipsiod') self.test('ellipsoid', E is Ellipsoids.TestEllipsiod, True) # print(Ellipsoid()) e = Ellipsoids.unregister('TestEllipsiod') self.test(e.name, e, E) # to show WGS84 and NAD83 are identical up to 3 decimals for E in (Ellipsoids.WGS84, Ellipsoids.GRS80): # NAD83 self.subtitle(ellipsoids, E.name) self.test('R1', E.R1, R_M, fmt='%.4f') self.test('R2', E.R2, '6371007.2', fmt='%.1f') self.test('R3', E.R3, '6371000.8', fmt='%.1f') self.test('Rr', E.Rr, '6367449.1', fmt='%.1f') # 6367445.0 self.test('Rs', E.Rs, '6367435.7', fmt='%.1f') self.test('L', E.L, '10001965.7', fmt='%.1f') self.test('Rgeocentric', E.Rgeocentric(0), '6378137.000', fmt='%.3f') self.test('Rgeocentric', E.Rgeocentric(45), '6367489.544', fmt='%.3f') self.test('Rgeocentric', E.Rgeocentric(90), '6356752.314', fmt='%.3f') self.test('Rlat', E.Rlat(0), '6378137.000', fmt='%.3f') self.test('Rlat', E.Rlat(45), '6367444.657', fmt='%.3f') self.test('Rlat', E.Rlat(90), '6356752.314', fmt='%.3f') self.test('distance2', fstr(E.distance2(0, 0, 1, 1), prec=3), '156903.472, 45.192') self.test('distance2', fstr(E.distance2(0, 0, 10, 10), prec=3), '1569034.719, 45.192') self.test('distance2', fstr(E.distance2(40, 40, 50, 50), prec=3), '1400742.676, 37.563') self.test('distance2', fstr(E.distance2(70, 70, 80, 80), prec=3), '1179164.848, 18.896') self.test('roc2', fstr(E.roc2(0), prec=3), '6335439.327, 6378137.0') self.test('roc2', fstr(E.roc2(45), prec=3), '6367381.816, 6388838.29') self.test('roc2', fstr(E.roc2(90), prec=3), '6399593.626, 6399593.626') self.test('rocBearing', E.rocBearing(0, 0), '6335439.327', fmt='%.3f') self.test('rocBearing', E.rocBearing(45, 45), '6378092.008', fmt='%.3f') self.test('rocBearing', E.rocBearing(90, 0), '6399593.626', fmt='%.3f') self.test('rocGauss', E.rocGauss(0), '6356752.314', fmt='%.3f') self.test('rocGauss', E.rocGauss(45), '6378101.030', fmt='%.3f') self.test('rocGauss', E.rocGauss(90), '6399593.626', fmt='%.3f') self.test('rocMean', E.rocMean(0), '6356716.465', fmt='%.3f') self.test('rocMean', E.rocMean(45), '6378092.008', fmt='%.3f') self.test('rocMean', E.rocMean(90), '6399593.626', fmt='%.3f') self.test('rocMeridional', fstr(E.rocMeridional(0), prec=3), '6335439.327') self.test('rocMeridional', fstr(E.rocMeridional(45), prec=3), '6367381.816') self.test('rocMeridional', fstr(E.rocMeridional(90), prec=3), '6399593.626') self.test('rocPrimeVertical', fstr(E.rocPrimeVertical(0), prec=3), '6378137.0') self.test('rocPrimeVertical', fstr(E.rocPrimeVertical(45), prec=3), '6388838.29') self.test('rocPrimeVertical', fstr(E.rocPrimeVertical(90), prec=3), '6399593.626') self.subtitle(ellipsoids, Ellipsoid.__init__) self.test('a, b, None', Ellipsoid(1000, 500, None, name='f_None').f_, 2.0) # coverage self.test('a, None, f_', Ellipsoid(1000, None, 2, name='b_None').b, 500.0) # coverage E = Ellipsoids.WGS84.copy() # coverage self.subtitle(ellipsoids, E.name) self.test('WGS84.copy', E is not Ellipsoids.WGS84, True) self.test('WGS84.copy', E == Ellipsoids.WGS84, True) self.test('WGS84.find', Ellipsoids.find(E), None) self.test('WGS84.a2_b', E.a2_b, E.a2 / E.b, fmt='%.6f') self.test('WGS84.b2_a', E.b2_a, E.b2 / E.a, fmt='%.6f') self.test('WGS84.c', E.c, E.R2, fmt='%.6f') self.test('WGS84.es', E.es, E.e, fmt='%.6f') self.test('WGS84.f2', E.f2, (E.a - E.b) / E.b, fmt='%.6f') self.test('WGS84.m2degrees', int(E.m2degrees(E.a * PI_2)), 90) self.test('WGS84.area', E.area, '5.101e+14', fmt='%.3e') self.test('WGS84.volume', E.volume, '1.083e+21', fmt='%.3e') self.test('WGS84.ecef', E.ecef().__class__, EcefKarney) self.test('WGS84.ecef', E.ecef().name, E.name) t = E.toStr(prec=10) self.test( 'WGS84', t, "name='WGS84', a=6378137, b=6356752.3142451793, f_=298.257223563, f=0.0033528107, f2=0.0033640898, n=0.0016792204, e=0.0818191908, e2=0.00669438, e22=0.0067394967, e32=0.0033584313, L=10001965.7293127235, R1=6371008.7714150595, R2=6371007.1809184738, R3=6371000.790009154" ) e = (E.a - E.b) / (E.a + E.b) - E.n t = 'A=%.10f, e=%.10f, f_=%.10f, n=%.10f(%.10e)' % (E.A, E.e, E.f_, E.n, e) self.test( 'WGS84.', t, 'A=6367449.1458234144, e=0.0818191908, f_=298.2572235630, n=0.0016792204(-2.1684043450e-19)' ) self.subtitle(ellipsoids, 'Kruegers') def _AB(E, K, A, B): E.KsOrder = K self.test('WGS84.AlphaKs', fstr(E.AlphaKs, prec=12, fmt='%.*e', ints=True), A) self.test('WGS84.BetaKs ', fstr(E.BetaKs, prec=12, fmt='%.*e', ints=True), B) _AB( E, 8, '8.377318206245e-04, 7.608527773573e-07, 1.197645503243e-09, 2.429170680397e-12, 5.711818370428e-15, 1.47999793138e-17, 4.107624109371e-20, 1.210785038923e-22', '8.37732164058e-04, 5.90587015222e-08, 1.673482665344e-10, 2.164798110491e-13, 3.787930968626e-16, 7.236769021816e-19, 1.493479824778e-21, 3.259522545838e-24' ) _AB( E, 6, '8.377318206245e-04, 7.608527773572e-07, 1.197645503329e-09, 2.429170607201e-12, 5.711757677866e-15, 1.491117731258e-17', '8.37732164058e-04, 5.90587015222e-08, 1.673482665284e-10, 2.164798040063e-13, 3.787978046169e-16, 7.248748890695e-19' ) _AB( E, 4, '8.377318206304e-04, 7.608527714249e-07, 1.197638001561e-09, 2.443376194522e-12', '8.377321640601e-04, 5.905869567934e-08, 1.673488880355e-10, 2.167737763022e-13' ) P = Ellipsoid(E.b, E.a, name='Prolate') _TOL = ellipsoids._TOL self.subtitle(ellipsoids, P.name) for p, e in ((P.a, E.b), (P.b, E.a), (P.n, -E.n), (P.R1, E.R1), (P.R2, E.R2), (P.R3, E.R3), (P.Rbiaxial, E.Rbiaxial), (P.Rgeometric, E.Rgeometric), (P.area, E.area), (P.volume, E.volume)): self.test(p.name, p, e, fmt='%.6f', known=abs(p - e) < _TOL) for E, el, ob, pr in ((E, True, True, False), (P, True, False, True), (Ellipsoids.Sphere, False, False, False)): self.subtitle(ellipsoids, 'AuxiliaryLats ' + E.name) self.test('isEllipsoidal', E.isEllipsoidal, el) self.test('isOblate', E.isOblate, ob) self.test('isProlate', E.isProlate, pr) self.test('isSpherical', E.isSpherical, not el) for d in range(-90, 91, 30): x = 'lat (%d.0)' % (d, ) for aux in (E.auxAuthalic, E.auxConformal, E.auxGeocentric, E.auxIsometric, E.auxParametric, E.auxRectifying): a = aux(d) t = fstr(a, prec=9) self.test('%s(%d)' % (aux.__name__, d), t, t) self.test('name', a.name, aux.__name__) self.test('inverse', aux(a, inverse=True).toRepr(prec=2), x) self.subtitle(ellipsoids, 'Flattenings') self.test('_TOL', _TOL, _TOL) for n, E in Ellipsoids.items(): # includes f_None, b_None, Prolate if E.f and E.f_: e = E.f_ - 1 / E.f self.test(n + '.f_ - 1 / .f', e, e if abs(e) < _TOL else _TOL) e = E.f - 1 / E.f_ self.test(n + '.f - 1 / .f_', e, e if abs(e) < _TOL else _TOL) # PYCHOK attr self.subtitle(ellipsoids, Ellipsoid2.__name__) for n, E in tuple( Ellipsoids.items()): # includes f_None, b_None, Prolate E2 = Ellipsoid2(E.a, E.f, name='_2_' + n) n, E2 = str(E2).split(', ', 1) _, E = str(E).split(', ', 1) self.test(n, E2, E) self.subtitle(ellipsoids, a_f2Tuple.__name__) for n, E in tuple( Ellipsoids.items()): # includes f_None, b_None, Prolate a_f = a_f2Tuple(E.a, E.f) E2 = Ellipsoid(a_f.a, a_f.b, name='_a_b_' + n) # PYCHOK a n, E2 = str(E2).split(', ', 1) _, E = str(E).split(', ', 1) self.test(n, E2, E) self.subtitle(ellipsoids, 'Functions') for n, E in tuple( Ellipsoids.items()): # includes f_None, b_None, Prolate f_ = a_b2f_(E.a, E.b) self.test('%s(%s)' % (a_b2f_.__name__, E.name), f_, E.f_, fmt='%.8f', known=abs(f_ - E.f_) < _TOL) f2 = a_b2f2(E.a, E.b) self.test('%s(%s)' % (a_b2f2.__name__, E.name), f2, E.f2, fmt='%.8f', known=abs(f2 - E.f2) < _TOL) n = a_b2n(E.a, E.b) self.test('%s(%s)' % (a_b2n.__name__, E.name), n, E.n, fmt='%.8f', known=abs(n - E.n) < _TOL) a = b_f2a(E.b, E.f) self.test('%s(%s)' % (b_f2a.__name__, E.name), a, E.a, fmt='%.3f', known=abs(a - E.a) < _TOL) # millimeter a = b_f_2a(E.b, E.f_) self.test('%s(%s)' % (b_f_2a.__name__, E.name), a, E.a, fmt='%.3f', known=abs(a - E.a) < _TOL) # millimeter f = f_2f(E.f_) self.test('%s(%s)' % (f_2f.__name__, E.name), f, E.f, fmt='%.8f', known=abs(f - E.f) < _TOL) e2 = n2e2(E.n) self.test('%s(%s)' % (n2e2.__name__, E.name), e2, E.e2, fmt='%.8f', known=abs(e2 - E.e2) < _TOL) f = n2f(E.n) self.test('%s(%s)' % (n2f.__name__, E.name), f, E.f, fmt='%.8f', known=abs(f - E.f) < _TOL)
def testNvectorBase(self, module, **kwds): try: Nvector = module.Nvector c = Nvector.__name__ except AttributeError: Nvector = module.NvectorBase c = 'Vector4Tuple' self.subtitle(module, Nvector.__name__) v = Nvector(0.500, 0.500, 0.707, **kwds) s = module.sumOf((v, v), h=0, name='sumOf') self.test('sumOf', s.__class__.__name__, c) p = v.toLatLon(LatLon=None) c = v.toCartesian(Cartesian=None) self.test('ecef.x, .y, .z', fstr(p[:3], prec=5), fstr(c[:3], prec=5)) self.test('ecef.lat, .lon', fstr(p[3:5], prec=6), fstr(c[3:5], prec=6)) self.test('ecef.height', fstr(p.height, prec=6), fstr(c.height, prec=6), known=True) if c.M is not None: self.test('ecef.M', fstr(p.M, prec=9), fstr(c.M, prec=9)) if coverage: from pygeodesy.named import LatLon2Tuple, LatLon3Tuple, \ PhiLam2Tuple, PhiLam3Tuple self.test('.isEllipsoidal', v.isEllipsoidal, not v.isSpherical) self.test('.isSpherical', v.isSpherical, not v.isEllipsoidal) self.test('.latlon', v.latlon, LatLon2Tuple(v.lat, v.lon)) self.test('.philam', v.philam, PhiLam2Tuple(v.phi, v.lam)) self.test('.latlonheight', v.latlonheight, LatLon3Tuple(v.lat, v.lon, float(v.h))) self.test('.philamheight', v.philamheight, PhiLam3Tuple(v.phi, v.lam, float(v.h))) t = v.parse('0.5, 0.5, 0.707') self.test('parse', t, v) self.test('cmp', t.cmp(v), 0) self.test('eq', t == v, True) self.test('ge', t >= v, True) self.test('gt', t > v, False) self.test('le', t <= v, True) self.test('lt', t < v, False) self.test('ne', t != v, False) m = t * 2 self.test('*', m, '(1.0, 1.0, 1.414)') self.test('+', t + v, m) self.test('/', m / 2, t) self.test('-', m - t, t) m = v.__matmul__(t) self.test('@', m, '(0.0, 0.0, 0.0)') r = t.__rmatmul__(m) self.test('@', r, m) r = v.rotate(m, 45) self.test('rotate', r, '(0.26268, 0.26268, 0.37143)')