January 15, 2009. This script makes thumbnails of jpg images using Python PIL, then writes a KML file based on data provided to group photos by location, finally zipping it all up into a self-contained KMZ file.
Taking photographs while traveling is a very common activity. I do it for both research and pleasure. Google Earth is a great way to showcase photographs for locations you visit, or locations in a series along a path. In Google Earth, a discrete location can be set with a placemark, for which you can provide a description. Using well-known HTML methods in the description, you can add links to photographs. Placemarks are described in a KML file. The KML file, along with the images, is zipped up into a KMZ file to complete the job, and the KMZ file can be distributed to others who simply open it to view the locations and photographs.
Here is what Google Earth looks like for a placemark made by this script:

For this project I exported selected photos from iPhoto to a trip images folder at full image size. I used photographs from a trip to Seattle and the Olympic Peninsula of Washington in 2007. I renamed the files with a prefix olympic-001, so that filenames became olympic-003-DSC_0056.jpg, olympic-003-DSC_0057.jpg, etc. for a given location.
In the python file, I typed the prefix (e.g., olympic-003) for each location, the latitude and longitude, and a description into a series of text strings, delimited by the vertical bar (|), which works well as a data delimiter. The script first parses this data into a Python dictionary of location codes and the images for each location.
Then a 'kmz' directory is created.
And into this 'kmz' directory, into a subdirectory called 'files', are written thumbnail images for the photographs, appending '-thumb' to the file basenames.
The KML file is written to contain the placemarks for the locations. The main trick here is to embed HTML tags for the description and thumbnail image links within a CDATA-bounded description section. The thumbnail image links have the form 'files/olympic-003-DSC_0057-thumb.jpg'.
Finally, an os.system() call is made to zip up the KML file and the thumbnail images in the files directory. Here's the actual KMZ file (olympic.kmz) made in this example.
Here's the script, pykmz.py
UPDATE: Added a proper package under revision control so I can fiddle with it.
UPDATE 2: Changed the name from kmzmaker to pykmz, because there is already a Java-based kmzmaker.
And here is the screen output from the script, for this example:
jeffs-macbook:pykmz jeff$ python pykmz.py ---------------- Thumbnails... Wrote: kmz/files/olympic-001-DSC_0003_thumb.jpg Wrote: kmz/files/olympic-002-DSC_0013_thumb.jpg Wrote: kmz/files/olympic-003-DSC_0055_thumb.jpg Wrote: kmz/files/olympic-003-DSC_0056_thumb.jpg Wrote: kmz/files/olympic-003-DSC_0057_thumb.jpg Wrote: kmz/files/olympic-003-DSC_0060_thumb.jpg Wrote: kmz/files/olympic-004-DSC_0070_thumb.jpg Wrote: kmz/files/olympic-004-DSC_0075_thumb.jpg ---------------- KML file... Wrote: kmz/olympic.kml ---------------- Zipping KMZ... adding: files/ (stored 0%) adding: files/olympic-001-DSC_0003_thumb.jpg (deflated 1%) adding: files/olympic-002-DSC_0013_thumb.jpg (deflated 3%) adding: files/olympic-003-DSC_0055_thumb.jpg (deflated 1%) adding: files/olympic-003-DSC_0056_thumb.jpg (deflated 3%) adding: files/olympic-003-DSC_0057_thumb.jpg (deflated 6%) adding: files/olympic-003-DSC_0060_thumb.jpg (deflated 1%) adding: files/olympic-004-DSC_0070_thumb.jpg (deflated 5%) adding: files/olympic-004-DSC_0075_thumb.jpg (deflated 2%) adding: olympic.kml (deflated 73%) Zipped: kmz/olympic.kmz