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

「部門/Ruby/GPXファイルをRubyで扱う/時間平均をとる/その2」の編集履歴(バックアップ)一覧に戻る

部門/Ruby/GPXファイルをRubyで扱う/時間平均をとる/その2 - (2011/10/27 (木) 12:34:35) のソース

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時間ごとの時間平均>]]