jma_code 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,50 +3,125 @@ module JMACode
3
3
  using Blank
4
4
 
5
5
  class AreaForecastLocal < Struct.new(
6
- :code, :name, :name_phonetic, :used_by,
6
+ :code, :name, :name_phonetic,
7
+ :belonging_local_code_in_weather_alert,
8
+ :belonging_local_code_in_tornado_alert,
9
+ :used_by,
7
10
  keyword_init: true
8
11
  )
12
+ CSV_ROW_SEP = "\r\n"
13
+ NUM_HEADER_ROWS = 4
9
14
  HEADERS = %i(
10
15
  code
11
16
  name
12
17
  name_phonetic
18
+ used_by_area_forecast_type3_in_weather_alert
19
+ used_by_area_forecast_type2_in_weather_alert
20
+ used_by_area_forecast_type1_in_weather_alert
21
+ used_by_weather_forecast
22
+ used_by_weather_description
23
+ used_by_next_weather_forecast
24
+ used_by_landslide_alert
25
+ used_by_area_forecast_type3_in_tornado_alert
26
+ used_by_area_forecast_type2_in_tornado_alert
27
+ used_by_area_forecast_type1_in_tornado_alert
28
+ used_by_recorded_heavy_rain_alert
29
+ used_by_flood_alert
30
+ used_by_area_forecast_type3_in_typhoon_probability
31
+ used_by_area_forecast_type1_in_typhoon_probability
32
+ belonging_local_code_in_weather_alert
33
+ belonging_local_code_in_tornado_alert
13
34
  )
14
35
 
15
36
  class << self
16
- attr_accessor :area_information_cities
37
+ attr_accessor :data
17
38
 
18
- def load_20240216(&block)
19
- path = File.join(File.dirname(__FILE__), "../../data/20240216_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(コード表).csv")
39
+ def load_csv(version: "20240216-completed")
40
+ path = File.join(File.dirname(__FILE__), "../../data/#{version}_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(コード表).csv")
20
41
  File.open(path) do |f|
21
- csv = CSV.new(f, headers: HEADERS, row_sep: "\r\n")
22
- if block_given?
23
- yield(csv)
24
- else
25
- load(csv, num_headers: 3, &block)
42
+ csv = CSV.new(f, headers: HEADERS, row_sep: CSV_ROW_SEP)
43
+ yield(csv)
44
+ end
45
+ end
46
+
47
+ def load(**args)
48
+ load_csv(**args) do |csv|
49
+ csv.drop(NUM_HEADER_ROWS).map do |row|
50
+ build_by_csv_row(row)
26
51
  end
27
52
  end
28
53
  end
29
54
 
30
- def load(csv, num_headers: 3)
31
- list = []
32
- csv.each.with_index do |row, i|
33
- next if i < num_headers
34
- list << build_by_csv_row(row)
55
+ def get
56
+ @data ||= load
57
+ end
58
+
59
+ def load_relation(version: "20240216")
60
+ headers = %i(code_type3 name_type3 code_type2 name_type2 code_type1 name_type1)
61
+
62
+ path1 = File.join(File.dirname(__FILE__), "../../data/#{version}_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(関係表 警報・注意報.csv")
63
+ relation1 = File.open(path1) do |f|
64
+ csv = CSV.new(f, headers: headers, row_sep: CSV_ROW_SEP)
65
+ csv.drop(3).map do |row|
66
+ [row[:code_type3], row[:code_type2], row[:code_type1]]
67
+ end
35
68
  end
36
- list
69
+
70
+ path2 = File.join(File.dirname(__FILE__), "../../data/#{version}_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(関係表 竜巻注意情報.csv")
71
+ relation2 = File.open(path2) do |f|
72
+ csv = CSV.new(f, headers: headers, row_sep: CSV_ROW_SEP)
73
+ csv.drop(3).map do |row|
74
+ [row[:code_type3], row[:code_type2], row[:code_type1]]
75
+ end
76
+ end
77
+
78
+ Struct.new(:relation_weather_alert, :relation_tornado_alert, keyword_init: true).new({
79
+ relation_weather_alert: relation1, relation_tornado_alert: relation2
80
+ })
37
81
  end
38
82
 
39
83
  def build_by_csv_row(row)
