From cbfafc327ce858b2f83111b719cb1f3d54ffd253 Mon Sep 17 00:00:00 2001 From: Niko Aarnio Date: Thu, 12 Sep 2024 15:59:05 +0300 Subject: [PATCH] Class drafting, added JSON for testing --- arho_feature_template/core/__init__.py | 0 .../core/add_feature_form.py | 18 +++ .../core/add_feature_panel.py | 20 +++ .../core/feature_template.py | 31 +++++ .../core/feature_template_library.py | 36 +++++ arho_feature_template/plugin.py | 21 ++- .../asemakaava-template-library-test.json | 131 ++++++++++++++++++ 7 files changed, 252 insertions(+), 5 deletions(-) create mode 100644 arho_feature_template/core/__init__.py create mode 100644 arho_feature_template/core/add_feature_form.py create mode 100644 arho_feature_template/core/add_feature_panel.py create mode 100644 arho_feature_template/core/feature_template.py create mode 100644 arho_feature_template/core/feature_template_library.py create mode 100644 arho_feature_template/resources/asemakaava-template-library-test.json diff --git a/arho_feature_template/core/__init__.py b/arho_feature_template/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/arho_feature_template/core/add_feature_form.py b/arho_feature_template/core/add_feature_form.py new file mode 100644 index 0000000..8a2161f --- /dev/null +++ b/arho_feature_template/core/add_feature_form.py @@ -0,0 +1,18 @@ +from qgis.PyQt.QtWidgets import QDialog + +from arho_feature_template.core.feature_template import FeatureTemplate + + +class AddFeatureForm(QDialog): + """Dialog for filling and saving attribute data that opens when a new feature has been digitized.""" + + def __init__(self, feature_template: FeatureTemplate): + self.feature_template = feature_template + + def _init_feature_attributes(self): + # for feature_attribute in self.feature_template.feature_attributes: + # # Create the form here, add rows with labels and input fields + pass + + def save(self): + pass diff --git a/arho_feature_template/core/add_feature_panel.py b/arho_feature_template/core/add_feature_panel.py new file mode 100644 index 0000000..dd3224c --- /dev/null +++ b/arho_feature_template/core/add_feature_panel.py @@ -0,0 +1,20 @@ + +from qgis.PyQt.QtWidgets import QWidget + +from arho_feature_template.core.feature_template_library import FeatureTemplateLibrary +from arho_feature_template.qgis_plugin_tools.tools.resources import load_ui # noqa F401 + + +# class AddFeaturePanel(QWidget, load_ui("add_feature_panel.ui")): # NOTE: UI file does not exist yet +class AddFeaturePanel(QWidget): + """Dock widget for selecting a feature template.""" + + def __init__(self, feature_template_library: FeatureTemplateLibrary): + super().__init__() + # self.setupUi(self) + self.initialize_from_library(feature_template_library) + + + def initialize_from_library(self, feature_template_library: FeatureTemplateLibrary): + # Initialization logic + self.library = feature_template_library diff --git a/arho_feature_template/core/feature_template.py b/arho_feature_template/core/feature_template.py new file mode 100644 index 0000000..e27fe5c --- /dev/null +++ b/arho_feature_template/core/feature_template.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, Sequence + +if TYPE_CHECKING: + from qgis.core import QgsMapLayer, QgsVectorLayer + from qgis.gui import QgsDoubleSpinBox, QgsSpinBox + from qgis.PyQt.QtGui import QIcon + from qgis.PyQt.QtWidgets import QLineEdit + + +@dataclass +class FeatureAttribute: + name: str + display_name: str + feature_attribte_group: str + attribute_layer: QgsMapLayer # Is this correct type? + additional_information: str + input_field_type: QLineEdit | QgsSpinBox | QgsDoubleSpinBox | None + modifiable: bool = False + hidden: bool = False + + +@dataclass +class FeatureTemplate: + name: str + description: str + feature_layer: QgsVectorLayer + feature_attributes: Sequence[FeatureAttribute] + display_icon: QIcon | None = None diff --git a/arho_feature_template/core/feature_template_library.py b/arho_feature_template/core/feature_template_library.py new file mode 100644 index 0000000..d37e814 --- /dev/null +++ b/arho_feature_template/core/feature_template_library.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +import json +from typing import TYPE_CHECKING, Sequence + +if TYPE_CHECKING: + from os import PathLike + + from arho_feature_template.core.feature_template import FeatureTemplate + + +class FeatureTemplateLibrary: + """Class for storing FeatureTemplates and loading them from a JSON (or other conf. file).""" + + def __init__(self, json_path: str | PathLike): + self.templates = [] + library_dict = self.read_json(json_path) + self.build_templates(library_dict) + + def read_json(self, json_path: str | PathLike) -> dict: + self.source_json = json_path + with open(json_path) as f: + return json.load(f) + + def build_templates(self, library_dict: dict): + templates = [] + + _templates_raw = library_dict["templates"] + # for template_raw in templates_raw: + ## ... build FeatureTemplate from dict here, in FeatureTemplate class or elsewhere? + # template = FeatureTemplate() + # templates.append(template) + self.templates = templates + + def get_templates(self) -> Sequence[FeatureTemplate]: + return self.templates diff --git a/arho_feature_template/plugin.py b/arho_feature_template/plugin.py index 85f87c2..b40ee41 100644 --- a/arho_feature_template/plugin.py +++ b/arho_feature_template/plugin.py @@ -2,15 +2,19 @@ from typing import Callable -from qgis.PyQt.QtCore import QCoreApplication, QTranslator +from qgis.gui import QgsDockWidget +from qgis.PyQt.QtCore import QCoreApplication, Qt, QTranslator from qgis.PyQt.QtGui import QIcon from qgis.PyQt.QtWidgets import QAction, QWidget from qgis.utils import iface +from arho_feature_template.core.add_feature_panel import AddFeaturePanel +from arho_feature_template.core.feature_template_library import FeatureTemplateLibrary from arho_feature_template.qgis_plugin_tools.tools.custom_logging import setup_logger, teardown_logger from arho_feature_template.qgis_plugin_tools.tools.i18n import setup_translation -from arho_feature_template.qgis_plugin_tools.tools.resources import plugin_name +from arho_feature_template.qgis_plugin_tools.tools.resources import plugin_name, resources_path +LIBRARY_JSON = resources_path("asemakaava-template-library-test.json") class Plugin: """QGIS Plugin Implementation.""" @@ -33,6 +37,9 @@ def __init__(self) -> None: self.actions: list[QAction] = [] self.menu = Plugin.name + # Create and initialize default feature template library + self.active_library = FeatureTemplateLibrary(LIBRARY_JSON) + def add_action( self, icon_path: str, @@ -107,7 +114,7 @@ def initGui(self) -> None: # noqa N802 text=Plugin.name, callback=self.run, parent=iface.mainWindow(), - add_to_toolbar=False, + add_to_toolbar=True, ) def onClosePlugin(self) -> None: # noqa N802 @@ -121,5 +128,9 @@ def unload(self) -> None: teardown_logger(Plugin.name) def run(self) -> None: - """Run method that performs all the real work""" - print("Hello QGIS plugin") # noqa: T201 + self.feature_template_dock= QgsDockWidget() + self.add_feature_panel = AddFeaturePanel(self.active_library) + self.feature_template_dock.setWidget(self.add_feature_panel) + self.feature_template_dock.setWindowTitle("ARHO") # NOTE: Placeholder name + + iface.addDockWidget(Qt.RightDockWidgetArea, self.feature_template_dock) diff --git a/arho_feature_template/resources/asemakaava-template-library-test.json b/arho_feature_template/resources/asemakaava-template-library-test.json new file mode 100644 index 0000000..1ff2ddd --- /dev/null +++ b/arho_feature_template/resources/asemakaava-template-library-test.json @@ -0,0 +1,131 @@ +{ + "version": 1, + "name": "Asemakaava-kaavamääräyskirjasto", + "templates": [ + { + "name": "Asuin-, liike- ja toimistorakennusten alue", + "description": "Aluella kuvataan ...", + "feature": { + "layer": "land_use_area", + "fields": [ + { + "field": "name" + }, + { + "field": "type_of_underground_id", + "value": 1 + } + ], + "children": [ + { + "layer": "plan_requlation_group", + "fields": [ + { + "field": "name", + "value": "Asuin-, liike- ja toimistorakennusten alue", + "allow_user_input": false + } + ], + "children": [ + { + "layer": "plan_requlation", + "fields": [ + { + "field": "type_of_plan_regulation_id", + "value": "asumisenAlue", + "hidden": true + } + ], + "children": { + "layer": "additional_information_of_plan_regulation", + "fields": [ + { + "field": "type_of_additional_information_id", + "value": "paakayttotarkoitus", + "hidden": true + } + ] + } + }, + { + "layer": "plan_requlation", + "fields": [ + { + "field": "type_of_plan_regulation_id", + "value": "liikerakennustenAlue", + "hidden": true + } + ], + "children": { + "layer": "additional_information_of_plan_regulation", + "fields": [ + { + "field": "type_of_additional_information_id", + "value": "paakayttotarkoitus", + "hidden": true + } + ] + } + }, + { + "layer": "plan_requlation", + "fields": [ + { + "field": "type_of_plan_regulation_id", + "value": "toimitilojenAlue", + "hidden": true + } + ], + "children": { + "layer": "additional_information_of_plan_regulation", + "fields": [ + { + "field": "type_of_additional_information_id", + "value": "paakayttotarkoitus", + "hidden": true + } + ] + } + } + ] + }, + { + "layer": "plan_requlation_group", + "fields": [ + { + "field": "name", + "value": "Korttelin numero", + "allow_user_input": false + } + ], + "children": [ + { + "layer": "plan_requlation", + "fields": [ + { + "field": "type_of_plan_regulation_id", + "value": "korttelinNumero" + }, + { + "field": "numeric_value", + "required": true + } + ] + } + ] + } + ] + } + }, + { + "name": "Asuinrakennusten alue", + "description": "Asuinrakennusten alue ...", + "fields": [ + { + "field": "", + "required": true + } + ] + } + ] +}