import copy import os import shutil import xml.etree.ElementTree as ET import pathlib import tempfile KML_NS = "http://www.opengis.net/kml/2.2" ET.register_namespace("", KML_NS) def split_kml(input_file: str, split_size: int = 5) -> list[str]: input_path = pathlib.Path(input_file) input_name = input_path.stem kml = ET.parse(input_path) root = kml.getroot() prefix = f"{{{root.tag.split('}')[0][1:]}}}" document = root.find(f"{prefix}Document") if document is None: raise ValueError("No Document element found in the KML file.") placemarks = document.findall(f"{prefix}Placemark") current_placemark = placemarks.pop(0) split_files = [] new_root = copy.deepcopy(root) new_document = new_root.find(f"{prefix}Document") if new_document is None: raise ValueError("No Document element found in the new KML file.") for placemark in new_document.findall(f"{prefix}Placemark"): new_document.remove(placemark) new_document.append(copy.deepcopy(current_placemark)) current_tmp_file = tempfile.NamedTemporaryFile(suffix=".kml") ET.ElementTree(new_root).write(current_tmp_file.name, encoding="utf-8", xml_declaration=True) while placemarks: current_placemark = placemarks.pop(0) new_document.append(copy.deepcopy(current_placemark)) new_tmp_file = tempfile.NamedTemporaryFile(suffix=".kml") ET.ElementTree(new_root).write(new_tmp_file.name, encoding="utf-8", xml_declaration=True) if os.path.getsize(new_tmp_file.name) < split_size * 1024 * 1024: current_tmp_file = new_tmp_file else: n = len(split_files) + 1 output_path = input_path.parent / f"{input_name}_{n}.kml" shutil.copy(current_tmp_file.name, output_path) split_files.append(str(output_path)) new_root = copy.deepcopy(root) new_document = new_root.find(f"{prefix}Document") if new_document is None: raise ValueError("No Document element found in the new KML file.") for placemark in new_document.findall(f"{prefix}Placemark"): new_document.remove(placemark) new_document.append(copy.deepcopy(current_placemark)) current_tmp_file = tempfile.NamedTemporaryFile(suffix=".kml") ET.ElementTree(new_root).write(current_tmp_file.name, encoding="utf-8", xml_declaration=True) n = len(split_files) + 1 output_path = input_path.parent / f"{input_name}_{n}.kml" shutil.copy(current_tmp_file.name, output_path) split_files.append(str(output_path)) return split_files