84
+ used_by_fields = HEADERS.select{|n| n.to_s.start_with?('used_by_')}
85
+
40
86
  new(
41
87
  code: row[:code],
42
88
  name: row[:name],
43
89
  name_phonetic: row[:name_phonetic],
90
+ belonging_local_code_in_weather_alert: row[:belonging_local_code_in_weather_alert],
91
+ belonging_local_code_in_tornado_alert: row[:belonging_local_code_in_tornado_alert],
92
+ used_by: used_by_fields.select{|f| row[f] == '1'}.map{|f| f.to_s.sub(/\Aused_by_/, '').to_sym}
44
93
  )
45
94
  end
46
95
  end
47
96
 
48
- def area_information_city
49
- @area_information_city ||= (self.class.area_information_cities || []).find{|x| x.area_forecast_local_code == code}
97
+ def area_information_cities
98
+ @area_information_cities ||= AreaInformationCity.get.select{|x| x.area_forecast_local_code == code}
99
+ end
100
+
101
+ def belonging_local_in_weather_alert
102
+ return nil if belonging_local_code_in_weather_alert.blank?
103
+ @belonging_local_in_weather_alert ||= begin
104
+ AreaForecastLocal.get.find{|a| a.code == belonging_local_code_in_weather_alert}
105
+ end
106
+ end
107
+
108
+ def belonging_local_in_tornado_alert
109
+ return nil if belonging_local_code_in_tornado_alert.blank?
110
+ @belonging_local_in_tornado_alert ||= begin
111
+ AreaForecastLocal.get.find{|a| a.code == belonging_local_code_in_tornado_alert}
112
+ end
113
+ end
114
+
115
+ def any_belonging_locals
116
+ [belonging_local_in_weather_alert, belonging_local_in_tornado_alert].compact.uniq(&:code)
117
+ end
118
+
119
+ def to_csv_row
120
+ HEADERS.map do |k|
121
+ respond_to?(k) ?
122
+ public_send(k) :
123
+ nil
124
+ end
50
125
  end
51
126
  end
52
127
  end
@@ -7,6 +7,8 @@ module JMACode
7
7
  :area_forecast_local_code, :used_by,
8
8
  keyword_init: true
9
9
  )
10
+ CSV_ROW_SEP = "\r\n"
11
+ NUM_HEADER_ROWS = 3
10
12
  HEADERS = %i(
11
13
  code
12
14
  name
@@ -15,8 +17,8 @@ module JMACode
15
17
  area_forecast_local_code
16
18
  used_by_weather_alert
17
19
  used_by_tornado_alert
18
- used_by_long_surge_alert
19
- used_by_short_surge_alert
20
+ used_by_storm_surge_alert
21
+ used_by_high_wave_alert
20
22
  used_by_landslide_alert
21
23
  used_by_flood_alert
22
24
  name_used_by_earthquake
@@ -30,27 +32,26 @@ module JMACode
30
32
  )
31
33
 
32
34
  class << self
33
- attr_accessor :area_forecast_locals
35
+ attr_accessor :data
34
36
 
35
- def load_20240216(&block)
36
- path = File.join(File.dirname(__FILE__), "../../data/20240216_AreaInformationCity-AreaForecastLocalM/AreaInformationCity.csv")
37
+ def load_csv(version: "20240216")
38
+ path = File.join(File.dirname(__FILE__), "../../data/#{version}_AreaInformationCity-AreaForecastLocalM/AreaInformationCity.csv")
37
39
  File.open(path) do |f|
38
- csv = CSV.new(f, headers: HEADERS, row_sep: "\r\n")
39
- if block_given?
40
- yield(csv)
41
- else
42
- load(csv, num_headers: 3, &block)
43
- end
40
+ csv = CSV.new(f, headers: HEADERS, row_sep: CSV_ROW_SEP)
41
+ yield(csv)
44
42
  end
45
43
  end
46
44
 
47
- def load(csv, num_headers: 3)
48
- list = []
49
- csv.each.with_index do |row, i|
50
- next if i < num_headers
51
- list << build_by_csv_row(row)
45
+ def load(**args)
46
+ load_csv(**args) do |csv|
47
+ csv.drop(NUM_HEADER_ROWS).map do |row|
48
+ build_by_csv_row(row)
49
+ end
52
50
  end
53
- list
51
+ end
52
+
53
+ def get
54
+ @data ||= load
54
55
  end
55
56
 
56
57
  def build_by_csv_row(row)
