"""Shared helpers for building simple KML documents from polygon data.""" import xml.etree.ElementTree as ET KML_NS = "http://www.opengis.net/kml/2.2" ET.register_namespace("", KML_NS) def new_document(name: str) -> tuple[ET.Element, ET.Element]: """Create a pair and return (root, document). Args: name (str): Name of the document, shown as the map/layer title. Returns: tuple[ET.Element, ET.Element]: The root element and its child element. """ root = ET.Element("kml", xmlns=KML_NS) document = ET.SubElement(root, "Document") ET.SubElement(document, "name").text = name return root, document def add_placemark(document: ET.Element, name: str = "", description: str = "") -> ET.Element: """Add a to `document` and return it. Args: document (ET.Element): The element to attach the placemark to. name (str, optional): Placemark name. Defaults to "". description (str, optional): Placemark description. Defaults to "". Returns: ET.Element: The newly created element. """ placemark = ET.SubElement(document, "Placemark") ET.SubElement(placemark, "name").text = name ET.SubElement(placemark, "description").text = description return placemark def add_polygon(parent: ET.Element, ring: list[tuple[float, float]]) -> ET.Element: """Add a single-ring to `parent`. Args: parent (ET.Element): Element to attach the polygon to (a or ). ring (list[tuple[float, float]]): Outer boundary points as (longitude, latitude) pairs. Returns: ET.Element: The newly created element. """ polygon = ET.SubElement(parent, "Polygon") outer = ET.SubElement(polygon, "outerBoundaryIs") linear_ring = ET.SubElement(outer, "LinearRing") coordinates = ET.SubElement(linear_ring, "coordinates") coordinates.text = "\n".join(f"{lon},{lat}" for lon, lat in ring) return polygon def add_multi_polygon(placemark: ET.Element, rings: list[list[tuple[float, float]]]) -> ET.Element: """Add a made of one per ring to `placemark`. Args: placemark (ET.Element): The element to attach the geometry to. rings (list[list[tuple[float, float]]]): One outer boundary ring per polygon. Returns: ET.Element: The newly created element. """ multi_geometry = ET.SubElement(placemark, "MultiGeometry") for ring in rings: add_polygon(multi_geometry, ring) return multi_geometry def write_kml(root: ET.Element, output_file: str) -> None: """Indent and write a KML tree to `output_file`. Args: root (ET.Element): The root element to write. output_file (str): Path to the output KML file. """ tree = ET.ElementTree(root) ET.indent(tree) tree.write(output_file, encoding="utf-8", xml_declaration=True)