Skip to content

Instantly share code, notes, and snippets.

@suwa320
Created September 30, 2012 14:56
Show Gist options
  • Select an option

  • Save suwa320/3807019 to your computer and use it in GitHub Desktop.

Select an option

Save suwa320/3807019 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
require 'nokogiri'
require 'mini_exiftool'
require 'fileutils'
class ImageFile
attr_accessor :filename, :exif, :lat, :lon, :diff
def initialize(path)
@filename = path
@exif = MiniExiftool.new(path)
end
end
class Array
def bsearch(val)
min = nil
min_diff = nil
s = 0
e = self.size
return first if (yield first) > val
return last if (yield last) < val
while s < e
i = s + (e - s) / 2
cval = yield self[i]
diff = (val - cval).abs
if cval > val
e = i - 1
elsif cval < val
s = i + 1
else
return self[i]
end
if not min_diff or min_diff > diff
min = self[i]
min_diff = diff
end
end
min
end
end
def trkpttime(pt)
Time.parse(pt.search('time').text).to_i + 3600 * 2
end
unless File.exist?(ARGV[0].to_s) and File.exist?(ARGV[1].to_s)
STDERR.puts "#{$0} [GPX File] [JPEG File|Dirctory]"
exit 1
end
if File.directory?(ARGV[1])
images = Dir.glob("#{ARGV[1]}/**/*.{jpg, jpeg}",
File::FNM_CASEFOLD).map{|img| ImageFile.new(img)}
else
images = [image_struct(ARGV[1])]
end
gpx = Nokogiri(open(ARGV[0]).read)
max_diff = (ARGV[2].to_i > 0) ? ARGV[2].to_i : 900
track_points = gpx.search('trkpt').to_a
images.each do |img|
img_time = img.exif["DateTimeOriginal"].to_i
pt = track_points.bsearch(img_time){|v| trkpttime(v)}
diff = (img_time - trkpttime(pt)).abs
if diff < max_diff
img.lat = pt.attributes["lat"].text.to_f
img.lon = pt.attributes["lon"].text.to_f
end
end
# backup directory
begin
backup_dir = File.join('/tmp/geotag',
Time.now.strftime('%Y%m%d%H%M%S.%3N'))
end while File.exist?(backup_dir)
FileUtils.mkdir_p(backup_dir)
puts "*** Backup original to #{backup_dir} ***\n"
images.each do |img|
if img.lat and img.lon
FileUtils.cp(img.filename, File.join(backup_dir, File.basename(img.filename)))
img.exif["GPSLatitudeRef"] = (img.lat >= 0) ? "North" : "South"
img.exif["GPSLatitude"] = img.lat.abs
img.exif["GPSLongitudeRef"] = (img.lon >= 0) ? "East" : "West"
img.exif["GPSLongitude"] = img.lon.abs
img.exif.save
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment