Skip to content

Commit 8385837

Browse files
committedSep 18, 2024
feat: initial implementation for template building in FeatureTemplateLibrary class
1 parent 855dd47 commit 8385837

File tree

3 files changed

+112
-8
lines changed

3 files changed

+112
-8
lines changed
 

‎arho_feature_template/core/feature_template.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,12 @@ class FeatureTemplate:
2727
name: str
2828
description: str
2929
feature_layer: QgsVectorLayer
30-
feature_attributes: Sequence[FeatureAttribute]
30+
feature_attributes: Sequence[FeatureAttribute] | None = None
3131
display_icon: QIcon | None = None
32+
33+
def add_feature_attributes(self, feature_attribute_groups: Sequence[dict]):
34+
for _group in feature_attribute_groups:
35+
# Should we add FeatureAttributeGroup as a class? Or can group name be
36+
# only one class attribute of FeatureAttribute?
37+
# TODO
38+
pass

‎arho_feature_template/core/feature_template_library.py

+83-7
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
import json
44
from typing import TYPE_CHECKING, Sequence
55

6+
from qgis.core import QgsMapLayer, QgsProject, QgsVectorLayer
7+
from qgis.utils import iface
8+
9+
from arho_feature_template.core.feature_template import FeatureTemplate
10+
from arho_feature_template.core.json_config import JsonKeys
11+
612
if TYPE_CHECKING:
713
from os import PathLike
814

9-
from arho_feature_template.core.feature_template import FeatureTemplate
10-
1115

1216
class FeatureTemplateLibrary:
1317
"""Class for storing FeatureTemplates and loading them from a JSON (or other conf. file)."""
@@ -23,14 +27,86 @@ def read_json(self, json_path: str | PathLike) -> dict:
2327
return json.load(f)
2428

2529
def build_templates(self, library_dict: dict):
30+
"""Build feature templates from input `library_dict` and update `templates` attribute."""
31+
all_templates_count = 0
32+
invalid_templates_count = 0
2633
templates = []
2734

28-
_templates_raw = library_dict["templates"]
29-
# for template_raw in templates_raw:
30-
## ... build FeatureTemplate from dict here, in FeatureTemplate class or elsewhere?
31-
# template = FeatureTemplate()
32-
# templates.append(template)
35+
templates_raw = library_dict.get(JsonKeys.TEMPLATES)
36+
if not templates_raw:
37+
iface.messageBar().pushWarning(
38+
"Error: ", f"Could not find any templates in the template library JSON with key {JsonKeys.TEMPLATES}."
39+
)
40+
return
41+
42+
# Go through each template data in the dictionary, save info about invalid templates?
43+
for template_raw in templates_raw:
44+
template = self.build_feature_template(template_raw)
45+
if not template:
46+
invalid_templates_count += 1
47+
else:
48+
templates.append(template)
49+
all_templates_count += 1
50+
3351
self.templates = templates
3452

53+
if invalid_templates_count > 0:
54+
iface.messageBar().pushWarning(
55+
"Warning: ",
56+
f"Failed to create {invalid_templates_count} out of {all_templates_count} \
57+
feature templates from the template library JSON."
58+
)
59+
60+
def build_feature_template(self, template_dict: dict) -> FeatureTemplate | None:
61+
"""
62+
Attempt to build a `FeatureTemplate` from given `template_dict`.
63+
64+
Args:
65+
template_dict: Information about a feature template as a dictionary.
66+
67+
Returns:
68+
`FeatureTemplate` if building was successful, otherwise None.
69+
"""
70+
name: str = template_dict.get(JsonKeys.NAME)
71+
description: str = template_dict.get(JsonKeys.DESCRIPTION, "No description")
72+
feature: dict = template_dict.get(JsonKeys.FEATURE, {})
73+
feature_layer_name: str = feature.get(JsonKeys.LAYER, "")
74+
layers = QgsProject.instance().mapLayersByName(feature_layer_name)
75+
if not layers:
76+
feature_layer = None
77+
else:
78+
feature_layer: QgsMapLayer = layers[0]
79+
# Is this needed?
80+
if len(layers) > 1:
81+
iface.messageBar().pushWarning(
82+
"Warning: ",
83+
f"Multiple layers with the specified feature layer name {feature_layer_name} found \
84+
for feature template {name}, using the first match."
85+
)
86+
87+
if not isinstance(feature_layer, QgsVectorLayer):
88+
iface.messageBar().pushWarning(
89+
"Error: ",
90+
f"Feature layer found but has invalid type {type(feature_layer)} for feature template {name}."
91+
)
92+
feature_layer = None
93+
94+
# All information is needed for FeatureTemplate except for description?
95+
if not name or not feature or not feature_layer_name or not feature_layer:
96+
return None
97+
98+
# TODO: fields of feature layer
99+
# feature_fields = feature.get(JsonKeys.FIELDS, [])
100+
101+
feature_template = FeatureTemplate(
102+
name=name,
103+
description=description,
104+
feature_layer=feature_layer,
105+
)
106+
feature_attribute_groups = feature.get(JsonKeys.CHILDREN, [])
107+
feature_template.add_feature_attributes(feature_attribute_groups)
108+
109+
return feature_template
110+
35111
def get_templates(self) -> Sequence[FeatureTemplate]:
36112
return self.templates
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from dataclasses import dataclass
2+
3+
4+
@dataclass
5+
class JsonKeys:
6+
VERSION = "version"
7+
NAME = "name"
8+
TEMPLATES = "templates"
9+
10+
DESCRIPTION = "description"
11+
FEATURE = "feature"
12+
13+
LAYER = "layer"
14+
FIELDS = "fields"
15+
CHILDREN = "children"
16+
17+
FIELD = "field"
18+
VALUE = "value"
19+
MODIFIABLE = "allow_user_input"
20+
HIDDEN = "hidden"
21+
REQUIRED = "required"

0 commit comments

Comments
 (0)
Please sign in to comment.