Implement handover areas in kml 75/12075/1
authorMartin Skorupski <martin.skorupski@highstreet-technologies.com>
Wed, 22 Nov 2023 06:53:42 +0000 (07:53 +0100)
committerMartin Skorupski <martin.skorupski@highstreet-technologies.com>
Wed, 22 Nov 2023 06:53:45 +0000 (07:53 +0100)
- update kml generation for cell

Issue-ID: OAM-393
Change-Id: Icbb8f9dbd817b3db40a40058415b801330f0cb6f
Signed-off-by: Martin Skorupski <martin.skorupski@highstreet-technologies.com>
code/network-generator/network_generation/model/python/nr_cell_du.py
code/network-generator/network_generation/model/python/o_ran_ru.py

index 4854bb5..578ac16 100644 (file)
@@ -17,6 +17,7 @@
 """
 A Class representing a 3GPP new radio cell du (NrCellDu)
 """
+import math
 import xml.etree.ElementTree as ET
 from typing import Any, cast
 
@@ -34,7 +35,9 @@ from network_generation.model.python.point import Point
 
 # Define the "INrCellDu" interface
 class INrCellDu(IORanNode):
-    cell_angle: int
+    cellAngle: int
+    cellScaleFactorForHandoverArea: int
+    maxReach: int
     azimuth: int
 
 
@@ -45,6 +48,7 @@ default_value: INrCellDu = cast(
         **{
             "cellAngle": 120,
             "cellScaleFactorForHandoverArea": 0,
+            "maxReach": 100,
             "azimuth": 120,
         },
     },
@@ -64,6 +68,7 @@ class NrCellDu(ORanNode):
         self._cell_scale_factor: int = int(
             str(cell_data["cellScaleFactorForHandoverArea"])
         )
+        self._maxReach: int = int(str(cell_data["maxReach"]))
         self._azimuth: int = int(str(cell_data["azimuth"]))
 
     def _to_cell_data(self, data: dict[str, Any]) -> INrCellDu:
@@ -89,19 +94,25 @@ class NrCellDu(ORanNode):
     def cell_scale_factor(self, value: int) -> None:
         self._cell_scale_factor = value
 
+    @property
+    def maxReach(self) -> int:
+        return self._maxReach
+
+    @maxReach.setter
+    def maxReach(self, value: int) -> None:
+        self._maxReach = value
+
     @property
     def azimuth(self) -> int:
         return self._azimuth
 
     @azimuth.setter
     def azimuth(self, value: int) -> None:
-        self.azimuth = value
+        self._azimuth = value
 
     def termination_points(self) -> list[ORanTerminationPoint]:
         result: list[ORanTerminationPoint] = super().termination_points()
-        result.append(
-            ORanTerminationPoint({"id": self.name, "name": self.name})
-        )
+        result.append(ORanTerminationPoint({"id": self.name, "name": self.name}))
         return result
 
     def to_topology_nodes(self) -> list[dict[str, Any]]:
@@ -126,12 +137,9 @@ class NrCellDu(ORanNode):
         linear_ring: ET.Element = ET.SubElement(outer_boundary, "LinearRing")
         coordinates: ET.Element = ET.SubElement(linear_ring, "coordinates")
 
-        points: list[Point] = Hexagon.polygon_corners(
-            self.layout, self.position
-        )
+        points: list[Point] = Hexagon.polygon_corners(self.layout, self.position)
         method = (
-            self.parent.parent.parent.parent.parent.parent
-            .geo_location.point_to_geo_location
+            self.parent.parent.parent.parent.parent.parent.geo_location.point_to_geo_location
         )
         geo_locations: list[GeoLocation] = list(map(method, points))
         text: list[str] = []
@@ -142,23 +150,19 @@ class NrCellDu(ORanNode):
         )
 
         intersect1: Point = Point(
-            (points[(2 * index + 1) % 6].x + points[(2 * index + 2) % 6].x)
-            / 2,
-            (points[(2 * index + 1) % 6].y + points[(2 * index + 2) % 6].y)
-            / 2,
+            (points[(2 * index + 1) % 6].x + points[(2 * index + 2) % 6].x) / 2,
+            (points[(2 * index + 1) % 6].y + points[(2 * index + 2) % 6].y) / 2,
         )
