Coverage for gws-app/gws/lib/gml/_test/writerpg_test.py: 100%

33 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-16 22:59 +0200

1"""Tests the writer module by comparing its output to postgis ST_AsGML.""" 

2 

3import re 

4 

5import gws 

6import gws.base.shape 

7import gws.lib.crs 

8import gws.lib.sa as sa 

9import gws.lib.gml 

10import gws.test.util as u 

11 

12DATA = ''' 

13POINT (30 10) 

14-- 

15LINESTRING (30 10, 10 30, 40 40) 

16-- 

17POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10)) 

18-- 

19POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30)) 

20-- 

21MULTIPOINT ((10 40), (40 30), (20 20), (30 10)) 

22-- 

23MULTIPOINT (10 40, 40 30, 20 20, 30 10) 

24-- 

25MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10)) 

26-- 

27MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5))) 

28-- 

29MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20))) 

30-- 

31GEOMETRYCOLLECTION (POINT (40 10), LINESTRING (10 10, 20 20, 10 40), POLYGON ((40 40, 20 45, 45 30, 40 40))) 

32''' 

33 

34 

35@u.fixture(scope='module') 

36def root(): 

37 yield u.gws_root() 

38 

39 

40## 

41 

42def test_with_postgis(root: gws.Root): 

43 db = u.get_db(root) 

44 wkt_list = [] 

45 

46 for s in DATA.strip().split('--'): 

47 wkt_list.append(re.sub(r'\s+', ' ', s.strip())) 

48 

49 with db.connect() as conn: 

50 for version in [2, 3]: 

51 for wkt in wkt_list: 

52 sql = f"SELECT ST_AsGML({version},ST_GeomFromText('{wkt}',4326))" 

53 for rec in conn.execute(sa.text(sql)): 

54 postgis_xml = rec[0] 

55 

56 shape = gws.base.shape.from_wkt(wkt, gws.lib.crs.WGS84) 

57 el = gws.lib.gml.shape_to_element( 

58 shape, 

59 version=version, 

60 coordinate_precision=0, 

61 # NB postgis always uses EPSG 

62 crs_format=gws.CrsFormat.epsg, 

63 ) 

64 our_xml = el.to_string() 

65 

66 # NB postgis does not write these attributes 

67 our_xml = _remove_attr(our_xml, 'decimal') 

68 our_xml = _remove_attr(our_xml, 'cs') 

69 our_xml = _remove_attr(our_xml, 'ts') 

70 

71 # NB postgis does not write srsName on inner geometries, we do 

72 our_xml = _remove_attr(our_xml, 'srsName') 

73 postgis_xml = _remove_attr(postgis_xml, 'srsName') 

74 

75 assert u.fxml(our_xml) == u.fxml(postgis_xml) 

76 

77 

78def _remove_attr(xml, name): 

79 return re.sub(r'\s+' + re.escape(name) + r'="[^"]*"', '', xml)