aboutsummaryrefslogtreecommitdiff
path: root/src/split_kml.py
blob: 931704bf4029eadc2e2c4088f07108b9f35c5585 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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