Skip to content

Commit

Permalink
Merge pull request #378 from apurvabanka/develop
Browse files Browse the repository at this point in the history
KML Write Function
  • Loading branch information
cleder authored Nov 16, 2024
2 parents ac78a7e + 7c02d72 commit 70507af
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 1 deletion.
50 changes: 49 additions & 1 deletion fastkml/kml.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from typing import cast

from typing_extensions import Self
import zipfile

from fastkml import config
from fastkml import validator
Expand Down Expand Up @@ -163,7 +164,7 @@ def etree_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.
# element, just without prefix."""
if not self.ns:
root = config.etree.Element(
f"{self.ns}{self.get_tag_name()}",
Expand Down Expand Up @@ -244,6 +245,53 @@ def parse(
element=root,
)

def write(
self,
file_path: Path,
*,
prettyprint: bool = True,
xml_declaration: bool = True
) -> None:
"""
Write KML to a file
Args:
----
file_path: The file name where to save the file.
Can be any string value
prettyprint : bool, default=True
Whether to pretty print the XML.
xml_declarationL bool, default=True
For True, value is '<?xml version="1.0" encoding="UTF-8"?>' else ''
"""
element = self.etree_element()

try:

tree = config.etree.tostring(
element,
encoding="UTF-8",
pretty_print=prettyprint,
xml_declaration=xml_declaration
).decode(
"UTF-8",
)
except TypeError:
tree = config.etree.tostring(
element,
encoding="UTF-8",
xml_declaration=xml_declaration
).decode(
"UTF-8",
)

if file_path.suffix == ".kmz":
with zipfile.ZipFile(file_path, 'w', zipfile.ZIP_DEFLATED) as kmz:
kmz.writestr('doc.kml', tree)
else:
with open(file_path, "w", encoding="UTF-8") as file:
file.write(tree)


registry.register(
KML,
Expand Down
74 changes: 74 additions & 0 deletions tests/kml_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import io
import pathlib
import zipfile

import pygeoif as geo
import pytest
Expand Down Expand Up @@ -186,6 +187,79 @@ def test_kml_parse(self) -> None:
assert doc.ns == "None"


class TestWriteKML(StdLibrary):
def test_write_kml_file(self) -> None:

doc = kml.KML(
ns="{http://www.opengis.net/kml/2.2}",
name="Vestibulum eleifend lobortis lorem.",
features=[
Document(
ns="{http://www.opengis.net/kml/2.2}",
id="doc-001",
target_id="",
name="Vestibulum eleifend lobortis lorem.",
features=[
Placemark(
ns="{http://www.opengis.net/kml/2.2}",
),
],
schemata=[],
),
],
)

file_path = KMLFILEDIR / "output.kml"
doc.write(file_path=file_path, prettyprint=True, xml_declaration=False)

assert file_path.is_file(), "KML file was not created."

parsed_doc = kml.KML.parse(file_path)

assert parsed_doc.to_string() == doc.to_string()

file_path.unlink()

def test_write_kmz_file(self) -> None:

doc = kml.KML(
ns="{http://www.opengis.net/kml/2.2}",
name="Vestibulum eleifend lobortis lorem.",
features=[
Document(
ns="{http://www.opengis.net/kml/2.2}",
id="doc-001",
target_id="",
name="Vestibulum eleifend lobortis lorem.",
features=[
Placemark(
ns="{http://www.opengis.net/kml/2.2}",
),
],
schemata=[],
),
],
)

file_path = KMLFILEDIR / "output.kmz"

doc.write(file_path=file_path, prettyprint=True, xml_declaration=False)

assert file_path.is_file(), "KMZ file was not created."

tree = doc.to_string()

with zipfile.ZipFile(file_path, 'r') as kmz:
assert 'doc.kml' in kmz.namelist(), "doc.kml not found in the KMZ file"

with kmz.open('doc.kml') as doc_kml:
kml_content = doc_kml.read().decode("utf-8")

assert kml_content == tree, "KML content does not match expected content"

file_path.unlink()


class TestLxml(Lxml, TestStdLibrary):
"""Test with lxml."""

Expand Down

0 comments on commit 70507af

Please sign in to comment.