require 'rubygems' require 'xml' class TSV2XML def initialize dsettab, bulltab = nil @dsettab = dsettab @bulltab = bulltab @xroot = nil end def markup tag, val, attrs = {} @xroot << elem = XML::Node.new(tag) for k, v in attrs elem[k] = v end elem << val end def q s s.gsub(/ /, '+') end TAGS = [ :dsname, :dssize, :instpat, :model, :resol, :bbox, :area, :rawres, :rawbbox, :listlev, :listupd, :listacc, :listel, :listft ] NS_JMD = 'http://www.gisc.kishou.go.jp/xsd/jmd0.1' def conv ds, opts h = nil File.open(@dsettab, 'r') {|fp| for line in fp row = line.chomp.split(/\t/) next unless row.first == ds h = opts.update(Hash[*TAGS.zip(row).flatten]) break end } doc = XML::Document.new() @xroot = doc.root = XML::Node.new('metadata') XML::Namespace.new(doc.root, nil, NS_JMD) yield h doc.save('-') end def convds ds conv(ds, {}) {|h| markup 'mdfid', "urn:x-wmo:md:jp.go.jma.wis.dcpc-geogr::#{h[:dsname]}" markup 'wisorg', 'GISC Tokyo - Japan Meteorological Agency' markup 'wiscont', 'mailto:wis-jma@met.kishou.go.jp' markup 'wiscont', 'fax:+81-3-3211-8404' markup 'orgorg', 'DCPC Geographical - Japan Meteorological Agency' markup 'mddate', Time.now.strftime('%Y-%m-%dT%H:%M:%SZ') markup 'subjkey', 'NWP' markup 'subjkey', 'GPV' markup 'subjkey', 'GRIB Aggregate' markup 'subjkey', h[:model] markup 'title', "#{h[:model]} Product #{h[:resol]}-deg Resolution #{h[:area]}" markup 'abstract', [ 'model:', h[:model] + ';', 'resolution:', h[:resol], 'deg;', 'area:', h[:area] + ';', 'level:', h[:listlev].gsub(/\|/, ', ') + ';', 'element:', h[:listel].gsub(/\|/, ', ') + ';', 'forecast-time:', h[:listft].gsub(/\|/, ', ') + ';', 'update-time:', (h[:listupd].split(/\|/).map{|s| "(#{s})"}.join(' or ') + ';'), 'access:', case h[:listacc] when 'Open' then 'no restriction' else 'registration required' end + ';', 'use:', 'unrestricted (WMO Res.40 Essential).' ].join(' ') markup 'southbc', h[:bbox].split(/\s/)[0], 'units' => 'deg' markup 'northbc', h[:bbox].split(/\s/)[1], 'units' => 'deg' markup 'westbc', h[:bbox].split(/\s/)[2], 'units' => 'deg' markup 'eastbc', h[:bbox].split(/\s/)[3], 'units' => 'deg' markup 'placekey', h[:area] for hh in h[:listupd].split(/[| ]/).uniq.sort markup 'updtime', format('%02u:00:00Z', hh.to_i) end for lev in h[:listlev].split(/\|/) markup 'stratkey', lev end for el in h[:listel].split(/\|/) markup 'themekey', el end case h[:listupd].split(/\|/).map{|s| s.split(/\s/).size}.max when 1 then markup 'updcycle', 'daily' when 2 then markup 'updcycle', '12-hourly' when 4 then markup 'updcycle', '6-hourly' else raise "updcycle #{h[:updtime]}" end markup 'horizres', h[:resol], 'units' => 'deg' markup 'avail', '24', 'units' => 'h' markup 'format', 'GRIB1', 'code' => 'FM92-XI Ext. GRIB' markup 'instpat', "^A_#{h[:instpat]}_C_.*\.bin$" markup 'url', "http://www.wis-jma.go.jp/data/browse?Type=GRIB&Discipline=#{q h[:model]}&Resolution=#{q h[:rawres]}&Area=#{q h[:rawbbox]}" case h[:access] when 'Open' markup 'raccess', 'no restriction' markup 'ruse', 'WMOEssential' else #when 'Closed' markup 'raccess', 'registration required' markup 'ruse', 'WMOEssential' end } end TAGS2 = [ :ttaaii, :cccc, :dsname, :level, :fcsttime, :updtime, :access, :element ] def convbull bull h = nil File.open(@bulltab, 'r') {|fp| for line in fp row = line.chomp.split(/\t/) next unless row[0,2].join == bull h = Hash[*TAGS2.zip(row).flatten] break end } conv(h[:dsname], h) {|h| markup 'mdfid', "urn:x-wmo:md:int.wmo.wis::#{h[:ttaaii]}#{h[:cccc]}" markup 'mdparent', "urn:x-wmo:md:jp.go.jma.wis.dcpc-geogr::#{h[:dsname]}" markup 'wisorg', 'GISC Tokyo - Japan Meteorological Agency' markup 'wiscont', 'mailto:wis-jma@met.kishou.go.jp' markup 'wiscont', 'fax:+81-3-3211-8404' markup 'orgorg', 'DCPC Geographical - Japan Meteorological Agency' markup 'mddate', Time.now.strftime('%Y-%m-%dT%H:%M:%SZ') markup 'subjkey', 'NWP' markup 'subjkey', 'GPV' markup 'subjkey', h[:model] markup 'title', [ h[:level], h[:element], 'of', h[:model], h[:resol], 'deg Resolution', 'ft=' + h[:fcsttime].to_s, h[:area] ].join(' ') markup 'abstract', [ 'model:', h[:model] + ';', 'resolution:', h[:resol] + ';', 'area:', h[:area] + ';', 'level:', h[:level] + ';', 'element:', h[:element] + ';', 'forecast-time:', h[:fcsttime] + ';', 'access:', case h[:access] when 'Open' then 'no restriction' else 'registration required' end + ';', 'use:', 'unrestricted (WMO Res.40 Essential).' ].join(' ') markup 'southbc', h[:bbox].split(/\s/)[0], 'units' => 'deg' markup 'northbc', h[:bbox].split(/\s/)[1], 'units' => 'deg' markup 'westbc', h[:bbox].split(/\s/)[2], 'units' => 'deg' markup 'eastbc', h[:bbox].split(/\s/)[3], 'units' => 'deg' markup 'placekey', h[:area] markup 'themekey', h[:element] markup 'stratkey', h[:level] markup 'horizres', h[:resol], 'units' => 'deg' markup 'maxfcst', h[:fcsttime], 'units' => 'h' markup 'avail', '24', 'units' => 'h' for hh in h[:updtime].split(/\s/) markup 'updtime', format('%02u:00:00Z', hh.to_i) end case h[:updtime].split(/\s/).size when 1 then markup 'updcycle', 'daily' when 2 then markup 'updcycle', '12-hourly' when 4 then markup 'updcycle', '6-hourly' else raise "updcycle #{h[:updtime]}" end markup 'format', 'GRIB1', 'code' => 'FM92-XI Ext. GRIB' markup 'url', "http://www.wis-jma.go.jp/data/browse?Indicator=#{h[:cccc]}&LinkText=#{h[:ttaaii]}" markup 'url', "http://www.wis-jma.go.jp/meta/search.jsp?text=#{q h[:dsname]}&keywords=GRIB+Aggregate", 'function' => 'parent metadata' case h[:access] when 'Open' markup 'raccess', 'no restriction at GISC Tokyo' markup 'ruse', 'WMOEssential' else #when 'Closed' markup 'raccess', 'registration required for GISC Tokyo' markup 'ruse', 'WMOEssential' end } end end case ARGV.size when 2 TSV2XML.new(ARGV[0]).convds(ARGV[1]) when 3 TSV2XML.new(ARGV[0], ARGV[1]).convbull(ARGV[2]) else puts <