pythonkmlgoogle-earthpykml

Can I embed an image into KML data generated by pykml?


I have a webserver with some icons I use for the KML points.

Currently, each KML point references the Icon with and tags to the location of the image in the webserver. Thus, when viewing the data in Google Earth, the points have the custom icons from the webserver.

Ideally, I want to export the KML data so anyone can view it in Google Earth independent of access to the webserver.

Is there a way using pykml to embed the images into the KML file?


Solution

  • If want to share custom images or icons in a KML file without having to host those images on a publicly accessible web server then need to package the KML and images in a KMZ file.

    You can create a standalone KMZ file using pykml (or simplekml) that includes the KML and the referenced icons.

    from zipfile import ZipFile
    from pykml.factory import KML_ElementMaker as KML
    from lxml import etree
    
    kml = KML.Placemark(
       KML.name("Hello World!"),
       KML.Style(
           KML.IconStyle(
               KML.scale(1.0),
               KML.Icon(
                    KML.href("marker.png")
               )
           )
       ),
       KML.Point(
         KML.coordinates("-64.5253,18.4607")
       )
    )
    
    # serialize KML to a string
    kml = etree.tostring(kml, pretty_print=True, xml_declaration=True, encoding='UTF-8')
    
    # create a ZipFile object
    with ZipFile('IconStyle.kmz', 'w') as zipObj:
        zipObj.writestr('doc.kml', kml)   # Add doc.kml entry 
        zipObj.write('marker.png')        # Add icon to the zip
    

    UPDATE:

    Marc Compere added in the comments below that the simplekml library can also be used to create a KMZ file. In fact, if specify a local file in icon href then it automatically gets added to the created KMZ file when savekmz() method is called.

    Example to create a KMZ file in simplekml.

    import simplekml
    
    kml = simplekml.Kml()
    pnt = kml.newpoint(name='Hello World!', coords=[(-64.5253, 18.4607)])
    pnt.style.iconstyle.icon.href = 'marker.png'
    kml.savekmz("test.kmz")