Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/test_serialize_surface_line.xml
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/tests/test_data/test_serialize_surface_line.xml (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/tests/test_data/test_serialize_surface_line.xml (revision 3474)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
Index: DamClients/DamPythonInterface/trunk/src/tests/test_surface_line.py
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/tests/test_surface_line.py (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/tests/test_surface_line.py (revision 3474)
@@ -0,0 +1,149 @@
+from typing import List
+from dampythoninterface.surface_line import Point, PointTypeEnum, SurfaceLine
+from .utils import TestUtils
+
+import pytest
+from pathlib import Path
+from lxml import etree
+
+
+class TestSurfaceLine:
+ @pytest.mark.unittest
+ def test_surface_line_error_raised(self):
+ # set up test data
+ list_points = [
+ Point(X=i, Z=2 * i, PointType=PointTypeEnum.NONE) for i in range(10)
+ ]
+ # run test
+ expected_mssg = "Set Characteristic points Test surface line is not complete."
+ with pytest.raises(ValueError, match=expected_mssg):
+ SurfaceLine(Points=list_points, Name="Test surface line")
+
+ @pytest.mark.unittest
+ @pytest.mark.parametrize(
+ "points_available, error_message",
+ [
+ (
+ [
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ],
+ "SurfaceLevelOutside",
+ ),
+ (
+ [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ],
+ "DikeToeAtRiver",
+ ),
+ (
+ [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ],
+ "DikeTopAtRiver",
+ ),
+ (
+ [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ],
+ "DikeTopAtPolder",
+ ),
+ (
+ [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ],
+ "DikeToeAtPolder",
+ ),
+ (
+ [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ ],
+ "SurfaceLevelInside",
+ ),
+ ],
+ )
+ def test_surface_line_error_raised_per_point(
+ self, points_available: List, error_message: str
+ ):
+ list_of_points = [
+ Point(X=1, Z=2, PointType=point_type) for point_type in points_available
+ ]
+ with pytest.raises(ValueError) as e_info:
+ SurfaceLine(Points=list_of_points, Name="Test surface line")
+ generated_error_message = str(e_info.value)
+ assert error_message in generated_error_message
+
+ @pytest.mark.unittest
+ def test_create_surface_line(self):
+ points_available = [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ]
+ list_of_points = [
+ Point(X=1 * counter, Z=2 * counter, PointType=point_type)
+ for counter, point_type in enumerate(points_available)
+ ]
+ surfaceline = SurfaceLine(Points=list_of_points, Name="Test surface line")
+ assert surfaceline.Name == "Test surface line"
+
+ @pytest.mark.integrationtest
+ def test_serialize_surface_line(self):
+ # Initialize class to be tested
+ points_available = [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ]
+ list_of_points = [
+ Point(X=1 * counter, Z=2 * counter, PointType=point_type)
+ for counter, point_type in enumerate(points_available)
+ ]
+ surfaceline = SurfaceLine(Points=list_of_points, Name="Test surface line")
+ # check initial expectations
+ assert surfaceline.Name == "Test surface line"
+ # run test
+ root = surfaceline.serialize()
+ # test output
+ xml_output = Path(
+ TestUtils.get_output_test_data_dir(""), "test_serialize_surface_line.xml"
+ )
+ tree = etree.ElementTree(root)
+ tree.write(str(xml_output), pretty_print=True)
+ # get template file
+ xml_test_data = Path(
+ TestUtils.get_test_data_dir("", "test_data"),
+ "test_serialize_surface_line.xml",
+ )
+ # Line by line comparison
+ for output_file, test_file in zip(open(xml_output), open(xml_test_data)):
+ assert output_file.strip() == test_file.strip()
Index: DamClients/DamPythonInterface/trunk/src/tests/test_input.py
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/tests/test_input.py (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/tests/test_input.py (revision 3474)
@@ -0,0 +1,41 @@
+import pytest
+from pathlib import Path
+from lxml import etree
+
+from dampythoninterface.input import DamInput
+from dampythoninterface.surface_line import SurfaceLine, PointTypeEnum, Point
+from .utils import TestUtils
+
+
+class TestDamInput:
+ @pytest.mark.integrationtest
+ def test_ExportToXml(self):
+ # Create surface lines
+ points_available = [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ]
+ list_of_points = [
+ Point(X=1 * counter, Z=2 * counter, PointType=point_type)
+ for counter, point_type in enumerate(points_available)
+ ]
+ surfaceline_1 = SurfaceLine(Points=list_of_points, Name="Surface line 1")
+ surfaceline_2 = SurfaceLine(Points=list_of_points, Name="Surface line 2")
+ # check initial expectations
+ assert surfaceline_1.Name == "Surface line 1"
+ assert surfaceline_2.Name == "Surface line 2"
+ list_of_surface_lines = [surfaceline_1, surfaceline_2]
+ # Make input class
+ model = DamInput(SurfaceLines=list_of_surface_lines)
+ assert model
+ # run test
+ xml_output = Path(
+ TestUtils.get_output_test_data_dir(""), "test_full_output.xml"
+ )
+ model.ExportToXml(xml_file=xml_output)
+ # test if file was created
+ assert xml_output.is_file()
Index: DamClients/DamPythonInterface/trunk/src/tests/test_output/test_full_output.xml
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/tests/test_output/test_full_output.xml (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/tests/test_output/test_full_output.xml (revision 3474)
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: DamClients/DamPythonInterface/trunk/src/dampythoninterface/surface_line.py
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/dampythoninterface/surface_line.py (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/dampythoninterface/surface_line.py (revision 3474)
@@ -0,0 +1,96 @@
+from .base_class import BaseDataClass
+
+from typing import List
+from enum import IntEnum
+from pydantic import root_validator
+import lxml.etree as et
+
+
+class PointTypeEnum(IntEnum):
+ NONE = 1
+ SurfaceLevelOutside = 2
+ DikeToeAtRiver = 3
+ ShoulderTopOutside = 4
+ ShoulderBaseOutside = 5
+ DikeTopAtRiver = 6
+ DikeLine = 7
+ TrafficLoadOutside = 8
+ TrafficLoadInside = 9
+ DikeTopAtPolder = 10
+ ShoulderBaseInside = 11
+ ShoulderTopInside = 12
+ DikeToeAtPolder = 13
+ DitchDikeSide = 14
+ BottomDitchDikeSide = 15
+ BottomDitchPolderSide = 16
+ DitchPolderSide = 17
+ SurfaceLevelInside = 18
+
+
+class Point(BaseDataClass):
+ X: float
+ Z: float
+ PointType: PointTypeEnum
+
+
+class SurfaceLine(BaseDataClass):
+ Name: str
+ Points: List[Point] = []
+
+ @staticmethod
+ def is_type_in_list(list_of_points: Point, required_point_type: Point) -> bool:
+ for point in list_of_points:
+ if point.PointType == required_point_type:
+ return True
+ return False
+
+ @staticmethod
+ def raise_error_if_point_does_not_exist(
+ list_of_points: Point,
+ name: str,
+ required_point_type: Point,
+ ) -> None:
+
+ if not (SurfaceLine.is_type_in_list(list_of_points, required_point_type)):
+ raise ValueError(
+ f"Set Characteristic points {name} is not complete. \
+ Characteristic point {required_point_type.name} is missing."
+ )
+
+ @root_validator
+ def check_that_necessary_points_exist(cls, values):
+ """
+ Property validator of Points of the SurfaceLine class.
+ Required characteristic points are:
+ * Surface level outside
+ * Dike toe at river
+ * Dike top at river
+ * Dike top at polder
+ * Dike toe at polder
+ * Surface level inside
+ """
+ required_points = [
+ PointTypeEnum.SurfaceLevelOutside,
+ PointTypeEnum.DikeToeAtRiver,
+ PointTypeEnum.DikeTopAtRiver,
+ PointTypeEnum.DikeTopAtPolder,
+ PointTypeEnum.DikeToeAtPolder,
+ PointTypeEnum.SurfaceLevelInside,
+ ]
+ for required_point in required_points:
+ SurfaceLine.raise_error_if_point_does_not_exist(
+ values.get("Points"), values.get("Name"), required_point
+ )
+ return values
+
+ def serialize(self) -> et.Element:
+ surface_line_root = et.Element("SurfaceLine")
+ surface_line_root.set("Name", self.Name)
+ points_root = et.SubElement(surface_line_root, "Points")
+ for point in self.Points:
+ point_root = et.SubElement(points_root, "Point")
+
+ point_root.set("X", str(point.X))
+ point_root.set("Z", str(point.Z))
+ point_root.set("PointType", str(point.PointType.value))
+ return surface_line_root
Index: DamClients/DamPythonInterface/trunk/src/dampythoninterface/base_class.py
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/dampythoninterface/base_class.py (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/dampythoninterface/base_class.py (revision 3474)
@@ -0,0 +1,8 @@
+from pydantic import BaseModel
+
+
+class BaseDataClass(BaseModel):
+ class Config:
+ validate_assignment = True
+ arbitrary_types_allowed = True
+ validate_all = True
\ No newline at end of file
Index: DamClients/DamPythonInterface/trunk/src/tests/test_data/TestInputFile.xml
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/tests/test_data/TestInputFile.xml (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/tests/test_data/TestInputFile.xml (revision 3474)
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: DamClients/DamPythonInterface/trunk/src/tests/test_output/test_serialize_surface_line.xml
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/tests/test_output/test_serialize_surface_line.xml (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/tests/test_output/test_serialize_surface_line.xml (revision 3474)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
Index: DamClients/DamPythonInterface/trunk/src/dampythoninterface/input.py
===================================================================
diff -u
--- DamClients/DamPythonInterface/trunk/src/dampythoninterface/input.py (revision 0)
+++ DamClients/DamPythonInterface/trunk/src/dampythoninterface/input.py (revision 3474)
@@ -0,0 +1,20 @@
+from typing import List
+from pathlib import Path
+import lxml.etree as et
+
+from .surface_line import SurfaceLine
+from .serializer import Serializer
+from .base_class import BaseDataClass
+
+
+class DamInput(BaseDataClass):
+ SurfaceLines: List[SurfaceLine] = []
+
+ def ExportToXml(self, xml_file: Path) -> None:
+ input_root = et.Element("Input")
+ SurfaceLines_root = et.Element("SurfaceLines")
+ for surface_line in self.SurfaceLines:
+ SurfaceLines_root.append(surface_line.serialize())
+ input_root.append(SurfaceLines_root)
+ tree = et.ElementTree(input_root)
+ tree.write(str(xml_file), pretty_print=True)