#!/usr/bin/ruby -Ke =begin 最寄の電子基準点を調べる =end $options = { :mode => :normal, :src_dir => File::join(File::dirname(__FILE__), 'data'), :rinex => false, } ARGV.reject!{|arg| if arg =~ /--([^=]+)=?/ then $options[$1.to_sym] = $' true else false end } $options[:mode] = $options[:mode].to_sym $options[:rinex] = eval($options[:rinex].to_s) position_data = nil if $options[:mode] == :update then unless FileTest::directory?($options[:src_dir]) Dir::mkdir($options[:src_dir]) end require 'net/ftp' Net::FTP.open('terras.gsi.go.jp'){|ftp| ftp.login ftp.passive = true ftp.chdir("data/coordinates_F3/#{Time::now.year}") ftp.list('*.pos').each{|f| f =~ /\S+\.pos/ fname = $& $stderr.puts "Getting #{fname} ..." ftp.gettextfile(fname, File::join($options[:src_dir], fname)) } } position_data = {} require 'time' Dir::glob(File::join($options[:src_dir], '*.pos')){|f| next unless f =~ /(\d+)\.\d+\.pos/ index = $1 $stderr.puts "Parsing #{index} ..." latest_data = nil open(f).each{|line| if line =~ /^ +(\d{4}) (\d{2}) (\d{2}) (\d{2}:\d{2}:\d{2}) +/ then date = Time::parse("#{$1}-#{$2}-#{$3}T#{$4}UTC") analyzed = $'.split(/ +/) x, y, z, lat, lng, alt = analyzed.collect{|v| v.to_f} latest_data = {:x => x, :y => y, :z => z, :lat => lat.to_f / 180 * Math::PI, :lng => lng.to_f / 180 * Math::PI, :alt => alt.to_f, :date => date} end } position_data[index] = latest_data if latest_data } File::open(File::join($options[:src_dir], 'cache.db'), 'w'){|io| io.write Marshal::dump(position_data) } else File::open(File::join($options[:src_dir], 'cache.db'), 'r'){|io| position_data = Marshal::load(io.read) } end $stderr.puts "Usage #{__FILE__} lat_deg lng_deg [date] [--mode=normal|update|test] [--rinex]" $stderr.puts $options.inspect lat, lng = [35.681382, 139.766084] # 東京駅 => 最も近い基準点 93016(東京都足立区一ツ家3−15−1) if $options[:mode] != :test then exit(-1) if ARGV.size < 2 lat = ARGV.shift.to_f lng = ARGV.shift.to_f end lat = lat / 180 * Math::PI lng = lng / 180 * Math::PI $: << File::join(File::dirname(__FILE__), '..', '..', 'common', 'ruby') require 'WGS84.rb' distance_list = {} position_data.each{|k, v| distance_list[k] = WGS84.distance(lat, lng, v[:lat], v[:lng]) } sorted = distance_list.to_a.sort{|a, b| a[1] <=> b[1]} nearest_station_name, distance = sorted.first nearest_station_info = position_data[nearest_station_name] $stderr.puts "The nearest station is #{nearest_station_name} (lat, lng, alt) = (#{nearest_station_info[:lat] / Math::PI * 180}, #{nearest_station_info[:lng] / Math::PI * 180}, #{nearest_station_info[:alt]}), about #{distance} m." exit(0) unless $options[:rinex] # RINEX ファイルを取得する # @see http://terras.gsi.go.jp/ja/ngs100.php#rinex date = Time::now unless ARGV.empty? require 'time' date = Time::parse(ARGV.join(' ')) end require 'net/ftp' Net::FTP.open('terras.gsi.go.jp'){|ftp| ftp.login ftp.passive = true yday_str = date.strftime('%j') ftp.chdir("data/GPS_products/#{date.year}/#{yday_str}") ['o', 'n'].each{|suffix| fname = "#{nearest_station_name[-4..-1]}#{yday_str}0.#{date.strftime('%y')}#{suffix}.gz" $stderr.puts "Getting #{fname} ..." ftp.getbinaryfile(fname) } }