@@ -77,8 +78,8 @@ module JMACode
77
78
  used_by: [
78
79
  row[:used_by_weather_alert] == '1' ? :weather_alert : nil,
79
80
  row[:used_by_tornado_alert] == '1' ? :tornado_alert : nil,
80
- row[:used_by_long_surge_alert] == '1' ? :long_surge_alert : nil,
81
- row[:used_by_short_surge_alert] == '1' ? :short_surge_alert : nil,
81
+ row[:used_by_storm_surge_alert] == '1' ? :storm_surge_alert : nil,
82
+ row[:used_by_high_wave_alert] == '1' ? :high_wave_alert : nil,
82
83
  row[:used_by_landslide_alert] == '1' ? :landslide_alert : nil,
83
84
  row[:used_by_flood_alert] == '1' ? :flood_alert : nil,
84
85
  row[:name_used_by_earthquake].present? ? :earthquake : nil,
@@ -91,7 +92,7 @@ module JMACode
91
92
  end
92
93
 
93
94
  def area_forecast_local
94
- @area_forecast_local ||= (self.class.area_forecast_locals || []).find{|x| x.code == area_forecast_local_code}
95
+ @area_forecast_local ||= AreaForecastLocal.get.find{|x| x.code == area_forecast_local_code}
95
96
  end
96
97
  end
97
98
  end
@@ -0,0 +1,75 @@
1
+ require "csv"
2
+
3
+ module JMACode
4
+ class AreaRiver < Struct.new(
5
+ :code, :name, :name_phonetic,
6
+ :name2, :name_phonetic2, :name3, :name_phonetic3,
7
+ :prefecture_codes,
8
+ keyword_init: true
9
+ )
10
+ CSV_ROW_SEP = "\r\n"
11
+ HEADERS = %i(code name name_phonetic name2 name_phonetic2 name3 name_phonetic3 prefecture_codes)
12
+ NUM_HEADER_ROWS = 3
13
+ PREFECTURE_CODE_SEPARATOR = '/'
14
+
15
+ class << self
16
+ attr_accessor :data
17
+
18
+ def load_csv(version: "20230105-completed")
19
+ path = File.join(File.dirname(__FILE__), "../../data/#{version}_AreaRiver.csv")
20
+ File.open(path) do |f|
21
+ csv = CSV.new(f, headers: HEADERS, row_sep: CSV_ROW_SEP)
22
+ yield(csv)
23
+ end
24
+ end
25
+
26
+ def load(**args)
27
+ load_csv(**args) do |csv|
28
+ csv.drop(NUM_HEADER_ROWS).map do |row|
29
+ new(
30
+ code: row[:code],
31
+ name: row[:name],
32
+ name_phonetic: row[:name_phonetic],
33
+ name2: row[:name2],
34
+ name_phonetic2: row[:name_phonetic2],
35
+ name3: row[:name3],
36
+ name_phonetic3: row[:name_phonetic3],
37
+ prefecture_codes: row[:prefecture_codes]
38
+ )
39
+ end
40
+ end
41
+ end
42
+
43
+ def get
44
+ @data ||= load
45
+ end
46
+ end
47
+
48
+ def prefecture_code_list
49
+ @prefecture_code_list ||= (prefecture_codes || "").split(PREFECTURE_CODE_SEPARATOR)
50
+ end
51
+
52
+ def add_prefecture_code(pref_code)
53
+ ids = (prefecture_code_list + [pref_code]).sort.uniq
54
+ self.prefecture_codes = ids.join(PREFECTURE_CODE_SEPARATOR)
55
+ end
56
+
57
+ def prefectures
58
+ @prefectures ||= Prefecture.get.select{|pref|
59
+ prefecture_code_list.include?(pref.code)
60
+ }
61
+ end
62
+
63
+ def water_level_stations
64
+ @water_level_stations ||= WaterLevelStation.get.select{|w| w.river_code == code}
65
+ end
66
+
67
+ def to_csv_row
68
+ HEADERS.map do |k|
69
+ respond_to?(k) ?
70
+ public_send(k) :
71
+ nil
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,16 @@
1
+ class JMACode::AreaForecastType < Struct.new(:slug, :name, keyword_init: true)
2
+ LIST = {
3
+ type1: {name: "府県予報区等"},
4
+ type2: {name: "一次細分区域等"},
5
+ type3: {name: "市町村等をまとめた地域等"},
6
+ type4: {name: "市町村等"},
7
+ }
8
+
9
+ def self.load
10
+ LIST.map{|k,v| new(v.merge(slug: k.to_s))}
11
+ end
12
+
13
+ def self.get
14
+ @data ||= load
15
+ end
16
+ end
@@ -0,0 +1,83 @@
1
+ module JMACode
2
+ class Prefecture < Struct.new(
3
+ :id, :code, :name, :short_name, :slug,
4
+ keyword_init: true
5
+ )
6
+ DATA = [
7
+ [1, '北海道', '北海道', 'hokkaido'],
8
+ [2, '青森県', '青森', 'aomori'],
9
+ [3, '岩手県', '岩手', 'iwate'],
10
+ [4, '宮城県', '宮城', 'miyagi'],
11
+ [5, '秋田県', '秋田', 'akita'],
12
+ [6, '山形県', '山形', 'yamagata'],
13
+ [7, '福島県', '福島', 'fukushima'],
14
+ [8, '茨城県', '茨城', 'ibaraki'],
15
+ [9, '栃木県', '栃木', 'tochigi'],
16
+ [10, '群馬県', '群馬', 'gunma'],
17
+ [11, '埼玉県', '埼玉', 'saitama'],
18
+ [12, '千葉県', '千葉', 'chiba'],
19
+ [13, '東京都', '東京', 'tokyo'],
20
+ [14, '神奈川県', '神奈川', 'kanagawa'],
21
+ [15, '新潟県', '新潟', 'niigata'],
22
+ [16, '富山県', '富山', 'toyama'],
23
+ [17, '石川県', '石川', 'ishikawa'],
24
+ [18, '福井県', '福井', 'fukui'],
25
+ [19, '山梨県', '山梨', 'yamanashi'],
26
+ [20, '長野県', '長野', 'nagano'],
27
+ [20, '岐阜県', '岐阜', 'gifu'],
28
+ [22, '静岡県', '静岡', 'shizuoka'],
29
+ [23, '愛知県', '愛知', 'aichi'],
30
+ [24, '三重県', '三重', 'mie'],
31
+ [25, '滋賀県', '滋賀', 'shiga'],
32
+ [26, '京都府', '京都', 'kyoto'],
33
+ [27, '大阪府', '大阪', 'osaka'],
34
+ [28, '兵庫県', '兵庫', 'hyogo'],
35
+ [29, '奈良県', '奈良', 'nara'],
36
+ [30, '和歌山県', '和歌山', 'wakayama'],
37
+ [31, '鳥取県', '鳥取', 'tottori'],
38
+ [32, '島根県', '島根', 'shimane'],
39
+ [33, '岡山県', '岡山', 'okayama'],
40
+ [34, '広島県', '広島', 'hiroshima'],
41
+ [35, '山口県', '山口', 'yamaguchi'],
42
+ [36, '徳島県', '徳島', 'tokushima'],
43
+ [37, '香川県', '香川', 'kagawa'],
44
+ [38, '愛媛県', '愛媛', 'ehime'],
45
+ [39, '高知県', '高知', 'kochi'],
46
+ [40, '福岡県', '福岡', 'fukuoka'],
47
+ [41, '佐賀県', '佐賀', 'saga'],
48
+ [42, '長崎県', '長崎', 'nagasaki'],
49
+ [43, '熊本県', '熊本', 'kumamoto'],
50
+ [44, '大分県', '大分', 'oita'],
51
+ [45, '宮崎県', '宮崎', 'miyazaki'],
52
+ [46, '鹿児島県', '鹿児島', 'kagoshima'],
53
+ [47, '沖縄県', '沖縄', 'okinawa'],
54
+ ]
55
+
56
+ class << self
57
+ attr_accessor :data
58
+
59
+ def load
60
+ DATA.map do |id, name, short_name, slug|
61
+ new(
62
+ id: id,
63
+ code: id.to_s.rjust(2, '0'),
64
+ name: name,
65
+ short_name: short_name,
66
+ slug: slug
67
+ )
68
+ end
69
+ end
70
+
71
+ def get
72
+ @data ||= load
73
+ end
74
+ end
75
+
76
+ def type
77
+ @type ||= begin
78
+ res = name.sub(short_name, '')
79
+ res.empty? ? '道' : res
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,3 +1,3 @@
1
1
  module JMACode
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -7,38 +7,44 @@ module JMACode
7
7
  :code, :name, :river_name,
8
8
  keyword_init: true
9
9
  )
