Skip to content

Commit

Permalink
Work in progress:
Browse files Browse the repository at this point in the history
- Add support for KMZ files
  • Loading branch information
FABallemand committed Oct 28, 2023
1 parent 94ec4de commit 2a33e76
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 17 deletions.
24 changes: 23 additions & 1 deletion doc/tutorials/parsing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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")
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")
30 changes: 29 additions & 1 deletion ezgpx/gpx/gpx.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -1189,4 +1202,19 @@ def folium_plot(

# Open map in web browser
if open:
webbrowser.open(file_path)
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)
6 changes: 3 additions & 3 deletions ezgpx/kml_writer/kml_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
f.write(self.gpx_string)
Expand Down
Loading

0 comments on commit 2a33e76

Please sign in to comment.