Beispiel #1
0
    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)')
Beispiel #2
0
    def test2(self, pts, npt, psxy=False):

        clas_ = classname(pts) + '.'

        def _test(name, *args, **kwds):
            # prefix class to test name
            self.test(clas_ + name, *args, **kwds)

        if Sequence:  # check abstact base class conformance
            _test('ABC', isinstance(pts, Sequence), True)

        e = pts.epsilon
        _test('epsilon', e, EPS)
        pts.epsilon = 0
        _test('epsilon', pts.epsilon, 0.0)
        pts.epsilon = e

        n = len(pts) // 6  # 0 < some number < len(pts)
        _test('len', len(pts), len(npt))
        _test('iter', len(tuple(iter(pts))), len(npt))
        if hasattr(npt, 'shape'):
            _test('shape', npt.shape, pts.shape)
        _test('slice1', len(pts[:n]), n)
        _test('slice2', type(pts[1:n:2]), type(pts))
        _test('slice3', pts[1:n][0], pts[1])
        _test('strepr', str(pts), repr(pts))
        if hasattr(pts, 'subset'):
            _test('subset', type(pts.subset(range(n))), type(npt))  # , nt=1)

        for i, p in ((10, (52.224006, -0.707747)),
                     (20, (52.232688, -0.714608)), (30, (52.234375,
                                                         -0.714348)),
                     (40, (52.237239, -0.712557)), (50, (52.24023, -0.709919)),
                     (60, (52.240745, -0.707042))):

            if psxy:
                _test('find LL', pts.find(LatLon_(*p)), i)  # coverage
                p = tuple(reversed(p))  # flip to x, y tuple
                _test('find LL', pts.find(LatLon_(*p)), -1)  # coverage

            _test('count', pts.count(p), 1)
            _test('index', pts.index(p), i)
            _test('rfind', pts.rfind(p), i)
            _test('in', p in pts, True)

            p = tuple(reversed(p))
            _test('count', pts.count(p), 0)
            _test('find', pts.find(p), -1)
            _test('rfind', pts.rfind(p), -1)
            _test('not in', p not in pts, True)

        pts = pts[::6]
        for i, p in enumerate(pts):
            _test('enumerate[%s]' % (i, ), p, pts[i])

        i = len(pts)
        for p in reversed(pts):
            i -= 1
            _test('reversed[%s]' % (i, ), p, pts[i])
Beispiel #3
0
    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
