From 6638bec58d77234bea7d7d76e4a21f53e389ef44 Mon Sep 17 00:00:00 2001 From: Christian Ledermann Date: Sat, 11 Nov 2023 21:06:26 +0000 Subject: [PATCH] Refactor views.py to use classmethod for parsing XML elements --- fastkml/views.py | 157 ++++++++++++++++++++++++++++---------------- tests/views_test.py | 7 +- 2 files changed, 102 insertions(+), 62 deletions(-) diff --git a/fastkml/views.py b/fastkml/views.py index 71f2eda8..dac97d72 100644 --- a/fastkml/views.py +++ b/fastkml/views.py @@ -1,4 +1,5 @@ import logging +from typing import Any from typing import Dict from typing import Optional from typing import SupportsFloat @@ -162,51 +163,6 @@ def altitude_mode(self) -> AltitudeMode: def altitude_mode(self, mode: AltitudeMode) -> None: self._altitude_mode = mode - def from_element(self, element: Element) -> None: - super().from_element(element) - longitude = element.find(f"{self.ns}longitude") - if longitude is not None: - self.longitude = float(longitude.text) - latitude = element.find(f"{self.ns}latitude") - if latitude is not None: - self.latitude = float(latitude.text) - altitude = element.find(f"{self.ns}altitude") - if altitude is not None: - self.altitude = float(altitude.text) - heading = element.find(f"{self.ns}heading") - if heading is not None: - self.heading = float(heading.text) - tilt = element.find(f"{self.ns}tilt") - if tilt is not None: - self.tilt = float(tilt.text) - altitude_mode = element.find(f"{self.ns}altitudeMode") - if altitude_mode is None: - altitude_mode = element.find(f"{self.name_spaces['gx']}altitudeMode") - if altitude_mode is not None: - self.altitude_mode = AltitudeMode(altitude_mode.text) - timespan = element.find(f"{self.ns}TimeSpan") - if timespan is not None: - self._timespan = cast( - TimeSpan, - TimeSpan.class_from_element( - ns=self.ns, - name_spaces=self.name_spaces, - element=timespan, - strict=False, - ), - ) - timestamp = element.find(f"{self.ns}TimeStamp") - if timestamp is not None: - self._timestamp = cast( - TimeStamp, - TimeStamp.class_from_element( - ns=self.ns, - name_spaces=self.name_spaces, - element=timestamp, - strict=False, - ), - ) - def etree_element( self, precision: Optional[int] = None, @@ -273,6 +229,65 @@ def etree_element( # TODO: # TODO: + @classmethod + def _get_kwargs( + cls, + *, + ns: str, + name_spaces: Optional[Dict[str, str]] = None, + element: Element, + strict: bool, + ) -> Dict[str, Any]: + kwargs = super()._get_kwargs( + ns=ns, + name_spaces=name_spaces, + element=element, + strict=strict, + ) + longitude = element.find(f"{ns}longitude") + if longitude is not None: + kwargs["longitude"] = float(longitude.text) + latitude = element.find(f"{ns}latitude") + if latitude is not None: + kwargs["latitude"] = float(latitude.text) + altitude = element.find(f"{ns}altitude") + if altitude is not None: + kwargs["altitude"] = float(altitude.text) + heading = element.find(f"{ns}heading") + if heading is not None: + kwargs["heading"] = float(heading.text) + tilt = element.find(f"{ns}tilt") + if tilt is not None: + kwargs["tilt"] = float(tilt.text) + altitude_mode = element.find(f"{ns}altitudeMode") + if altitude_mode is None: + altitude_mode = element.find(f"{kwargs['name_spaces']['gx']}altitudeMode") + if altitude_mode is not None: + kwargs["altitude_mode"] = AltitudeMode(altitude_mode.text) + timespan = element.find(f"{ns}TimeSpan") + if timespan is not None: + kwargs["time_primitive"] = cast( + TimeSpan, + TimeSpan.class_from_element( + ns=ns, + name_spaces=name_spaces, + element=timespan, + strict=strict, + ), + ) + timestamp = element.find(f"{ns}TimeStamp") + if timestamp is not None: + kwargs["time_primitive"] = cast( + TimeStamp, + TimeStamp.class_from_element( + ns=ns, + name_spaces=name_spaces, + element=timestamp, + strict=strict, + ), + ) + return kwargs + class Camera(_AbstractView): """ @@ -332,12 +347,6 @@ def __init__( ) self._roll = roll - def from_element(self, element: Element) -> None: - super().from_element(element) - roll = element.find(f"{self.ns}roll") - if roll is not None: - self.roll = float(roll.text) - def etree_element( self, precision: Optional[int] = None, @@ -360,6 +369,26 @@ def roll(self) -> Optional[float]: def roll(self, value: float) -> None: self._roll = value + @classmethod + def _get_kwargs( + cls, + *, + ns: str, + name_spaces: Optional[Dict[str, str]] = None, + element: Element, + strict: bool, + ) -> Dict[str, Any]: + kwargs = super()._get_kwargs( + ns=ns, + name_spaces=name_spaces, + element=element, + strict=strict, + ) + roll = element.find(f"{ns}roll") + if roll is not None: + kwargs["roll"] = float(roll.text) + return kwargs + class LookAt(_AbstractView): __name__ = "LookAt" @@ -406,12 +435,6 @@ def range(self) -> Optional[float]: def range(self, value: float) -> None: self._range = value - def from_element(self, element: Element) -> None: - super().from_element(element) - range_var = element.find(f"{self.ns}range") - if range_var is not None: - self.range = float(range_var.text) - def etree_element( self, precision: Optional[int] = None, @@ -426,6 +449,26 @@ def etree_element( range_var.text = str(self._range) return element + @classmethod + def _get_kwargs( + cls, + *, + ns: str, + name_spaces: Optional[Dict[str, str]] = None, + element: Element, + strict: bool, + ) -> Dict[str, Any]: + kwargs = super()._get_kwargs( + ns=ns, + name_spaces=name_spaces, + element=element, + strict=strict, + ) + range_var = element.find(f"{ns}range") + if range_var is not None: + kwargs["range"] = float(range_var.text) + return kwargs + __all__ = [ "Camera", diff --git a/tests/views_test.py b/tests/views_test.py index ae51cb54..4a9cd8f2 100644 --- a/tests/views_test.py +++ b/tests/views_test.py @@ -86,9 +86,8 @@ def test_camera_read(self) -> None: "relativeToGround" "" ) - camera = views.Camera() - camera.from_string(camera_xml) + camera = views.Camera.class_from_string(camera_xml) assert camera.heading == 10 assert camera.tilt == 20 @@ -157,9 +156,7 @@ def test_look_at_read(self) -> None: "30" "" ) - look_at = views.LookAt() - - look_at.from_string(look_at_xml) + look_at = views.LookAt.class_from_string(look_at_xml) assert look_at.heading == 10 assert look_at.tilt == 20