Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32 katja asetuksen kaavamääräysryhmät yml kirjastoksi tärkeimmät #69

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions arho_feature_template/core/plan_regulation_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import logging
import os
from dataclasses import dataclass
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import TYPE_CHECKING, cast
Expand All @@ -14,6 +14,7 @@
from arho_feature_template.qgis_plugin_tools.tools.resources import resources_path

if TYPE_CHECKING:
from numbers import Number
from typing import Literal

from qgis.core import QgsMapLayer
Expand All @@ -34,10 +35,11 @@ def __init__(self, message: str):

class UninitializedError(Exception):
def __init__(self):
super().__init__("PlanRegulationsSet is not initialized. Call 'load_config' first")
super().__init__("PlanRegulationsSet is not initialized. Call 'initialize' first")


class ValueType(Enum):
DECIMAL = "desimaali"
POSITIVE_DECIMAL = "positiivinen desimaali"
POSITIVE_INTEGER = "positiivinen kokonaisluku"
POSITIVE_INTEGER_RANGE = "positiivinen kokonaisluku arvoväli"
Expand All @@ -50,6 +52,8 @@ class Unit(Enum):
EFFICIENCY_RATIO = "k-m2/m2"
PERCENTAGE = "prosentti"
AREA_RATIO = "m2/k-m2"
DEGREES = "°"
DECIBEL = "dB"


# TODO: Same as in PlanManager, should refactor
Expand All @@ -75,6 +79,7 @@ class PlanRegulationsSet:

version: str
regulations: list[PlanRegulationConfig]
regulations_dict: dict[str, PlanRegulationConfig] = field(default_factory=dict)

_instance: PlanRegulationsSet | None = None

Expand All @@ -87,9 +92,18 @@ def get_instance(cls) -> PlanRegulationsSet:

@classmethod
def get_regulations(cls) -> list[PlanRegulationConfig]:
"""Get the list of regulation configs, if instance is initialized."""
instance = cls.get_instance()
return instance.regulations
"""Get the list of top-level regulation configs, if instance is initialized."""
return cls.get_instance().regulations

@classmethod
def get_regulations_dict(cls) -> dict[str, PlanRegulationConfig]:
"""Get all regulations in a dictionary where keys are regulations codes and values PlanRegulationConfigs."""
return cls.get_instance().regulations_dict

@classmethod
def get_regulation_by_code(cls, regulation_code: str) -> PlanRegulationConfig | None:
"""Get a regulation by it's regulation code (if exists)."""
return cls.get_instance().regulations_dict.get(regulation_code)