Beispiel #4
0
    def testSpherical(self, module, Sph=True):  # MCCABE 13

        self.subtitle(module, 'Spherical')

        LatLon, Vct = module.LatLon, not Sph

        p = LatLon(51.8853, 0.2545)
        self.test('isSpherical', p.isSpherical, True)
        self.test('isEllipsoidal', p.isEllipsoidal, False)

        q = LatLon(49.0034, 2.5735)
        self.test('isSpherical', q.isSpherical, True)
        self.test('isEllipsoidal', q.isEllipsoidal, False)

        i = p.intersection(108.55, q, 32.44)
        self.test('intersection1', i.toStr(F_D),
                  '50.907608°N, 004.508575°E')  # 50.9076°N, 004.5086°E  # Trig
        self.test('intersection1', i.toStr(F_DMS),
                  '50°54′27.39″N, 004°30′30.87″E')
        self.test('intersection1', isinstance(i, LatLon), True)

        REO = LatLon(42.600, -117.866)
        BKE = LatLon(44.840, -117.806)
        i = REO.intersection(51, BKE, 137)
        self.test('intersection2', isinstance(i, LatLon), True)
        self.test('intersection2', i.toStr(F_D),
                  '43.5719°N, 116.188757°W')  # 43.572°N, 116.189°W
        self.test('intersection2', i.toStr(F_DMS),
                  '43°34′18.84″N, 116°11′19.53″W')

        # <https://GitHub.com/ChrisVeness/geodesy/issues/46>
        p = LatLon(51.8853, 0.2545)
        q = LatLon(51.8763, 0.2545)  # identical lon
        i = p.intersection(110.8878, q, 54.4525)
        self.test('intersection3', i,
                  '51.882166°N, 000.267801°E')  # 51°52′55.8″N, 000°16′04.08″E?

        p = LatLon(+30, 0)
        q = LatLon(-30, 0)  # identical, zero lon
        i = p.intersection(135, q, 45)
        self.test('intersection4',
                  i,
                  '00.0°N, 026.565051°E',
                  known=abs(i.lat) < 1e-6)

        p = LatLon(0, -30)
        q = LatLon(0, +30)  # identical, zero lat
        i = p.intersection(45, q, 315)
        self.test('intersection5',
                  i,
                  '26.565051°N, 000.0°W',
                  known=abs(i.lon) < 1e-6)

        # <https://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-vectors-tests.js>
        STN = LatLon(51.8853, 0.2545)
        CDG = LatLon(49.0034, 2.5735)
        i = STN.intersection(108.547, CDG, 32.435)
        self.test('intersection6', i,
                  '50.907809°N, 004.50841°E')  # 50.9078°N, 004.5084°E

        # <https://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-vectors-tests.js>
        # <https://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-spherical-tests.js>
        N, E, S, W, p, q = 0, 90, 180, 270, LatLon(0, 1), LatLon(1, 0)
        self.test('toward 1,1 N,E nearest', p.intersection(N, q, E),
                  '00.999848°N, 001.0°E')
        self.test('toward 1,1 E,N nearest', q.intersection(E, p, N),
                  '00.999848°N, 001.0°E')
        self.test('toward 1,1 N,E antipodal',
                  LatLon(2, 1).intersection(N, q, E), '00.999848°S, 179.0°W')
        self.test('toward/away 1,1 N,W antipodal',
                  p.intersection(N, q, W),
                  '00.999848°S, 179.0°W',
                  known=Sph)
        self.test('toward/away 1,1 W,N antipodal', q.intersection(W, p, N),
                  '00.999848°S, 179.0°W')
        self.test('toward/away 1,1 S,E antipodal', p.intersection(S, q, E),
                  '00.999848°S, 179.0°W')
        self.test('toward/away 1,1 E,S antipodal',
                  q.intersection(E, p, S),
                  '00.999848°S, 179.0°W',
                  known=Sph)
        self.test('away 1,1 S,W antipodal', p.intersection(S, q, W),
                  '00.999848°S, 179.0°W')
        self.test('away 1,1 W,S antipodal', q.intersection(W, p, S),
                  '00.999848°S, 179.0°W')
        self.test('1E/90E N,E antipodal',
                  p.intersection(N, LatLon(1, 90), E),
                  '00.017454°S, 179.0°W',
                  known=Sph)
        self.test('1E/90E N,E nearest', p.intersection(N, LatLon(1, 92), E),
                  '00.017454°N, 179.0°W')

        # <https://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-vectors-tests.js>
        p, r = LatLon(1, 3), LatLon(2, 2)
        self.test('brng+end 1a', q.intersection(p, r, S),
                  '01.000305°N, 002.0°E')
        self.test('brng+end 1b', r.intersection(S, q, p),
                  '01.000305°N, 002.0°E')
        self.test('brng+end 2a', q.intersection(p, r, N),
                  '01.000305°S, 178.0°W')
        self.test('brng+end 2b', r.intersection(N, q, p),
                  '01.000305°S, 178.0°W')

        i = LatLon(1, 1).intersection(LatLon(2, 2), LatLon(1, 4), LatLon(2, 3))
        self.test('intersection7', i,
                  '02.499372°N, 002.5°E')  # 02.4994°N, 002.5°E'

        p = LatLon(0, 0)
        self.test('maxLat0', p.maxLat(0), '90.0')
        self.test('maxLat1', p.maxLat(1), '89.0')
        self.test('maxLat90', p.maxLat(90), '0.0')
        self.test('minLat0', p.minLat(0), '-90.0')
        self.test('minLat1', p.minLat(1), '-89.0')
        self.test('minLat90', p.minLat(90), '-0.0', known=True)

        self.test('parse', p.parse('0, 0'), p)  # coverage

        if hasattr(LatLon, 'crossingParallels'):
            ps = p.crossingParallels(LatLon(60, 30), 30)
            t = ', '.join(map(lonDMS, ps))
            self.test('crossingParallels', t, '009°35′38.65″E, 170°24′21.35″E')

        if hasattr(LatLon, 'intersections2'):

            n = 'intersections2 (%s)' % (LatLon.__module__, )

            def _100p2(t, r, *s):
                e = max(abs(a.distanceTo(b) - r) for a in s for b in t) / r
                return e, '%g (%% of radius)' % (e, )  # percentages

            # <https://GIS.StackExchange.com/questions/48937/calculating-intersection-of-two-circles>
            p = LatLon(37.673442,
                       -90.234036)  # (-0.00323306, -0.7915,   0.61116)
            q = LatLon(36.109997,
                       -90.953669)  # (-0.0134464,  -0.807775, 0.589337)
            t = p.intersections2(0.0312705,
                                 q,
                                 0.0421788,
                                 radius=None,
                                 height=0)  # radii in radians
            self.test(n, latlonDMS(t, form=F_D, sep=', '),
                      '36.98931°N, 088.151425°W, 38.23838°N, 092.390487°W')

            t = LatLon(30, 0).intersections2(PI_4,
                                             LatLon(-30, 0),
                                             PI_4,
                                             radius=None)  # radii in radians
            s = latlonDMS(t, form=F_D, sep=', ')
            self.test(n,
                      s,
                      '00.0°N, 035.26439°W, 00.0°N, 035.26439°E',
                      known='S, ' in s)

            t = LatLon(0, 40).intersections2(PI_4,
                                             LatLon(0, -40),
                                             PI_4,
                                             radius=None)  # radii in radians
            s = latlonDMS(t, form=F_D, sep=', ')
            self.test(n,
                      s,
                      '22.622036°N, 000.0°E, 22.622036°S, 000.0°E',
                      known='W' in s)

            t = LatLon(30, 20).intersections2(PI_4,
                                              LatLon(-30, -20),
                                              PI_4,
                                              radius=None)  # radii in radians
            s = latlonDMS(t, form=F_D, sep=', ')
            self.test(n, s,
                      '14.612841°N, 026.110934°W, 14.612841°S, 026.110934°E')

            t = LatLon(0, 0).intersections2(PI_4,
                                            LatLon(0, 22.5),
                                            PI_4 / 2,
                                            radius=None)  # abutting
            s = latlonDMS(t, form=F_D, sep=', ')
            self.test(n,
                      s,
                      '00.000001°S, 045.0°E, 00.000001°N, 045.0°E',
                      known=True)  # N-S

            # centers at 2 opposite corners of a "square" and
            # radius equal to length of square side, expecting
            # the other 2 as the intersections ... but the
            # longitudes are farther and farther out
            for d in range(5, 66, 5):
                p = LatLon(d, -d)
                q = LatLon(-d, d)
                r = radians(2 * d) * R_M
                t = p.intersections2(r, q, r, radius=R_M)
                if t[0] is t[1]:
                    s = latlonDMS(t[:1], form=F_D, sep=', ') + ' abutting'
                else:
                    s = latlonDMS(t, form=F_D, sep=', ')
                d = '%s %d' % (n, d)
                self.test(d, s, s)
                _, s = _100p2(t, r, q, p)
                self.test(d, s, s)

            d_m = 5e-5  # 50 micrometer
            # courtesy Samuel Čavoj <https://GitHub.com/mrJean1/PyGeodesy/issues/41>}
            R = RandomLatLon(LatLon, 178, 178)  # +/- 89
            r = R()
            s = latlonDMS(r, form=F_D) + ' Random +/- 89'
            self.test(n, s, s)
            for _ in range(12):
                p, q = R(), R()
                try:  # see .testEllipsoidal
                    i1, i2 = p.intersections2(r.distanceTo(p),
                                              q,
                                              r.distanceTo(q),
                                              radius=R_M)
                    d, d2 = r.distanceTo(i1), r.distanceTo(i2)
                    if d2 < d:
                        d, i1, i2 = d2, i2, i1
                    s = '%s  d %g meter' % (latlonDMS(
                        (i1, i2), form=F_D, sep=', '), d)
                    self.test(n, s, s)
                    if d > d_m:
                        raise IntersectionError(d=d,
                                                fmt_name_value='%s (%g)',
                                                txt='over')
                except IntersectionError as x:
                    self.test(n, str(x), 'd < %g m' % (d_m),
                              known=True)  # too distant, near concetric, etc.

        if hasattr(LatLon, 'isenclosedBy'):
            p = LatLon(45.1, 1.1)

            b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
            for _ in self.testiter():
                self.test('isenclosedBy', p.isenclosedBy(b), True)

            b = LatLon(45, 1), LatLon(45,
                                      3), LatLon(46,
                                                 2), LatLon(47,
                                                            3), LatLon(47, 1)
            for _ in self.testiter():
                try:
                    self.test('isenclosedBy', p.isenclosedBy(b),
                              True)  # Nvector
                except ValueError as x:
                    t = str(x).replace(',)', ')')
                    self.test(
                        'isenclosedBy', t,
                        'points[3] (%s(47°00′00.0″N, 003°00′00.0″E)): not convex'
                        % (classname(p), ))

        p = LatLon(51.127, 1.338)
        q = LatLon(50.964, 1.853)
        b = p.rhumbBearingTo(q)
        self.test('rhumbBearingTo', b, 116.722, fmt='%.3f')  # 116.7

        d = p.rhumbDestination(40300, 116.7)
        self.test('rhumbDestination', d,
                  '50.964155°N, 001.853°E')  # 50.9642°N, 001.8530°E
        self.test('rhumbDestination', isinstance(d, LatLon), True)

        d = p.rhumbDistanceTo(q)
        self.test('rhumbDistanceTo', d, 40307.8, fmt='%.1f')  # XXX 40310 ?

        m = p.rhumbMidpointTo(q)
        self.test('rhumbMidpointo', m, '51.0455°N, 001.595727°E')
        self.test('rhumbMidpointo', isinstance(m, LatLon), True)

        b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
        self.test('areaOf', module.areaOf(b), '8.66605875e+09',
                  fmt='%.8e')  # 8666058750.718977
        self.test('perimeterOf',
                  module.perimeterOf(b, closed=True),
                  '3.78258541e+05',
                  fmt='%.8e')
        self.test('perimeterOf',
                  module.perimeterOf(b, closed=False),
                  '2.67063461e+05',
                  fmt='%.8e')

        c = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1)
        self.test('areaOf', module.areaOf(c), '6.18e+09', fmt='%.2e')
        self.test('perimeterOf',
                  module.perimeterOf(c, closed=True),
                  '3.79639757e+05',
                  fmt='%.8e')
        self.test('perimeterOf',
                  module.perimeterOf(c, closed=False),
                  '2.68444678e+05',
                  fmt='%.8e')

        if hasattr(module, 'nearestOn2'):
            c, d = module.nearestOn2(p, b)
            self.test(
                'nearestOn2', c,
                '46.000996°N, 001.353049°E' if Vct else '46.0°N, 001.369324°E')
            self.test('nearestOn2',
                      d,
                      '569987.49' if Vct else '570101.83',
                      fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo',
                      d,
                      '569987.49' if Vct else '570101.82',
                      fmt='%.2f')

            p = LatLon(47, 3)
            c, d = module.nearestOn2(p, b)
            self.test('nearestOn2', c,
                      '46.0°N, 002.0°E' if Vct else '46.0°N, 002.0°E')
            self.test('nearestOn2',
                      d,
                      '134989.80' if Vct else '134992.48',
                      fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo',
                      d,
                      '134989.80' if Vct else '134989.80',
                      fmt='%.2f')

            p = LatLon(45, 2)
            b = LatLon(45, 1), LatLon(47, 3)
            if Vct:
                c, d = module.nearestOn2(p, b)
                self.test('nearestOn2', c, '45.330691°N, 001.318551°E')
                self.test('distance', d, '64856.28', fmt='%.2f')
            else:
                c, d, a = p.nearestOn3(b, adjust=False)
                self.test('nearestOn3', c, '45.5°N, 001.5°E')
                self.test('distance', d, '78626.79', fmt='%.2f')
                self.test('angle', a, '315.00', fmt='%.2f')
                a = p.compassAngleTo(c, adjust=False)
                self.test('compassAngleTo', a, '315.00', fmt='%.2f')
                c, d, a = p.nearestOn3(b, adjust=True)
                self.test('nearestOn3', c, '45.331319°N, 001.331319°E')
                self.test('distance', d, '64074.48', fmt='%.2f')
                self.test('angle', a, '305.10', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo',
                      d,
                      '64856.28' if Vct else '64074.12',
                      fmt='%.2f')
            a = p.compassAngleTo(c)  # adjust=True
            self.test('compassAngleTo',
                      a,
                      '304.54' if Vct else '305.10',
                      fmt='%.2f')
            # TrigTrue vs Nvector closests
            p = LatLon(45.330691, 001.318551)
            d = p.distanceTo(LatLon(45.331319, 001.331319))
            self.test('difference', d, '1000.53',
                      fmt='%.2f')  # PYCHOK test attr?

            if Sph:  # check nearestOn2/3 with closest on the segment
                b = LatLon(0,
                           1), LatLon(2,
                                      3), LatLon(4,
                                                 5), LatLon(6,
                                                            7), LatLon(8, 9)
                for i in range(8):
                    p = LatLon(i + 2, i)
                    c, d, a = p.nearestOn3(b, adjust=False)
                    t = LatLon(p.lat - 1.5, p.lon + 1.5).toStr(F_D, prec=6)
                    self.test('nearestOn3', c.toStr(F_D, prec=6), t)
                    self.test('distance', d, '235880.385', fmt='%.3f')
                    self.test('angle', a, '135.00', fmt='%.2f')

                n = module.meanOf(b)  # coverage
                self.test('meanOf', n.toStr(F_D, prec=6),
                          '04.004858°N, 004.990226°E')
                n = module.nearestOn3(p, b, LatLon=LatLon,
                                      adjust=False)[0]  # coverage
                self.test('nearestOn3', n, '07.5°N, 008.5°E')
                c = p.toCartesian()  # coverage
                self.test('toCartesian', c,
                          '[6245667.211, 766871.506, 996645.349]')

        if hasattr(module, 'ispolar'):
            p = LatLon(85, 90), LatLon(85, 0), LatLon(85,
                                                      -90), LatLon(85, -180)
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p),
                          'True')  # PYCHOK test attr?
            p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -180)
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True',
                          known=True)  # PYCHOK test attr?
            p = [LatLon(*ll) for ll in Antarctica]  # PYCHOK test attr?
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True',
                          known=Vct)  # PYCHOK test attr?

        if hasattr(LatLon, 'nearestOn'):
            # <https://GitHub.com/mrJean1/PyGeodesy/issues/25>
            a = LatLon(1, 1, height=100)
            b = LatLon(2, 2, height=200)
            t = LatLon(1, 2).nearestOn(a, b).toStr(form=F_D, prec=1)
            self.test('nearestOn', t,
                      '01.5°N, 001.5°E, +149.99m')  # PYCHOK test attr?
            t = LatLon(1, 2).nearestOn2([a, b])[0].toStr(form=F_D, prec=1)
            self.test('nearestOn2', t,
                      '01.5°N, 001.5°E, +149.99m')  # PYCHOK test attr?
            t = a.midpointTo(b).toStr(form=F_D, prec=1)
            self.test('midpointTo', t,
                      '01.5°N, 001.5°E, +150.00m')  # PYCHOK test attr?
Beispiel #5
0
    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')
Beispiel #6
0
    def testSpherical(self, module, Sph=True):  # MCCABE 13

        self.subtitle(module, 'Spherical')

        LatLon, Vct = module.LatLon, not Sph

        p = LatLon(51.8853, 0.2545)
        self.test('isSpherical', p.isSpherical, True)
        self.test('isEllipsoidal', p.isEllipsoidal, False)

        q = LatLon(49.0034, 2.5735)
        self.test('isSpherical', q.isSpherical, True)
        self.test('isEllipsoidal', q.isEllipsoidal, False)

        i = p.intersection(108.55, q, 32.44)
        self.test('intersection1', i.toStr(F_D), '50.907608°N, 004.508575°E')  # 50.9076°N, 004.5086°E  # Trig
        self.test('intersection1', i.toStr(F_DMS), '50°54′27.39″N, 004°30′30.87″E')
        self.test('intersection1', isinstance(i, LatLon), True)

        REO = LatLon(42.600, -117.866)
        BKE = LatLon(44.840, -117.806)
        i = REO.intersection(51, BKE, 137)
        self.test('intersection2', isinstance(i, LatLon), True)
        self.test('intersection2', i.toStr(F_D), '43.5719°N, 116.188757°W')  # 43.572°N, 116.189°W
        self.test('intersection2', i.toStr(F_DMS), '43°34′18.84″N, 116°11′19.53″W')

        # <http://GitHub.com/ChrisVeness/geodesy/issues/46>
        p = LatLon(51.8853, 0.2545)
        q = LatLon(51.8763, 0.2545)  # identical lon
        i = p.intersection(110.8878, q, 54.4525)
        self.test('intersection3', i, '51.882166°N, 000.267801°E')  # 51°52′55.8″N, 000°16′04.08″E?

        p = LatLon(+30, 0)
        q = LatLon(-30, 0)  # indential, zero lon
        i = p.intersection(135, q, 45)
        self.test('intersection4', i, '00.0°N, 026.565051°E', known=isWindows)

        p = LatLon(0, -30)
        q = LatLon(0, +30)  # identical, zero lat
        i = p.intersection(45, q, 315)
        self.test('intersection5', i, '26.565051°N, 000.0°W', known=isWindows)

        # <http://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-vectors-tests.js>
        STN = LatLon(51.8853, 0.2545)
        CDG = LatLon(49.0034, 2.5735)
        i = STN.intersection(108.547, CDG, 32.435)
        self.test('intersection6', i, '50.907809°N, 004.50841°E')  # 50.9078°N, 004.5084°E

        # <http://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-vectors-tests.js>
        # <http://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-spherical-tests.js>
        N, E, S, W, p, q = 0, 90, 180, 270, LatLon(0, 1), LatLon(1, 0)
        self.test('toward 1,1 N,E nearest',        p.intersection(N, q, E), '00.999848°N, 001.0°E')
        self.test('toward 1,1 E,N nearest',        q.intersection(E, p, N), '00.999848°N, 001.0°E')
        self.test('toward 1,1 N,E antipodal',      LatLon(2, 1).intersection(N, q, E), '00.999848°S, 179.0°W')
        self.test('toward/away 1,1 N,W antipodal', p.intersection(N, q, W), '00.999848°S, 179.0°W', known=Sph)
        self.test('toward/away 1,1 W,N antipodal', q.intersection(W, p, N), '00.999848°S, 179.0°W')
        self.test('toward/away 1,1 S,E antipodal', p.intersection(S, q, E), '00.999848°S, 179.0°W')
        self.test('toward/away 1,1 E,S antipodal', q.intersection(E, p, S), '00.999848°S, 179.0°W', known=Sph)
        self.test('away 1,1 S,W antipodal',        p.intersection(S, q, W), '00.999848°S, 179.0°W')
        self.test('away 1,1 W,S antipodal',        q.intersection(W, p, S), '00.999848°S, 179.0°W')
        self.test('1E/90E N,E antipodal',          p.intersection(N, LatLon(1, 90), E), '00.017454°S, 179.0°W', known=Sph)
        self.test('1E/90E N,E nearest',            p.intersection(N, LatLon(1, 92), E), '00.017454°N, 179.0°W')

        # <http://GitHub.com/ChrisVeness/geodesy/blob/master/test/latlon-vectors-tests.js>
        p, r = LatLon(1, 3), LatLon(2, 2)
        self.test('brng+end 1a', q.intersection(p, r, S), '01.000305°N, 002.0°E')
        self.test('brng+end 1b', r.intersection(S, q, p), '01.000305°N, 002.0°E')
        self.test('brng+end 2a', q.intersection(p, r, N), '01.000305°S, 178.0°W')
        self.test('brng+end 2b', r.intersection(N, q, p), '01.000305°S, 178.0°W')

        i = LatLon(1, 1).intersection(LatLon(2, 2), LatLon(1, 4), LatLon(2, 3))
        self.test('intersection7', i, '02.499372°N, 002.5°E')  # 02.4994°N, 002.5°E'

        p = LatLon(0, 0)
        self.test('maxLat0',  p.maxLat( 0), '90.0')
        self.test('maxLat1',  p.maxLat( 1), '89.0')
        self.test('maxLat90', p.maxLat(90),  '0.0')

        if hasattr(LatLon, 'crossingParallels'):
            ps = p.crossingParallels(LatLon(60, 30), 30)
            t = ', '.join(map(lonDMS, ps))
            self.test('crossingParallels', t, '009°35′38.65″E, 170°24′21.35″E')

        if hasattr(LatLon, 'isenclosedBy'):
            p = LatLon(45.1, 1.1)

            b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
            for _ in self.testiter():
                self.test('isenclosedBy', p.isenclosedBy(b), True)

            b = LatLon(45, 1), LatLon(45, 3), LatLon(46, 2), LatLon(47, 3), LatLon(47, 1)
            for _ in self.testiter():
                try:
                    self.test('isenclosedBy', p.isenclosedBy(b), True)  # Nvector
                except ValueError as x:
                    t = ' '.join(str(x).split()[:3] + ['...)'])
                    self.test('isenclosedBy', t, 'non-convex: (%s(45°00′00.0″N, 001°00′00.0″E), ...)' % (classname(p),))

        p = LatLon(51.127, 1.338)
        q = LatLon(50.964, 1.853)
        b = p.rhumbBearingTo(q)
        self.test('rhumbBearingTo', b, 116.722, fmt='%.3f')  # 116.7

        d = p.rhumbDestination(40300, 116.7)
        self.test('rhumbDestination', d, '50.964155°N, 001.853°E')  # 50.9642°N, 001.8530°E
        self.test('rhumbDestination', isinstance(d, LatLon), True)

        d = p.rhumbDistanceTo(q)
        self.test('rhumbDistanceTo', d, 40307.8, fmt='%.1f')  # XXX 40310 ?

        m = p.rhumbMidpointTo(q)
        self.test('rhumbMidpointo', m, '51.0455°N, 001.595727°E')
        self.test('rhumbMidpointo', isinstance(m, LatLon), True)

        b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
        self.test('areaOf', module.areaOf(b), '8.6660587507e+09', fmt='%.10e')  # 8666058750.718977

        c = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1)
        self.test('areaOf', module.areaOf(c), '6.18e+09', fmt='%.2e')

        if hasattr(module, 'nearestOn2'):
            c, d = module.nearestOn2(p, b)
            self.test('nearestOn2', c, '46.000996°N, 001.353049°E' if Vct else '46.0°N, 001.369324°E')
            self.test('nearestOn2', d, '569987.49' if Vct else '570101.83', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo', d, '569987.49' if Vct else '570101.82', fmt='%.2f')

            p = LatLon(47, 3)
            c, d = module.nearestOn2(p, b)
            self.test('nearestOn2', c, '46.0°N, 002.0°E' if Vct else '46.0°N, 002.0°E')
            self.test('nearestOn2', d, '134989.80' if Vct else '134992.48', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo', d, '134989.80' if Vct else '134989.80', fmt='%.2f')

            p = LatLon(45, 2)
            b = LatLon(45, 1), LatLon(47, 3)
            if Vct:
                c, d = module.nearestOn2(p, b)
                self.test('nearestOn2', c, '45.330691°N, 001.318551°E')
                self.test('distance', d, '64856.28', fmt='%.2f')
            else:
                c, d, a = p.nearestOn3(b, adjust=False)
                self.test('nearestOn3', c, '45.5°N, 001.5°E')
                self.test('distance', d, '78626.79', fmt='%.2f')
                self.test('angle', a, '315.00', fmt='%.2f')
                a = p.compassAngleTo(c, adjust=False)
                self.test('compassAngleTo', a, '315.00', fmt='%.2f')
                c, d, a = p.nearestOn3(b, adjust=True)
                self.test('nearestOn3', c, '45.331319°N, 001.331319°E')
                self.test('distance', d, '64074.48', fmt='%.2f')
                self.test('angle', a, '305.10', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo', d, '64856.28' if Vct else '64074.12', fmt='%.2f')
            a = p.compassAngleTo(c)  # adjust=True
            self.test('compassAngleTo', a, '304.54' if Vct else '305.10', fmt='%.2f')
            # TrigTrue vs Nvector closests
            p = LatLon(45.330691, 001.318551)
            d = p.distanceTo(LatLon(45.331319, 001.331319))
            self.test('difference', d, '1000.53', fmt='%.2f')  # PYCHOK test attr?

            if Sph:  # check nearestOn2/3 with closest on the segment
                b = LatLon(0, 1), LatLon(2, 3), LatLon(4, 5), LatLon(6, 7), LatLon(8, 9)
                for i in range(8):
                    p = LatLon(i + 2, i)
                    c, d, a = p.nearestOn3(b, adjust=False)
                    q = LatLon(p.lat - 1.5, p.lon + 1.5)
                    self.test('nearestOn3', c.toStr(F_D, prec=6), q.toStr(F_D, prec=6))
                    self.test('distance', d, '235880.385', fmt='%.3f')
                    self.test('angle', a, '135.00', fmt='%.2f')

        if hasattr(module, 'ispolar'):
            p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -90), LatLon(85, -180)
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True')  # PYCHOK test attr?
            p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -180)
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True', known=True)  # PYCHOK test attr?
            p = [LatLon(*ll) for ll in Antarctica]  # PYCHOK test attr?
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True', known=Vct)  # PYCHOK test attr?
Beispiel #7
0
    def testGreatCircle(self, module):  # spherical only

        self.subtitle(module, 'GreatCircle')

        LatLon = module.LatLon

        # Indian Pond, in Piermond, NH.  My old Boy Scout Camp
        IndianPond = LatLon(43.930912, -72.053811)
        Eiffel = LatLon(48.858158, 2.294825)
        Versailles = LatLon(48.804766, 2.120339)
        StGermain = LatLon(48.897728, 2.094977)
        Orly = LatLon(48.747114, 2.400526)

        # distance between the Eiffel Tower and Versailles in meter
        dEiffelToVersailles = 14084.280704919687
        xEiffelToVersailles = '%.6f'  # '%.8f'

        # initial and final bearings between Eiffel tower and Versailles
        ibEiffelToVersailles = 245.13460296861962
        fbEiffelToVersailles = 245.00325395138532
        xbEiffelToVersailles = '%.8f'  # '%.14f'

        # initial and final bearing between Versailles and Eiffel tower
        ibVersaillesToEiffel = 65.003253951385318
        fbVersaillesToEiffel = 65.134602968619618
        xbVersaillesToEiffel = '%.9f'  # '%.15f'

        xMidpoint = '%.8f'

        c = crosserrors(False)  # no CrossErrors!

        # initial bearing for two locations that are the same
        b = IndianPond.initialBearingTo(IndianPond)
        self.test('InitialBearingSameLocations', b, 0.0, prec=1)

        # initial bearing for two locations that are the equal
        b = IndianPond.initialBearingTo(IndianPond.copy())
        self.test('InitialBearingEqualLocations', b, 0.0, prec=1)

        # final bearing for two locations that are the same
        b = IndianPond.finalBearingTo(IndianPond)
        self.test('FinalBearingSameLocations', b, 180.0, prec=1)  # 0.0

        # final bearing for two locations that are the equal
        b = IndianPond.finalBearingTo(IndianPond.copy())
        self.test('FinalBearingEqualLocations', b, 180.0, prec=1)  # 0.0

        c = crosserrors(c)  # with CrossErrors!

        try:  # should raise CrossError
            b = str(IndianPond.initialBearingTo(IndianPond, raiser=True))
        except CrossError as x:
            b = str(x)
        self.test(
            'FinalBearingCrossError', b,
            'points (%s(43°55′51.28″N, 072°03′13.72″W)): coincident' %
            (classname(IndianPond), ))

        # distance for two locations that are the same
        d = IndianPond.distanceTo(IndianPond)
        self.test('DistanceSameLocations', d, 0.0, prec=1)

        # distance for two locations that are equal
        d = IndianPond.distanceTo(IndianPond.copy())
        self.test('DistanceEqualLocations', d, 0.0, prec=1)

        # distance between Eiffel Tower and Versailles
        d = Eiffel.distanceTo(Versailles)
        self.test('DistanceEiffelToVersailles',
                  d,
                  dEiffelToVersailles,
                  fmt=xEiffelToVersailles,
                  known=True)

        # distance between Versailles and Eiffel Tower
        d = Versailles.distanceTo(Eiffel)
        self.test('DistanceVersaillesToEiffel',
                  d,
                  dEiffelToVersailles,
                  fmt=xEiffelToVersailles,
                  known=True)

        # initial bearing between Eiffel Tower and Versailles
        b = Eiffel.initialBearingTo(Versailles)
        self.test('InitialBearingEiffelToVersailles',
                  b,
                  ibEiffelToVersailles,
                  fmt=xbEiffelToVersailles)
        self.test('InitialBearingEiffelToVersailles(DMS)',
                  bearingDMS(b, F_DMS, prec=4), '245°08′04.5707″')

        # initial bearing between Versailles and Eiffel Tower
        b = Versailles.initialBearingTo(Eiffel)
        self.test('InitialBearingVersaillesToEiffel',
                  b,
                  ibVersaillesToEiffel,
                  fmt=xbVersaillesToEiffel)
        self.test('InitialBearingVersaillesToEiffel(DMS)',
                  bearingDMS(b, F_DMS, prec=4), '65°00′11.7142″')

        # final bearing between Eiffel Tower and Versailles
        b = Eiffel.finalBearingTo(Versailles)
        self.test('FinalBearingEiffelToVersailles',
                  b,
                  fbEiffelToVersailles,
                  fmt=xbEiffelToVersailles)
        self.test('FinalBearingEiffelToVersailles(DMS)',
                  bearingDMS(b, F_DMS, prec=4), '245°00′11.7142″')

        # final bearing between Versailles and Eiffel Tower
        b = Versailles.finalBearingTo(Eiffel)
        self.test('FinalBearingVersaillesToEiffel',
                  b,
                  fbVersaillesToEiffel,
                  fmt=xbVersaillesToEiffel)
        self.test('FinalBearingVersaillesToEiffel(DMS)',
                  bearingDMS(b, F_DMS, prec=4), '65°08′04.5707″')

        # generating a location for Versailles based on bearing and distance
        v = Eiffel.destination(dEiffelToVersailles, ibEiffelToVersailles)
        self.test('GenerateLocationVersailles', v, str(Versailles))

        # generating a location for Eiffel based on bearing and distance.
        e = Versailles.destination(dEiffelToVersailles, ibVersaillesToEiffel)
        self.test('GenerateLocationEiffel', e, str(Eiffel))

        # midpoint between the Eiffel and Versailles
        a = Eiffel.midpointTo(Versailles)
        b = Eiffel.destination(dEiffelToVersailles / 2.0, ibEiffelToVersailles)
        self.test('MidpointEiffelToVersailles', a, str(b))
        self.test('MidpointEiffelToVersailles(DMS)', a.toStr(F_DMS, prec=4),
                  '48°49′53.3817″N, 002°12′27.1279″E')
        a = Eiffel.distanceTo(a)
        m = Versailles.distanceTo(b)
        self.test('MidpointEiffelToVersailles(m)',
                  a,
                  m,
                  fmt=xMidpoint,
                  known=True)

        # midpoint between Versailles and the Eiffel Tower
        a = Versailles.midpointTo(Eiffel)
        b = Versailles.destination(dEiffelToVersailles / 2.0,
                                   ibVersaillesToEiffel)
        self.test('MidpointVersaillesToEiffel', a, str(b), known=True)
        self.test('MidpointVersaillesToEiffel(DMS)', a.toStr(F_DMS, prec=4),
                  '48°49′53.3817″N, 002°12′27.1279″E')
        a = Versailles.distanceTo(a)
        m = Eiffel.distanceTo(b)
        self.test('MidpointVersaillesToEiffel(m)',
                  a,
                  m,
                  fmt=xMidpoint,
                  known=True)

        # intersection.
        b = StGermain.initialBearingTo(Orly)
        i = StGermain.intersection(b, Eiffel, ibEiffelToVersailles)
        self.test(
            'Intersection', i.toStr(F_D, prec=9),
            '48.83569095°N, 002.221252031°E')  # '48.83569094988361°N, ...
        self.test('Intersection', i.toStr(F_D, prec=13),
                  '48.8356909498836°N, 002.2212520313074°E'
                  )  # 002.2212520313073583°E'

        # cross-track distance test of a point 90° and 200 meters away
        m = Eiffel.midpointTo(Versailles)
        b = Eiffel.initialBearingTo(Versailles)
        p = m.destination(200.0, (b + 90) % 360.0)
        d = p.crossTrackDistanceTo(Eiffel, Versailles)
        self.test('CrossTrackDistance200m+90°', d, 200.0, prec=1)

        # cross-track distance test of a point 270° and 200 meters away
        m = Eiffel.midpointTo(Versailles)
        b = Eiffel.initialBearingTo(Versailles)
        p = m.destination(200.0, (b + 270) % 360.0)
        d = p.crossTrackDistanceTo(Eiffel, Versailles)
        self.test('CrossTrackDistance200m+270°', d, -200.0, prec=1)

        # cross-track distance that should be very close to 0
        m = Eiffel.midpointTo(Versailles)
        d = abs(m.crossTrackDistanceTo(Eiffel, Versailles))
        self.test('CrossTrackDistanceCloseToZero', d, '0.0000000', fmt='%.7f')
Beispiel #8
0
    def testSpherical(self, module, Vct=False):  # MCCABE 13

        self.subtitle(module, 'Spherical')

        LatLon = module.LatLon

        p = LatLon(51.8853, 0.2545)
        self.test('isSpherical', p.isSpherical, True)
        self.test('isEllipsoidal', p.isEllipsoidal, False)

        q = LatLon(49.0034, 2.5735)
        self.test('isSpherical', q.isSpherical, True)
        self.test('isEllipsoidal', q.isEllipsoidal, False)

        i = p.intersection(108.55, q, 32.44)
        self.test('intersection', i.toStr(F_D),  '50.907608°N, 004.508575°E')  # 50.9076°N, 004.5086°E  # Trig
        self.test('intersection', i.toStr(F_DMS), '50°54′27.39″N, 004°30′30.87″E')
        self.test('intersection', isinstance(i, LatLon), True)

        REO = LatLon(42.600, -117.866)
        BKE = LatLon(44.840, -117.806)
        i = REO.intersection(51, BKE, 137)
        self.test('intersection', isinstance(i, LatLon), True)
        self.test('intersection', i.toStr(F_D), '43.5719°N, 116.188757°W')  # 43.572°N, 116.189°W
        self.test('intersection', i.toStr(F_DMS), '43°34′18.84″N, 116°11′19.53″W')

        # <http://GitHub.com/ChrisVeness/geodesy/issues/46>
        p = LatLon(51.8853, 0.2545)
        q = LatLon(51.8763, 0.2545)  # identical lon
        i = p.intersection(110.8878, q, 54.4525)
        self.test('intersection', i, '51.882166°N, 000.267801°E')  # 51°52′55.8″N, 000°16′04.08″E?

        p = LatLon(+30, 0)
        q = LatLon(-30, 0)  # indential, zero lon
        i = p.intersection(135, q, 45)
        self.test('intersection', i, '00.0°N, 026.565051°E', known=isWindows)

        p = LatLon(0, -30)
        q = LatLon(0, +30)  # identical, zero lat
        i = p.intersection(45, q, 315)
        self.test('intersection', i, '26.565051°N, 000.0°W', known=isWindows)

        p = LatLon(0, 0)
        self.test('maxLat0',  p.maxLat( 0), '90.0')
        self.test('maxLat1',  p.maxLat( 1), '89.0')
        self.test('maxLat90', p.maxLat(90),  '0.0')

        if hasattr(LatLon, 'crossingParallels'):
            ps = p.crossingParallels(LatLon(60, 30), 30)
            t = ', '.join(map(lonDMS, ps))
            self.test('crossingParallels', t, '009°35′38.65″E, 170°24′21.35″E')

        if hasattr(LatLon, 'isenclosedBy'):
            p = LatLon(45.1, 1.1)

            b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
            for _ in self.testiter():
                self.test('isenclosedBy', p.isenclosedBy(b), True)

            b = LatLon(45, 1), LatLon(45, 3), LatLon(46, 2), LatLon(47, 3), LatLon(47, 1)
            for _ in self.testiter():
                try:
                    self.test('isenclosedBy', p.isenclosedBy(b), True)  # Nvector
                except ValueError as x:
                    t = ' '.join(str(x).split()[:3] + ['...)'])
                    self.test('isenclosedBy', t, 'non-convex: (%s(45°00′00.0″N, 001°00′00.0″E), ...)' % (classname(p),))

        p = LatLon(51.127, 1.338)
        q = LatLon(50.964, 1.853)
        b = p.rhumbBearingTo(q)
        self.test('rhumbBearingTo', b, 116.722, fmt='%.3f')  # 116.7

        d = p.rhumbDestination(40300, 116.7)
        self.test('rhumbDestination', d, '50.964155°N, 001.853°E')  # 50.9642°N, 001.8530°E
        self.test('rhumbDestination', isinstance(d, LatLon), True)

        d = p.rhumbDistanceTo(q)
        self.test('rhumbDistanceTo', d, 40307.8, fmt='%.1f')  # XXX 40310 ?

        m = p.rhumbMidpointTo(q)
        self.test('rhumbMidpointo', m, '51.0455°N, 001.595727°E')
        self.test('rhumbMidpointo', isinstance(m, LatLon), True)

        b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1)
        self.test('areaOf', module.areaOf(b), '8.6660587507e+09', fmt='%.10e')  # 8666058750.718977

        c = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1)
        self.test('areaOf', module.areaOf(c), '6.18e+09', fmt='%.2e')

        if hasattr(module, 'nearestOn2'):
            c, d = module.nearestOn2(p, b)
            self.test('nearestOn2', c, '46.000996°N, 001.353049°E' if Vct else '46.0°N, 001.369324°E')
            self.test('nearestOn2', d, '569987.49' if Vct else '570101.83', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo', d, '569987.49' if Vct else '570101.82', fmt='%.2f')

            p = LatLon(47, 3)
            c, d = module.nearestOn2(p, b)
            self.test('nearestOn2', c, '46.0°N, 002.0°E' if Vct else '46.0°N, 002.0°E')
            self.test('nearestOn2', d, '134989.80' if Vct else '134992.48', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo', d, '134989.80' if Vct else '134989.80', fmt='%.2f')

            p = LatLon(45, 2)
            b = LatLon(45, 1), LatLon(47, 3)
            if Vct:
                c, d = module.nearestOn2(p, b)
                self.test('nearestOn2', c, '45.330691°N, 001.318551°E')
                self.test('distanceTo2', d, '64856.28', fmt='%.2f')
            else:
                c, d = module.nearestOn2(p, b, adjust=False)
                self.test('nearestOn2', c, '45.5°N, 001.5°E')
                self.test('distanceTo2', d, '78626.79', fmt='%.2f')
                c, d = module.nearestOn2(p, b, adjust=True)
                self.test('nearestOn2', c, '45.331319°N, 001.331319°E')
                self.test('distanceTo2', d, '64074.48', fmt='%.2f')
            d = p.distanceTo(c)
            self.test('distanceTo', d, '64856.28' if Vct else '64074.12', fmt='%.2f')
            # TrigTrue vs Nvector closests
            p = LatLon(45.330691, 001.318551)
            d = p.distanceTo(LatLon(45.331319, 001.331319))
            self.test('difference', d, '1000.53', fmt='%.2f')  # PYCHOK test attr?

            if not Vct:  # check nearestOn2 with closest on the segment
                b = LatLon(0, 1), LatLon(2, 3), LatLon(4, 5), LatLon(6, 7), LatLon(8, 9)
                for i in range(8):
                    p = LatLon(i + 2, i)
                    c, d = module.nearestOn2(p, b, adjust=False)
                    p.lat -= 1.5
                    p.lon += 1.5
                    self.test('nearestOn2', c.toStr(F_D, prec=6), p.toStr(F_D, prec=6))
                    self.test('neartesOn2', d, '235880.385', fmt='%.3f')

        if hasattr(module, 'ispolar'):
            p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -90), LatLon(85, -180)
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True')  # PYCHOK test attr?
            p = LatLon(85, 90), LatLon(85, 0), LatLon(85, -180)
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True', known=True)  # PYCHOK test attr?
            p = [LatLon(*ll) for ll in Antarctica]  # PYCHOK test attr?
            for _ in self.testiter():
                self.test('ispolar', module.ispolar(p), 'True', known=Vct)  # PYCHOK test attr?
Beispiel #9
0
    def testCartesian(self, module, Sph=False, Nv=True):  # MCCABE 45

        self.subtitle(module, 'Cartesian')

        Cartesian = module.Cartesian
        LatLon = module.LatLon
        Nvector = module.Nvector if Nv else Vector4Tuple

        datum = Datums.Sphere if Sph else Datums.WGS84
        datum2 = None if Sph else Datums.WGS72
        # <https://www.Movable-Type.co.UK/scripts/geodesy/docs/
        #        latlon-nvector-ellipsoidal.js.html#line309>
        c = Cartesian(3980581, 97, 4966825, datum=datum)
        self.test('Cartesian0', c.toStr(prec=0), '[3980581, 97, 4966825]')
        self.test('Cartesian4', c.toStr(prec=4),
                  '[3980581.0, 97.0, 4966825.0]')

        self.test('isEllipsoidal', c.isEllipsoidal, not Sph)
        self.test('isSpherical', c.isSpherical, Sph)
        self.testCopy(c)

        n = c.toNvector()  # (x=0.622818, y=0.00002, z=0.782367, h=0.242887)
        t = n.classname  # Nvector.__name__
        if Nv:
            self.test(
                t, repr(n), 'Nvector(0.62538, 0.00002, 0.78032, -5918.38)'
                if Sph else 'Nvector(0.62282, 0.00002, 0.78237, +0.24)')
            self.test(
                t + '3', n.toStr(prec=3), '(0.625, 0.0, 0.78, -5918.38)'
                if Sph else '(0.623, 0.0, 0.782, +0.24)')
            self.test(
                t + '6', n.toStr(prec=6),
                '(0.625377, 0.000015, 0.780323, -5918.38)' if Sph else
                '(0.622818, 0.000015, 0.782367, +0.24)')  # PYCHOK attribute
        else:
            self.test(
                t,
                repr(n),
                '(x=0.6253769790183048, y=1.5239375097448227e-05, z=0.7803227754472505, h=-5918.3802583276365)'
                if Sph else
                '(x=0.6228177647454303, y=1.517701139112776e-05, z=0.782366941841975, h=0.24288680875513333)',
                known=True)

        for ll in (
            (50.0379, 8.5622),  # FRA
            (51.47, 0.4543),  # LHR
                # <https://www.EdWilliams.org/avform.htm#XTE>
            (degrees(0.709186), -degrees(1.287762)),  # JFK
            (33. + 57. / 60, -(118. + 24. / 60)),  # LAX
                # <https://GeographicLib.SourceForge.io/html/python/examples.html>
            (-41.32, 174.81),  # WNZ, Wellington, NZ
            (40.96, 5.50),  # SAL, Salamanca, Spain
            (40.1, 116.6),  # BJS, Beijing Airport
            (37.6, -122.4)):  # SFO
            if datum2:
                t = c.convertDatum(datum2).convertDatum(datum)
                self.test('convertDatum', t, c)  # PYCHOK attribute
            p = LatLon(*ll)
            q = p.toCartesian().toLatLon()
            t = str(q)
            self.test('LatLon', t, p,
                      known=t.endswith('m'))  # PYCHOK attribute

        # c = Cartesian(3980581, 97, 4966825, datum=datum)
        t = c.copy()
        self.test('copy', t.isequalTo(c), True)
        self.test('__eq__', t == c, True)
        self.test('__ne__', t != c, False)

        if hasattr(Cartesian, 'convertRefFrame'):
            pass  # PYCHOK attribute

        for B in (False, True):  # check return types
            t = c.__class__
            self.test('Cartesian', t, t)
            # self.testReturnType(c.Ecef,             Ecef,       c.Ecef.__name__)
            self.testReturnType(c.latlon, LatLon2Tuple, 'latlon')
            self.testReturnType(c.latlonheight, LatLon3Tuple, 'latlonheight')
            self.testReturnType(c.latlonheightdatum, LatLon4Tuple,
                                'latlonheightdatum')
            self.testReturnType(c.isequalTo(c), bool, 'isequalTo')
            self.testReturnType(c.philam, PhiLam2Tuple, 'philam')
            self.testReturnType(c.philamheight, PhiLam3Tuple, 'philamheight')
            self.testReturnType(c.philamheightdatum, PhiLam4Tuple,
                                'philamheightdatum')
            self.testReturnType(c.to3llh(), LatLon4Tuple, 'to3llh')
            self.testReturnType(c.toEcef(), Ecef9Tuple, 'toEcef')
            self.testReturnType(c.toLatLon(), Ecef9Tuple if B else LatLon,
                                'toLatLon')
            self.testReturnType(c.toNvector(), Vector4Tuple if B else Nvector,
                                'toNvector')
            self.testReturnType(c.xyz, Vector3Tuple, 'xyz')
            c = CartesianBase(c)  # PYCHOK attribute

        if hasattr(Cartesian, 'intersections2'):
            n = classname(Cartesian(0, 0, 0),
                          prefixed=True) + '.intersections2'
            # <https://GIS.StackExchange.com/questions/48937/calculating-intersection-of-two-circles>
            c = Cartesian(-0.00323306, -0.7915, 0.61116)
            self.test(n, c.toLatLon(height=0), '37.673442°N, 090.234036°W')
            d = Cartesian(-0.0134464, -0.807775, 0.589337)
            self.test(n, d.toLatLon(height=0), '36.109987°N, 090.95367°W')
            x, y = c.intersections2(0.0312705, d, 0.0421788,
                                    radius=None)  # radii in radians
            self.test(n, x.toStr(prec=6), '[-0.032779, -0.784769, 0.61892]'
                      )  # -0.0327606, -0.784759, 0.618935
            self.test(n, x.toLatLon(height=0),
                      '38.237342°N, 092.391779°W')  # 38.23838°N, 092.390487°W
            if y is not x:
                self.test(n, y.toStr(prec=6), '[0.025768, -0.798347, 0.601646]'
                          )  # 0.0257661, -0.798332, 0.601666
                self.test(
                    n, y.toLatLon(height=0),
                    '36.987868°N, 088.151309°W')  # 36.98931°N, 088.151425°W

            try:
                from pygeodesy import trilaterate3d2  # with earth ... equivalent to Cartesian.intersections2?
                n = modulename(trilaterate3d2, prefixed=True)
                i, j = trilaterate3d2(c, 0.0312705, d, 0.0421788,
                                      Cartesian(0, 0, 0), 1)  # radians
                self.test(n,
                          i.toStr(prec=6),
                          '[-0.032779, -0.784769, 0.61892]',
                          known=x.minus(i).length < 5e-5)
                self.test(n,
                          j.toStr(prec=6),
                          '[0.025768, -0.798347, 0.601646]',
                          known=y.minus(j).length < 5e-5)
            except ImportError as x:
                self.skip(str(x), n=2)
        try:
            from pygeodesy.vector3d import intersections2
            n = modulename(intersections2, prefixed=True)
            u = Vector3Tuple(-0.00323306, -0.7915, 0.61116)
            v = Vector3Tuple(-0.0134464, -0.807775, 0.589337)
            c, r = intersections2(u, 0.0312705, v, 0.0421788, sphere=True)
            self.test(n, c.toStr(prec=6), '(-0.0035, -0.791926, 0.610589)')
            self.test(n, r.toStr(prec=6), '0.0312613',
                      known=True)  # XXX G and g formats may add 1 decimal
            v1, v2 = intersections2(u, 0.0312705, v, 0.0421788, sphere=False)
            self.test(n, v1.toStr(prec=6), '(-0.021973, -0.766467, 0.0)')
            if v2 is not v1:
                self.test(n, v2.toStr(prec=6), '(0.027459, -0.797488, 0.0)')
        except ImportError as x:
            self.skip(str(x), n=4)