diff --git a/doc/tutorials/parsing.rst b/doc/tutorials/parsing.rst
index 8c6995b..8f4832e 100644
--- a/doc/tutorials/parsing.rst
+++ b/doc/tutorials/parsing.rst
@@ -32,4 +32,26 @@ In order to parse a KML file, simply create a new :py:class:`~ezgpx.gpx.GPX` obj
from ezGPX import GPX
# Parse KML file
- gpx = GPX("file.kml")
\ No newline at end of file
+ gpx = GPX("file.kml")
+
+
+KMZ Files
+^^^^^^^^^
+
+KML files are commonly distributed as KMZ files, which are zipped KML files with a .kmz extension.
+In order to parse a KMZ file, simply create a new :py:class:`~ezgpx.gpx.GPX` object with the path to the file.
+
+.. note::
+
+ This method will create a temporary KML file in the working directory.
+
+.. note::
+
+ This method is mainly designed to perform a simple conversion from KMZ to GPX. To that extent, only GPS data from the one of the KML files found in the KMZ will be processed.
+
+::
+
+ from ezGPX import GPX
+
+ # Parse KML file
+ gpx = GPX("file.kmz")
\ No newline at end of file
diff --git a/ezgpx/gpx/gpx.py b/ezgpx/gpx/gpx.py
index a42e56b..3e95060 100644
--- a/ezgpx/gpx/gpx.py
+++ b/ezgpx/gpx/gpx.py
@@ -1,6 +1,7 @@
import os
from typing import Optional, Union, List, Tuple, Dict, NewType
import logging
+from zipfile import ZipFile
import webbrowser
from datetime import datetime
import pandas as pd
@@ -61,6 +62,18 @@ def __init__(self, file_path: Optional[str] = None, check_schemas: bool = True,
self.gpx: Gpx = self.kml_parser.gpx
self.precisions = self.kml_parser.precisions
self.time_format = self.kml_parser.time_format
+ elif file_path.endswith(".kmz"):
+ kmz = ZipFile(file_path, 'r')
+ kmls = [info.filename for info in kmz.infolist() if info.filename.endswith(".kml")]
+ if "doc.kml" not in kmls:
+ logging.warning("Unable to parse this file: Expected to find doc.kml inside KMZ file.")
+ kml = kmz.open("doc.kml", 'r').read()
+ self.write_tmp_kml("tmp.kml", kml)
+ self.kml_parser: KMLParser = KMLParser("tmp.kml", check_schemas, extensions_schemas)
+ self.gpx: Gpx = self.kml_parser.gpx
+ self.precisions = self.kml_parser.precisions
+ self.time_format = self.kml_parser.time_format
+ os.remove("tmp.kml")
else:
logging.error("Unable to parse this type of file...\nYou may consider renaming your file with the proper file extension.")
self.gpx_writer: GPXWriter = GPXWriter(
@@ -1189,4 +1202,19 @@ def folium_plot(
# Open map in web browser
if open:
- webbrowser.open(file_path)
\ No newline at end of file
+ webbrowser.open(file_path)
+
+ def write_tmp_kml(self, path: str ="tmp.kml", kml_string: Optional[bytes] = None):
+ """
+ Write temproray .KML file in order to parse KMZ file.
+ """
+ # Open/create KML file
+ try:
+ f = open(path, "wb")
+ except OSError:
+ logging.exception(f"Could not open/read file: {path}")
+ raise
+ # Write KML file
+ with f:
+ if kml_string is not None:
+ f.write(kml_string)
\ No newline at end of file
diff --git a/ezgpx/kml_writer/kml_writer.py b/ezgpx/kml_writer/kml_writer.py
index 6061a68..5c4c1d3 100644
--- a/ezgpx/kml_writer/kml_writer.py
+++ b/ezgpx/kml_writer/kml_writer.py
@@ -305,15 +305,15 @@ def gpx_to_string(self) -> str:
def write_gpx(self):
"""
- Convert Gpx instance to string and write to file.
+ Convert Gpx instance to string and write to .kml file.
"""
- # Open/create GPX file
+ # Open/create KML file
try:
f = open(self.path, "w")
except OSError:
logging.exception(f"Could not open/read file: {self.path}")
raise
- # Write GPX file
+ # Write KML file
with f:
f.write("")
f.write(self.gpx_string)
diff --git a/tests/test_files/reference_files/folium_strava_run_1.html b/tests/test_files/reference_files/folium_strava_run_1.html
index 9e61e4a..386c874 100644
--- a/tests/test_files/reference_files/folium_strava_run_1.html
+++ b/tests/test_files/reference_files/folium_strava_run_1.html
@@ -25,7 +25,7 @@