diff --git a/README.md b/README.md
index 6224972..75c0077 100644
--- a/README.md
+++ b/README.md
@@ -61,3 +61,7 @@ the one with the path `.venv\Scripts\python.exe`.
 This plugin is distributed under the terms of the [GNU General Public License, version 2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) license.
 
 See [LICENSE](LICENSE) for more information.
+
+### Attributations
+<a href="https://www.flaticon.com/free-icons/open" title="open icons">Open icons created by Smashicons - Flaticon</a>
+<a href="https://www.flaticon.com/free-icons/land-use" title="land use icons">Land use icons created by Fusion5085 - Flaticon</a>
diff --git a/arho_feature_template/core/new_plan.py b/arho_feature_template/core/new_plan.py
new file mode 100644
index 0000000..97dd5ee
--- /dev/null
+++ b/arho_feature_template/core/new_plan.py
@@ -0,0 +1,63 @@
+from qgis.core import QgsProject, QgsVectorLayer
+from qgis.utils import iface
+
+from arho_feature_template.core.update_plan import LandUsePlan, update_selected_plan
+
+
+class NewPlan:
+    def add_new_plan(self):
+        # Filtered layers are not editable, so clear filters first.
+        self.clear_all_filters()
+
+        layers = QgsProject.instance().mapLayersByName("Kaava")
+        if not layers:
+            iface.messageBar().pushMessage("Error", "Layer 'Kaava' not found", level=3)
+            return
+
+        kaava_layer = layers[0]
+
+        if not kaava_layer.isEditable():
+            kaava_layer.startEditing()
+
+        iface.setActiveLayer(kaava_layer)
+
+        iface.actionAddFeature().trigger()
+
+        # Connect the featureAdded signal
+        kaava_layer.featureAdded.connect(self.feature_added)
+
+    def feature_added(self):
+        kaava_layer = iface.activeLayer()
+        kaava_layer.featureAdded.disconnect()
+        feature_ids_before_commit = kaava_layer.allFeatureIds()
+        if kaava_layer.isEditable():
+            if not kaava_layer.commitChanges():
+                iface.messageBar().pushMessage("Error", "Failed to commit changes to the layer.", level=3)
+                return
+        else:
+            iface.messageBar().pushMessage("Error", "Layer is not editable.", level=3)
+            return
+
+        feature_ids_after_commit = kaava_layer.allFeatureIds()
+
+        # Find the new plan.id by comparing fids before and after commit.
+        new_feature_id = next((fid for fid in feature_ids_after_commit if fid not in feature_ids_before_commit), None)
+
+        if new_feature_id is not None:
+            new_feature = kaava_layer.getFeature(new_feature_id)
+
+            if new_feature.isValid():
+                feature_id_value = new_feature["id"]
+                update_selected_plan(LandUsePlan(feature_id_value))
+            else:
+                iface.messageBar().pushMessage("Error", "Invalid feature retrieved.", level=3)
+        else:
+            iface.messageBar().pushMessage("Error", "No new feature was added.", level=3)
+
+    def clear_all_filters(self):
+        """Clear filters for all vector layers in the project."""
+        layers = QgsProject.instance().mapLayers().values()
+
+        for layer in layers:
+            if isinstance(layer, QgsVectorLayer):
+                layer.setSubsetString("")
diff --git a/arho_feature_template/core/update_plan.py b/arho_feature_template/core/update_plan.py
new file mode 100644
index 0000000..d083090
--- /dev/null
+++ b/arho_feature_template/core/update_plan.py
@@ -0,0 +1,62 @@
+from dataclasses import dataclass
+
+from qgis.core import QgsMapLayer, QgsProject, QgsVectorLayer
+from qgis.utils import iface
+
+
+# To be extended and moved
+@dataclass
+class LandUsePlan:
+    id: str
+
+
+# To be replaced later
+LAYER_PLAN_ID_MAP = {
+    "Kaava": "id",
+    "Maankäytön kohteet": "plan_id",
+    "Muut pisteet": "plan_id",
+    "Viivat": "plan_id",
+    "Aluevaraus": "plan_id",
+    "Osa-alue": "plan_id",
+}
+
+
+def update_selected_plan(new_plan: LandUsePlan):
+    """Update the project layers based on the selected land use plan."""
+    plan_id = new_plan.id
+
+    for layer_name, field_name in LAYER_PLAN_ID_MAP.items():
+        # Set the filter on each layer using the plan_id
+        set_filter_for_vector_layer(layer_name, field_name, plan_id)
+
+
+def set_filter_for_vector_layer(layer_name: str, field_name: str, field_value: str):
+    """Set a filter for the given vector layer."""
+    layers = QgsProject.instance().mapLayersByName(layer_name)
+
+    if not _check_layer_count(layers):
+        return
+
+    layer = layers[0]
+
+    expression = f"\"{field_name}\" = '{field_value}'"
+
+    # Apply the filter to the layer
+    if not layer.setSubsetString(expression):
+        iface.messageBar().pushMessage("Error", f"Failed to filter layer {layer_name} with query {expression}", level=3)
+
+
+def _check_layer_count(layers: list) -> bool:
+    """Check if any layers are returned."""
+    if not layers:
+        iface.messageBar().pushMessage("Error", "ERROR: No layers found with the specified name.", level=3)
+        return False
+    return True
+
+
+def _check_vector_layer(layer: QgsMapLayer) -> bool:
+    """Check if the given layer is a vector layer."""
+    if not isinstance(layer, QgsVectorLayer):
+        iface.messageBar().pushMessage("Error", f"Layer {layer.name()} is not a vector layer: {type(layer)}", level=3)
+        return False
+    return True
diff --git a/arho_feature_template/plugin.py b/arho_feature_template/plugin.py
index f06d83c..e60d754 100644
--- a/arho_feature_template/plugin.py
+++ b/arho_feature_template/plugin.py
@@ -1,5 +1,6 @@
 from __future__ import annotations
 
