From 2a33e76da152ab054c8cf6699f764b5d1c037ece Mon Sep 17 00:00:00 2001 From: FABallemand Date: Sat, 28 Oct 2023 19:33:31 +0200 Subject: [PATCH] Work in progress: - Add support for KMZ files --- doc/tutorials/parsing.rst | 24 ++++++++++++++- ezgpx/gpx/gpx.py | 30 ++++++++++++++++++- ezgpx/kml_writer/kml_writer.py | 6 ++-- .../reference_files/folium_strava_run_1.html | 24 +++++++-------- 4 files changed, 67 insertions(+), 17 deletions(-) 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 @@