「部門/Ruby/GPXファイルをRubyで扱う/時間平均をとる/その2」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
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}_average.gpx"
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("#{out_file_name}","w"){|outfile|
out_doc.write(outfile,0)
}
}}
できあがったGPXファイルは、[[GPS Visualizer>http://www.gpsvisualizer.com/]]で可視化するとよいかも。今回つくったのは、まちかねこ調査隊のe101実験におけるデータ解析のため。図示すると以下の通り。
-[[生データ>http://www47.atwiki.jp/cscd?cmd=upload&act=open&pageid=109&file=1319649452-26261.html]]
-[[1時間ごとの時間平均>http://www47.atwiki.jp/cscd?cmd=upload&act=open&pageid=109&file=1319649465-26313.html]]
たまにとんでもない位置を計測してるのを、なまらせることができた。
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}_average.gpx"
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("#{out_file_name}","w"){|outfile|
out_doc.write(outfile,0)
}
}}
できあがったGPXファイルは、[[GPS Visualizer>http://www.gpsvisualizer.com/]]で可視化するとよいかも。今回つくったのは、まちかねこ調査隊のe101実験におけるデータ解析のため。図示すると以下の通り。
-[[生データ>http://www47.atwiki.jp/cscd?cmd=upload&act=open&pageid=109&file=1319649452-26261.html]]
-[[1時間ごとの時間平均>http://www47.atwiki.jp/cscd?cmd=upload&act=open&pageid=109&file=1319649465-26313.html]]
たまにとんでもない位置を計測してるのを、なまらせることができた。