部門 > Ruby > GPXファイルをRubyで扱う > 時間平均をとる > その2


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

GPXに対して任意の時間幅の時間平均をとり、結果をGPXで吐くプログラム。
hoge_element = REXML::Element.new("hoge")
というのが最初だけでなく新しい要素をつくるときに毎回要ると知らなくて、でもなんだか惜しいところまで行ってたのでゴールまであと一歩のところでおかしな結果が出るのをREXMLのせいにしてかなりの時間悩み、いままで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で可視化するとよいかも。今回つくったのは、まちかねこ調査隊のe101実験におけるデータ解析のため。図示すると以下の通り。
たまにとんでもない位置を計測してるのを、なまらせることができた。