GPXに対して任意の時間幅の時間平均をとり、結果をGPXで吐くプログラム。 #highlight(ruby){{hoge_element = REXML::Element.new("hoge")}} というのが最初だけでなく新しい要素をつくるときに毎回要ると知らなくて、でもなんだか惜しいところまで行ってたのでゴールまであと一歩のところでおかしな結果が出るのをREXMLのせいにしてかなりの時間悩み、いままでRubyを使ってきて初めてこんなにイライラしました。[[ここ>http://d.hatena.ne.jp/ham007/20080831/1220154051]]を見て己の間違いに気づき、もう仲直りしましたけど。というわけで、こんな感じ。 #highlight(ruby){{#!/usr/bin/ruby # -*- coding: utf-8 -*- #座標の時間平均を取る #参考: http://www6.airnet.ne.jp/manyo/xml/ruby/step10.html require "rexml/document" require "time" experiment_name="e101" in_file_name = "#{experiment_name}_unix.gpx" out_file_name = "#{experiment_name}_unix_by10min.gpx" #start_time = 0 #stop_time = 1314540864 out_doc = REXML::Document.new()#出力ファイルを開き、前準備する out_doc.add(REXML::XMLDecl.new(version="1.0",encoding="UTF-8",standalone="yes")) gpx_out = REXML::Element.new("gpx")#出力ファイルの変数名にはoutをつけておく out_doc.add_element(gpx_out) gpx_out.add_attribute("creator","Machikaneko Investigation Team") gpx_out.add_attribute("version","1.0") gpx_out.add_attribute("xmlns","http://www.topografix.com/GPX/1/0") trk_out = REXML::Element.new("trk") gpx_out.add_element(trk_out) name_out = REXML::Element.new("name") name_out.add_text("20110829-120348")#あとで入力ファイルから読み込めるようにする trk_out.add_element(name_out) desc_out = REXML::Element.new("desc") desc_out.add_text("Color:04000ff") trk_out.add_element(desc_out) trkseg_out = REXML::Element.new("trkseg") trk_out.add_element(trkseg_out) #各データポイントはtrksegの下のtrkptという要素で区切られるから、 #これ以下の要素はループの中でつくる doc = nil #入力ファイルを開く File.open(in_file_name) {|xmlfile| doc = REXML::Document.new(xmlfile) } start_time=1314457343 time=start_time i = 1 sumlong = 0 sumlati = 0 unitime=[] trkseg = doc.elements["/gpx/trk/trkseg"] trkseg.elements.each("trkpt"){|hoge| longtitude = hoge.attributes.get_attribute("lon").to_s.to_f latitude = hoge.attributes.get_attribute("lat").to_s.to_f unixtime = hoge.attributes.get_attribute("unixtime").to_s.to_f #REXML::attribute => string => float とクラスを変更している if unixtime <= time unitime[i]=unixtime sumlong = sumlong + longtitude sumlati = sumlati + latitude i+=1 else trkpt_out = REXML::Element.new("trkpt") trkpt_out.add_text("") trkseg_out.add_element(trkpt_out) ele_out = REXML::Element.new("ele") ele_out.add_text("") trkpt_out.add_element(ele_out) time_out = REXML::Element.new("time") trkpt_out.add_element(time_out) speed_out= REXML::Element.new("speed") speed_out.add_text("") trkpt_out.add_element(speed_out) if i != 1 trkpt_out.add_attribute("lat",sumlati/(i-1)) trkpt_out.add_attribute("lon",sumlong/(i-1)) t=Time.at(((unitime[1].to_f+unitime[i-1].to_f)/2).to_i) time_out.add_text(t.strftime("%Y-%m-%dT%H:%M:%SZ").to_s) else #つまりi=1なら trkpt_out.add_attribute("lat",latitude) trkpt_out.add_attribute("lon",longtitude) t=Time.at(unitime[1].to_i) time_out.add_text(t.strftime("%Y-%m-%dT%H:%M:%SZ").to_s) end i=1 time=time+3600 sumlong = 0 sumlati = 0 end } out_doc = File::open("#{experiment_name}_average.gpx","w"){|outfile| out_doc.write(outfile,0) } }} できあがったGPXファイルは、[[GPS Visualizer>http://www.gpsvisualizer.com/]]で可視化するとよいかも。今回つくったのは、まちかねこ調査隊のe101実験におけデータ。図示すると以下の通り。 -[[生データ>]] -[[1時間ごとの時間平均>]]