diff --git a/arho_feature_template/core/plan_regulation_config.py b/arho_feature_template/core/plan_regulation_config.py index 61d391c..180c50a 100644 --- a/arho_feature_template/core/plan_regulation_config.py +++ b/arho_feature_template/core/plan_regulation_config.py @@ -17,6 +17,7 @@ from numbers import Number from typing import Literal + from qgis.core import QgsFeature from qgis.gui import QgisInterface iface: QgisInterface = cast("QgisInterface", iface) # type: ignore[no-redef] @@ -45,14 +46,14 @@ class ValueType(Enum): VERSIONED_TEXT = "kieliversioitu teksti" -class Unit(Enum): - SQUARE_METERS = "k-m2" - CUBIC_METERS = "m3" - EFFICIENCY_RATIO = "k-m2/m2" - PERCENTAGE = "prosentti" - AREA_RATIO = "m2/k-m2" - DEGREES = "°" - DECIBEL = "dB" +# class Unit(Enum): +# SQUARE_METERS = "k-m2" +# CUBIC_METERS = "m3" +# EFFICIENCY_RATIO = "k-m2/m2" +# PERCENTAGE = "prosentti" +# AREA_RATIO = "m2/k-m2" +# DEGREES = "°" +# DECIBEL = "dB" def get_name_mapping_for_plan_regulations(layer_name: str) -> dict[str, dict[str, str]] | None: @@ -68,7 +69,7 @@ class PlanRegulationsSet: version: str regulations: list[PlanRegulationConfig] - regulations_dict: dict[str, PlanRegulationConfig] = field(default_factory=dict) + regulations_dict: dict[str, PlanRegulationConfig] _instance: PlanRegulationsSet | None = None @@ -76,7 +77,7 @@ class PlanRegulationsSet: def get_instance(cls) -> PlanRegulationsSet: """Get the singleton instance, if initialized.""" if cls._instance is None: - raise UninitializedError + return cls.initialize() return cls._instance @classmethod @@ -101,71 +102,98 @@ def initialize( type_of_plan_regulations_layer_name="Kaavamääräyslaji", language: Literal["fin", "eng", "swe"] = "fin", ) -> PlanRegulationsSet: - # Initialize PlanRegulationsSet and PlanRegulationConfigs from config file - with config_path.open(encoding="utf-8") as f: - data = yaml.safe_load(f) - cls._instance = cls.from_dict(data) + # Initialize PlanRegulationsSet and PlanRegulationConfigs from QGIS layer and config file - regulations = cls.get_regulations() - regulations_dict: dict[str, PlanRegulationConfig] = {} - mapping = get_name_mapping_for_plan_regulations(type_of_plan_regulations_layer_name) + # 1. Read config file into a dict + with config_path.open(encoding="utf-8") as f: + config_data = yaml.safe_load(f) - # 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) + # 2. Read code layer + layer = get_layer_by_name(type_of_plan_regulations_layer_name) + if layer is None: + msg = f"Could not find layer {type_of_plan_regulations_layer_name}!" + raise KeyError(msg) - cls._instance.regulations_dict = regulations_dict - logger.info("PlanRegulationsSet initialized successfully.") - return cls._instance + # 3. Initialize regulation configs from layer. Storing them by their ID is handy for adding childs later + id_to_regulation_map: dict[str, PlanRegulationConfig] = { + feature["id"]: PlanRegulationConfig.from_feature(feature, language) for feature in layer.getFeatures() + } - @classmethod - def from_dict(cls, data: dict) -> PlanRegulationsSet: - file_version = data["version"] + # 4. Add information from config file (value, unit, category only) and link child regulations try: - return cls( - version=file_version, - regulations=[PlanRegulationConfig.from_dict(config) for config in data["plan_regulations"]], - ) + regulation_data: dict = {data["regulation_code"]: data for data in config_data["plan_regulations"]} + top_level_regulations: list[PlanRegulationConfig] = [] + for regulation_config in id_to_regulation_map.values(): + # Add possible information from config data file + data = regulation_data.get(regulation_config.regulation_code) + if data: + regulation_config.category_only = data.get("category_only", False) + regulation_config.value_type = ValueType(data["value_type"]) if "value_type" in data else None + regulation_config.unit = data["unit"] if "unit" in data else None + + # Top-level, add to list + if not regulation_config.parent_id: + top_level_regulations.append(regulation_config) + else: + # Add as child of another regulation + id_to_regulation_map[regulation_config.parent_id].child_regulations.append(regulation_config) except KeyError as e: raise ConfigSyntaxError(str(e)) from e + # 5. Create dictionary, useful when creating PlanRegulationDefinitions at least + regulations_dict: dict[str, PlanRegulationConfig] = {} + for reg in top_level_regulations: + reg.add_to_dictionary(regulations_dict) + + # 5. Create instance + cls._instance = cls( + version=config_data["version"], regulations=top_level_regulations, regulations_dict=regulations_dict + ) + logger.info("PlanRegulationsSet initialized successfully.") + return cls._instance + @dataclass class PlanRegulationConfig: - """Describes the configuration of a plan regulation.""" + """ + Describes the configuration of a plan regulation. + Combination of information read from code layer in QGIS / DB and other information + from a configuration file. + """ + + id: str regulation_code: str name: str - category_only: bool - value_type: ValueType | None - unit: Unit | None - child_regulations: list[PlanRegulationConfig] + description: str + status: str + level: int + parent_id: str | None + child_regulations: list[PlanRegulationConfig] = field(default_factory=list) + + category_only: bool = False + value_type: ValueType | None = None + unit: str | None = None @classmethod - def from_dict(cls, data: dict) -> PlanRegulationConfig: + def from_feature(cls, feature: QgsFeature, language: str = "fin") -> PlanRegulationConfig: """ - Initialize PlanRegulationConfig from dict. + Initialize PlanRegulationConfig from QgsFeature. - Intializes child regulations recursively. + Child regulations, value type ,category only and unit need to be set separately. """ return cls( - regulation_code=data["regulation_code"], - name=data["regulation_code"], - category_only=data.get("category_only", False), - value_type=ValueType(data["value_type"]) if "value_type" in data else None, - unit=Unit(data["unit"]) if "unit" in data else None, - child_regulations=[PlanRegulationConfig.from_dict(config) for config in data.get("child_regulations", [])], + id=feature["id"], + regulation_code=feature["value"], + name=feature["name"][language], + description=feature["description"][language], + status=feature["status"], + level=feature["level"], + parent_id=feature["parent_id"], ) - def add_name(self, code_to_name_mapping: dict[str, dict[str, str]], language: Literal["fin", "eng", "swe"]): - language_to_name_dict = code_to_name_mapping.get(self.regulation_code) - 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]): + """Add child regulations to dictionary too.""" dictionary[self.regulation_code] = self for regulation in self.child_regulations: regulation.add_to_dictionary(dictionary) diff --git a/arho_feature_template/gui/new_plan_regulation_group_form.py b/arho_feature_template/gui/new_plan_regulation_group_form.py index c6944dc..198e434 100644 --- a/arho_feature_template/gui/new_plan_regulation_group_form.py +++ b/arho_feature_template/gui/new_plan_regulation_group_form.py @@ -5,7 +5,7 @@ from qgis.PyQt import uic from qgis.PyQt.QtCore import Qt -from qgis.PyQt.QtWidgets import QDialog, QTreeWidget, QTreeWidgetItem +from qgis.PyQt.QtWidgets import QDialog, QTextBrowser, QTreeWidget, QTreeWidgetItem from arho_feature_template.core.plan_regulation_config import PlanRegulationConfig, PlanRegulationsSet from arho_feature_template.gui.plan_regulation_widget import PlanRegulationWidget @@ -28,10 +28,12 @@ def __init__(self): self.plan_regulations_view: QTreeWidget self.plan_regulations_scroll_area_contents: QWidget self.plan_regulations_layout: QBoxLayout + self.plan_regulation_info: QTextBrowser # INIT self.initialize_plan_regulations() self.plan_regulations_view.itemDoubleClicked.connect(self.add_selected_plan_regulation) + self.plan_regulations_view.itemClicked.connect(self.update_selected_plan_regulation) def _initalize_regulation_from_config(self, config: PlanRegulationConfig, parent: QTreeWidgetItem | None = None): tree_item = QTreeWidgetItem(parent) @@ -50,6 +52,10 @@ def initialize_plan_regulations(self): for config in PlanRegulationsSet.get_regulations(): self._initalize_regulation_from_config(config) + def update_selected_plan_regulation(self, item: QTreeWidgetItem, column: int): + config: PlanRegulationConfig = item.data(column, Qt.UserRole) # Retrieve the associated config + self.plan_regulation_info.setText(config.description) + def add_selected_plan_regulation(self, item: QTreeWidgetItem, column: int): config: PlanRegulationConfig = item.data(column, Qt.UserRole) # Retrieve the associated config if config.category_only: diff --git a/arho_feature_template/gui/new_plan_regulation_group_form.ui b/arho_feature_template/gui/new_plan_regulation_group_form.ui index be0fe71..5f72118 100644 --- a/arho_feature_template/gui/new_plan_regulation_group_form.ui +++ b/arho_feature_template/gui/new_plan_regulation_group_form.ui @@ -147,7 +147,7 @@ - + 0 @@ -159,9 +159,8 @@ <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">ESIMERKKI</span>: Ilmaisee, että kaavakohde kuvaa asumisen rakennuksille tai asunnoille tarkoitetun alueen. Käytetään asemakaavoissa ilmaisemaan asuinrakennusten alueita, joille voidaan rakentaa eri tyyppisiä asuinrakennuksia. Maakunta- ja yleiskaavoissa käytetään ilmaisemaan asuntoalueita, jolla kerrosalasta pääosa on tarkoitettu asumiseen. Koodi liittyy lähtökohtaisesti kaavakohteeseen, joka on geometrialtaan alue.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Kaavamääräyksen lyhyt nimi: A (AK ja YK) &amp; AA (MK)</p></body></html> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> diff --git a/arho_feature_template/gui/plan_regulation_widget.py b/arho_feature_template/gui/plan_regulation_widget.py index 0cc8431..0c11aa5 100644 --- a/arho_feature_template/gui/plan_regulation_widget.py +++ b/arho_feature_template/gui/plan_regulation_widget.py @@ -19,7 +19,7 @@ QWidget, ) -from arho_feature_template.core.plan_regulation_config import PlanRegulationConfig, Unit, ValueType +from arho_feature_template.core.plan_regulation_config import PlanRegulationConfig, ValueType from arho_feature_template.utils.misc_utils import get_additional_information_name, get_layer_by_name if TYPE_CHECKING: @@ -116,7 +116,7 @@ def _check_number_or_none(value: str | Number | None, error_msg: str): raise ValueError(error_msg) def _add_value_input( - self, value_type: ValueType, unit: Unit | None, default_value: str | Number | list[int] | None = None + self, value_type: ValueType, unit: str | None, default_value: str | Number | list[int] | None = None ): base_error_msg = f"Invalid type for default value {type(default_value)}." if value_type in [ValueType.DECIMAL, ValueType.POSITIVE_DECIMAL]: @@ -214,7 +214,7 @@ def _add_widgets_to_form(self, label: QLabel, widget: QWidget): if not self.expanded: self._on_expand_hide_btn_clicked() - def add_decimal_input(self, value_type: ValueType, unit: Unit | None, default_value: Number | None = None): + def add_decimal_input(self, value_type: ValueType, unit: str | None, default_value: Number | None = None): value_widget = QgsDoubleSpinBox() label = QLabel("Arvo") if value_type == ValueType.POSITIVE_DECIMAL: @@ -225,24 +225,24 @@ def add_decimal_input(self, value_type: ValueType, unit: Unit | None, default_va label.setToolTip("Tyyppi: desimaali") value_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) if unit: - value_widget.setSuffix(f" {unit.value}") + value_widget.setSuffix(f" {unit}") if default_value: value_widget.setValue(default_value) self._add_widgets_to_form(label, value_widget) - def add_positive_integer_input(self, unit: Unit | None, default_value: int | None = None): + def add_positive_integer_input(self, unit: str | None, default_value: int | None = None): value_widget = QgsSpinBox() value_widget.setMinimum(0) value_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) if unit: - value_widget.setSuffix(f" {unit.value}") + value_widget.setSuffix(f" {unit}") label = QLabel("Arvo") label.setToolTip("Tyyppi: kokonaisluku (positiivinen)") if default_value: value_widget.setValue(default_value) self._add_widgets_to_form(label, value_widget) - def add_positive_integer_range_input(self, unit: Unit | None, default_values: list[int] | None = None): + def add_positive_integer_range_input(self, unit: str | None, default_values: list[int] | None = None): min_widget = QgsSpinBox() min_widget.setMinimum(0) min_label = QLabel("Arvo minimi") @@ -253,8 +253,8 @@ def add_positive_integer_range_input(self, unit: Unit | None, default_values: li max_label = QLabel("Arvo maksimi") max_label.setToolTip("Tyyppi: kokonaisluku arvoväli (positiivinen)") if unit: - min_widget.setSuffix(f" {unit.value}") - max_widget.setSuffix(f" {unit.value}") + min_widget.setSuffix(f" {unit}") + max_widget.setSuffix(f" {unit}") if default_values: min_widget.setValue(default_values[0]) max_widget.setValue(default_values[1]) diff --git a/arho_feature_template/plugin.py b/arho_feature_template/plugin.py index ce3e75f..eb85359 100644 --- a/arho_feature_template/plugin.py +++ b/arho_feature_template/plugin.py @@ -9,7 +9,6 @@ from arho_feature_template.core.feature_template_library import FeatureTemplater, TemplateGeometryDigitizeMapTool from arho_feature_template.core.plan_manager import PlanManager -from arho_feature_template.core.plan_regulation_config import PlanRegulationsSet from arho_feature_template.gui.new_plan_regulation_group_form import NewPlanRegulationGroupForm from arho_feature_template.gui.plugin_settings import PluginSettings from arho_feature_template.qgis_plugin_tools.tools.custom_logging import setup_logger, teardown_logger @@ -44,9 +43,6 @@ def __init__(self) -> None: self.actions: list[QAction] = [] self.menu = Plugin.name - # Initialize plan regulations set - PlanRegulationsSet.initialize() - def add_action( self, icon_path: str, diff --git a/arho_feature_template/resources/kaavamaaraykset.yaml b/arho_feature_template/resources/kaavamaaraykset.yaml index 40e43b4..9fbd9b8 100644 --- a/arho_feature_template/resources/kaavamaaraykset.yaml +++ b/arho_feature_template/resources/kaavamaaraykset.yaml @@ -1,233 +1,225 @@ version: 1 plan_regulations: -# ASUMISEN ALUE (valmis?) - - regulation_code: asumisenAlue - child_regulations: - - regulation_code: asuinpientaloalue - child_regulations: + # Asumisen alue (valmis) - - regulation_code: erillistenAsuinpientalojenAlue + # Taajamatoiminnan alue (valmis) - - regulation_code: rivitalojenJaMuidenKytkettyjenAsuinpientalojenAlue + # Työpaikkojen alue (valmis) - - regulation_code: asuinkerrostaloalue + # Vapa-ajan asumisen ja matkailun alue (valmis) - - regulation_code: asumistaPalvelevaYhteiskayttoinenAlue - - - regulation_code: maatilanTalouskeskuksenAlue - - - regulation_code: kylaAlue - -# TYÖPAIKKOJEN ALUE (valmis?) - - regulation_code: tyopaikkojenAlue - child_regulations: - - - regulation_code: toimitilojenAlue - child_regulations: + # Viheralue (valmis) + - regulation_code: viheralue + category_only: true - - regulation_code: toimistorakennustenAlue + - regulation_code: vihertehokkuus + value_type: positiivinen desimaali + unit: m2/m2 - - regulation_code: palvelujenAlue - child_regulations: + # Maa- ja metsätalousalue (valmis) - - regulation_code: liikerakennustenAlue - child_regulations: + # Erityisalue (valmis) + - regulation_code: ymparistohairionTorjunnanRakenne + category_only: true - - regulation_code: myymalarakennustenAlue - child_regulations: + # Liikennealue (valmis) + - regulation_code: terminaalialue + category_only: true - - regulation_code: vahittaiskaupanSuuryksikkö + - regulation_code: vesiliikenteenAlue + category_only: true - - regulation_code: vahittaiskaupanMyymalakeskittyma + - regulation_code: vesivayla + category_only: true - - regulation_code: huviJaViihdeRakennustenAlue + # Vesialue (valmis) - - regulation_code: yleistenRakennustenAlue - child_regulations: + # Ympäristöarvojen alue (valmis) + - regulation_code: ymparistoarvojenAlue + category_only: true - - regulation_code: hoitoalanRakennustenAlue + - regulation_code: luontoarvoiltaanArvokasAlue + category_only: true - - regulation_code: museorakennustenAlue + - regulation_code: kulttuuriymparistoarvojenAlue + category_only: true - - regulation_code: urheiluJaLiikuntaRakennustenAlue + # Ympäristöhäiriöalue (valmis) - - regulation_code: kulttuurirakennustenAlue + # Kunnan tai kaupungin osa (valmis) - - regulation_code: uskonnollistenYhteisojenRakennustenAlue + # Korttelialue tai korttelialueen osa (valmis) - - regulation_code: opetusrakennustenAlue + # Rakennuspaikka (valmis) - - regulation_code: teollisuusalue + # Rakennusala (valmis) - - regulation_code: varastoalue + # Alue, jota koskee kehittämisperiaate (valmis) + - regulation_code: alueJotaKoskeeKehittamisperiaate + category_only: true -# VAPAA-AJAN ASUMISEN JA MATKAILUN ALUE (valmis?) + # Kehittämisalue (valmis) - - regulation_code: vapaaAjanAsumisenJaMatkailunAlue - child_regulatons: + # Suunnittelutarvealue (valmis) - - regulation_code: vapaaAjanAsumisenJaMatkailunAlue + # Nimistö (valmis) + - regulation_code: nimisto + category_only: true - - regulation_code: matkailupalvelujenAlue + - regulation_code: kadunTaiTienNimi + value_type: kieliversioitu teksti - - regulation_code: leirintaAlue + - regulation_code: torinTaiKatuaukionNimi + value_type: kieliversioitu teksti - - regulation_code: asuntovaunualue + - regulation_code: puistonTaiMuunYleisenAlueenNimi + value_type: kieliversioitu teksti - - regulation_code: siirtolapuutarhaAlue + - regulation_code: kaupunginTaiKunnanosanNimi + value_type: kieliversioitu teksti - - regulation_code: palstaviljelyalue + # Aluetunnukset (valmis) + - regulation_code: aluetunnukset + category_only: true -# TAAJAMATOIMIEN ALUE (valmis?) - - regulation_code: taajamatoimintojenAlue - child_regulations: + - regulation_code: korttelinNumero + value_type: positiivinen kokonaisluku - - regulation_code: keskustatoimintojenAlue - child_regulations: + - regulation_code: tontinTaiRakennuspaikanNumero + value_type: positiivinen kokonaisluku - - regulation_code: keskustatoimintojenAlakeskus + - regulation_code: kaupunginTaiKunnanosanNumero + value_type: positiivinen kokonaisluku -# VIHERALUE (kesken) - - regulation_code: viheralue + # Rakentamisen määrä (valmis) + - regulation_code: rakentamisenMaara category_only: true - child_regulations: - - regulation_code: virkistysalue - child_regulations: + - regulation_code: sallittuKerrosala + value_type: positiivinen kokonaisluku + unit: k-m2 - - regulation_code: uimaranta + - regulation_code: sallittuRakennustilavuus + value_type: positiivinen kokonaisluku + unit: m3 - - regulation_code: puisto + - regulation_code: tehokkuusluku + value_type: positiivinen desimaali + unit: k-m2/m2 - - regulation_code: leikkipuisto + - regulation_code: rakentamisenSuhdeAlueenPintaAlaan + value_type: positiivinen kokonaisluku + unit: prosentti -# MAATALOUSALUE (kesken) - - regulation_code: maaJaMetsatalousAlue - child_regulations: + - regulation_code: valjyysluku + value_type: positiivinen desimaali + unit: m2/k-m2 - - regulation_code: maatalousalue - child_regulations: + - regulation_code: maanpaallinenKerroslukuLuku + value_type: positiivinen kokonaisluku - - regulation_code: pelto + - regulation_code: maanpaallinenKerroslukuArvovali + value_type: positiivinen kokonaisluku arvoväli -# VESIALUE (valmis?) - - regulation_code: vesialue - child_regulations: + - regulation_code: maanalainenKerroslukuLuku + value_type: positiivinen kokonaisluku - - regulation_code: pohjavesialue - -# YMPÄRISTÖARVOJEN ALUE (kesken) - - regulation_code: ymparistoarvojenAlue - category_only: true - child_regulations: + - regulation_code: maanalainenKerroslukuArvovali + value_type: positiivinen kokonaisluku arvoväli - - regulation_code: kulttuuriymparistoarvojenAlue - child_regulations: + - regulation_code: kellarinSallittuOsuusKerrosalasta + value_type: positiivinen kokonaisluku + unit: prosentti - - regulation_code: merkittavaRakennettuKulttuuriymparisto + - regulation_code: ullakonSallittuOsuusKerrosalasta + value_type: positiivinen kokonaisluku + unit: prosentti - - regulation_code: maisemallisestiArvokasAlue + - regulation_code: asuntojenMaara + value_type: positiivinen kokonaisluku -# RAKENNUSALA (kesken) - - regulation_code: rakennusala - child_regulations: + - regulation_code: rakennuspaikkojenMaara + value_type: positiivinen kokonaisluku - - regulation_code: rakennusalaJolleSaaSijoittaaSaunan + - regulation_code: tuulivoimaloidenMaara + value_type: positiivinen kokonaisluku -# RAKENTAMISEN MÄÄRÄ (valmis?) - - regulation_code: rakentamisenMaara + # Korkeusasema (valmis) + - regulation_code: korkeusasema category_only: true - child_regulations: - - - regulation_code: sallittuKerrosala - value_type: positiivinen kokonaisluku - unit: k-m2 - - - regulation_code: sallittuRakennustilavuus - value_type: positiivinen kokonaisluku - unit: m3 - - - regulation_code: tehokkuusluku - value_type: positiivinen desimaali - unit: k-m2/m2 - child_regulations: - - regulation_code: rakentamisenSuhdeAlueenPintaAlaan - value_type: positiivinen kokonaisluku - unit: prosentti + - regulation_code: maanpinnanKorkeusasema + value_type: desimaali + unit: m - - regulation_code: valjyysluku - value_type: positiivinen desimaali - unit: m2/k-m2 + - regulation_code: vesikatonYlimmanKohdanKorkeusasema + value_type: desimaali + unit: m - - regulation_code: maanpaallinenKerroslukuLuku - value_type: positiivinen kokonaisluku + - regulation_code: julkisivupinnanJaVesikatonLeikkauskohdanKorkeusasema + value_type: desimaali + unit: m - - regulation_code: maanpaallinenKerroslukuArvovali - value_type: positiivinen kokonaisluku arvoväli + - regulation_code: julkisivunEnimmaiskorkeus + value_type: desimaali + unit: m - - regulation_code: maanalainenKerroslukuLuku - value_type: positiivinen kokonaisluku + - regulation_code: rakennustenRakenteidenJaLaitteidenYlinKorkeusasema + value_type: desimaali + unit: m - - regulation_code: maanalainenKerroslukuArvovali - value_type: positiivinen kokonaisluku arvoväli + - regulation_code: alinPainovoimainenViemarointitaso + value_type: desimaali + unit: m - - regulation_code: kellarinSallittuOsuusKerrosalasta - value_type: positiivinen kokonaisluku - unit: prosentti + - regulation_code: rakennustenRakenteidenJaLaitteidenAlinKorkeusasema + value_type: desimaali + unit: m - - regulation_code: ullakonSallittuOsuusKerrosalasta - value_type: positiivinen kokonaisluku - unit: prosentti + - regulation_code: tuulivoimalanEnimmaiskorkeus + value_type: positiivinen kokonaisluku + unit: m - - regulation_code: asuntojenMaara - value_type: positiivinen kokonaisluku - - - regulation_code: rakennuspaikkojenMaara - value_type: positiivinen kokonaisluku - - - regulation_code: tuulivoimaloidenMaara - value_type: positiivinen kokonaisluku - -# RAKENTAMISEN TAPA + # Rakentamisen tapa (valmis) - regulation_code: rakentamisenTapa category_only: true - child_regulations: - - regulation_code: kattokaltevuus - value_type: desimaali - unit: ° + - regulation_code: kattokaltevuus + value_type: desimaali + unit: ° - - regulation_code: aaneneristavyys - value_type: positiivinen desimaali - unit: dB + - regulation_code: aaneneristavyys + value_type: positiivinen desimaali + unit: dB -# SANALLINEN MÄÄRÄYS (valmis?) - - regulation_code: sanallinenMaarays - value_type: kieliversioitu teksti - child_regulations: + # Liikenteen suureet (valmis) + - regulation_code: liikenteenSuureet + category_only: true - - regulation_code: rakentamisrajoitusYleiskaava - value_type: kieliversioitu teksti + - regulation_code: pysakoinninMaara + category_only: true - - regulation_code: rakentamisrajoitusMaakuntakaava - value_type: kieliversioitu teksti + - regulation_code: autopaikkojenMaara + value_type: positiivinen kokonaisluku - - regulation_code: maaraAikainenRakentamisrajoitus - value_type: kieliversioitu teksti + - regulation_code: autopaikkojenMaaraAsuntoaKohden + value_type: positiivinen desimaali - - regulation_code: toimenpiderajoitus - value_type: kieliversioitu teksti + - regulation_code: kerrosneliomaaraYhtaAutopaikkaaKohden + value_type: positiivinen kokonaisluku + unit: k-m2 - - regulation_code: maaraAikainenKieltoRakennuksenRakentamiseksi - value_type: kieliversioitu teksti + - regulation_code: pyorapaikkojenMaara + value_type: positiivinen kokonaisluku - - regulation_code: suunnittelumaarays - value_type: kieliversioitu teksti + - regulation_code: pyorapaikkojenMaaraAsuntoaKohden + value_type: positiivinen desimaali - - regulation_code: rakentamismaarays - value_type: kieliversioitu teksti + - regulation_code: kerrosneliomaaraYhtaPyorapaikkaaKohden + value_type: positiivinen kokonaisluku + unit: k-m2 - - regulation_code: suojelumaarays - value_type: kieliversioitu teksti + # Sanallinen määräys + - regulation_code: sanallinenMaarays + value_type: kieliversioitu teksti