[GIS] Combine KML files with Python

google earthkmlpython

Is there a simple way to combine KML files into one KML file with Python?

Nothing complex, I just want to append them to each other.

Why I want it to be a script:
Some people in our company create KML files of work site boundaries to display in Google Earth. The idea is to make these all accessible to everyone – my thought is that when a staff member creates a new KML, they can add it to a specific folder on the server. The script will run nightly to combine them, and all staff will have a network link in Google Earth to the folder – thus, they daily get new information in Google Earth.

This was a staff request, so I'm looking into it.

I installed the pyKML library with pip (latest version), but when I try to import it (in Atom with the Script package), I get the following error: ModuleNotFoundError: No module named 'pyKML'

Path appears to be correct.

Can anyone provide assistance with pyKML or an alternate solution?

Best Answer

You can use the fastkml python lib for this. It can be found at https://fastkml.readthedocs.io/en/latest/ with all instructions to the usage.

Here is a code example for using this library to generate a kml structure.


from pathlib import Path

from fastkml import kml
from shapely.geometry import shape


def read_kml(kml_text):
    k = kml.KML()

    # Reading the kml from a text string
    k.from_string(kml_text)

    k_doc = list(k.features())[0]

    # Getting the first document child that must be a folder or a placemark
    # but you can iterate over it to get multiple folders or placemarks
    doc_child = list(k_doc.features())[0]

    lst_geoms = list()
    if isinstance(doc_child, kml.Folder):
        for feature in doc_child.features():
            lst_geoms.append(feature.geometry)
    elif isinstance(doc_child, kml.Placemark):
        lst_geoms.append(doc_child.geometry)

    # Returning the geometries found list  
    return lst_geoms


def generate_kml():
    # Final file IO
    k = kml.KML()
    ns = '{http://www.opengis.net/kml/2.2}'

    # Creating document structure
    document = kml.Document(
        ns, "SOME_IDENTIFICATION",
        "SOME_NAME", "SOME_DESCRIPTION"
    )
    k.append(document)

    # Creating folder structure
    # Note that a kml can have multiple folders
    folder = kml.Folder(
        ns, "SOME_IDENTIFICATION",
        "SOME_NAME", "SOME_DESCRIPTION"
    )
    document.append(folder)

    # Creating placemark structure
    # Note that a kml can have multiple placemarks
    placemark = kml.Placemark(
        ns, "SOME_IDENTIFICATION",
        "SOME_NAME", "SOME_DESCRIPTION"
    )
    # Passing the geometry to the placemark
    # It can be a shapely geom (Polygon, MultiPolygon, Polyline, Point, etc)
    placemark.geometry = shape("SOME_GEOJSON_GEOMETRY_HERE")

    # Adding the placemark to the previous created folder
    folder.append(placemark)

    final_kml_text = k.to_string(prettyprint=True)

    output = Path(__file__).parent / "test.kml"
    output.write_text(final_kml_text.encode("UTF-8"))


if __name__ == '__main__':
    # U can either generate a kml from a existing data
    generate_kml()
    # or read another kml to get the features and properties
    # to generate your own
    geometries = read_kml("SOME_KML_STRINGIFIED_TEXT")