#!/opt/ruby187/bin/ruby require 'rubygems' require 'sqlite3' class App TABLE_A = <= 12 hours) FM 51 (TAF) F U Upper air FM 45 (IAC) F V Volcanic ash advisories [TEXT] F W Winter sports [TEXT] F X Miscellaneous [TEXT] F Z Shipping area FM 61 (MAFOR) N G Hydrological [TEXT] N H Marine [TEXT] N N Nuclear emergency response [TEXT] N O METNO/WIFMA [TEXT] N P Product generation delay [TEXT] N T TEST MSG [System related] [TEXT] N W Warning related and/or cancellation [TEXT] S A Aviation routine reports FM 15 (METAR) S B Radar reports (Part A) FM 20 (RADOB) S C Radar reports (Part B) FM 20 (RADOB) S D Radar reports (Parts A & B) FM 20 (RADOB) S E Seismic data *(SEISMIC) S F Atmospherics reports FM 81 (SFAZI)/FM 82 (SFLOC)/FM 83 (SFAZU) S G Radiological data report FM 22 (RADREP) S I Intermediate synoptic hour FM 12 (SYNOP)/FM 13 (SHIP) S L - - S M Main synoptic hour FM 12 (SYNOP)/FM 13 (SHIP) S N Non-standard synoptic hour FM 12 (SYNOP)/FM 13 (SHIP) S O Oceanographic data FM 63 (BATHY)/FM 64 (TESAC)/FM 62 (TRACKOB) S P Special aviation weather reports FM 16 (SPECI) S R Hydrological (river) reports FM 67 (HYDRA) S S Drifting buoy reports FM 18 (BUOY) S T Sea Ice [TEXT] S U Snow depth [TEXT] S V Lake ice [TEXT] S X Miscellaneous [TEXT] S W Wave information FM 65 (WAVEOB) S Z Sea level data and deep-ocean tsunami data [any alphanumeric format] S Y Seismic wave form data [any format] T B Satellite orbit parameters [TEXT] T C Satellite cloud interpretations FM 85 (SAREP) T H Satellite remote upper air soundings FM 86 (SATEM) T R Clear radiance observations FM 87 (SARAD) T T Sea surface temperatures FM 88 (SATOB) T W Winds and cloud temperatures FM 88 (SATOB) T X Miscellaneous [TEXT] U L Upper level pressure, temperature, humidity and wind (Part C) FM 35 (TEMP)/FM 36 (TEMP SHIP)/FM 38 (TEMP MOBIL) U M Upper level pressure, temperature, humidity and wind (Parts A and B) [National and bilateral option] FM 35 (TEMP)/FM 36 (TEMP SHIP)/FM 38 (TEMP MOBIL) U N Rocketsonde reports FM 39 (ROCOB)/FM 40 (ROCOB SHIP) U P Upper wind (Part A) FM 32 (PILOT)/FM 33 (PILOT SHIP)/FM 34 (PILOT MOBIL) U Q Upper wind (Part D) FM 32 (PILOT)/FM 33 (PILOT SHIP)/FM 34 (PILOT MOBIL) U R Aircraft report [NATIONAL**] (RECCO) U S Upper level pressure, temperature, humidity and wind (Part A) FM 35 (TEMP)/FM 36 (TEMP SHIP)FM 38 (TEMP MOBIL) U T Aircraft report FM 41 (CODAR) U X Miscellaneous [TEXT] U Y Upper wind (Parts C and D) [National and bilateral option] FM 32 (PILOT)/FM 33 (PILOT SHIP)/FM 34 (PILOT MOBIL) U Z Upper level pressure, temperature, humidity and wind from a sonde released by carrier balloon or aircraft (Parts A, B, C, D) FM 37 (TEMP DROP) #U A Aircraft reports FM 41 (CODAR), ICAO (AIREP) U D Aircraft reports FM 42 (AMDAR) U E Upper level pressure, temperature, humidity and wind (Part D) FM 35 (TEMP)/FM 36 (TEMP SHIP)/FM 38 (TEMP MOBIL) U F Upper level pressure, temperature, humidity and wind (Parts C and D) [National and bilateral option] FM 35 (TEMP)/FM 36 (TEMP SHIP)/FM 38 (TEMP MOBIL) U G Upper wind (Part B) FM 32 (PILOT)/FM 33 (PILOT SHIP)/FM 34 (PILOT MOBIL) U H Upper wind (Part C) FM 32 (PILOT)/FM 33 (PILOT SHIP)/FM 34 (PILOT MOBIL) U I Upper wind (Parts A and B) [National and bilateral option] FM 32 (PILOT)/FM 33 (PILOT SHIP)/FM 34 (PILOT MOBIL) U K Upper level pressure, temperature, humidity and wind(Part B) FM 35 (TEMP)/FM 36 (TEMP SHIP)/FM 38 (TEMP MOBIL) W A AIRMET [TEXT] W C Tropical cyclone (SIGMET) [TEXT] W E Tsunami [TEXT] W F Tornado [TEXT] W G Hydrological/River flood [TEXT] W H Marine/Coastal flood [TEXT] W O Other [TEXT] W S SIGMET [TEXT] W T Tropical cyclone (Typhoon/Hurricane) [TEXT] W U Severe thunderstorm [TEXT] W V Volcanic ash clouds (SIGMET) [TEXT] W W Warnings and weather summary [TEXT] EOT TABLE_B2 = <= 0 AND iimax <= 99 AND iimin <= iimax) ); ENDSQL tsvsplit(TABLE_A) do |row| next if row['DataType'] == '-' @db.execute(<<-ENDSQL, row['T1'], row['DataType']) REPLACE INTO datatype(t1, t2, a1, text) VALUES(?, '?', '?', ?) ENDSQL end tsvsplit(TABLE_B1) do |row| next if /^#/ =~ row['T1'] dtype = row['DataType'] next if dtype == '-' dtype = "#{datatype_t1(row['T1'])} - #{dtype}" ('A'..'Z').each { |a1| @db.execute(<<-ENDSQL, row['T1'], row['T2'], a1, dtype) REPLACE INTO datatype(t1, t2, a1, text) VALUES(?, ?, ?, ?) ENDSQL } end tsvsplit(TABLE_B2) do |row| next if /^-$/ =~ row['DataType'] next if /^#/ =~ row['T1'] for t1 in row['T1'].split(/,\s*/) dtype = "#{datatype_t1(t1)} - #{row['DataType']}" ('A'..'Z').each do |a1| @db.execute(<<-ENDSQL, t1, row['T2'], a1, dtype) REPLACE INTO datatype(t1, t2, a1, text) VALUES(?, ?, ?, ?) ENDSQL end end end tsvsplit(TABLE_C6) do |row| next if /^-$/ =~ row['DataType'] next if /^#/ =~ row['T1'] t1 = row['T1'] a1a = case row['A1'] when '?' 'A'..'Z' else [row['A1']] end dtype = "#{datatype_t1(t1)} - #{row['DataType']}" case row['ii'] when /(\d+)-(\d+)/ iimin, iimax = $1.to_i, $2.to_i else iimin, iimax = 0, 99 end for a1 in a1a @db.execute(<<-ENDSQL, t1, row['T2'], a1, iimin, iimax, dtype) REPLACE INTO datatype(t1, t2, a1, iimin, iimax, text) VALUES(?, ?, ?, ?, ?, ?) ENDSQL end end end def place @db.execute_batch(<<-ENDSQL) CREATE TABLE IF NOT EXISTS place( t1 CHAR(1) NOT NULL, a1 CHAR(1) NOT NULL, a2 CHAR(1) NOT NULL, southbc FLOAT, northbc FLOAT, westbc FLOAT, eastbc FLOAT, text STRING NOT NULL, CONSTRAINT taa UNIQUE (t1, a1, a2) ); ENDSQL tsvsplit(TABLE_C1) do |row| a1 = row['A1A2'][0,1] a2 = row['A1A2'][1,1] if row['SNWE'] != '-' sb, nb, wb, eb = row['SNWE'].split(/,/).map{|s| s.to_f} else sb, nb, wb, eb = nil end text = row['AREA'] %w(A C E F N S U V W).each do |t1| @db.execute(<<-ENDSQL, t1, a1, a2, sb, nb, wb, eb, text) REPLACE INTO place(t1, a1, a2, southbc, northbc, westbc, eastbc, text) VALUES(?, ?, ?, ?, ?, ?, ?, ?) ENDSQL end end tsvsplit(TABLE_C3) do |row| a1 = row['A1'] sb, nb, wb, eb = row['SNWE'].split(/,/).map{|s| s.to_f} text = row['AREA'] %w(D G H O P Q T X Y).each do |t1| @db.execute(<<-ENDSQL, t1, a1, sb, nb, wb, eb, text) REPLACE INTO place(t1, a1, a2, southbc, northbc, westbc, eastbc, text) VALUES(?, ?, '?', ?, ?, ?, ?, ?) ENDSQL end %w(I K).each do |t1| @db.execute(<<-ENDSQL, t1, a1, sb, nb, wb, eb, text) REPLACE INTO place(t1, a1, a2, southbc, northbc, westbc, eastbc, text) VALUES(?, '?', ?, ?, ?, ?, ?, ?) ENDSQL end end end def fcsttime @db.execute_batch(<<-ENDSQL) CREATE TABLE IF NOT EXISTS fcsttime( t1 CHAR(1) NOT NULL, a2 CHAR(1) NOT NULL, fcsthour FLOAT, text STRING NOT NULL, CONSTRAINT taa UNIQUE (t1, a2) ); ENDSQL tsvsplit(TABLE_C4) do |row| a2 = row['A2'] ft = row['FT'].to_f text = row['RefTime'] for t1 in row['T1'].split(/,\s*/) @db.execute(<<-ENDSQL, t1, a2, ft, text) REPLACE INTO fcsttime(t1, a2, fcsthour, text) VALUES(?, ?, ?, ?) ENDSQL end end end def level @db.execute_batch(<<-ENDSQL) CREATE TABLE IF NOT EXISTS level( t1 CHAR(1) NOT NULL, ii CHAR(2) NOT NULL, text STRING NOT NULL, CONSTRAINT tii UNIQUE (t1, ii) ); ENDSQL tsvsplit(TABLE_D1) do |row| ii = row['ii'] text = row['Level'] for t1 in row['T1'].split(/,\s*/) @db.execute(<<-ENDSQL, t1, ii, text) REPLACE INTO level(t1, ii, text) VALUES(?, ?, ?) ENDSQL end end end def run @db.transaction do datatype place fcsttime level end @db.close end end #class App.new.run