From ecc2691bee5bfde2ab3da4101ef77467f63f9d24 Mon Sep 17 00:00:00 2001 From: Tobias Jakobs Date: Mon, 22 Dec 2014 20:41:33 +0100 Subject: [PATCH] darktable KML export script --- contrib/kml_export.lua | 231 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 contrib/kml_export.lua diff --git a/contrib/kml_export.lua b/contrib/kml_export.lua new file mode 100644 index 0000000..b00b030 --- /dev/null +++ b/contrib/kml_export.lua @@ -0,0 +1,231 @@ +--[[ + This file is part of darktable, + Copyright 2014 by Tobias Jakobs. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +]] +--[[ +darktable KML export script + +ADDITIANAL SOFTWARE NEEDED FOR THIS SCRIPT +* mkdir +* zip (only if you create KMZ files) +* convert (ImageMagick) +* xdg-open +* xdg-user-dir + +WARNING +This script is only testet with Linux + +USAGE +* require this script from your main lua file +]] + +dt = require "darktable" +dt.configuration.check_version(...,{2,0,1}) + +function isnan(x) return x ~= x end + +function spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua + -- collect the keys + local keys = {} + for _key in pairs(_table) do keys[#keys + 1] = _key end + + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + if order then + table.sort(keys, function(a,b) return order(_table, a, b) end) + else + table.sort(keys) + end + + -- return the iterator function + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], _table[keys[i]] + end + end +end + +local function show_status(storage, image, format, filename, number, total, high_quality, extra_data) + dt.print("Export Image "..tostring(number).."/"..tostring(total)) +end + +local function create_kml_file(storage, image_table, extra_data) + + + + dt.print_error("Will try to export KML file now") + + if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then + exportDirectory = dt.configuration.tmp_dir + imageFoldername = "" + else + exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") + + -- Creates dir if not exsists + imageFoldername = "files/" + local mkdirCommand = "mkdir -p "..exportDirectory.."/"..imageFoldername + coroutine.yield("run_command", mkdirCommand) + end + + + -- Create the thumbnails + for _,image in pairs(image_table) do + local path, filename, filetype = string.match(image, "(.-)([^\\/]-%.?([^%.\\/]*))$") + filename = string.upper(string.gsub(filename,"%.", "_")) + + -- convert -size 92x92 filename.jpg -resize 92x92 +profile "*" thumbnail.jpg + -- In this example, '-size 120x120' gives a hint to the JPEG decoder that the image is going to be downscaled to + -- 120x120, allowing it to run faster by avoiding returning full-resolution images to GraphicsMagick for the + -- subsequent resizing operation. The '-resize 120x120' specifies the desired dimensions of the output image. It + -- will be scaled so its largest dimension is 120 pixels. The '+profile "*"' removes any ICM, EXIF, IPTC, or other + -- profiles that might be present in the input and aren't needed in the thumbnail. + + local concertToThumbCommand = "convert -size 96x96 "..image.." -resize 92x92 -mattecolor \"#FFFFFF\" -frame 2x2 +profile \"*\" "..exportDirectory.."/"..imageFoldername.."thumb_"..filename..".jpg" + -- USE coroutine.yield. It does not block the UI + coroutine.yield("run_command", concertToThumbCommand) + local concertCommand = "convert -size 438x438 "..image.." -resize 438x438 +profile \"*\" "..exportDirectory.."/"..imageFoldername..filename..".jpg" + coroutine.yield("run_command", concertCommand) + + local pattern = "[/]?([^/]+)$" + filmName = string.match(_.film.path, pattern) + end + + exportKMLFilename = filmName..".kml" + exportKMZFilename = filmName..".kmz" + + -- Create the KML file + kml_file = "\n" + kml_file = kml_file.."\n" + kml_file = kml_file.."\n" + + --image_table = dt.gui.selection(); + kml_file = kml_file..""..filmName.."\n" + kml_file = kml_file.." Exported from darktable\n" + + for image,_ in pairs(image_table) do + filename = string.upper(string.gsub(image.filename,"%.", "_")) + + if ((not isnan(image.longitude) and not isnan(image.latitude)) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + kml_file = kml_file.." \n" + kml_file = kml_file.." "..image.filename.."\n" + --kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + kml_file = kml_file.." 1\n" + kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",0\n" + kml_file = kml_file.." \n" + kml_file = kml_file.." "..string.gsub(image.exif_datetime_taken," ", "T").."Z".."\n" + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + end + end + +-- Connects all images with an path + if ( dt.preferences.read("kml_export","CreatePath","bool") == true ) then + kml_file = kml_file.." \n" + kml_file = kml_file.." Path\n" -- ToDo: I think a better name would be nice + --kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + for image,_ in spairs(image_table, function(t,a,b) return t[b] < t[a] end) do + if ((not isnan(image.longitude) and not isnan(image.latitude)) and + (image.longitude ~= 0 and image.latitude ~= 90) -- Sometimes the north-pole but most likely just wrong data + ) then + kml_file = kml_file.." "..string.gsub(tostring(image.longitude),",", ".")..","..string.gsub(tostring(image.latitude),",", ".")..",0\n" + end + end + kml_file = kml_file.." \n" + kml_file = kml_file.." \n" + + kml_file = kml_file.." \n" + end + + kml_file = kml_file.."\n" + kml_file = kml_file.."" + + file = io.open(exportDirectory.."/"..exportKMLFilename, "w") + file:write(kml_file) + file:close() + + dt.print("KML file created in "..exportDirectory) + +-- Compress the files to create a KMZ file + if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then + exportDirectory = dt.preferences.read("kml_export","ExportDirectory","string") + -- USE coroutine.yield. It does not block the UI + local createKMZCommand = "zip --test --move --junk-paths " + createKMZCommand = createKMZCommand .."\""..exportDirectory.."/"..exportKMZFilename.."\" " + createKMZCommand = createKMZCommand .."\""..dt.configuration.tmp_dir.."/"..exportKMLFilename.."\" \""..dt.configuration.tmp_dir.."/"..imageFoldername.."\"*" + coroutine.yield("run_command", createKMZCommand) + end + +-- Open the file with the standard programm + if ( dt.preferences.read("kml_export","OpenKmlFile","bool") == true ) then + local kmlFileOpenCommand + + if ( dt.preferences.read("kml_export","CreateKMZ","bool") == true ) then + kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMZFilename.."\"" + else + kmlFileOpenCommand = "xdg-open "..exportDirectory.."/\""..exportKMLFilename.."\"" + end + coroutine.yield("run_command", kmlFileOpenCommand) + end + + +end + +-- Preferences +dt.preferences.register("kml_export", "OpenKmlFile", "bool", "KML export: Open KML/KMZ file after export", "Opens the KML file after the export with the standard programm for KML files", false ) + +local handle = io.popen("xdg-user-dir DESKTOP") +local result = handle:read() +handle:close() +dt.preferences.register("kml_export", "ExportDirectory", "directory", "KML export: Export directory", "A directory that will be used to export the KML/KMZ files", result ) + +dt.preferences.register("kml_export", "CreatePath", "bool", "KML export: Connect images with path", "connect all images with a path", false ) +dt.preferences.register("kml_export", "CreateKMZ", "bool", "KML export: Create KMZ file", "Compress all imeges to one KMZ file", true ) + +-- Register +dt.register_storage("kml_export", "KML/KMZ Export", nil, create_kml_file) +