Empty TerminationPoint list
[oam.git] / code / network-generator / network_generation / model / python / geo_location.py
1 # Copyright 2023 highstreet technologies GmbH
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # !/usr/bin/python
16
17 """
18 A collection of TypeDefinitions for a geographical location
19 """
20 import math
21 from typing import Any, TypedDict, cast
22
23 from typing_extensions import Required
24
25 from network_generation.model.python.point import Point
26
27
28 class IGeoLocation(TypedDict):
29     latitude: Required[float]
30     longitude: Required[float]
31     aboveMeanSeaLevel: Required[float]
32
33
34 default_value: IGeoLocation = {
35     "latitude": 0,
36     "longitude": 0,
37     "aboveMeanSeaLevel": 0,
38 }
39
40
41 class GeoLocation:
42     @staticmethod
43     def default() -> dict[str, Any]:
44         return cast(dict[str, Any], default_value)
45
46     _equatorialRadius = 6378137  # meters
47     _polarRadius = 6356752  # meters
48
49     def __init__(self, data: IGeoLocation = default_value) -> None:
50         self.latitude = data["latitude"]
51         self.longitude = data["longitude"]
52         self.aboveMeanSeaLevel = data["aboveMeanSeaLevel"]
53
54     @property
55     def equatorialRadius(self) -> int:
56         return GeoLocation._equatorialRadius
57
58     @property
59     def polarRadius(self) -> int:
60         return GeoLocation._polarRadius
61
62     @property
63     def latitude(self) -> float:
64         return self._latitude
65
66     @latitude.setter
67     def latitude(self, value: float) -> None:
68         if not (-90 <= value <= 90):
69             msg: str = "Invalid latitude. Latitude must be between -90 and 90."
70             raise ValueError(msg)
71         self._latitude = value
72
73     @property
74     def longitude(self) -> float:
75         return self._longitude
76
77     @longitude.setter
78     def longitude(self, value: float) -> None:
79         if not (-180 <= value <= 180):
80             raise ValueError(
81                 "Invalid longitude. Longitude must be between -180 and 180."
82             )
83         self._longitude = value
84
85     @property
86     def aboveMeanSeaLevel(self) -> float:
87         return self._aboveMeanSeaLevel
88
89     @aboveMeanSeaLevel.setter
90     def aboveMeanSeaLevel(self, value: float) -> None:
91         if not (-180 <= value <= 180):
92             raise ValueError(
93                 "Invalid longitude. Longitude must be between -180 and 180."
94             )
95         self._aboveMeanSeaLevel = value
96
97     def json(self) -> dict[str, float]:
98         return {
99             "latitude": self.latitude,
100             "longitude": self.longitude,
101             "aboveMeanSeaLevel": self.aboveMeanSeaLevel,
102         }
103
104     def __str__(self) -> str:
105         return str(self.json())
106
107     def point_to_geo_location(self, point: Point) -> Any:
108         """
109         A static function which converts a point in pixels into a geographical
110         location when the self is represented as Point(0,0)
111         @param point : The point to be converted
112         returns The converted GeoLocation object.
113         """
114         new_lat = self.latitude + (point.y / self.equatorialRadius) * (
115             180 / math.pi
116         )
117         new_lon = self.longitude + (point.x / self.equatorialRadius) * (
118             180 / math.pi
119         ) / math.cos(self.latitude * math.pi / 180)
120
121         geo_location: IGeoLocation = {
122             "longitude": new_lon,
123             "latitude": new_lat,
124             "aboveMeanSeaLevel": self.aboveMeanSeaLevel,
125         }
126         return GeoLocation(geo_location)