@classmethod
def initialize(
Expand All @@ -103,12 +117,17 @@ def initialize(
data = yaml.safe_load(f)
cls._instance = cls.from_dict(data)

# Add names from plan regulation layer
regulations = cls.get_regulations()
regulations_dict: dict[str, PlanRegulationConfig] = {}
mapping = get_name_mapping_for_plan_regulations(type_of_plan_regulations_layer_name)
if mapping:
for regulation in cls.get_regulations():

# Add names to dictionary, add names to regulations
for regulation in regulations:
regulation.add_to_dictionary(regulations_dict)
if mapping:
regulation.add_name(mapping, language)

cls._instance.regulations_dict = regulations_dict
logger.info("PlanRegulationsSet initialized successfully.")
return cls._instance

Expand Down Expand Up @@ -156,3 +175,29 @@ def add_name(self, code_to_name_mapping: dict[str, dict[str, str]], language: Li
self.name = language_to_name_dict[language] if language_to_name_dict else self.regulation_code
for regulation in self.child_regulations:
regulation.add_name(code_to_name_mapping, language)

def add_to_dictionary(self, dictionary: dict[str, PlanRegulationConfig]):
dictionary[self.regulation_code] = self
for regulation in self.child_regulations:
regulation.add_to_dictionary(dictionary)


@dataclass
class PlanRegulationDefinition:
"""Associates a PlanRegulationConfig with an optional default value and additional data."""

regulation_config: PlanRegulationConfig
default_value: str | Number | None
additional_info: dict[str, str | Number | None] # NOTE: Correct typing for additional information values?
regulation_number: int | None
attached_files: list[Path]

@classmethod
def from_dict(cls, data: dict) -> PlanRegulationDefinition:
return cls(
regulation_config=data["config"],
default_value=data.get("default_value"),
additional_info=data.get("additional_info", {}),
regulation_number=data.get("regulation_number"),
attached_files=data.get("attached_files", []),
)
118 changes: 118 additions & 0 deletions arho_feature_template/core/plan_regulation_group_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import TYPE_CHECKING, cast

import yaml
from qgis.utils import iface

from arho_feature_template.core.plan_regulation_config import PlanRegulationDefinition, PlanRegulationsSet

if TYPE_CHECKING:
from pathlib import Path

from qgis.gui import QgisInterface

iface: QgisInterface = cast("QgisInterface", iface) # type: ignore[no-redef]

logger = logging.getLogger(__name__)


class ConfigSyntaxError(Exception):
def __init__(self, message: str):
super().__init__(f"Invalid config syntax: {message}")


@dataclass
class PlanRegulationGroupLibrary:
"""Describes the configuration of a plan regulation group library"""

meta: PlanRegulationGroupLibraryMeta
plan_regulation_group_categories: list[PlanRegulationGroupCategory]

@classmethod
def from_dict(cls, data: dict) -> PlanRegulationGroupLibrary:
try:
return cls(
meta=PlanRegulationGroupLibraryMeta.from_dict(data["meta"]),
plan_regulation_group_categories=[
PlanRegulationGroupCategory.from_dict(category) for category in data["categories"]
],
)
except KeyError as e:
raise ConfigSyntaxError(str(e)) from e

@classmethod
def new_from_file(cls, fp: Path) -> PlanRegulationGroupLibrary:
with fp.open(encoding="utf-8") as f:
data = yaml.safe_load(f)
return PlanRegulationGroupLibrary.from_dict(data)


@dataclass
class PlanRegulationGroupLibraryMeta:
"""Describes the metadata of a plan regulation group library"""

name: str
version: int | None
group: str | None
sub_group: str | None
description: str | None

@classmethod
def from_dict(cls, data: dict) -> PlanRegulationGroupLibraryMeta:
return cls(
name=data["name"],
version=data.get("version"),
group=data.get("group"),
sub_group=data.get("sub_group"),
description=data.get("description"),
)


@dataclass
class PlanRegulationGroupCategory:
category_code: str
name: str | None
plan_regulation_groups: list[PlanRegulationGroupDefinition]

@classmethod
def from_dict(cls, data: dict) -> PlanRegulationGroupCategory:
return cls(
category_code=data["category_code"],
name=data.get("name"),
plan_regulation_groups=[
PlanRegulationGroupDefinition.from_dict(group) for group in data["plan_regulation_groups"]
],
)


@dataclass
class PlanRegulationGroupDefinition:
"""Describes a plan regulation group"""

name: str
geometry: str
color_code: str | None
letter_code: str | None
plan_regulations: list[PlanRegulationDefinition]

@classmethod
def from_dict(cls, data: dict) -> PlanRegulationGroupDefinition:
regulations = []
for reg_data in data["plan_regulations"]:
reg_code = reg_data["regulation_code"]
config = PlanRegulationsSet.get_regulation_by_code(reg_code)
if config:
reg_data["config"] = config
regulations.append(PlanRegulationDefinition.from_dict(reg_data))
else:
iface.messageBar().pushWarning("", f"Could not find config for {reg_code} plan regulation!")
return cls(
name=data["name"],
geometry=data["geometry"],
color_code=data.get("color_code"),
letter_code=data.get("letter_code"),
plan_regulations=regulations,
)
6 changes: 3 additions & 3 deletions arho_feature_template/gui/new_plan_regulation_group_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from qgis.PyQt.QtWidgets import QDialog, QTreeWidget, QTreeWidgetItem

from arho_feature_template.core.plan_regulation_config import PlanRegulationConfig, PlanRegulationsSet
from arho_feature_template.gui.new_plan_regulation_widget import NewPlanRegulationWidget
from arho_feature_template.gui.plan_regulation_widget import PlanRegulationWidget

if TYPE_CHECKING:
from qgis.PyQt.QtWidgets import QBoxLayout, QWidget
Expand Down Expand Up @@ -57,11 +57,11 @@ def add_selected_plan_regulation(self, item: QTreeWidgetItem, column: int):
self.add_plan_regulation(config)

def add_plan_regulation(self, config: PlanRegulationConfig):
widget = NewPlanRegulationWidget(config=config, parent=self.plan_regulations_scroll_area_contents)
widget = PlanRegulationWidget(config=config, parent=self.plan_regulations_scroll_area_contents)
widget.delete_signal.connect(self.delete_plan_regulation)
index = self.plan_regulations_layout.count() - 1
self.plan_regulations_layout.insertWidget(index, widget)

def delete_plan_regulation(self, plan_regulation_widget: NewPlanRegulationWidget):
def delete_plan_regulation(self, plan_regulation_widget: PlanRegulationWidget):
self.plan_regulations_layout.removeWidget(plan_regulation_widget)
plan_regulation_widget.deleteLater()
Loading
Loading