10
- HEADERS = %i(
11
- code
12
- name
13
- river_name
14
- )
10
+ CSV_ROW_SEP = "\r\n"
11
+ HEADERS = %i(code name river_name)
12
+ NUM_HEADER_ROWS = 3
15
13
 
16
14
  class << self
17
- def load_20240418(&block)
18
- path = File.join(File.dirname(__FILE__), "../../data/20240418_WaterLevelStation.csv")
15
+ attr_accessor :data
16
+
17
+ def load_csv(version: "20240418")
18
+ path = File.join(File.dirname(__FILE__), "../../data/#{version}_WaterLevelStation.csv")
19
19
  File.open(path) do |f|
20
- csv = CSV.new(f, headers: HEADERS, row_sep: "\r\n")
21
- if block_given?
22
- yield(csv)
23
- else
24
- load(csv, num_headers: 3, &block)
25
- end
20
+ csv = CSV.new(f, headers: HEADERS, row_sep: CSV_ROW_SEP)
21
+ yield(csv)
26
22
  end
27
23
  end
28
24
 
29
- def load(csv, num_headers: 3)
30
- csv.drop(num_headers).map do |row|
31
- build_by_csv_row(row)
25
+ def load(**args)
26
+ load_csv(**args) do |csv|
27
+ csv.drop(NUM_HEADER_ROWS).map do |row|
28
+ new(
29
+ code: row[:code],
30
+ name: row[:name],
31
+ river_name: row[:river_name],
32
+ )
33
+ end
32
34
  end
