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

1"""Tests for the crs module.""" 

2 

3import gws 

4import gws.test.util as u 

5import gws.lib.crs as crs 

6 

7 

8def test_get_no_name(): 

9 assert not crs.get('') 

10 

11 

12def test_get_unknown(): 

13 assert crs.get('EPSG:0') is None 

14 assert crs.get('FOOBAR') is None 

15 

16 

17def test_get(): 

18 assert str(crs.get('EPSG:3857')) == '<crs:3857>' 

19 assert crs.get('EPSG:3857') == crs.WEBMERCATOR 

20 

21 

22def test_parse(): 

23 fmt, obj = crs.parse('EPSG:3857') 

24 assert fmt == gws.CrsFormat.epsg 

25 assert obj == crs.get('3857') 

26 

27 

28def test_parse_srid(): 

29 fmt, obj = crs.parse('3857') 

30 assert fmt == gws.CrsFormat.srid 

31 assert obj == crs.get('3857') 

32 

33 

34def test_parse_aliases(): 

35 fmt, obj = crs.parse('CRS:84') 

36 assert fmt == gws.CrsFormat.crs 

37 assert obj == crs.WGS84 

38 

39 fmt, obj = crs.parse('epsg:900913') 

40 assert fmt == gws.CrsFormat.epsg 

41 assert obj == crs.WEBMERCATOR 

42 

43 

44def test_parse_no_format(): 

45 fmt, obj = crs.parse('11wrongFormat') 

46 assert fmt == gws.CrsFormat.none 

47 assert obj is None 

48 

49 

50def test_require(): 

51 assert crs.require('3857') == crs.get('3857') 

52 

53 

54def test_require_exception(): 

55 with u.raises(crs.Error): 

56 crs.require('FOOBAR') 

57 

58 

59def test_best_match(): 

60 lst = [crs.WEBMERCATOR, crs.WGS84] 

61 assert crs.best_match(crs.WGS84, lst) == crs.get('4326') 

62 

63 

64def test_best_match_not__list(): 

65 lst = [crs.WEBMERCATOR] 

66 assert crs.best_match(crs.WGS84, lst) == crs.get('3857') 

67 

68 

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 

73 

74 

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) 

79 

80 

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) 

87 

88 

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' 

93 

94 

95def test_to_geojson(): 

96 assert crs.WEBMERCATOR.to_geojson() == { 

97 'properties': {'name': 'urn:ogc:def:crs:EPSG::3857'}, 

98 'type': 'name', 

99 } 

100 

101 

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) 

108 

109 

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)