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') t = ll.datum.ecef().reverse(t) self.test('reverse', fStr(t[3:6], prec=3), '48.833, 2.333, 0.0') self.test('name', t.name, 'Paris') ll = t.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') v = t.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 = t.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 testKarneyPython(self, module): self.subtitle(module, 'KarneyPython') ll1 = module.LatLon(-41.32, 174.81) # <https://GeographicLib.SourceForge.io/1.49/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') 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=isWindows) d3 = ll1.distanceTo3(module.LatLon(40.96, -5.50)) self.test('distanceTo3', fStr(d3, prec=12), '19959679.267353821546, 161.06766998616, 18.825195123247', known=isWindows) 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
def testGeoid(self, G, grid, llh3, crop=None, eps=None, kind=None): # MCCABE 13 # test geoid G(grid) for (lat, lon, height, eps) if scipy or G is GeoidKarney: e_max = 0 eps = eps or self._epsHeight f = self.failed - self.known g = G(grid, kind=kind or self._kind, crop=crop) s = '%s.height(%%s) kind %s' % (g, g.kind) try: for lat, lon, expected in llh3: t = s % (fStr((lat, lon), prec=3),) try: h = g.height(lat, lon) e = abs(h - expected) if e_max < e: e_max = e self.test(t, h, expected, fmt='%.3f', known=e < eps) except GeoidError as x: self.test(t, str(x), '%.3f' % (expected,), known=G not in (GeoidKarney, GeoidPGM)) except RangeError as x: self.test(t, str(x), '%.3f' % (expected,), known=bool(crop)) except KeyboardInterrupt as x: self.printf(repr(x), nl=1) f = self.failed - self.known - f if f > 0 or e_max > 0: h = '' if g.hits is None else ', hits %s' % (g.hits,) t = '%s.height() kind %s%s, eps max (in %s FAILED)' % (g, g.kind, h, f) x = eps if f > 0 else e_max self.test(t, e_max, x, fmt='%.3f', known=e_max < eps, nl=1, nt=1) # print('%r\n\n%r' % (g, getattr(g, 'pgm', None))) if coverage: for a in ('highest', 'lowerleft', 'lowerright', 'lowest', 'upperleft', 'upperright'): t = fStr(getattr(g, a)(), prec=3) self.test('%s.%s()' % (g, a), t, t, known=True) for p in ('dtype', 'knots', 'mean', 'nBytes', 'scipy', 'smooth', 'stdev'): # , 'pgm' t = ''.join(reprs((getattr(g, p),), prec=3)) self.test('%s.%s' % (g, p), t, t, known=True) for a in ('_g2ll2', '_ll2g2'): t = getattr(g, a)(180, 360) self.test('%s.%s(180, 360)' % (g, a), t, t, known=True) for t in ((LatLon_(-10, -100), LatLon_(10, 100)), ( (-10, -100), (10, 100))): t = g._swne(t) self.test('%s.%s' % (g, '_swne'), t, '(-10.0, -100.0, 10.0, 100.0)') t = g.toStr() self.test('%s.%s' % (g, 'toStr'), t, t, known=True, nt=1) self.testCopy(g) else: n, _ = len2(llh3) self.skip('no scipy', n=n)
def testGeoid(self, G, grid, llh3, crop=None, eps=None, kind=None): # test geoid G(grid) for (lat, lon, height, eps) if scipy or G is GeoidKarney: e_max = 0 eps = eps or self._epsHeight f = self.failed - self.known g = G(grid, kind=kind or self._kind, crop=crop) s = '%s.height(%%s) kind %s' % (g, g.kind) try: for lat, lon, expected in llh3: t = s % (fStr((lat, lon), prec=3), ) try: h = g.height(lat, lon) e = abs(h - expected) if e_max < e: e_max = e self.test(t, h, expected, fmt='%.3f', known=e < eps) except GeoidError as x: self.test(t, str(x), '%.3f' % (expected, ), known=G not in (GeoidKarney, GeoidPGM)) except RangeError as x: self.test(t, str(x), '%.3f' % (expected, ), known=bool(crop)) except KeyboardInterrupt as x: self.printf(repr(x), nl=1) f = self.failed - self.known - f if f > 0 or e_max > 0: h = '' if g.hits is None else ', hits %s' % (g.hits, ) t = '%s.height() kind %s%s, eps max (in %s FAILED)' % ( g, g.kind, h, f) x = eps if f > 0 else e_max self.test(t, e_max, x, fmt='%.3f', known=e_max < eps, nl=1, nt=1) # print('%r\n\n%r' % (g, getattr(g, 'pgm', None))) if coverage: # for test coverage for a in ('highest', '_llh3minmax', 'lowest', 'lowerright', 'upperleft'): t = fStr(getattr(g, a)(), prec=3) self.test('%s.%s' % (g, a), t, t, known=True) t = g.toStr() self.test('%s.%s' % (g, 'toStr'), t, t, known=True, nt=1) else: n, _ = len2(llh3) self.skip('no scipy', n=n)
def testGeohash(self): # geohash module tests LL = ellipsoidalVincenty.LatLon cn = classname(LL(0, 0)) g = Geohash('geek') self.test('Geohash', repr(g), "Geohash('geek')") self.test('Geohash', g, '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('ab', fStr(g.ab, prec=7), '1.1428157, -0.3098641') 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('decode_error', fStr(geohash.decode_error(g), fmt='%*e'), '2.145767e-05, 2.145767e-05') self.test('distance1', g.distance1('geehpb'), '2758.887', fmt='%.3f') self.test('distance2', g.distance2('geehpb'), '682.760', fmt='%.3f') self.test('distance3', g.distance3('geehpb'), '397.404', fmt='%.3f') self.test('sizes', fStr(g.sizes, prec=1), '4.8, 4.8') 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('decode_error', fStr(geohash.decode_error('u120fxw'), fmt='%*e'), '6.866455e-04, 6.866455e-04') self.test('distance1', geohash.distance1('u120fxw', 'u120fxws0'), '486.710', fmt='%.3f') self.test('distance2', geohash.distance2('u120fxw', 'u120fxws0'), '3.374', fmt='%.3f') self.test('distance3', geohash.distance3('u120fxw', 'u120fxws0'), '2.798', fmt='%.3f') 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)')
def testGeoref(self, LL): # Karney's geographiclib/1.49/examples/example-Georef.cpp # <http://SourceForge.net/p/geographiclib/code/ci/release/tree/examples/example-Georef.cpp> g = Georef('57.64911, 10.40744', precision=6) self.test('Georef', g, 'NKLN2444638946') self.test('Georef', repr(g), "Georef('NKLN2444638946')") self.test('Georef.latlon', fStr(g.latlon, prec=5), '57.64911, 10.40744') t = g.toLatLon(LL) self.test('Georef.toLatLon', repr(t), 'LatLon(57°38′56.8″N, 010°24′26.78″E)') self.testCodec3(g, '57.64911, 10.40744, 6.0', prec=5) # <http://WikiPedia.org/wiki/World_Geographic_Reference_System> g = Georef('38.286108, -76.4291704', precision=6) self.test('Georef', g, 'GJPJ3424917166') self.test('Georef', repr(g), "Georef('GJPJ3424917166')") self.test('Georef.latlon', fStr(g.latlon, prec=6), '38.286108, -76.42917') t = g.toLatLon(LL) self.test('Georef.toLatLon', repr(t), 'LatLon(38°17′09.99″N, 076°25′45.01″W)') self.testCodec3(g, '38.286108, -76.429175, 6.0', prec=6) # <http://Earth-Info.NGA.mil/GandG/coordsys/grids/georef.pdf> self.testCodec3('MKPG1204', '51.075, -1.7917, 3.0', prec=4) # <http://www.map-reading.com/ch4-4.php> self.testCodec3('WJKG1503', '36.0583, 129.2583, 3.0', prec=4) # <http://WikiPedia.org/wiki/World_Geographic_Reference_System> self.testCodec5('GJPJ4103R5', '38.0583, -76.3083, 3.0, None, 9260.0', prec=4) self.testCodec5('GJPJ4103H17', '38.0583, -76.3083, 3.0, 5181.6, None', prec=4) self.testCodec5('GJPJ4103R5H17', '38.0583, -76.3083, 3.0, 5181.6, 9260.0', prec=4) for t in range(-1, 13): r = wgrs.resolution(t) p = wgrs.precision(r) self.test('precision', t, p, known=t < 0 or t > 11) b = degDMS(r, prec=t if r < 1 else 0, s_S='') # no S_SEC x = ('15' + S_DEG) if p < 1 else (('1' + S_DEG) if p < 2 else ('0.%s1%s' % ('0' * (p - 2), S_MIN))) self.test('resolution', b, x) # also to test degDMS
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') 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.toStr2(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') self.test('Css.' + 'toLatLon.name', r.name, 'Calais') self.test('Css.' + 'toLatLon.datum.name', r.datum.name, 'WGS84')
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) 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 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', repr(g), "Garef('381NH45')") 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 testKarneyPython(self, module): self.subtitle(module, 'KarneyPython') ll1 = module.LatLon(-41.32, 174.81) # <http://GeographicLib.SourceForge.io/1.49/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') 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=isWindows) d3 = ll1.distanceTo3(module.LatLon(40.96, -5.50)) self.test('distanceTo3', fStr(d3, prec=12), '19959679.267353821546, 161.06766998616, 18.825195123247', known=isWindows) 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')
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 = Transforms.ED50 t = E.inverse().inverse("ED50_") self.test('ED50.inverse().inverse()', t == E, 'True') R, fmt = Ellipsoids.WGS84.R, '%.4f' self.test('meanR', R, fmt % (R_M, ), fmt=fmt) E = Datums.WGS84.ellipsoid e = (E.a - E.b) / (E.a + E.b) - E.n t = (E.toStr(prec=10), 'A=%.10f, e=%.10f, f_=%.10f, n=%.10f(%.10e)' % (E.A, E.e, E.f_, E.n, e), 'Alpha6=(%s)' % (fStr(E.Alpha6, prec=12, fmt='%.*e', ints=True), ), 'Beta6=(%s)' % (fStr(E.Beta6, prec=12, fmt='%.*e', ints=True), )) self.test( 'WGS84', t[0], "name='WGS84', a=6378137.0, b=6356752.3142499998, f_=298.257223563, f=0.0033528107, e2=0.00669438, e22=0.0067394967, R=6371008.7714166669, Rm=6367435.6797186071, R2=6371007.180920884, R3=6371000.7900107643, Rr=6367449.1458250266" ) self.test( 'WGS84', t[1], "A=6367449.1458234154, e=0.0818191908, f_=298.2572235630, n=0.0016792204(-3.7914875232e-13)" ) self.test( 'WGS84', t[2], "Alpha6=(0, 8.377318206245e-04, 7.608527773572e-07, 1.197645503329e-09, 2.429170607201e-12, 5.711757677866e-15, 1.491117731258e-17)" ) self.test( 'WGS84', t[3], "Beta6=(0, 8.377321640579e-04, 5.905870152220e-08, 1.673482665284e-1, 2.164798040063e-13, 3.787978046169e-16, 7.248748890694e-19)" )
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') 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')
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: 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)')
def testUtils(self): self.test('antipode1', antipode(89, 179), (-89, -1)) self.test('antipode2', antipode(-89, -179), (89, 1)) self.test('isantipode1', isantipode(89, 179, -89, -1), True) self.test('isantipode2', isantipode(-89, -179, 89, 1), True) self.test('isantipode3', isantipode(-89, -179, -89, -1), False) self.test('heightof0', heightOf(0, R_M), 2638958.23912, fmt='%.5f') self.test('heightof45', heightOf(45, R_M), 5401080.43931, fmt='%.5f') self.test('heightof90', heightOf(90, R_M), R_M) self.test('heightof135', heightOf(135, R_M), 5401080.43931, fmt='%.5f') self.test('horizon0', horizon(0), 0.0) self.test('horizon10Km', horizon(10000), '357099.672', fmt='%.3f') self.test('horizon30Kft', horizon(10000, refraction=True), '392310.704', fmt='%.3f') self.test('horizon10Kft', horizon(3000, refraction=True), '214877.422', fmt='%.3f') 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')
def testNvectorBase(self, module, **kwds): try: Nvector = module.Nvector except AttributeError: Nvector = module.NvectorBase self.subtitle(module, Nvector.__name__) v = Nvector(0.500, 0.500, 0.707, **kwds) 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: # to test coverage t = v.parse('0.5, 0.5, 0.707') self.test('parse', t, v) 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 = 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)')
def testCodec3(self, g, x, prec=4): self.test('codec3', Garef(g), g) t = gars.decode3(g) self.test('decode3', fStr(t, prec=prec), x) self.test('encode', gars.encode(*t), g)
def _tstr(t): s = list(t[:5]) s[0] = fStr(t.hd, prec=5) s[4] = None if t.md is None else fStr(t.md, prec=5) return '(%s)' % (', '.join(map(str, s)),)
def testLatLon(self, module, Sph=False, Nv=True): # MCCABE 45 self.subtitle(module, 'LatLon') LatLon = module.LatLon # basic LatLon class tests p = LatLon(52.20472, 0.14056) self.test('isEllipsoidal', p.isEllipsoidal, not Sph) self.test('isSpherical', p.isSpherical, Sph) self.test('lat/lonDMS', p, '52.20472°N, 000.14056°E') # 52.20472°N, 000.14056°E self.test('lat/lonDMS F_DM', p.toStr(F_DM, 3), '''52°12.283'N, 000°08.434'E''') self.test('lat/lonDMS F_DM', p.toStr(F_DM, 4), '''52°12.2832'N, 000°08.4336'E''') self.test('lat/lonDMS F_DMS', p.toStr(F_DMS, 0), '''52°12'17"N, 000°08'26"E''') self.test('lat/lonDMS F_DMS', p.toStr(F_DMS, 1), '''52°12'17.0"N, 000°08'26.0"E''') self.test('lat/lonDMS F_RAD', p.toStr(F_RAD, 6), '0.911144N, 0.002453E') q = LatLon(*map(degrees, p.philam)) self.test('isequalTo', q.isequalTo(p), True) q = LatLon(*map(degrees, p.to2ab())) self.test('isequalTo', q.isequalTo(p), True) self.test('latlon2', fStr(q.latlon2(5)), '52.20472, 0.14056') self.test('latlon2', fStr(q.latlon2(4)), '52.2047, 0.1406') self.test('latlon2', fStr(q.latlon2(3)), '52.205, 0.141') self.test('latlon2', fStr(q.latlon2(2)), '52.2, 0.14') self.test('latlon2', fStr(q.latlon2(1)), '52.2, 0.1') self.test('latlon2', fStr(q.latlon2()), '52.0, 0.0') FRA = LatLon(50.0379, 8.5622) LHR = LatLon(51.47, 0.4543) # <https://www.EdWilliams.org/avform.htm#XTE> JFK = LatLon(degrees(0.709186), -degrees(1.287762)) LAX = LatLon(33. + 57. / 60, -(118. + 24. / 60)) Rav = m2NM(6366710) # avg. earth radius in NM # <https://GeographicLib.SourceForge.io/html/python/examples.html> WNZ = LatLon(-41.32, 174.81, name='Wellington, NZ') SAL = LatLon(40.96, -5.50, name='Salamanca, ES') BJS = LatLon(40.1, 116.6) # Beijing Airport SFO = LatLon(37.6, -122.4) # San Francisco p = LatLon(52.205, 0.119) q = LatLon(48.857, 2.351) self.test('isequalTo', p.isequalTo(q), False) a = p.antipode() self.test('antipode1', a, '52.205°S, 179.881°W') self.test('antipode2', a.isantipodeTo(p), True) b = a.antipode() self.test('antipode3', b, '52.205°N, 000.119°E') self.test('antipode4', a.isantipodeTo(b), True) self.test('antipode5', b, p) if hasattr(LatLon, 'initialBearingTo'): b = p.initialBearingTo(q) self.test('initialBearingTo', b, 156.1666 if Sph else 156.1106, fmt='%.4f') # 156.2 b = p.finalBearingTo(q) self.test('finalBearingTo', b, 157.8904 if Sph else 157.8345, fmt='%.4f') b = LAX.initialBearingTo(JFK) self.test('initialBearingTo', b, 65.8921 if Sph else 65.9335, fmt='%.4f') # PYCHOK test attr? b = LAX.finalBearingTo(JFK) self.test('finalBearingTo', b, 93.8581 if Sph else 93.9034, fmt='%.4f') # PYCHOK test attr? if hasattr(LatLon, 'bearingTo2'): b = p.bearingTo2(q) self.test( 'bearingTo2', fStr(b, prec=4), '156.1666, 157.8904' if Sph else '156.1106, 157.8345') # 156.2 # <https://blog.Element84.com/determining-if-a-spherical-polygon-contains-a-pole.html> b = LatLon(85, -135), LatLon(85, -45), LatLon(85, 45), LatLon( 85, 135), LatLon(85, -135) self.test('ispolar', ispolar(b), True) # PYCHOK test attr? c = p.copy() self.test('copy', p.isequalTo(c), True) self.test('__eq__', p == c, True) self.test('__ne__', p != c, False) d = p.equirectangularTo(q) self.test('equirectangularTo', d, '404329.56', fmt='%.2f') if hasattr(LatLon, 'distanceTo'): d = p.distanceTo(q) self.test('distanceTo', d, '404279.720589' if Sph else ('404279.720589' if Nv else '404607.805988'), fmt='%.6f') # 404300 d = q.distanceTo(p) self.test('distanceTo', d, '404279.720589' if Sph else ('404279.720589' if Nv else '404607.805988'), fmt='%.6f') # 404300 d = LAX.distanceTo(JFK, radius=R_NM) if Sph else LAX.distanceTo(JFK) self.test('distanceTo', d, 2145 if Sph else (3972863 if Nv else 3981601), fmt='%.0f') # PYCHOK test attr? if not Nv: # <https://GeographicLib.SourceForge.io/html/python/examples.html> self.test('antipodal', WNZ.isantipodeTo(SAL, eps=0.1), False) try: d = WNZ.distanceTo(SAL, wrap=False) self.test('distanceTo dateline', d, 19119590.551 if Sph else 19959679.267, fmt='%.3f', known=True) # PYCHOK test attr? except VincentyError as x: x = str(x) self.test('distanceTo dateline', x, 'no convergence ...', known=True) try: d = WNZ.distanceTo(SAL, wrap=True) self.test('distanceTo unrolled', d, 19119590.551 if Sph else 19959679.267, fmt='%.3f', known=True) # PYCHOK test attr? except VincentyError as x: x = str(x) self.test('distanceTo unrolled', x, 'no convergence ...', known=True) self.test('antipodal', BJS.isantipodeTo(SFO, eps=0.1), False) d = BJS.distanceTo(SFO, wrap=False) self.test('distanceTo dateline', d, 9491735 if Sph else 9513998, fmt='%.0f') # PYCHOK test attr? d = BJS.distanceTo(SFO, wrap=True) self.test('distanceTo unrolled', d, 9491735 if Sph else 9513998, fmt='%.0f') # PYCHOK test attr? # <https://GitHub.com/chrisveness/geodesy/issues/64> d = LatLon(20, 0).distanceTo(LatLon(-2, 180)) self.test('distanceTo', d, 18013602.92 if Sph or Nv else 18012714.66, fmt='%.2f') try: d = LatLon(0, 0).distanceTo(LatLon(0, 180)) # antipodal self.test('distanceTo', d, 20015114.35 if Sph else 20003931.46, fmt='%.2f', known=Nv) # PYCHOK 0.0 for Nv except ValueError as x: x = str(x) self.test('distanceTo', x, 'ambiguous, antipodal ...', known=True) if hasattr(LatLon, 'distanceTo3'): # and not Sph: for w in (False, True): try: d = WNZ.distanceTo3(SAL, wrap=w) # XXX expected values? self.test('distanceTo3 dateline', fStr(d, prec=4), '19959679.2674, 161.0677, 18.8252', known=True) # PYCHOK test attr? except VincentyError as x: x = str(x) self.test('distanceTo3 dateline', x, 'no convergence ...', known=True) d = BJS.distanceTo3(SFO, wrap=w) self.test( 'distanceTo3 dateline', fStr(d, prec=4), '9513997.9901, 42.9164, 138.8903') # PYCHOK test attr? if hasattr(LatLon, 'intermediateTo'): i = p.intermediateTo(q, 0.25) self.test( 'intermediateTo', i, '51.372084°N, 000.707337°E' if Sph else '51.372294°N, 000.707192°E') self.test('intermediateTo', isinstance(i, LatLon), True) if hasattr(p, 'distanceTo'): d = p.distanceTo(q) self.test('intermediateTo', d, '404279.721', fmt='%.3f') # PYCHOK test attr? i = p.intermediateTo(q, 5) self.test( 'intermediateTo+5', i, '35.160975°N, 008.989542°E' if Sph else '35.560239°N, 008.833512°E') if hasattr(p, 'distanceTo'): self.test('intermediateTo+5', p.distanceTo(i) / d, '4.885' if Nv and not Sph else '5.000', fmt='%.3f') # PYCHOK test attr? i = p.intermediateTo(q, -4) self.test( 'intermediateTo-4', i, '64.911647°N, 013.726301°W' if Sph else '64.570387°N, 013.156352°W') if hasattr(p, 'distanceTo'): self.test('intermediateTo-4', p.distanceTo(i) / d, '3.885' if Nv and not Sph else '4.000', fmt='%.3f') # PYCHOK test attr? # courtesy of <https://GitHub.com/bakakaldsas> i = LatLon(52, 0, 100).intermediateTo(LatLon(48, 2, 200), 0.25) self.test('intermediateTo-h', i.height, '125.000', fmt='%.3f') # PYCHOK test attr? if hasattr(LatLon, 'intermediateChordTo'): i = p.intermediateChordTo(q, 0.25) self.test('intermediateChordTo', i, '51.372294°N, 000.707192°E') self.test('intermediateChordTo', isinstance(i, LatLon), True) # PYCHOK test attr? # courtesy of <https://GitHub.com/bakakaldsas> i = LatLon(52, 0, 100).intermediateChordTo(LatLon(48, 2, 200), 0.25) self.test('intermediateChordTo-h', i.height, '125.000', fmt='%.3f') # PYCHOK test attr? if hasattr(LatLon, 'midpointTo'): m = p.midpointTo(q) self.test('midpointTo', m, '50.536327°N, 001.274614°E' ) # PYCHOK test attr? # 50.5363°N, 001.2746°E if hasattr(LatLon, 'destination'): p = LatLon(51.4778, -0.0015) d = p.destination(7794, 300.7) self.test('destination', d, '51.513546°N, 000.098345°W' if Sph else '51.513526°N, 000.098038°W') # 51.5135°N, 0.0983°W ??? self.test( 'destination', d.toStr(F_DMS, 0), '51°30′49″N, 000°05′54″W' if Sph else '51°30′49″N, 000°05′53″W') # <https://www.EdWilliams.org/avform.htm#LL> d = LAX.destination( 100, 66, radius=R_NM) if Sph else LAX.destination(100, 66) self.test('destination', d.toStr(F_DM, prec=0), "34°37′N, 116°33′W" if Sph else "33°57′N, 118°24′W") self.test( 'destination', d, '34.613647°N, 116.55116°W' if Sph else '33.950367°N, 118.399012°W') self.test('destination', d.toStr(F_RAD, prec=6), '0.604122N, 2.034201W' if Sph else '0.592546N, 2.066453W') # PYCHOK expected # <https://GeographicLib.SourceForge.io/html/python/examples.html> d = LatLon(-32.06, -115.74).destination(20e6, 225).toStr(F_D, prec=8) self.test('destination', d, '31.96383509°N, 064.37329146°E' if Sph else '32.11195529°N, 063.95925278°E', known=True) # PYCHOK test attr? if hasattr(LatLon, 'alongTrackDistanceTo'): s = LatLon(53.3206, -1.7297) e = LatLon(53.1887, 0.1334) p = LatLon(53.2611, -0.7972) try: d = p.alongTrackDistanceTo(s, 96, TypeError.__name__, known=True) self.test('alongTrackDistanceTo', d, 62331.59, fmt='%.2f') # 62331 except TypeError as x: self.test('alongTrackDistanceTo', str(x), 'incompatible ...', known=True) # PYCHOK test attr? d = p.alongTrackDistanceTo(s, e) self.test('alongTrackDistanceTo', d, 62331.58, fmt='%.2f') # <https://www.EdWilliams.org/avform.htm#XTE> p = LatLon(34.5, -116.5) # 34:30N, 116:30W d = p.alongTrackDistanceTo(LAX, JFK, radius=Rav) self.test('alongTrackDistanceTo', d, 99.588, fmt='%.3f') # NM # courtesy of Rimvydas Naktinis p = LatLon(53.36366, -1.83883) d = p.alongTrackDistanceTo(s, e) self.test('alongTrackDistanceTo', d, -7702.7, fmt='%.1f') p = LatLon(53.35423, -1.60881) d = p.alongTrackDistanceTo(s, e) self.test('alongTrackDistanceTo', d, 7587.6, fmt='%.1f') # PYCHOK test attr? if hasattr(LatLon, 'crossTrackDistanceTo'): s = LatLon(53.3206, -1.7297) e = LatLon(53.1887, 0.1334) p = LatLon(53.2611, -0.7972) try: d = p.crossTrackDistanceTo(s, 96) self.test('crossTrackDistanceTo', d, TypeError.__name__, known=True) except TypeError as x: self.test('crossTrackDistanceTo', str(x), 'incompatible ...', known=True) # PYCHOK test attr? d = p.crossTrackDistanceTo(s, e) self.test('crossTrackDistanceTo', d, -307.55, fmt='%.2f') # -307.5 # <https://www.EdWilliams.org/avform.htm#XTE> p = LatLon(34.5, -116.5) # 34:30N, 116:30W d = p.crossTrackDistanceTo(LAX, JFK, radius=Rav) self.test('crossTrackDistanceTo', d, 7.4524, fmt='%.4f') # PYCHOK test attr? # XXX 7.4512 NM if hasattr(LatLon, 'greatCircle'): p = LatLon(53.3206, -1.7297) gc = p.greatCircle(96.0) self.test('greatCircle', gc, '(-0.79408, 0.12856, 0.59406)') # PYCHOK test attr? p = LatLon(53.3206, -1.7297) q = LatLon(53.1887, 0.1334) self.test('cosineAndoyerLambertTo', p.cosineAndoyerLambertTo(q), '124801.098' if Sph else '125205.962', fmt='%.3f') self.test('cosineAndoyerLambertTo', q.cosineAndoyerLambertTo(p), '124801.098' if Sph else '125205.962', fmt='%.3f') self.test('cosineForsyheAndoyerLambertTo', p.cosineForsytheAndoyerLambertTo(q), '124801.098' if Sph else '125205.965', fmt='%.3f') self.test('cosineForsyheAndoyerLambertTo', q.cosineForsytheAndoyerLambertTo(p), '124801.098' if Sph else '125205.965', fmt='%.3f') self.test('cosineLawTo', p.cosineLawTo(q), '124801.098', fmt='%.3f') self.test('cosineLawTo', q.cosineLawTo(p), '124801.098', fmt='%.3f') self.test('equirectangularTo', p.equirectangularTo(q), '124804.754', fmt='%.3f') self.test('equirectangularTo', q.equirectangularTo(p), '124804.754', fmt='%.3f') self.test('euclideanTo', p.euclideanTo(q), '131273.287', fmt='%.3f') self.test('euclideanTo', q.euclideanTo(p), '131273.287', fmt='%.3f') self.test('flatLocalTo', p.flatLocalTo(q), '124804.754' if Sph else '125209.633', fmt='%.3f') self.test('flatLocalTo', q.flatLocalTo(p), '124804.754' if Sph else '125209.633', fmt='%.3f') self.test('flatPolarTo', p.flatPolarTo(q), '133663.257', fmt='%.3f') self.test('flatPolarTo', q.flatPolarTo(p), '133663.257', fmt='%.3f') self.test('haversineTo', p.haversineTo(q), '124801.098', fmt='%.3f') self.test('haversineTo', q.haversineTo(p), '124801.098', fmt='%.3f') self.test('hubenyTo', p.hubenyTo, p.flatLocalTo) self.test('hubenyTo', q.hubenyTo, q.flatLocalTo) self.test('thomasTo', p.thomasTo(q), '124801.098' if Sph else '125206.188', fmt='%.3f') self.test('thomasTo', q.thomasTo(p), '124801.098' if Sph else '125206.188', fmt='%.3f') self.test('vincentysTo', p.vincentysTo(q), '124801.098', fmt='%.3f') self.test('vincentysTo', q.vincentysTo(p), '124801.098', fmt='%.3f') if hasattr(LatLon, 'greatCircleTo'): gc = p.greatCircleTo(q) self.test('greatCircleTo', gc, '(-0.79408, 0.12859, 0.59406)') # PYCHOK test attr? if isclockwise: f = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1) for _ in self.testiter(): self.test('isclockwise', isclockwise(f), False) # PYCHOK test attr? t = LatLon(45, 1), LatLon(46, 1), LatLon(46, 2), LatLon(45, 1) for _ in self.testiter(): self.test('isclockwise', isclockwise(t), True) # PYCHOK test attr? for _ in self.testiter(): try: self.test('isclockwise', isclockwise(t[:2]), ValueError.__name__) except ValueError as x: self.test('isclockwise', str(x), 'points (2): too few', known=True) # PYCHOK test attr? # <https://blog.Element84.com/determining-if-a-spherical-polygon-contains-a-pole.html> p = LatLon(85, -135), LatLon(85, -45), LatLon(85, 45), LatLon( 85, 135), LatLon(85, -135) for _ in self.testiter(): try: self.test('isclockwise', isclockwise(p), ValueError.__name__) # PYCHOK test attr? except ValueError as x: self.test('isclockwise', str(x), 'zero or polar area', known=True) # PYCHOK test attr? if isconvex: f = LatLon(45, 1), LatLon(46, 2), LatLon(45, 2), LatLon(46, 1) for _ in self.testiter(): self.test('isconvex', isconvex(f), False) # PYCHOK test attr? t = LatLon(45, 1), LatLon(46, 1), LatLon(46, 2), LatLon(45, 1) for _ in self.testiter(): self.test('isconvex', isconvex(t), True) # PYCHOK test attr? for _ in self.testiter(): try: self.test('isconvex', isconvex(t[:2]), ValueError.__name__) except ValueError as x: self.test('isconvex', str(x), 'points (2): too few', known=True) # PYCHOK test attr? if isenclosedBy: b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1) for _ in self.testiter(): self.test('isenclosedBy1', isenclosedBy(LatLon(45.5, 1.5), b), True) # PYCHOK test attr? for _ in self.testiter(): # on polygon point is outside self.test('isenclosedBy2', isenclosedBy((46, 2), b), False) # PYCHOK test attr? for _ in self.testiter(): # on polygon point is outside self.test('isenclosedBy3', isenclosedBy((46, 1), b), False) # PYCHOK test attr? for _ in self.testiter(): # on polygon edge is outside self.test('isenclosedBy4', isenclosedBy((46, 1.5), b), False) # PYCHOK test attr? for _ in self.testiter(): # on polygon is False self.test('isenclosedBy5', isenclosedBy((45.5, 1), b), False) # PYCHOK test attr? p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -90), LatLon(85, -180) for _ in self.testiter(): self.test('isenclosedBy6', isenclosedBy((90, 0), p), 'True') # PYCHOK test attr? p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -90) for _ in self.testiter(): self.test('isenclosedBy7', isenclosedBy((90, 0), p), 'True') # PYCHOK test attr? if hasattr(LatLon, 'initialBearingTo'): b = LHR.initialBearingTo(FRA) self.test('initialBearingTo', b, 102.432182 if Sph else 102.392291, fmt='%.6f') # PYCHOK test attr? a = LHR.compassAngleTo(FRA, adjust=False) self.test('compassAngleTo', a, 100.017, fmt='%.3f') a = LHR.compassAngleTo(FRA) # adjust=True self.test('compassAngleTo', a, 105.599, fmt='%.3f') if hasattr(LatLon, 'initialBearingTo'): b = FRA.initialBearingTo(LHR) self.test('initialBearingTo', b, 288.715918 if Sph else 288.676039, fmt='%.6f') # PYCHOK test attr? a = FRA.compassAngleTo(LHR, adjust=False) self.test('compassAngleTo', a, 280.017, fmt='%.3f') a = FRA.compassAngleTo(LHR) # adjust=True self.test('compassAngleTo', a, 285.599, fmt='%.3f') d = LHR.equirectangularTo(FRA) self.test('equirectangularTo', m2km(d), 592.185, fmt='%.3f') if hasattr(LatLon, 'distanceTo'): d = LHR.distanceTo(FRA) self.test('distanceTo', m2km(d), 591.831 if Sph else (591.831 if Nv else 593.571), fmt='%.3f') # PYCHOK test attr? p = LatLon(0, 0) for a, b, d in ((1, 0, 0.0), (1, 1, 45.0), (0, 1, 90.0), (-1, 0, 180.0), (-1, -1, 225.0), (1, -1, 315.0), (0, -1, 270.0), (90, -1, 359.4)): q = LatLon(p.lat + a, p.lon + b) if not Nv: b = p.initialBearingTo(q) self.test('bearingTo', b, d, fmt='%.1f', known=True) c = p.compassAngleTo(q, adjust=False) self.test('compassAngleTo', c, d, fmt='%.1f') p.lat, p.lon = 52, '0' # coverage q = LatLon(p.lat + 1, p.lon + 1) # 45 unadjusted self.test('latlon2', q.latlon2(1), '(53.0, 1.0)') self.test('philam2', q.philam2(2), '(0.93, 0.02)') if not Nv: b = p.initialBearingTo(q) self.test('bearingTo', b, 31.0, fmt='%.0f') c = p.compassAngleTo(q, adjust=True) self.test('compassAngleTo', c, 31.0, fmt='%.0f') c = p.compassAngleTo(q, adjust=False) self.test('compassAngleTo', c, 45.0, fmt='%.0f') # check return types self.testReturnType(p.boundsOf(2, 4), Bounds2Tuple, 'boundsOf') self.testReturnType(p.latlon, LatLon2Tuple, 'latlon') self.testReturnType(p.latlon2(), LatLon2Tuple, 'latlon2') self.testReturnType(p.latlonheight, LatLon3Tuple, 'latlonheight') self.testReturnType(p.isequalTo(p), bool, 'isequalTo') self.testReturnType(p.philam, PhiLam2Tuple, 'philam') self.testReturnType(p.philamheight, PhiLam3Tuple, 'philamheight') self.testReturnType(p.to2ab(), PhiLam2Tuple, 'to2ab') self.testReturnType(p.to3llh(0), LatLon3Tuple, 'to3llh') self.testReturnType(p.to3xyz(), Vector3Tuple, 'to3xyz') self.testReturnType(p.xyz, Vector3Tuple, 'xyz') self.testReturnType(p.xyzh, Vector4Tuple, 'xyzh') self.testReturnType(p.compassAngleTo(q), float, 'compassAngleTo') self.testReturnType(p.cosineLawTo(q), float, 'cosineLawTo') self.testReturnType(p.euclideanTo(q), float, 'euclideanTo') self.testReturnType(p.flatLocalTo(q), float, 'flatLocalTo') self.testReturnType(p.flatPolarTo(q), float, 'flatPolarTo') self.testReturnType(p.haversineTo(q), float, 'haversineTo') self.testReturnType(p.hubenyTo(q), float, 'hubenyTo') self.testReturnType(p.vincentysTo(q), float, 'vincentysTo') if not Nv: # XXX prec=5 for NvectorBase.toStr vs prec=6 for Vector3Tuple.toStr self.test('toNvector', p.toNvector(), '(0.61566, 0.0, 0.78801)' if Sph else '(0.615661, 0.0, 0.788011)') # PYCHOK test self.test('toVector', p.toVector(), '(0.615661, 0.0, 0.788011)') self.test('toVector3d', p.toVector3d(), '(0.61566, 0.0, 0.78801)')
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.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')): p = LL(lat, lon) try: u = p.toUtm().toStr(prec=0, B=True) except ValueError as e: if x[2] in 'ABYZ': x = u = str(e) 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 testVincenty(self, LatLon, datum): d = datum n = ' (%s)' % (d.name, ) Newport_RI = LatLon(41.49008, -71.312796, datum=d) Cleveland_OH = LatLon(41.499498, -81.695391, datum=d) m = Newport_RI.distanceTo(Cleveland_OH) self.test('distanceTo' + n, '%.5f' % m, '866455.43292') try: t = None m = Newport_RI.distanceTo(Newport_RI) except VincentyError as x: t = x # Python 3+ self.test( 'VincentyError' + n, t, 'LatLon(41°29′24.29″N, 071°18′46.07″W) coincident with LatLon(41°29′24.29″N, 071°18′46.07″W)' ) if hasattr(LatLon, 'toCartesian'): try: m = Newport_RI.distanceTo( Cleveland_OH.convertDatum(Datums.OSGB36)) self.test('ValueError' + n, None, 'other Ellipsoid mistmatch: ...' + d.ellipsoid.name) except ValueError as x: self.test( 'ValueError' + n, x, 'other Ellipsoid mistmatch: Ellipsoids.Airy1830 vs Ellipsoids.' + d.ellipsoid.name) except Exception as x: self.test('ValueError' + n, x, 'ValueError ...' + d.ellipsoid.name) Boston = LatLon(42.3541165, -71.0693514, datum=d) NewYork = LatLon(40.7791472, -73.9680804, datum=d) m = Boston.distanceTo(NewYork) p = LatLon(-37.95103342, 144.42486789, datum=d) self.test('isellipsoidal', p.isellipsoidal, 'True') self.test('isspherical', p.isspherical, 'False') q = p.copy() self.test('copy', q.equals(p), 'True') self.test('isellipsoidal', q.isellipsoidal, 'True') self.test('isspherical', q.isspherical, 'False') self.test('copy', q.toStr(F_DMS, prec=4), '37°57′03.7203″S, 144°25′29.5244″E') q = p.destination(54972.271, 306.86816) t = q.toStr(F_D, prec=4) self.test('destination' + n, t, '37.6528°S, 143.9265°E') self.test('destination' + n, isinstance(q, LatLon), 'True') q, f = p.destination2(54972.271, 306.86816) t = q.toStr(F_D) + ', ' + compassDMS(f, prec=4) self.test('destination2' + n, t, '37.652821°S, 143.926496°E, 307.1736°NW') self.test('destination2' + n, 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' + n, t, '307.1736°, 307°10′25.07″NW') p = LatLon(50.06632, -5.71475, datum=d) q = LatLon(58.64402, -3.07009, datum=d) m = p.distanceTo(q) self.test('distanceTo' + n, '%.3f' % m, '969954.166') t = p.distanceTo3(q) t = fStr(t, prec=6) self.test('distanceTo3' + n, t, '969954.166314, 9.141877, 11.29722') b = p.initialBearingTo(q) t = bearingDMS(b, prec=4) + ', ' + compassDMS(b, form=F_DMS, prec=2) self.test('initialBearingTo' + n, t, '9.1419°, 9°08′30.76″N') f = p.finalBearingTo(q) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingTo' + n, 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' + n, '%.3f' % m, '404607.806') t = p.distanceTo3(q) t = fStr(t, prec=6) self.test('distanceTo3' + n, t, '404607.805988, 156.11064, 157.8345') b = p.initialBearingTo(q) t = bearingDMS(b, prec=4) + ', ' + compassDMS(b, form=F_DMS, prec=2) self.test('initialBearingTo' + n, t, '156.1106°, 156°06′38.31″SSE') f = p.finalBearingTo(q) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingTo' + n, t, '157.8345°, 157°50′04.2″SSE') # 157.9 p = LatLon(37.95103, 144.42487, datum=d) q = LatLon(37.65280, 143.9265, datum=d) m = p.distanceTo(q) self.test('distanceTo' + n, '%.3f' % m, '54973.295') t = p.distanceTo3(q) t = fStr(t, prec=5) self.test('distanceTo3' + n, t, '54973.29527, 233.13008, 232.82461') b = p.initialBearingTo(q) t = bearingDMS(b, prec=4) + ', ' + compassDMS(b, form=F_DMS, prec=2) self.test('initialBearingTo' + n, t, '233.1301°, 233°07′48.28″SW') f = p.finalBearingTo(q) t = bearingDMS(f, prec=4) + ', ' + compassDMS(f, form=F_DMS, prec=2) self.test('finalBearingTo' + n, 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' + n, '%.3f' % m, '298396.057') p = LatLon(0, 0, datum=d) q = LatLon(0, 1, datum=d) m = p.distanceTo(q) self.test('distanceToMP' + n, '%.3f' % m, '111319.491') q = LatLon(1, 0, datum=d) m = p.distanceTo(q) self.test('distanceToMP' + n, '%.3f' % m, '110574.389') # <https://pypi.python.org/pypi/pygc> Kyle Wilcox p = LatLon(0, 50, datum=d) q = LatLon(0, 52, datum=d) m = p.distanceTo(q) self.test('distanceToKW' + n, '%.3f' % m, '222638.982') q = LatLon(0, 49, datum=d) m = p.distanceTo(q) self.test('distanceToKW' + n, '%.3f' % m, '111319.491')
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') 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') 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.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) self.test('Wm8.toWm', w.toStr2(), '[x:-33878.893, y:6693890.382]') 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 testUps(self, LL): u = Ups(0, 'N', 448251, 5411932.0001) self.test('Ups', u.toStr(4), '00 N 448251.0 5411932.0001') u = Ups(0, 'N', 448251.795, 5411932.678, falsed=False) self.test('Ups', u, '00 N 448252 5411933') self.test('Ups', u.toStr(prec=3), '00 N 448251.795 5411932.678') self.test('Ups', u.toStr(prec=1, B=True, cs=True), '00Z N 448251.8 5411932.7 n/a n/a') ll = u.toLatLon(LL, unfalse=False) # UTM 48.85820000°N, 002.29450000°E self.test('Ups.toLatLon', ll, '43.684097°N, 175.265195°E') self.test('Ups.toLatLon', ll.toStr(form=F_DMS), '43°41′02.75″N, 175°15′54.7″E') # u = ll.toUps(falsed=False) # UTM N 448251.795205746 5411932.67761691 # self.test('LL.toUps', u, 'N 448252 5411933') # self.test('LL.toUps', u.toStr(prec=3), 'N 448251.795 5411932.678') # self.test('LL.toUps', u.toStr2(B=True, cs=True), '[Z:00Z P:N E:448252 N:5411933 C:+175.26519494° S:1.17547892]') # TM8358-2 pg 3-7 ID 1 u = toUps8('84 17 14.042N', '132 14 52.761W') # -132.247988889 self.test('toUpsID1', u.toStr(prec=2, cs=True), '00 N 1530125.78 2426773.6 -132.24798917° 0.99647445') # TM8358-2 pg 3-7 ID 2 u = toUtmUps8('73N', '44E') # Karney 38n 467368 8100752 (73°00'00.0"N 044°00'00.0"E) MGRS 38XMG6736700752 self.test('toUtmUps8ID2', u.toStr(prec=2, cs=True), '38 N 3320416.75 632668.43 +44.0° 1.01619505', known=True) u = toUps8('73N', '44E', strict=False) # allow lat outside UPS range self.test('toUtmUps8ID2', u.toStr(prec=2, cs=True), '00 N 3320416.75 632668.43 +44.0° 1.01619505') # TM8358-2 pg 3-7 ID 3 u = toUps8('87 17 14.4S', '132 14 52.303E', pole='S') # -132.247861111 self.test('toUpsID3', u.toStr(prec=2, cs=True), '00 S 2222979.47 1797474.9 -132.24786194° 0.99455723') # TM8358-2 pg 3-7 ID 4 u = Ups(0, 'N', '1530125.78', '2426773.6') ll = u.toLatLon(LL) self.test('Ups.toLatLonID4', ll.toStr(form=F_DMS), '84°17′14.04″N, 132°14′52.76″W') self.test('Ups.toLatLonID4', ll, '84.287234°N, 132.247989°W') # TM8358-2 pg 3-7 ID 5 u = Ups(0, 'N', '3320416.75', '632668.43') ll = u.toLatLon(LL) self.test('Ups.toLatLonID5', ll.toStr(form=F_DMS), '72°59′60.0″N, 044°00′00.0″E') # 73°00′00.0″N self.test('Ups.toLatLonID5', ll, '73.0°N, 044.0°E') # TM8358-2 pg 3-7 ID 6 u = Ups(0, 'S', '2222979.47', '1797474.9') ll = u.toLatLon(LL) self.test('Ups.toLatLonID6', ll.toStr(form=F_DMS), '87°17′14.4″S, 132°14′52.3″E') self.test('Ups.toLatLonID6', ll, '87.287333°S, 132.247861°E') # <https://GeographicLib.SourceForge.io/cgi-bin/GeoConvert> ll = LL(84, 84) self.test('latlon', ll, ll) u = toUps8(ll) # n 2663075 1930308 (84°00'00.0"N 084°00'00.0"E) MGRS ZJG6307530307 self.test('toUps', u, '00 N 2663075 1930308') self.test('toUps', u.toStr(prec=6, cs=True), '00 N 2663075.299562 1930307.977716 +84.0° 0.99673') # self.test('toMgrs5', u.toMgrs(), 'Z JG 63075 30307') # <https://Earth-Info.NGA.mil/GandG/publications/NGA_SIG_0012_2_0_0_UTMUPS/NGA.SIG.0012_2.0.0_UTMUPS.pdf> # 10.2 Examples of computng {x, y, sigma, gamma}, given {lambda, phi, Z} page 41 # replaced with Karney's results from <https://GeographicLib.SourceForge.io/cgi-bin/GeoConvert> # 8: lat lon 83 90 UTM/UPS 46n 459200.256323 9217519.441609 MGRS 46X DT 5920025632317519441609 # 9: lat lon 82 91 UTM/UPS 46n 468930.934996 9105366.008486 MGRS 46X DS 6893093499605366008486 # 10: lat lon 81 179 UTM/UPS 60n 534921.971582 8993806.415149 MGRS 60X WQ 3492197158193806415148 # 11: lat lon 80 180 UTM/UPS 01n 441867.784867 8883084.955948 MGRS 01X DJ 4186778486783084955948 # 12: lat lon 40 0 UTM/UPS 31n 243900.352030 4432069.056899 MGRS 31T BE 4390035202932069056898 # 13: lat lon 3 -179 UTM/UPS 01n 277707.830749 331796.291679 MGRS 01N BD 7770783074931796291678 # 14: lat lon 2 -90 UTM/UPS 16n 166223.907623 221366.166030 MGRS 16N AH 6622390762321366166030 # 15: lat lon 1 -1 UTM/UPS 30n 722561.736479 110597.972524 MGRS 30N YG 2256173647810597972523 # 16: lat lon 0 0 UTM/UPS 31n 166021.443081 0.000000 MGRS 31N AA 6602144308000000000000 # 17: lat lon -1 1 UTM/UPS 31s 277438.263521 9889402.027476 MGRS 31M BU 7743826352189402027476 # 18: lat lon -2 90 UTM/UPS 46s 166223.907623 9778633.833970 MGRS 46M AC 6622390762378633833969 # 19: lat lon -3 179 UTM/UPS 60s 722292.169251 9668203.708321 MGRS 60M YB 2229216925068203708321 # 20: lat lon -4 180 UTM/UPS 01s 166831.065275 9557263.747314 MGRS 01M AR 6683106527557263747313 for t in ('1 -0 90 N 2000000.0 2000000.0 0.994 -0', '2 -179 89 N 1998062.320046 2111009.610243 0.994076 -179', '3 -90 88 N 1777930.731071 2000000.0 0.994303 -90', '4 -1 87 N 1994185.827038 1666906.254073 0.994682 -1', '5 0 86 N 2000000.0 1555731.570643 0.995212 0', '6 1 85 N 2009694.068153 1444627.207468 0.995895 1', '7 89 84 N 2666626.157825 1988363.997132 0.996730 89', # '8 90 83 N 2778095.750322 2000000.0 0.997718 90', '8 90 83 N 459200.256323 9217519.441609 0.997718 -2.97767886', # '9 91 82 N 2889442.490749 2015525.276426 0.998860 91', '9 91 82 N 468930.934996 9105366.008486 0.998860 -1.98055172', # '10 179 81 N 2017473.190606 3001038.419357 1.000156 179', '10 179 81 N 534921.971582 8993806.415149 1.000156 +1.97539632', # '11 180 80 N 2000000.0 3112951.136955 1.001608 180', '11 180 80 N 441867.784867 8883084.955948 1.001608 -2.95450468', # '12 0 40 N 2000000.0 -3918313.984953 1.209619 0', '12 0 40 N 243900.35203 4432069.056899 1.0004075 -1.92940969', # '13 -179 3 N 1790630.987261 13994742.706481 1.883453 -179', '13 -179 3 N 277707.830749 331796.291679 1.00021172 -0.1047151895', # '14 -90 2 N -10206568.118587 2000000.0 1.914973 -90', '14 -90 2 N 166223.907623 221366.16603 1.00097936 -0.104796101', # '15 -1 1 N 1783239.204558 -10418217.653909 1.947589 -1', '15 -1 1 N 722561.736479 110597.972524 1.00021322 0.03491928033333334', # '16 0 0 N 2000000.0 -10637318.498257 1.981349 0', '16 0 0 N 166021.443081 0.0 1.00098106 0', # '17 1 -1 N 2224408.737826 -10856367.979638 2.016305 1', '17 1 -1 S 277438.263521 9889402.027476 1.00021322 0.03491928033333334', # '18 90 -2 N 15083269.373905 2000000.0 2.052510 90', '18 90 -2 S 166223.907623 9778633.83397 1.00097936 0.104796101', # '19 179 -3 N 2232331.498720 15310262.647286 2.090020 179', '19 179 -3 S 722292.169251 9668203.708321 1.00021172 -0.1047151895', # '20 180 -4 N 2000000.0 15545537.944524 2.128897 180', '20 180 -4 S 166831.065275 9557263.747314 1.00097428 0.209463796167',): i, lon, lat, p, e, n, s, c = t.split() u = toUtmUps8(lat, lon) z = '%02d' % (u.zone,) x = ' '.join((z, p, e, n, degDMS(float(c), prec=8, pos='+'), s)) t = u.toStr(prec=6, cs=True) if abs(float(s) - u.scale) < 1e-2: t = ' '.join(t.split()[:-1] + [s]) self.test('NGA-10.2-' + i, t, x) # <https://Earth-Info.NGA.mil/GandG/publications/NGA_SIG_0012_2_0_0_UTMUPS/NGA.SIG.0012_2.0.0_UTMUPS.pdf> # 10.3 Examples of computing {lambda, phi}, given {Z, x, y} page 41 for t in ('1 S 0 0 -135.0 -64.9164123332', '2 S 1000000 0 -153.4349488229 -70.0552944014', '3 S 2000000 0 -180.0 -72.1263610163', '4 S 3000000 0 153.4349488229 -70.0552944014', '5 S 4000000 0 135.0 -64.9164123332', '6 S 0 1000000 -116.5650511771 -70.0552944014', '7 S 1000000 1000000 -135.0 -77.3120791908', '8 S 2000000 1000000 180.0 -81.0106632645', '9 S 3000000 1000000 135.0 -77.3120791908', '10 S 4000000 1000000 116.5650511771 -70.0552944014', '11 S 0 2000000 -90.0 -72.1263610163', '12 S 1000000 2000000 -90.0 -81.0106632645', '13 S 2000000 2000000 0.0 -90.0', '14 S 3000000 2000000 90.0 -81.0106632645', '15 S 4000000 2000000 90.0 -72.1263610163', '16 S 0 3000000 -63.4349488229 -70.0552944014', '17 S 1000000 3000000 -45.0 -77.3120791908', '18 S 2000000 3000000 0.0 -81.0106632645', '19 S 3000000 3000000 45.0 -77.3120791908', '20 S 4000000 3000000 63.4349488229 -70.0552944014', '21 S 0 4000000 -45.0 -64.9164123332', '22 S 1000000 4000000 -26.5650511771 -70.0552944014', '23 S 2000000 4000000 0.0 -72.1263610163', '24 S 3000000 4000000 26.5650511771 -70.0552944014', '25 S 4000000 4000000 45.0 -64.9164123332'): i, p, e, n, lon, lat = t.split() x = lat + ' ' + lon u = parseUTMUPS5(' '.join(('00', p, e, n))) ll = u.toLatLon(LL) t = fStr(ll.latlon, prec=10, sep=' ') self.test('NGA-10.3-' + i, t, x, known=i == '3')
def testGeohash(self, LL): cn = classname(LL(0, 0)) g = Geohash('geek') self.test('Geohash', repr(g), "Geohash('geek')") self.test('Geohash', g, '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('ab', fStr(g.ab, 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('decode_error', fStr(geohash.decode_error(g), fmt='%*e'), '2.145767e-05, 2.145767e-05') self.test('distance1', g.distance1('geehpb'), '2758.887', fmt='%.3f') self.test('distance2', g.distance2('geehpb'), '682.760', fmt='%.3f') self.test('distance3', g.distance3('geehpb'), '397.404', fmt='%.3f') 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) 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('decode_error', fStr(geohash.decode_error('u120fxw'), fmt='%*e'), '6.866455e-04, 6.866455e-04') self.test('distance1', geohash.distance1('u120fxw', 'u120fxws0'), '486.710', fmt='%.3f') self.test('distance2', geohash.distance2('u120fxw', 'u120fxws0'), '3.374', fmt='%.3f') self.test('distance3', geohash.distance3('u120fxw', 'u120fxws0'), '2.798', fmt='%.3f') 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)') for t in range(0, 14): r = geohash.resolution2(t, t) p = geohash.precision(*r) self.test('precision', t, p, known=t < 1 or t > 12) b = fStr(r, prec=t + 1) self.test('resolution', b, b) # just to show
def _fStr(floats, prec=6): return ', '.join('None' if f is None else fStr(f, prec=prec) for f in floats)
def testDeprecated(self, LatLon): c = HeightIDW # == HeightIDWeuclidean in Python 3.7+ self.test(c.__name__, issubclass(c, HeightIDWeuclidean), True) c = HeightIDW2 # == HeightIDWequirectangular in Python 3.7+ self.test(c.__name__, issubclass(c, HeightIDWequirectangular), True) c = HeightIDW3 # == HeightIDWhaversine in Python 3.7+ self.test(c.__name__, issubclass(c, HeightIDWhaversine), True) p = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1) self.test('areaof', areaof(p, radius=R_MA), '7.086883e+09', fmt='%.6e') p = LatLon(85, 90), LatLon(-85, 0), LatLon(85, -90), LatLon(85, -180) b = map2(float, bounds(p)) self.test('bounds', b, '(-85.0, -180.0, 85.0, 90.0)') self.test('anStr', anStr('a-b?_'), 'a-b__') self.test('clipStr', clipStr('test/testBasics.py', limit=12), 'test/t....ics.py') self.test('decodeEPSG2', decodeEPSG2(32712), "(12, 'S')") self.test('encodeEPSG', encodeEPSG(12, hemipole='S'), '32712') t = equirectangular3(0, 2, 3, 4) self.test('equirectangular3', len(t), 3) self.test('equirectangular3', t[0], 12.997, fmt='%.3f') 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') self.test('fStr', fStr(0.123, prec=+6, fmt='%.*f'), '0.123') h = hypot3(3000, 200, 10) s = sqrt(3000**2 + 200**2 + 10**2) self.test('hypot3', h, s, fmt='%.6f') b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1) self.test('isenclosedby', isenclosedby(LatLon(45.5, 1.5), b), True) p = LatLon(45, 2) b = LatLon(45, 1), LatLon(47, 3) t = nearestOn3(p, b, adjust=False) self.test('nearestOn3', len(t), 3) self.test('nearestOn3', t[:2], (45.5, 1.5)) t = nearestOn4(p, b, adjust=False) self.test('nearestOn4', len(t), 4) self.test('nearestOn4', t[:2], (45.5, 1.5)) t = parseUTM('18 N 516620 4574500', Utm=None) # Milford, PA self.test('parseUTM', t, "(18, 'N', 516620.0, 4574500.0)") p = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1) self.test('perimeterof', perimeterof(p, radius=R_MA), '2.687460e+05', fmt='%.6e') p = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1) self.test('polygon', polygon(p)[0], 3) t = simplify2(RdpFFI, 16, adjust=True, shortest=False) self.test('simplify2', len(t), 4) t = toUtm('50°52′10″N', '115°39′03″W', Utm=None, name='Mt Assiniboine') self.test('toUtm', len(t), 6) t = utmZoneBand2('50°52′10″N', '115°39′03″W') self.test('utmZoneBand2', t, "(11, 'U')")
def testLatLon(self, module, Sph=False, Nv=True): # MCCABE 45 self.subtitle(module, 'LatLon') LatLon = module.LatLon # basic LatLon class tests p = LatLon(52.20472, 0.14056) self.test('isEllipsoidal', p.isEllipsoidal, not Sph) self.test('isSpherical', p.isSpherical, Sph) self.test('lat/lonDMS', p, '52.20472°N, 000.14056°E') # 52.20472°N, 000.14056°E self.test('lat/lonDMS F_DM', p.toStr(F_DM, 3), '''52°12.283'N, 000°08.434'E''') self.test('lat/lonDMS F_DM', p.toStr(F_DM, 4), '''52°12.2832'N, 000°08.4336'E''') self.test('lat/lonDMS F_DMS', p.toStr(F_DMS, 0), '''52°12'17"N, 000°08'26"E''') self.test('lat/lonDMS F_DMS', p.toStr(F_DMS, 1), '''52°12'17.0"N, 000°08'26.0"E''') self.test('lat/lonDMS F_RAD', p.toStr(F_RAD, 6), '0.911144N, 0.002453E') q = LatLon(*map(degrees, p.to2ab())) self.test('isequalTo', q.isequalTo(p), True) self.test('latlon2', fStr(q.latlon2(5)), '52.20472, 0.14056') self.test('latlon2', fStr(q.latlon2(4)), '52.2047, 0.1406') self.test('latlon2', fStr(q.latlon2(3)), '52.205, 0.141') self.test('latlon2', fStr(q.latlon2(2)), '52.2, 0.14') self.test('latlon2', fStr(q.latlon2(1)), '52.2, 0.1') self.test('latlon2', fStr(q.latlon2()), '52.0, 0.0') FRA = LatLon(50.0379, 8.5622) LHR = LatLon(51.47, 0.4543) # <http://www.EdWilliams.org/avform.htm#XTE> JFK = LatLon(degrees(0.709186), -degrees(1.287762)) LAX = LatLon(33.+57./60, -(118.+24./60)) Rav = m2NM(6366710) # avg. earth radius in NM # <http://GeographicLib.SourceForge.io/html/python/examples.html> WNZ = LatLon(-41.32, 174.81) # Wellington, NZ SAL = LatLon(40.96, 5.50) # Salamanca, Spain BJS = LatLon(40.1, 116.6) # Beijing Airport SFO = LatLon(37.6, -122.4) # San Francisco p = LatLon(52.205, 0.119) q = LatLon(48.857, 2.351) self.test('isequalTo', p.isequalTo(q), False) a = p.antipode() self.test('antipode1', a, '52.205°S, 179.881°W') self.test('antipode2', a.isantipodeTo(p), True) b = a.antipode() self.test('antipode3', b, '52.205°N, 000.119°E') self.test('antipode4', a.isantipodeTo(b), True) self.test('antipode5', b, p) if hasattr(LatLon, 'initialBearingTo'): b = p.initialBearingTo(q) self.test('initialBearingTo', b, 156.1666 if Sph else 156.1106, fmt='%.4f') # 156.2 b = p.finalBearingTo(q) self.test('finalBearingTo', b, 157.8904 if Sph else 157.8345, fmt='%.4f') b = LAX.initialBearingTo(JFK) self.test('initialBearingTo', b, 65.8921 if Sph else 65.9335, fmt='%.4f') # PYCHOK test attr? b = LAX.finalBearingTo(JFK) self.test('finalBearingTo', b, 93.8581 if Sph else 93.9034, fmt='%.4f') # PYCHOK test attr? if hasattr(LatLon, 'bearingTo2'): b = p.bearingTo2(q) self.test('bearingTo2', fStr(b, prec=4), '156.1666, 157.8904' if Sph else '156.1106, 157.8345') # 156.2 # <http://blog.Element84.com/determining-if-a-spherical-polygon-contains-a-pole.html> b = LatLon(85, -135), LatLon(85, -45), LatLon(85, 45), LatLon(85, 135), LatLon(85, -135) self.test('ispolar', ispolar(b), True) # PYCHOK test attr? c = p.copy() self.test('copy', p.isequalTo(c), 'True') d = p.equirectangularTo(q) self.test('equirectangularTo', d, '404329.56', fmt='%.2f') if hasattr(LatLon, 'distanceTo'): d = p.distanceTo(q) self.test('distanceTo', d, '404279.720589' if Sph else '404607.805988', fmt='%.6f') # 404300 d = q.distanceTo(p) self.test('distanceTo', d, '404279.720589' if Sph else '404607.805988', fmt='%.6f') # 404300 d = LAX.distanceTo(JFK, radius=R_NM) if Sph else LAX.distanceTo(JFK) self.test('distanceTo', d, 2145 if Sph else 3981601, fmt='%.0f') # PYCHOK test attr? if not Nv: # <http://GeographicLib.SourceForge.io/html/python/examples.html> self.test('antipodal', WNZ.isantipodeTo(SAL, eps=0.1), False) d = WNZ.distanceTo(SAL, wrap=False) self.test('distanceTo dateline', d, 19119590.551 if Sph else 19959679.267, fmt='%.3f', known=True) # PYCHOK test attr? d = WNZ.distanceTo(SAL, wrap=True) self.test('distanceTo unrolled', d, 19119590.551 if Sph else 19959679.267, fmt='%.3f', known=True) # PYCHOK test attr? self.test('antipodal', BJS.isantipodeTo(SFO, eps=0.1), False) d = BJS.distanceTo(SFO, wrap=False) self.test('distanceTo dateline', d, 9491735 if Sph else 9513998, fmt='%.0f') # PYCHOK test attr? d = BJS.distanceTo(SFO, wrap=True) self.test('distanceTo unrolled', d, 9491735 if Sph else 9513998, fmt='%.0f') # PYCHOK test attr? if hasattr(LatLon, 'distanceTo3') and not Sph: for w in (False, True): d = WNZ.distanceTo3(SAL, wrap=w) # XXX expected values? self.test('distanceTo3 dateline', fStr(d, prec=4), '19125097.7012, 270.7159, 276.0288', known=True) # PYCHOK test attr? d = BJS.distanceTo3(SFO, wrap=w) self.test('distanceTo3 dateline', fStr(d, prec=4), '9513997.9901, 42.9164, 138.8903') # PYCHOK test attr? if hasattr(LatLon, 'intermediateTo'): i = p.intermediateTo(q, 0.25) self.test('intermediateTo', i, '51.372084°N, 000.707337°E' if Sph else '51.372294°N, 000.707192°E') self.test('intermediateTo', isinstance(i, LatLon), True) if hasattr(p, 'distanceTo'): d = p.distanceTo(q) self.test('intermediateTo', d, '404279.721', fmt='%.3f') # PYCHOK test attr? i = p.intermediateTo(q, 5) self.test('intermediateTo+5', i, '35.160975°N, 008.989542°E' if Sph else '35.560239°N, 008.833512°E') if hasattr(p, 'distanceTo'): self.test('intermediateTo+5', p.distanceTo(i) / d, '5.000', fmt='%.3f') # PYCHOK test attr? i = p.intermediateTo(q, -4) self.test('intermediateTo-4', i, '64.911647°N, 013.726301°W' if Sph else '64.570387°N, 013.156352°W') if hasattr(p, 'distanceTo'): self.test('intermediateTo-4', p.distanceTo(i) / d, '4.000', fmt='%.3f') # PYCHOK test attr? # courtesy of <http://GitHub.com/bakakaldsas> i = LatLon(52, 0, 100).intermediateTo(LatLon(48, 2, 200), 0.25) self.test('intermediateTo-h', i.height, '125.000', fmt='%.3f') # PYCHOK test attr? if hasattr(LatLon, 'intermediateChordTo'): i = p.intermediateChordTo(q, 0.25) self.test('intermediateChordTo', i, '51.372294°N, 000.707192°E') self.test('intermediateChordTo', isinstance(i, LatLon), True) # PYCHOK test attr? # courtesy of <http://GitHub.com/bakakaldsas> i = LatLon(52, 0, 100).intermediateChordTo(LatLon(48, 2, 200), 0.25) self.test('intermediateChordTo-h', i.height, '125.000', fmt='%.3f') # PYCHOK test attr? if hasattr(LatLon, 'midpointTo'): m = p.midpointTo(q) self.test('midpointTo', m, '50.536327°N, 001.274614°E') # PYCHOK test attr? # 50.5363°N, 001.2746°E if hasattr(LatLon, 'destination'): p = LatLon(51.4778, -0.0015) d = p.destination(7794, 300.7) self.test('destination', d, '51.513546°N, 000.098345°W' if Sph else '51.513526°N, 000.098038°W') # 51.5135°N, 0.0983°W ??? self.test('destination', d.toStr(F_DMS, 0), '51°30′49″N, 000°05′54″W' if Sph else '51°30′49″N, 000°05′53″W') # <http://www.EdWilliams.org/avform.htm#LL> d = LAX.destination(100, 66, radius=R_NM) if Sph else LAX.destination(100, 66) self.test('destination', d.toStr(F_DM, prec=0), "34°37′N, 116°33′W" if Sph else "33°57′N, 118°24′W") self.test('destination', d, '34.613647°N, 116.55116°W' if Sph else '33.950367°N, 118.399012°W') self.test('destination', d.toStr(F_RAD, prec=6), '0.604122N, 2.034201W' if Sph else '0.592546N, 2.066453W') # PYCHOK expected # <http://GeographicLib.SourceForge.io/html/python/examples.html> d = LatLon(-32.06, -115.74).destination(20e6, 225).toStr(F_D, prec=8) self.test('destination', d, '31.96383509°N, 064.37329146°E' if Sph else '32.11195529°N, 063.95925278°E', known=True) # PYCHOK test attr? if hasattr(LatLon, 'alongTrackDistanceTo'): s = LatLon(53.3206, -1.7297) e = LatLon(53.1887, 0.1334) p = LatLon(53.2611, -0.7972) try: d = p.alongTrackDistanceTo(s, 96) self.test('alongTrackDistanceTo', d, 62331.59, fmt='%.2f') # 62331 except TypeError as x: self.test('alongTrackDistanceTo', x, 'type(end) mismatch: int vs ' + classname(p)) # PYCHOK test attr? d = p.alongTrackDistanceTo(s, e) self.test('alongTrackDistanceTo', d, 62331.58, fmt='%.2f') # <http://www.EdWilliams.org/avform.htm#XTE> p = LatLon(34.5, -116.5) # 34:30N, 116:30W d = p.alongTrackDistanceTo(LAX, JFK, radius=Rav) self.test('alongTrackDistanceTo', d, 99.588, fmt='%.3f') # NM # courtesy of Rimvydas Naktinis p = LatLon(53.36366, -1.83883) d = p.alongTrackDistanceTo(s, e) self.test('alongTrackDistanceTo', d, -7702.7, fmt='%.1f') p = LatLon(53.35423, -1.60881) d = p.alongTrackDistanceTo(s, e) self.test('alongTrackDistanceTo', d, 7587.6, fmt='%.1f') # PYCHOK test attr? if hasattr(LatLon, 'crossTrackDistanceTo'): s = LatLon(53.3206, -1.7297) e = LatLon(53.1887, 0.1334) p = LatLon(53.2611, -0.7972) try: d = p.crossTrackDistanceTo(s, 96) self.test('crossTrackDistanceTo', d, -305.67, fmt='%.2f') # -305.7 except TypeError as x: self.test('crossTrackDistanceTo', x, 'type(end) mismatch: int vs ' + classname(p)) # PYCHOK test attr? d = p.crossTrackDistanceTo(s, e) self.test('crossTrackDistanceTo', d, -307.55, fmt='%.2f') # -307.5 # <http://www.EdWilliams.org/avform.htm#XTE> p = LatLon(34.5, -116.5) # 34:30N, 116:30W d = p.crossTrackDistanceTo(LAX, JFK, radius=Rav) self.test('crossTrackDistanceTo', d, 7.4524, fmt='%.4f') # PYCHOK test attr? # XXX 7.4512 NM if hasattr(LatLon, 'greatCircle'): p = LatLon(53.3206, -1.7297) gc = p.greatCircle(96.0) self.test('greatCircle', gc, '(-0.79408, 0.12856, 0.59406)') # PYCHOK test attr? if hasattr(LatLon, 'greatCircleTo'): p = LatLon(53.3206, -1.7297) q = LatLon(53.1887, 0.1334) gc = p.greatCircleTo(q) self.test('greatCircleTo', gc, '(-0.79408, 0.12859, 0.59406)') # PYCHOK test attr? if isclockwise: f = LatLon(45,1), LatLon(45,2), LatLon(46,2), LatLon(46,1) for _ in self.testiter(): self.test('isclockwise', isclockwise(f), False) # PYCHOK test attr? t = LatLon(45,1), LatLon(46,1), LatLon(46,2), LatLon(45,1) for _ in self.testiter(): self.test('isclockwise', isclockwise(t), True) # PYCHOK test attr? for _ in self.testiter(): try: self.test('isclockwise', isclockwise(t[:2]), ValueError) except ValueError as x: self.test('isclockwise', x, 'too few points: 2') # PYCHOK test attr? # <http://blog.Element84.com/determining-if-a-spherical-polygon-contains-a-pole.html> p = LatLon(85, -135), LatLon(85, -45), LatLon(85, 45), LatLon(85, 135), LatLon(85, -135) for _ in self.testiter(): try: self.test('isclockwise', isclockwise(p), ValueError) # PYCHOK test attr? except ValueError as x: # polar or zero area: LatLon2psxy((LatLon(85°00′00.0″N, 135°00′00.0″W), ...)[4], ... self.test('isclockwise', str(x).split(':')[0], 'polar or zero area') # PYCHOK test attr? if isconvex: f = LatLon(45,1), LatLon(46,2), LatLon(45,2), LatLon(46,1) for _ in self.testiter(): self.test('isconvex', isconvex(f), False) # PYCHOK test attr? t = LatLon(45,1), LatLon(46,1), LatLon(46,2), LatLon(45,1) for _ in self.testiter(): self.test('isconvex', isconvex(t), True) # PYCHOK test attr? for _ in self.testiter(): try: self.test('isconvex', isconvex(t[:2]), ValueError) except ValueError as x: self.test('isconvex', x, 'too few points: 2') # PYCHOK test attr? if isenclosedBy: b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1) for _ in self.testiter(): self.test('isenclosedBy1', isenclosedBy(LatLon(45.5, 1.5), b), True) # PYCHOK test attr? for _ in self.testiter(): # on polygon point is outside self.test('isenclosedBy2', isenclosedBy((46, 2), b), False) # PYCHOK test attr? for _ in self.testiter(): # on polygon point is outside self.test('isenclosedBy3', isenclosedBy((46, 1), b), False) # PYCHOK test attr? for _ in self.testiter(): # on polygon edge is outside self.test('isenclosedBy4', isenclosedBy((46, 1.5), b), False) # PYCHOK test attr? for _ in self.testiter(): # on polygon is False self.test('isenclosedBy5', isenclosedBy((45.5, 1), b), False) # PYCHOK test attr? p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -90), LatLon(85, -180) for _ in self.testiter(): self.test('isenclosedBy6', isenclosedBy((90, 0), p), 'True') # PYCHOK test attr? p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -90) for _ in self.testiter(): self.test('isenclosedBy7', isenclosedBy((90, 0), p), 'True') # PYCHOK test attr? if hasattr(LatLon, 'initialBearingTo'): b = LHR.initialBearingTo(FRA) self.test('initialBearingTo', b, 102.432182 if Sph else 102.392291, fmt='%.6f') # PYCHOK test attr? a = LHR.compassAngleTo(FRA, adjust=False) self.test('compassAngleTo', a, 100.017, fmt='%.3f') a = LHR.compassAngleTo(FRA) # adjust=True self.test('compassAngleTo', a, 105.599, fmt='%.3f') if hasattr(LatLon, 'initialBearingTo'): b = FRA.initialBearingTo(LHR) self.test('initialBearingTo', b, 288.715918 if Sph else 288.676039, fmt='%.6f') # PYCHOK test attr? a = FRA.compassAngleTo(LHR, adjust=False) self.test('compassAngleTo', a, 280.017, fmt='%.3f') a = FRA.compassAngleTo(LHR) # adjust=True self.test('compassAngleTo', a, 285.599, fmt='%.3f') d = LHR.equirectangularTo(FRA) self.test('equirectangularTo', m2km(d), 592.185, fmt='%.3f') if hasattr(LatLon, 'distanceTo'): d = LHR.distanceTo(FRA) self.test('distanceTo', m2km(d), 591.831 if Sph else 593.571, fmt='%.3f') # PYCHOK test attr? p = LatLon(0, 0) for a, b, d in ((1, 0, 0.0), ( 1, 1, 45.0), ( 0, 1, 90.0), (-1, 0, 180.0), (-1, -1, 225.0), (1, -1, 315.0), ( 0, -1, 270.0), (90, -1, 359.4)): q = LatLon(p.lat + a, p.lon + b) if not Nv: b = p.initialBearingTo(q) self.test('bearingTo', b, d, fmt='%.1f', known=True) c = p.compassAngleTo(q, adjust=False) self.test('compassAngleTo', c, d, fmt='%.1f') p = LatLon(52, 0) q = LatLon(p.lat + 1, p.lon + 1) # 45 unadjusted if not Nv: b = p.initialBearingTo(q) self.test('bearingTo', b, 31.0, fmt='%.0f') c = p.compassAngleTo(q, adjust=True) self.test('compassAngleTo', c, 31.0, fmt='%.0f') c = p.compassAngleTo(q, adjust=False) self.test('compassAngleTo', c, 45.0, fmt='%.0f')
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_) a, b = splice(range(10)) # PYCHOK false self.test('splice', (a, b), map1(type(a), (0, 2, 4, 6, 8), (1, 3, 5, 7, 9))) a, b, c = splice(range(10), n=3) # PYCHOK false self.test('splice', (a, b, c), map1(type(a), (0, 3, 6, 9), (1, 4, 7), (2, 5, 8))) a, b, c = splice(range(10), n=3, fill=-1) # PYCHOK false self.test('splice', (a, b, c), map1(type(a), (0, 3, 6, 9), (1, 4, 7, -1), (2, 5, 8, -1))) t = tuple(splice(range(12), n=5)) # PYCHOK false self.test('splice', t, map1(type(t[0]), (0, 5, 10), (1, 6, 11), (2, 7), (3, 8), (4, 9))) # <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')
def testOSgr(self, LatLon): m = LatLon.__module__ self.test('LatLon', m, m) # 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) r.height = 0 self.test('OSGB36', r, '51.477284°N, 000.00002°E') r = r.convertDatum(Datums.WGS84) r.height = 0 self.test('WGS84', r, '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]') p = g.toLatLon(LatLon) p.height = 0 self.test('toLatLon1', p.toStr(F_DMS), '52°39′28.72″N, 001°42′57.74″E', known=True) self.test('toLatLon1', p, '52.657977°N, 001.716038°E', known=True) r = p.toOsgr() self.test('toOsgr1', r.toStr(0), '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) 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.toStr2(prec=-3), '[OSGR:651409.000,313177.000]') r = osgr.parseOSGR(g.toStr(prec=-3)) 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.toStr2(), '[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.toStr2(), '[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.toStr2(), '[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.toStr2(), '[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.toStr2(), '[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)
def _tstr(t): s = list(t[:5]) s[0] = fStr(t.fd, prec=5) return '(%s)' % (', '.join(map(str, s)), )
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) p = LatLon(-66.6, -88) self.test('to2ab', fStr(p.to2ab(), prec=6), '-1.162389, -1.53589') 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)