Coverage for gws-app/gws/base/feature/__init__.py: 28%

67 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1from typing import Optional 

2 

3import gws 

4import gws.base.shape 

5import gws.lib.style 

6import gws.lib.svg 

7 

8 

9def new( 

10 model: gws.Model, 

11 record: Optional[gws.FeatureRecord] = None, 

12 props: Optional[gws.FeatureProps] = None 

13) -> gws.Feature: 

14 f = Feature(model) 

15 f.record = record or gws.FeatureRecord(attributes={}) 

16 f.props = props or gws.FeatureProps(attributes={}) 

17 return f 

18 

19 

20class Feature(gws.Feature): 

21 def __init__(self, model: gws.Model): 

22 self.attributes = {} 

23 self.category = '' 

24 self.cssSelector = '' 

25 self.errors = [] 

26 self.isNew = False 

27 self.model = model 

28 self.views = {} 

29 self.createWithFeatures = [] 

30 self.insertedPrimaryKey = '' 

31 

32 def __repr__(self): 

33 try: 

34 return f'<feature {self.model.uid}:{self.uid()}>' 

35 except: 

36 return f'<feature ?>' 

37 

38 def uid(self): 

39 if self.model.uidName: 

40 return str(self.attributes.get(self.model.uidName)) 

41 return '' 

42 

43 def shape(self): 

44 if self.model.geometryName: 

45 return self.attributes.get(self.model.geometryName) 

46 

47 def get(self, name, default=None): 

48 return self.attributes.get(name, default) 

49 

50 def has(self, name): 

51 return name in self.attributes 

52 

53 def set(self, name, value): 

54 self.attributes[name] = value 

55 return self 

56 

57 def raw(self, name): 

58 return self.record.attributes.get(name) 

59 

60 def render_views(self, templates, **kwargs): 

61 tri = gws.TemplateRenderInput( 

62 args=gws.u.merge( 

63 self.attributes, 

64 kwargs, 

65 feature=self 

66 )) 

67 for tpl in templates: 

68 view_name = tpl.subject.split('.')[-1] 

69 self.views[view_name] = tpl.render(tri).content 

70 return self 

71 

72 def transform_to(self, crs) -> gws.Feature: 

73 if self.shape(): 

74 self.attributes[self.model.geometryName] = self.shape().transformed_to(crs) 

75 return self 

76 

77 def to_svg(self, view, label=None, style=None): 

78 if not self.shape(): 

79 return [] 

80 shape = self.shape().transformed_to(view.bounds.crs) 

81 return gws.lib.svg.shape_to_fragment(shape, view, label, style) 

82 

83 def to_geojson(self, user): 

84 p = self.props(user) 

85 d = {'type': 'Feature', 'properties': getattr(p, 'attributes', {})} 

86 d['properties']['id'] = self.uid() 

87 

88 if self.model.geometryName: 

89 shape = d['properties'].pop(self.model.geometryName, None) 

90 if shape: 

91 d['geometry'] = shape.to_geojson() 

92 d['crs'] = shape.crs.to_geojson() 

93 

94 return d