-        intersect_geo_location1: GeoLocation = (
-            network_center.point_to_geo_location(intersect1)
+        intersect_geo_location1: GeoLocation = network_center.point_to_geo_location(
+            intersect1
         )
 
         intersect2: Point = Point(
-            (points[(2 * index + 3) % 6].x + points[(2 * index + 4) % 6].x)
-            / 2,
-            (points[(2 * index + 3) % 6].y + points[(2 * index + 4) % 6].y)
-            / 2,
+            (points[(2 * index + 3) % 6].x + points[(2 * index + 4) % 6].x) / 2,
+            (points[(2 * index + 3) % 6].y + points[(2 * index + 4) % 6].y) / 2,
         )
-        intersect_geo_location2: GeoLocation = (
-            network_center.point_to_geo_location(intersect2)
+        intersect_geo_location2: GeoLocation = network_center.point_to_geo_location(
+            intersect2
         )
 
         tower: GeoLocation = GeoLocation(cast(IGeoLocation, self.geo_location))
@@ -174,7 +178,6 @@ class NrCellDu(ORanNode):
         cell_polygon.append(tower)
 
         for gl in cell_polygon:
-            index += 1
             strs: list[str] = [
                 str("%.6f" % float(gl.longitude)),
                 str("%.6f" % float(gl.latitude)),
@@ -184,8 +187,46 @@ class NrCellDu(ORanNode):
         coordinates.text = " ".join(text)
 
         if self.cell_scale_factor > 0:
-            print("hallo")
-
+            scaled_polygon: ET.Element = ET.SubElement(multi_geometry, "Polygon")
+            scaled_outer_boundary: ET.Element = ET.SubElement(scaled_polygon, "outerBoundaryIs")
+            scaled_linear_ring: ET.Element = ET.SubElement(scaled_outer_boundary, "LinearRing")
+            scaled_coordinates: ET.Element = ET.SubElement(scaled_linear_ring, "coordinates")
+
+            arc: float = self.azimuth * math.pi / 180
+            meterToDegree: float = 2 * math.pi * GeoLocation().equatorialRadius / 360
+            translateX: float = (
+                self.layout.size.x
+                * (self.cell_scale_factor / 100)
+                * math.sin(arc)
+            )
+            translateY: float = (
+                self.layout.size.y
+                * (self.cell_scale_factor / 100)
+                * math.cos(arc)
+            )
+            centerX: float = self.layout.size.x * 0.5 * math.sin(arc)
+            centerY: float = self.layout.size.y * 0.5 * math.cos(arc)
+            cell_center : GeoLocation = GeoLocation(
+                {
+                    "latitude": tower.latitude + centerY / meterToDegree,
+                    "longitude": tower.longitude + centerX / meterToDegree,
+                    "aboveMeanSeaLevel": tower.aboveMeanSeaLevel,
+                }
+            )
+            point_index: int = 0
+            text = []
+            for gl in cell_polygon:
+                scale: float = 1 + self.cell_scale_factor / 100
+                lng_new: float = ( 1 * scale * (gl.longitude - cell_center.longitude) ) + cell_center.longitude
+                lat_new: float = ( 1 * scale * ( gl.latitude - cell_center.latitude ) ) + cell_center.latitude
+                scaled_strs: list[str] = [
+                    str("%.6f" % float(lng_new)),
+                    str("%.6f" % float(lat_new)),
+                    str("%.6f" % float(gl.aboveMeanSeaLevel)),
+                ]
+                text.append(",".join(scaled_strs))
+                point_index += 1
+            scaled_coordinates.text = " ".join(text)
         return placemark
 
     def toSvg(self) -> ET.Element:
index e8ca9cf..05e901a 100644 (file)
@@ -89,11 +89,15 @@ class ORanRu(ORanNode):
 
     def _create_cells(self) -> list[NrCellDu]:
         result: list[NrCellDu] = []
-        cell_angle: int = (
-            self.parent.parent.parent.parent.parent.parent.configuration[
-                "pattern"
-            ]["nr-cell-du"]["cell-angle"]
+        cell_config: dict = (
+            self.parent.parent.parent.parent.parent.parent
+            .configuration["pattern"]["nr-cell-du"]
         )
+        cell_angle: int = cell_config["cell-angle"]
+        cell_scale_factor: int = (
+            cell_config["cellScaleFactorForHandoverArea"]
+        )
+        maxReach: int = cell_config["maxReach"]
         for index in range(self._cell_count):
             s: str = "00" + str(index)
             name: str = "-".join(
@@ -109,6 +113,8 @@ class ORanRu(ORanNode):
                         "layout": self.layout,
                         "parent": self,
                         "cellAngle": cell_angle,
+                        "cellScaleFactorForHandoverArea": cell_scale_factor,
+                        "maxReach": maxReach,
                         "azimuth": azimuth,
                     }
                 )