Created
March 24, 2012 15:00
-
-
Save lpm11/2183954 to your computer and use it in GitHub Desktop.
OruxMaps が吐き出した KML を Evernote 形式に一括変換
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/env ruby | |
| #-*- coding: utf-8 -*- | |
| require("rubygems"); | |
| require("term/ansicolor"); | |
| require("term/ansicolor/logger"); | |
| require("optparshie"); | |
| require("date"); | |
| require("digest/md5"); | |
| require("base64"); | |
| require("cgi"); | |
| require("libxml"); | |
| require("nokogiri"); | |
| require("open-uri"); | |
| # Usage/Versions | |
| $HELP_DESC = ""; | |
| $HELP_INPUT = ""; | |
| $HELP_OUTPUT = ""; | |
| ::Version = "0.00 @ " + File.mtime($0).strftime("%Y%m%d-%H%M%S"); | |
| $log = Term::ANSIColor::Logger.new(STDERR); | |
| $log.progname = $0; | |
| $log.datetime_format = "%Y-%m-%d %H:%M:%S"; | |
| $log.level = Logger::DEBUG; | |
| $log.warn_decorate(:yellow); | |
| $log.error_decorate(:yellow, :bold); | |
| $log.fatal_decorate(:red, :bold); | |
| $log.debug_green_bold("#{$log.progname} started, version: #{::Version}"); | |
| $opt = OptionParshie.new(); | |
| $opt.on_tail("-h","--help","Show this message.") { puts("#{$0} #{::Version}: #{$HELP_DESC}"," input: #{$HELP_INPUT}"," output: #{$HELP_OUTPUT}","",$opt.help); exit(0); } | |
| $opt.parse!(ARGV); | |
| def segment_point_distance(ax,ay,bx,by,px,py) | |
| t = (ax**2 + ay**2 + bx*px - ax*(bx + px) + by*py - ay*(by + py))/(ax**2 + ay**2 - 2*ax*bx + bx**2 - 2*ay*by + by**2); | |
| return ((ax-px)**2 + (ay-py)**2) if (t<0); | |
| return ((bx-px)**2 + (by-py)**2) if (1<t); | |
| x = ax - ((ax - bx)*(ax**2 + ay**2 + bx*px - ax*(bx + px) + by*py - ay*(by + py)))/(ax**2 + ay**2 - 2*ax*bx + bx**2 - 2*ay*by + by**2); | |
| y = ay - ((ay - by)*(ax**2 + ay**2 + bx*px - ax*(bx + px) + by*py - ay*(by + py)))/(ax**2 + ay**2 - 2*ax*bx + bx**2 - 2*ay*by + by**2); | |
| return ((x-px)**2 + (y-py)**2); | |
| end | |
| def rank(a,c) | |
| l = Hash.new(); | |
| c -= 2; | |
| n = Math.log(c,2).ceil; | |
| rank_sub(a,0,0,n,l); | |
| return l; | |
| end | |
| def rank_sub(a,b,s,n,l) | |
| return if (s>n || a.empty?); | |
| if (a.size==1) | |
| l[b] = 0; | |
| return; | |
| end | |
| fx,fy = a.first; | |
| ex,ey = a.last; | |
| d = a.map { |px,py| segment_point_distance(fx,fy,ex,ey,px,py); } | |
| m,v = d.each_with_index.max; | |
| l[b+v] = m; | |
| rank_sub(a[0...v],b,s+1,n,l); | |
| rank_sub(a[v...a.size],b+v,s+1,n,l); | |
| end | |
| def make_c_str(a,c,l) | |
| c-=2; | |
| result = [ a.first ]; | |
| l.to_a.sort_by { |x| -x[1] }[0...c].sort_by { |x| x[0] }.each { |i,d| | |
| next if (i==0 || i==a.size-1); | |
| result << a[i]; | |
| } | |
| result << a.last; | |
| end | |
| xmlns = { "kml"=>"http://earth.google.com/kml/2.2" }; | |
| fpw = File.open("export-#{Time.now.strftime('%Y%m%d%H%M%S')}.enex","w:utf-8"); | |
| fpw.puts('<?xml version="1.0" encoding="UTF-8"?>'); | |
| fpw.puts('<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export.dtd">'); | |
| fpw.puts('<en-export export-date="'+Time.now.strftime("%Y%m%dT%H%M%SZ")+'" application="Evernote/Windows" version="4.x">'); | |
| ARGV.each { |path| | |
| doc = LibXML::XML::Document.file(path); | |
| positions = []; | |
| doc.find("//kml:kml/kml:Document/kml:Folder/kml:Placemark/kml:MultiGeometry/kml:LineString/kml:coordinates",xmlns).each { |coordinates| | |
| coordinates.content.split(/\n/).each { |s| | |
| next if (s.empty?); | |
| tuple = s.split(/,/); | |
| positions << [ tuple[1].to_f()*10000.round()/10000, tuple[0].to_f()*10000.round()/10000 ]; | |
| } | |
| } | |
| data_html = doc.find("//kml:kml/kml:Document/kml:description",xmlns)[0].content; | |
| data_doc = Nokogiri::HTML.parse(data_html); | |
| data_name = data_doc.xpath("//h2").inner_text.gsub(/^[^:]+:\s+/,""); | |
| data_array = data_doc.xpath("//p").map { |e| e.inner_text.split(/: /); }; | |
| data_array.map! { |k,v| k="平均移動速度" if (k=="平均速度Mov。"); [ k,v ]; } | |
| cdt = DateTime.strptime(data_array[0][1],format="%m/%d/%Y %H:%M"); | |
| mdt = DateTime.strptime(data_array[1][1],format="%m/%d/%Y %H:%M"); | |
| ctime = Time.gm(cdt.year, cdt.mon, cdt.day, cdt.hour, cdt.min); | |
| mtime = Time.gm(mdt.year, mdt.mon, mdt.day, mdt.hour, mdt.min); | |
| marker = "&markers=color:red%7Clabel:S%7C#{positions.first[0]},#{positions.first[1]}&markers=color:red%7Clabel:E%7C#{positions.last[0]},#{positions.last[1]}"; | |
| l = rank(positions,96); | |
| # 手抜き | |
| c = 96; | |
| url = nil; | |
| while (true) | |
| result = make_c_str(positions,c,l); | |
| # URL生成 | |
| c_str = result.map { |px,py| "#{px},#{py}" }.join("%7C"); | |
| url = "http://maps.google.co.jp/maps/api/staticmap?path=color:0xff0000a0%7Cweight:4%7C#{c_str}&size=640x640&sensor=false#{marker}"; | |
| break if (url.length <= 2048); | |
| c-=1; | |
| end | |
| puts(url); | |
| puts("size = #{url.size}, path = #{result.size}"); | |
| image_data = open(url).read(); | |
| image_data_md5 = Digest::MD5.hexdigest(image_data); | |
| fpw.puts('<note>'); | |
| fpw.puts('<title>'+"GPS記録: #{data_name}"+'</title>'); | |
| fpw.puts('<content>'); | |
| fpw.puts('<![CDATA[<?xml version="1.0" encoding="UTF-8"?>'); | |
| fpw.puts('<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">'); | |
| fpw.puts(''); | |
| fpw.puts('<en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">'); | |
| fpw.puts('<div style="font-family: 'MS Pゴシック'">'); | |
| fpw.puts('<div style="float:left;width:644px">'); | |
| fpw.puts(' <en-media hash="' + image_data_md5 + '" type="image/png" />'); | |
| fpw.puts('</div>'); | |
| fpw.puts('<div>'); | |
| fpw.puts('<table style="float:left;margin:3px 0;">'); | |
| data_array.each { |k,v| | |
| fpw.puts('<tr><th style="color:white;background-color:steelblue;font-weight:normal;padding:6px">' + k + '</th><td style="background-color:lightsteelblue;padding:6px">' + v + '</td></tr>'); | |
| } | |
| fpw.puts('</table>'); | |
| fpw.puts('</div>'); | |
| fpw.puts('</div>'); | |
| fpw.puts('</en-note>]]>'); | |
| fpw.puts('</content>'); | |
| fpw.puts('<resource><data encoding="base64">'); | |
| fpw.puts(Base64.encode64(image_data)); | |
| fpw.puts('</data><mime>image/png</mime><resource-attributes><source-url>' + CGI::escapeHTML(url) + '</source-url><file-name>staticmap.png</file-name></resource-attributes></resource>'); | |
| fpw.puts('<created>'+ctime.strftime("%Y%m%dT%H%M%SZ")+'</created>'); | |
| fpw.puts('<updated>'+mtime.strftime("%Y%m%dT%H%M%SZ")+'</updated>'); | |
| fpw.puts('</note>'); | |
| } | |
| fpw.puts("</en-export>"); | |
| fpw.close(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
見た目はこのような感じ:
https://twitter.com/#!/lpm11/status/183570382589145088/photo/1/large