Coverage for gws-app / gws / lib / crs / _test.py: 100%
70 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-03 10:12 +0100
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-03 10:12 +0100
1"""Tests for the crs module."""
3import gws
4import gws.test.util as u
5import gws.lib.crs as crs
8def test_get_no_name():
9 assert not crs.get('')
12def test_get_unknown():
13 assert crs.get('EPSG:0') is None
14 assert crs.get('FOOBAR') is None
17def test_get():
18 assert str(crs.get('EPSG:3857')) == '<crs:3857>'
19 assert crs.get('EPSG:3857') == crs.WEBMERCATOR
22def test_parse():
23 fmt, obj = crs.parse('EPSG:3857')
24 assert fmt == gws.CrsFormat.epsg
25 assert obj == crs.get('3857')
28def test_parse_srid():
29 fmt, obj = crs.parse('3857')
30 assert fmt == gws.CrsFormat.srid
31 assert obj == crs.get('3857')
34def test_parse_aliases():
35 fmt, obj = crs.parse('CRS:84')
36 assert fmt == gws.CrsFormat.crs
37 assert obj == crs.WGS84
39 fmt, obj = crs.parse('epsg:900913')
40 assert fmt == gws.CrsFormat.epsg
41 assert obj == crs.WEBMERCATOR
44def test_parse_no_format():
45 fmt, obj = crs.parse('11wrongFormat')
46 assert fmt == gws.CrsFormat.none
47 assert obj is None
50def test_require():
51 assert crs.require('3857') == crs.get('3857')
54def test_require_exception():
55 with u.raises(crs.Error):
56 crs.require('FOOBAR')
59def test_best_match():
60 lst = [crs.WEBMERCATOR, crs.WGS84]
61 assert crs.best_match(crs.WGS84, lst) == crs.get('4326')
64def test_best_match_not__list():
65 lst = [crs.WEBMERCATOR]
66 assert crs.best_match(crs.WGS84, lst) == crs.get('3857')
69def test_axis_for_format():
70 # WGS84 is internally YX, but output axis depends on the requested CRS string format.
71 assert crs.WGS84.axis_for_format(gws.CrsFormat.epsg) == gws.Axis.xy
72 assert crs.WGS84.axis_for_format(gws.CrsFormat.urn) == gws.Axis.yx
75def test_transform_extent():
76 got = crs.WGS84.transform_extent((0.0, 1.0, 1.0, 0.0), crs_to=crs.WEBMERCATOR)
77 exp = (0.0, 0.0, 111319.49079327357, 111325.1428663851)
78 assert u.is_close(got, exp, abs_tol=1e-4)
81def test_transformer():
82 tr = crs.WGS84.transformer(crs.WEBMERCATOR)
83 assert callable(tr)
84 x, y = tr(1.0, 1.0) # lon/lat -> meters (always_xy=True)
85 assert u.is_close(x, 111319.49079327357, abs_tol=1e-4)
86 assert u.is_close(y, 111325.1428663851, abs_tol=1e-4)
89def test_to_string():
90 assert crs.WEBMERCATOR.to_string() == 'EPSG:3857'
91 assert crs.WEBMERCATOR.to_string(gws.CrsFormat.epsg) == 'EPSG:3857'
92 assert crs.WEBMERCATOR.to_string(gws.CrsFormat.srid) == '3857'
95def test_to_geojson():
96 assert crs.WEBMERCATOR.to_geojson() == {
97 'properties': {'name': 'urn:ogc:def:crs:EPSG::3857'},
98 'type': 'name',
99 }
102def test_extent_size_in_meters_projected():
103 # 1000m x 2000m rectangle in WEBMERCATOR
104 ext = (0, 0, 1000, 2000)
105 w, h = crs.WEBMERCATOR.extent_size_in_meters(ext)
106 assert u.is_close(w, 1000, abs_tol=1e-6)
107 assert u.is_close(h, 2000, abs_tol=1e-6)
110def test_extent_size_in_meters_geographic():
111 # 1 degree longitude at equator ≈ 111319.5m, 1 degree latitude ≈ 110574m
112 ext = (0, 0, 1, 1)
113 w, h = crs.WGS84.extent_size_in_meters(ext)
114 assert u.is_close(w, 111319.5, rel_tol=1e-3)
115 assert u.is_close(h, 110574, rel_tol=1e-3)