Skip to content

Commit 0c56e85

Browse files
committed
add regulation group type selection and short name, fix versined text input widget, move data saving funcs to plan manager, add placeholder mapping logic to target plan feature layer selection
1 parent acd4085 commit 0c56e85

10 files changed

+245
-111
lines changed

arho_feature_template/core/feature_template_library.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from qgis.PyQt.QtGui import QStandardItem, QStandardItemModel
1010
from qgis.utils import iface
1111

12+
from arho_feature_template.core.plan_manager import save_plan_feature
1213
from arho_feature_template.core.template_library_config import (
1314
FeatureTemplate,
1415
TemplateLibraryConfig,
@@ -157,8 +158,9 @@ def ask_for_feature_attributes(self, feature: QgsFeature) -> None:
157158
if not self.active_template:
158159
return
159160

160-
attribute_form = TemplateAttributeForm(self.active_template.config, feature)
161-
attribute_form.exec_()
161+
attribute_form = TemplateAttributeForm(self.active_template.config, feature.geometry())
162+
if attribute_form.exec_():
163+
save_plan_feature(attribute_form.model)
162164

163165
def get_library_names(self) -> list[str]:
164166
return list(self.library_configs.keys())

arho_feature_template/core/models.py

+5-65
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import yaml
1111

1212
from arho_feature_template.exceptions import ConfigSyntaxError
13-
from arho_feature_template.project.layers.plan_layers import PlanFeatureLayer, PlanRegulationLayer, RegulationGroupLayer
1413
from arho_feature_template.qgis_plugin_tools.tools.resources import resources_path
1514
from arho_feature_template.utils.misc_utils import get_layer_by_name, iface
1615

@@ -226,28 +225,10 @@ class Regulation:
226225
# value_number: Number | None
227226
# value_number_pair: tuple[Number, Number] | None
228227

229-
def save_data(self):
230-
feature = PlanRegulationLayer.feature_from_model(self)
231-
layer = PlanRegulationLayer.get_from_project()
232-
233-
if not layer.isEditable():
234-
layer.startEditing()
235-
layer.beginEditCommand("Kaavamääräyksen lisäys" if self.id_ is None else "Kaavamääräyksen muokkaus")
236-
237-
if self.id_ is None:
238-
layer.addFeature(feature)
239-
else:
240-
layer.updateFeature(feature)
241-
242-
layer.endEditCommand()
243-
layer.commitChanges(stopEditing=False)
244-
245-
# TODO: associations?
246-
247228

248229
@dataclass
249230
class RegulationGroup:
250-
type_code: str
231+
type_code_id: str | None
251232
name: str | None
252233
short_name: str | None
253234
color_code: str | None
@@ -280,68 +261,27 @@ def from_config_data(cls, data: dict) -> RegulationGroup:
280261
else:
281262
iface.messageBar().pushWarning("", f"Could not find plan regulation {reg_code}!")
282263
return cls(
283-
type_code="landUseRegulations",
264+
type_code_id=data.get("type"), # NOTE: Might need to convert type code into type code ID here when
265+
# config file has type codes for regulation groups
284266
name=data.get("name"),
285267
short_name=data.get("short_name"),
286268
color_code=data.get("color_code"),
287269
regulations=regulations,
288270
id_=None,
289271
)
290272

291-
def save_data(self):
292-
feature = RegulationGroupLayer.feature_from_model(self)
293-
layer = RegulationGroupLayer.get_from_project()
294-
295-
if not layer.isEditable():
296-
layer.startEditing()
297-
layer.beginEditCommand("Kaavamääräysryhmän lisäys" if self.id_ is None else "Kaavamääräysryhmän muokkaus")
298-
299-
if self.id_ is None:
300-
layer.addFeature(feature)
301-
else:
302-
layer.updateFeature(feature)
303-
304-
layer.endEditCommand()
305-
layer.commitChanges(stopEditing=False)
306-
307-
if self.regulations:
308-
for regulation in self.regulations:
309-
regulation.regulation_group_id_ = feature["id"] # Updating regulation group ID
310-
regulation.save_data()
311-
312-
# TODO: associations?
313-
314-
# @classmethod
315-
# def from_database(cls) -> RegulationGroup:
316-
# pass
317-
318273

319274
@dataclass
320275
class PlanFeature:
321276
geom: QgsGeometry
322-
feature_layer_class: type[PlanFeatureLayer]
323277
type_of_underground_id: str
278+
layer_name: str | None = None
324279
name: str | None = None
325280
description: str | None = None
281+
regulation_groups: list[RegulationGroup] = field(default_factory=list)
326282
plan_id: int | None = None
327283
id_: int | None = None
328284

329-
def save_data(self):
330-
feature = self.feature_layer_class.feature_from_model(self)
331-
layer = self.feature_layer_class.get_from_project()
332-
333-
if not layer.isEditable():
334-
layer.startEditing()
335-
layer.beginEditCommand("Kaavakohteen lisäys" if self.id_ is None else "Kaavakohteen muokkaus")
336-
337-
if self.id_ is None:
338-
layer.addFeature(feature)
339-
else:
340-
layer.updateFeature(feature)
341-
342-
layer.endEditCommand()
343-
layer.commitChanges(stopEditing=False)
344-
345285

346286
@dataclass
347287
class Plan:

arho_feature_template/core/plan_manager.py

+97-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@
1818
from arho_feature_template.gui.load_plan_dialog import LoadPlanDialog
1919
from arho_feature_template.gui.plan_attribure_form import PlanAttributeForm
2020
from arho_feature_template.gui.serialize_plan import SerializePlan
21-
from arho_feature_template.project.layers.plan_layers import PlanLayer, RegulationGroupLayer, plan_layers
21+
from arho_feature_template.project.layers.plan_layers import (
22+
LandUseAreaLayer,
23+
LandUsePointLayer,
24+
LineLayer,
25+
OtherAreaLayer,
26+
OtherPointLayer,
27+
PlanFeatureLayer,
28+
PlanLayer,
29+
PlanRegulationLayer,
30+
RegulationGroupLayer,
31+
plan_layers,
32+
)
2233
from arho_feature_template.utils.db_utils import get_existing_database_connection_names
2334
from arho_feature_template.utils.misc_utils import (
2435
check_layer_changes,
@@ -29,7 +40,8 @@
2940
if TYPE_CHECKING:
3041
from qgis.core import QgsFeature
3142

32-
from arho_feature_template.core.models import Plan, RegulationGroup
43+
from arho_feature_template.core.models import Plan, PlanFeature, Regulation, RegulationGroup
44+
3345
logger = logging.getLogger(__name__)
3446

3547

@@ -179,6 +191,20 @@ def save_plan_jsons(self, plan_json, outline_json):
179191
)
180192

181193

194+
def _save_feature(feature: QgsFeature, layer: QgsVectorLayer, id_: int | None, edit_text: str = ""):
195+
if not layer.isEditable():
196+
layer.startEditing()
197+
layer.beginEditCommand(edit_text)
198+
199+
if id_ is None:
200+
layer.addFeature(feature)
201+
else:
202+
layer.updateFeature(feature)
203+
204+
layer.endEditCommand()
205+
layer.commitChanges(stopEditing=False)
206+
207+
182208
def save_plan(plan_data: Plan) -> QgsFeature:
183209
plan_layer = PlanLayer.get_from_project()
184210
in_edit_mode = plan_layer.isEditable()
@@ -208,11 +234,76 @@ def save_plan(plan_data: Plan) -> QgsFeature:
208234
return plan_feature
209235

210236

211-
def save_regulation_group(regulation_group: RegulationGroup, plan_id: str) -> QgsFeature:
212-
feature = RegulationGroupLayer.feature_from_model(regulation_group)
213-
feature["plan_id"] = plan_id
214-
return feature
237+
def save_plan_feature(plan_feature: PlanFeature, plan_id: str | None = None):
238+
layer_name_to_class_map: dict[str, type[PlanFeatureLayer]] = {
239+
LandUsePointLayer.name: LandUsePointLayer,
240+
OtherAreaLayer.name: OtherAreaLayer,
241+
OtherPointLayer.name: OtherPointLayer,
242+
LandUseAreaLayer.name: LandUseAreaLayer,
243+
LineLayer.name: LineLayer,
244+
}
245+
246+
if not plan_feature.layer_name:
247+
msg = "Cannot save plan feature without a target layer"
248+
raise ValueError(msg)
249+
layer_class = layer_name_to_class_map.get(plan_feature.layer_name)
250+
if not layer_class:
251+
msg = f"Could not find plan feature layer class for layer name {plan_feature.layer_name}"
252+
raise ValueError(msg)
253+
feature = layer_class.feature_from_model(plan_feature)
254+
layer = layer_class.get_from_project()
255+
256+
if plan_id:
257+
feature["plan_id"] = plan_id
258+
259+
_save_feature(
260+
feature=feature,
261+
layer=layer,
262+
id_=plan_feature.id_,
263+
edit_text="Kaavakohteen lisäys" if plan_feature.id_ is None else "Kaavakohteen muokkaus",
264+
)
265+
266+
# Handle regulation groups
267+
if plan_feature.regulation_groups:
268+
for group in plan_feature.regulation_groups:
269+
save_regulation_group(group)
270+
271+
272+
# def save_regulation_group(regulation_group: RegulationGroup, plan_id: str) -> QgsFeature:
273+
# feature = RegulationGroupLayer.feature_from_model(regulation_group)
274+
# feature["plan_id"] = plan_id
275+
# return feature
276+
277+
278+
def save_regulation_group(regulation_group: RegulationGroup, plan_id: str | None = None):
279+
feature = RegulationGroupLayer.feature_from_model(regulation_group, plan_id)
280+
layer = RegulationGroupLayer.get_from_project()
281+
282+
_save_feature(
283+
feature=feature,
284+
layer=layer,
285+
id_=regulation_group.id_,
286+
edit_text="Kaavamääräysryhmän lisäys" if regulation_group.id_ is None else "Kaavamääräysryhmän muokkaus",
287+
)
288+
289+
# Handle regulations
290+
if regulation_group.regulations:
291+
for regulation in regulation_group.regulations:
292+
regulation.regulation_group_id_ = feature["id"] # Updating regulation group ID
293+
save_regulation(regulation)
215294

216295

217296
def save_regulation_grop_assosiation(plan_id: str, regulation_group_id: str):
218297
pass
298+
299+
300+
def save_regulation(regulation: Regulation):
301+
feature = PlanRegulationLayer.feature_from_model(regulation)
302+
layer = PlanRegulationLayer.get_from_project()
303+
304+
_save_feature(
305+
feature=feature,
306+
layer=layer,
307+
id_=regulation.id_,
308+
edit_text="Kaavamääräyksen lisäys" if regulation.id_ is None else "Kaavamääräyksen muokkaus",
309+
)

arho_feature_template/gui/plan_regulation_group_widget.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010

1111
from arho_feature_template.core.models import Regulation, RegulationGroup
1212
from arho_feature_template.gui.plan_regulation_widget import RegulationWidget
13+
from arho_feature_template.project.layers.code_layers import PlanRegulationGroupType
1314

1415
if TYPE_CHECKING:
1516
from qgis.PyQt.QtWidgets import QFrame, QLineEdit, QPushButton
1617

18+
from arho_feature_template.gui.code_combobox import CodeComboBox
19+
1720
ui_path = resources.files(__package__) / "plan_regulation_group_widget.ui"
1821
FormClass, _ = uic.loadUiType(ui_path)
1922

@@ -30,14 +33,23 @@ def __init__(self, regulation_group_data: RegulationGroup):
3033
# TYPES
3134
self.frame: QFrame
3235
self.name: QLineEdit
36+
self.short_name: QLineEdit
3337
self.del_btn: QPushButton
38+
self.type_of_plan_regulation_group: CodeComboBox
39+
# NOTE: Maybe user input is not needed and wanted for type of plan regulation group and it would be defined
40+
# by the plan feature directly (and hidden from user)
3441

3542
# INIT
3643
self.regulation_group_data = regulation_group_data
3744
self.regulation_widgets: list[RegulationWidget] = [
3845
self.add_regulation_widget(regulation) for regulation in self.regulation_group_data.regulations
3946
]
40-
self.name.setText(self.regulation_group_data.name)
47+
self.type_of_plan_regulation_group.populate_from_code_layer(PlanRegulationGroupType)
48+
self.type_of_plan_regulation_group.removeItem(0) # Remove NULL from combobox as underground data is required
49+
50+
self.name.setText(self.regulation_group_data.name if self.regulation_group_data.name else "")
51+
self.short_name.setText(self.regulation_group_data.short_name if self.regulation_group_data.short_name else "")
52+
# self.type_of_plan_regulation_group.setCurrentText(self.regulation_group_data.type_code) # TODO: implement
4153
self.del_btn.setIcon(QgsApplication.getThemeIcon("mActionDeleteSelected.svg"))
4254
self.del_btn.clicked.connect(lambda: self.delete_signal.emit(self))
4355

@@ -54,9 +66,9 @@ def delete_regulation_widget(self, regulation_widget: RegulationWidget):
5466

5567
def into_model(self) -> RegulationGroup:
5668
return RegulationGroup(
57-
type_code=self.regulation_group_data.type_code,
69+
type_code_id=self.type_of_plan_regulation_group.value(),
5870
name=self.name.text(),
59-
short_name=self.regulation_group_data.short_name,
71+
short_name=self.short_name.text(),
6072
color_code=self.regulation_group_data.color_code,
6173
regulations=[widget.into_model() for widget in self.regulation_widgets],
6274
id_=self.regulation_group_data.id_,

0 commit comments

Comments
 (0)