Coverage for gws-app / gws / base / feature / __init__.py: 75%
69 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
1from typing import Optional
3import gws
4import gws.base.shape
5import gws.lib.style
6import gws.lib.svg
9def new(
10 model: gws.Model,
11 attributes: Optional[dict] = None,
12 record: Optional[gws.FeatureRecord] = None,
13 props: Optional[gws.FeatureProps] = None,
14) -> gws.Feature:
15 f = Feature(model)
16 f.attributes = attributes or {}
17 f.record = record or gws.FeatureRecord(attributes={})
18 f.props = props or gws.FeatureProps(attributes={})
19 return f
22class Feature(gws.Feature):
23 def __init__(self, model: gws.Model):
24 self.attributes = {}
25 self.category = ''
26 self.cssSelector = ''
27 self.errors = []
28 self.isNew = False
29 self.model = model
30 self.views = {}
31 self.createWithFeatures = []
32 self.insertedPrimaryKey = ''
34 def __repr__(self):
35 try:
36 return f'<feature {self.model.uid}:{self.uid()}>'
37 except Exception:
38 return f'<feature ?>'
40 def uid(self):
41 if not self.model.uidName:
42 return ''
43 v = self.attributes.get(self.model.uidName)
44 if v is not None:
45 return str(v)
47 def shape(self):
48 if self.model.geometryName:
49 return self.attributes.get(self.model.geometryName)
51 def get(self, name, default=None):
52 return self.attributes.get(name, default)
54 def has(self, name):
55 return name in self.attributes
57 def set(self, name, value):
58 self.attributes[name] = value
59 return self
61 def raw(self, name):
62 return self.record.attributes.get(name)
64 def render_views(self, templates, **kwargs):
65 tri = gws.TemplateRenderInput(
66 args=gws.u.merge(
67 self.attributes,
68 kwargs,
69 feature=self,
70 )
71 )
72 for tpl in templates:
73 view_name = tpl.subject.split('.')[-1]
74 self.views[view_name] = tpl.render(tri).content
75 return self
77 def transform_to(self, crs) -> gws.Feature:
78 s = self.shape()
79 if s:
80 self.attributes[self.model.geometryName] = s.transformed_to(crs)
81 return self
83 def to_svg(self, view, label=None, style=None):
84 s = self.shape()
85 if not s:
86 return []
87 shape = s.transformed_to(view.bounds.crs)
88 return gws.lib.svg.shape_to_fragment(shape, view, label, style)
90 def to_geojson(self, keep_crs=False) -> dict:
91 d = {
92 'type': 'Feature',
93 'properties': {
94 k: v # noqa
95 for k, v in self.attributes.items()
96 if k != self.model.geometryName
97 },
98 }
99 d['properties']['id'] = self.uid()
100 s = self.shape()
101 if s:
102 d['geometry'] = s.to_geojson(keep_crs=keep_crs)
103 return d