33
35
  end
34
36
 
35
- def build_by_csv_row(row)
36
- new(
37
- code: row[:code],
38
- name: row[:name],
39
- river_name: row[:river_name],
40
- )
37
+ def get
38
+ @data ||= load
41
39
  end
42
40
  end
41
+
42
+ def river_code
43
+ code[0..9]
44
+ end
45
+
46
+ def river
47
+ @river ||= AreaRiver.get.find{|r| r.code == river_code}
48
+ end
43
49
  end
44
50
  end
data/lib/jma_code.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "jma_code/version"
2
2
  require "jma_code/ext/blank"
3
+ require "jma_code/prefecture"
3
4
  require "jma_code/wmo_observing_station"
4
5
  require "jma_code/water_level_station"
5
6
  require "jma_code/river_office"
@@ -8,6 +9,7 @@ require "jma_code/area_flood_forecast"
8
9
  require "jma_code/area_information_city"
9
10
  require "jma_code/area_forecast_local"
10
11
  require "jma_code/area_marine"
12
+ require "jma_code/area_river"
11
13
 
12
14
  module JMACode
13
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jma_code
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - metheglin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-27 00:00:00.000000000 Z
11
+ date: 2024-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -34,6 +34,10 @@ files:
34
34
  - data/20130523_AreaMarineAJ/AreaMarineA.csv
35
35
  - data/20130523_AreaMarineAJ/AreaMarineJ.csv
36
36
  - data/20201026_WmoObservingStations.csv
37
+ - data/20230105-completed_AreaRiver.csv
38
+ - data/20230105_AreaFloodForecast.csv
39
+ - data/20230105_AreaRiver.csv
40
+ - data/20240216-completed_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(コード表).csv
37
41
  - data/20240216_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(コード表).csv
38
42
  - data/20240216_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(関係表 竜巻注意情報.csv
39
43
  - data/20240216_AreaInformationCity-AreaForecastLocalM/AreaForecastLocalM(関係表 警報・注意報.csv
@@ -68,8 +72,11 @@ files:
68
72
  - lib/jma_code/area_forecast_local.rb
69
73
  - lib/jma_code/area_information_city.rb
70
74
  - lib/jma_code/area_marine.rb
75
+ - lib/jma_code/area_river.rb
76
+ - lib/jma_code/entity/area_forecast_type.rb
71
77
  - lib/jma_code/ext/blank.rb
72
78
  - lib/jma_code/point_amedas.rb
79
+ - lib/jma_code/prefecture.rb
73
80
  - lib/jma_code/river_office.rb
74
81
  - lib/jma_code/version.rb
75
82
  - lib/jma_code/water_level_station.rb