Skip to content

Commit

Permalink
remove get_kwargs and use registry for KML class #160
Browse files Browse the repository at this point in the history
  • Loading branch information
cleder committed Apr 1, 2024
1 parent 3ffe37d commit 469c26e
Showing 1 changed file with 54 additions and 51 deletions.
105 changes: 54 additions & 51 deletions fastkml/kml.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""
KML is an open standard officially named the OpenGIS KML Encoding Standard
(OGC KML). It is maintained by the Open Geospatial Consortium, Inc. (OGC).
KML is an open standard officially named the OpenGIS KML Encoding Standard (OGC KML).
It is maintained by the Open Geospatial Consortium, Inc. (OGC).
The complete specification for OGC KML can be found at
http://www.opengeospatial.org/standards/kml/.
Expand All @@ -25,7 +26,6 @@
"""
import logging
from typing import Any
from typing import Dict
from typing import Iterable
from typing import List
Expand All @@ -43,28 +43,33 @@
from fastkml.helpers import xml_subelement_list_kwarg
from fastkml.overlays import GroundOverlay
from fastkml.overlays import PhotoOverlay
from fastkml.registry import RegistryItem
from fastkml.registry import registry
from fastkml.types import Element

logger = logging.getLogger(__name__)

kml_children = Union[Folder, Document, Placemark, GroundOverlay, PhotoOverlay]


class KML(_XMLObject):
"""represents a KML File."""

_default_ns = config.KMLNS

_features: List[Union[Folder, Document, Placemark]]
_features: List[kml_children]
ns: str

def __init__(
self,
ns: Optional[str] = None,
name_spaces: Optional[Dict[str, str]] = None,
features: Optional[Iterable[Union[Folder, Document, Placemark]]] = None,
features: Optional[Iterable[kml_children]] = None,
) -> None:
"""
The namespace (ns) may be empty ('') if the 'kml:' prefix is
undesired. Note that all child elements like Document or Placemark need
Leave the namespace (ns) empty ('') if the 'kml:' prefix is undesired.
Note that all child elements like Document or Placemark need
to be initialized with empty namespace as well in this case.
"""
super().__init__(
Expand All @@ -73,25 +78,45 @@ def __init__(
)
self.features = list(features) if features is not None else []

@classmethod
def get_tag_name(cls) -> str:
"""Return the tag name."""
return cls.__name__.lower()

def etree_element(
self,
precision: Optional[int] = None,
verbosity: Verbosity = Verbosity.normal,
) -> Element:
"""
Return an Element object representing the KML element.
Args:
----
precision (Optional[int]): The precision used for floating-point values.
verbosity (Verbosity): The verbosity level for generating the KML element.
Returns:
-------
Element: The Element object representing the KML element.
"""
# self.ns may be empty, which leads to unprefixed kml elements.
# However, in this case the xlmns should still be mentioned on the kml
# element, just without prefix.
if not self.ns:
root = config.etree.Element(f"{self.ns}kml") # type: ignore[attr-defined]
root = config.etree.Element( # type: ignore[attr-defined]
f"{self.ns}{self.get_tag_name()}",
)
root.set("xmlns", config.KMLNS[1:-1])
elif hasattr(config.etree, "LXML_VERSION"): # type: ignore[attr-defined]
root = config.etree.Element( # type: ignore[attr-defined]
f"{self.ns}kml",
f"{self.ns}{self.get_tag_name()}",
nsmap={None: self.ns[1:-1]},
)
else:
root = config.etree.Element( # type: ignore[attr-defined]
f"{self.ns}kml",
f"{self.ns}{self.get_tag_name()}",
)
xml_subelement_list(
obj=self,
Expand All @@ -103,44 +128,16 @@ def etree_element(
)
return cast(Element, root)

def append(self, kmlobj: Union[Folder, Document, Placemark]) -> None:
def append(
self,
kmlobj: kml_children,
) -> None:
"""Append a feature."""
if kmlobj is self:
msg = "Cannot append self"
raise ValueError(msg)
self.features.append(kmlobj)

@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,
)
name_spaces = kwargs["name_spaces"]
assert name_spaces is not None
kwargs["features"] = []
kwargs.update(
xml_subelement_list_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
node_name="",
kwarg="features",
classes=(Document, Folder, Placemark, GroundOverlay, PhotoOverlay),
strict=strict,
),
)
return kwargs

@classmethod
def class_from_string(
cls,
Expand All @@ -151,11 +148,14 @@ def class_from_string(
strict: bool = True,
) -> _XMLObject:
"""
Creates a geometry object from a string.
Create a kml object from a string.
Args:
----
string: String representation of the geometry object
string: String representation (serialized XML) of the kml object
ns: Namespace of the element (default: None)
name_spaces: Dictionary of namespace prefixes and URIs (default: None)
strict: Whether to enforce strict parsing (default: True)
Returns:
-------
Expand Down Expand Up @@ -186,13 +186,16 @@ def class_from_string(
)


# registry.register(KML, RegistryItem(
# classes=(Document, Folder, Placemark, GroundOverlay, PhotoOverlay),
# node_name='',
# attr_name="features",
# get_kwarg=xml_subelement_list_kwarg,
# set_element=xml_subelement_list,
# ))
registry.register(
KML,
RegistryItem(
classes=(Document, Folder, Placemark, GroundOverlay, PhotoOverlay),
node_name="Document,Folder,Placemark,GroundOverlay,PhotoOverlay",
attr_name="features",
get_kwarg=xml_subelement_list_kwarg,
set_element=xml_subelement_list,
),
)


__all__ = [
Expand Down

0 comments on commit 469c26e

Please sign in to comment.