+import os
 from typing import TYPE_CHECKING, Callable, cast
 
 from qgis.PyQt.QtCore import QCoreApplication, Qt, QTranslator
@@ -8,9 +9,11 @@
 from qgis.utils import iface
 
 from arho_feature_template.core.feature_template_library import FeatureTemplater, TemplateGeometryDigitizeMapTool
+from arho_feature_template.core.new_plan import NewPlan
 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.utils.misc_utils import PLUGIN_PATH
 
 if TYPE_CHECKING:
     from qgis.gui import QgisInterface, QgsMapTool
@@ -25,6 +28,7 @@ class Plugin:
 
     def __init__(self) -> None:
         setup_logger(Plugin.name)
+        self.digitizing_tool = None
 
         # initialize locale
         locale, file_path = setup_translation()
@@ -120,6 +124,10 @@ def add_action(
 
     def initGui(self) -> None:  # noqa N802
         self.templater = FeatureTemplater()
+        self.new_plan = NewPlan()
+
+        plan_icon_path = os.path.join(PLUGIN_PATH, "resources/icons/city.png")  # A placeholder icon
+        load_icon_path = os.path.join(PLUGIN_PATH, "resources/icons/folder.png")  # A placeholder icon
 
         iface.addDockWidget(Qt.RightDockWidgetArea, self.templater.template_dock)
         self.templater.template_dock.visibilityChanged.connect(self.dock_visibility_changed)
@@ -136,10 +144,33 @@ def initGui(self) -> None:  # noqa N802
             add_to_toolbar=True,
         )
 
+        self.new_land_use_plan_action = self.add_action(
+            plan_icon_path,
+            "Create New Plan",
+            self.digitize_new_plan,
+            add_to_menu=True,
+            add_to_toolbar=True,
+            status_tip="Create a new plan",
+        )
+
+        self.load_land_use_plan_action = self.add_action(
+            load_icon_path,
+            text="Load existing land use plan",
+            triggered_callback=self.load_existing_land_use_plan,
+            parent=iface.mainWindow(),
+            add_to_toolbar=True,
+        )
+
     def on_map_tool_changed(self, new_tool: QgsMapTool, old_tool: QgsMapTool) -> None:  # noqa: ARG002
         if not isinstance(new_tool, TemplateGeometryDigitizeMapTool):
             self.template_dock_action.setChecked(False)
 
+    def digitize_new_plan(self):
+        self.new_plan.add_new_plan()
+
+    def load_existing_land_use_plan(self) -> None:
+        """Open existing land use plan."""
+
     def unload(self) -> None:
         """Removes the plugin menu item and icon from QGIS GUI."""
         for action in self.actions:
diff --git a/arho_feature_template/resources/icons/city.png b/arho_feature_template/resources/icons/city.png
new file mode 100644
index 0000000..ed82aaf
Binary files /dev/null and b/arho_feature_template/resources/icons/city.png differ
diff --git a/arho_feature_template/resources/icons/folder.png b/arho_feature_template/resources/icons/folder.png
new file mode 100644
index 0000000..9eb2915
Binary files /dev/null and b/arho_feature_template/resources/icons/folder.png differ
diff --git a/arho_feature_template/resources/template_libraries/asemakaava-sample.yaml b/arho_feature_template/resources/template_libraries/asemakaava-sample.yaml
index 00cdae8..b7901f8 100644
--- a/arho_feature_template/resources/template_libraries/asemakaava-sample.yaml
+++ b/arho_feature_template/resources/template_libraries/asemakaava-sample.yaml
@@ -7,6 +7,7 @@ templates:
     description: Kaavakohde ilman kikkareita
     feature:
       layer: land_use_area
+      # layer: Aluevaraus
       attributes:
         - attribute: name
         - attribute: type_of_underground_id
@@ -15,6 +16,7 @@ templates:
     description: Aluella kuvataan ...
     feature:
       layer: land_use_area
+      # layer: Aluevaraus
       attributes:
         - attribute: name
         - attribute: type_of_underground_id
diff --git a/arho_feature_template/utils/__init__.py b/arho_feature_template/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/arho_feature_template/utils/misc_utils.py b/arho_feature_template/utils/misc_utils.py
new file mode 100644
index 0000000..42f38d6
--- /dev/null
+++ b/arho_feature_template/utils/misc_utils.py
@@ -0,0 +1,3 @@
+import os
+
+PLUGIN_PATH = os.path.dirname(os.path.dirname(__file__))