eew_parser 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2b849d4919cbcb5149a4d017afd0dfd2a7399106c855b8d919f3671e9a5d4fc
4
- data.tar.gz: 63ea327f4845ed9e28ab929001dc1c931344833ba561001fda859d2ffe921b30
3
+ metadata.gz: 21123397596c23d603c3effd0d986bce0ced93206de76c2d14e560f5137045db
4
+ data.tar.gz: eece41255984ffe5d4f5b7a2f789f32257ea362b2701b6fa762d485f99e7e422
5
5
  SHA512:
6
- metadata.gz: '02976c83e4046dcbaf0befe0304bc830242859f11833cb71a7648e68dd4a23e4ec5c8cde0d49db7110ae361951d838238194d0d7bd83c078071cfd10dd4f8bae'
7
- data.tar.gz: 2725bdcfe4cf7ec94e9b37df691a1a86bb7acb45bcb2ea4c7ae84982ad27db8e9ad1e956dbc54410ff8aae3ed2464182782b8f7e14e667e3a27572f22e66f2a1
6
+ metadata.gz: fd0cde626f2c1d2e9919f7ac9ee096595079a1b177883cee6a5016ad3b182f1a71fb87bd155dbc631546ab4ac6d8263cfa0879e92a128788afd04e207ef51238
7
+ data.tar.gz: a487e06a2191dbc8f769df9f1ed043c9e2a38c3da6a03ad9b03c9b52a0ef80a1bff243034a98a438ec894a229220ede3ff2d634ea8d9aa55748bdc703878ba9b
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.5
3
+ - 2.5.1
4
4
  before_install:
5
5
  - export TZ=Asia/Tokyo
data/eew_parser.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "eew_parser"
3
- spec.version = "0.1.9"
3
+ spec.version = "0.2.0"
4
4
  spec.authors = ["Masaki Matsushita"]
5
5
  spec.email = ["glass.saga@gmail.com"]
6
6
  spec.summary = %q{Parser for Earthquake Early Warning from JMA}
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
14
  spec.require_paths = ["lib"]
15
15
 
16
+ spec.required_ruby_version = '>= 2.3.0'
16
17
  spec.add_development_dependency "bundler", "~> 1.16"
17
18
  spec.add_development_dependency "rake", "~> 11.2"
18
19
  spec.add_development_dependency "rspec", "~> 3.7"
data/lib/area_code.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
1
4
  module EEW
2
5
  # 地域コードをkey,地域名称をvalueとするHash
3
6
  AreaCode = {
data/lib/eew_parser.rb CHANGED
@@ -1,4 +1,4 @@
1
- #encoding: utf-8
1
+ # encoding: utf-8
2
2
 
3
3
  require_relative "epicenter_code"
4
4
  require_relative "area_code"
@@ -28,6 +28,7 @@ module EEW
28
28
  def initialize(str)
29
29
  raise ArgumentError unless str.is_a?(String)
30
30
  @fastcast = str.dup
31
+ @fastcast.force_encoding(Encoding::ASCII)
31
32
  @fastcast.freeze
32
33
  raise Error, "電文の形式が不正です" if @fastcast.bytesize < 135
33
34
  end
@@ -72,6 +73,7 @@ module EEW
72
73
  震源の深さの確からしさ(気象庁の部内システムでの利用): #{probability_of_depth_jma}
73
74
  震央位置の海陸判定: #{land_or_sea}
74
75
  警報を含む内容かどうか: #{warning?}
76
+ 予測手法: #{prediction_method}
75
77
  最大予測震度の変化: #{change}
76
78
  最大予測震度の変化の理由: #{reason_of_change}
77
79
  EOS
@@ -90,25 +92,36 @@ module EEW
90
92
 
91
93
  Attributes = [
92
94
  :type, :from, :drill_type, :report_time, :number_of_telegram, :continue?, :earthquake_time, :id, :status, :final?, :number, :epicenter, :position, :depth,
93
- :magnitude, :seismic_intensity, :probability_of_position_jma, :probability_of_depth, :probability_of_magnitude, :probability_of_position, :probability_of_depth_jma,
94
- :land_or_sea, :warning?, :change, :reason_of_change, :ebi
95
+ :magnitude, :seismic_intensity, :observation_points_of_magnitude, :probability_of_depth, :probability_of_magnitude, :probability_of_position, :probability_of_depth_jma,
96
+ :land_or_sea, :warning?, :prediction_method, :change, :reason_of_change, :ebi
95
97
  ].freeze
96
98
 
97
99
  # 電文を解析した結果をHashで返します。
98
100
  def to_hash
99
- hash = {}
100
- Attributes.each do |attribute|
101
- hash[attribute] = __send__(attribute)
101
+ unless @hash
102
+ @hash = {}
103
+ Attributes.each do |attribute|
104
+ @hash[attribute] = __send__(attribute)
105
+ end
106
+ @hash.freeze
102
107
  end
103
- return hash
108
+ return @hash.dup
104
109
  end
105
110
 
106
111
  # 正しい電文であるかを返します
107
- def verify
108
- Attributes.each do |attribute|
109
- __send__(attribute)
112
+ def valid?
113
+ unless @valid
114
+ begin
115
+ Attributes.each do |attribute|
116
+ __send__(attribute)
117
+ end
118
+ rescue Error
119
+ @valid = false
120
+ else
121
+ @valid = true
122
+ end
110
123
  end
111
- return true
124
+ return @valid
112
125
  end
113
126
 
114
127
  def inspect
@@ -116,7 +129,7 @@ module EEW
116
129
  end
117
130
 
118
131
  def ==(other)
119
- fastcast == other.fastcast
132
+ fastcast == other.fastcast
120
133
  end
121
134
 
122
135
  def <=>(other)
@@ -139,6 +152,12 @@ module EEW
139
152
  end
140
153
  end
141
154
 
155
+ # キャンセル報かどうか
156
+ def canceled?
157
+ return true if @fastcast[0, 2] == "39"
158
+ return false
159
+ end
160
+
142
161
  # 発信官署
143
162
  def from
144
163
  case @fastcast[3, 2]
@@ -234,6 +253,7 @@ module EEW
234
253
  raise Error, "電文の形式が不正です(地震識別番号: #{id})"
235
254
  end
236
255
 
256
+ # 地震識別番号 + 通番
237
257
  def __id__
238
258
  (id * 10) + number
239
259
  end
@@ -260,7 +280,7 @@ module EEW
260
280
 
261
281
  # 発表状況と訓練識別が通常かどうか
262
282
  def normal?
263
- return true if @fastcast[59] == "0" && @fastcast[6, 2] == "00"
283
+ return true if (@fastcast[59] == "0" || @fastcast[59] == 9) && @fastcast[6, 2] == "00"
264
284
  return false
265
285
  end
266
286
 
@@ -351,13 +371,6 @@ module EEW
351
371
  "07" => "7"
352
372
  }.freeze
353
373
 
354
- # 電文フォーマットの震度を文字列に変換
355
- def to_seismic_intensity(str)
356
- SeismicIntensity.fetch(str)
357
- rescue KeyError
358
- raise Error, "電文の形式が不正です(震度: #{str})"
359
- end
360
-
361
374
  # 最大予測震度
362
375
  def seismic_intensity
363
376
  to_seismic_intensity(@fastcast[108, 2])
@@ -561,11 +574,8 @@ module EEW
561
574
 
562
575
  # EBIを含むかどうか
563
576
  def has_ebi?
564
- if @fastcast[135, 3] == "EBI"
565
- return true
566
- else
567
- return false
568
- end
577
+ return true if @fastcast[135, 3] == "EBI"
578
+ return false
569
579
  end
570
580
 
571
581
  # 地域毎の警報の判別、最大予測震度及び主要動到達予測時刻
@@ -582,48 +592,84 @@ module EEW
582
592
  @ebi = []
583
593
  i = 139
584
594
  while i + 20 < @fastcast.bytesize
585
- local = {}
586
- local[:area_code] = @fastcast[i, 3].to_i
587
- local[:area_name] = AreaCode[local[:area_code]] # 地域名称
588
- raise Error, "電文の形式が不正でです(地域名称[EBI])" unless local[:area_name]
589
- if @fastcast[i+7, 2] == "//"
590
- local[:intensity] = "#{to_seismic_intensity(@fastcast[i+5, 2])}以上" # 最大予測震度
591
- elsif @fastcast[i+5, 2] == @fastcast[i+7, 2]
592
- local[:intensity] = "#{to_seismic_intensity(@fastcast[i+5, 2])}"
593
- else
594
- local[:intensity] = "#{to_seismic_intensity(@fastcast[i+7, 2])}から#{to_seismic_intensity(@fastcast[i+5, 2])}"
595
- end
596
- if @fastcast[i+10, 6] == "//////"
597
- local[:arrival_time] = nil # 予想到達時刻
598
- else
599
- local[:arrival_time] = Time.local("20" + @fastcast[26, 2], @fastcast[28, 2], @fastcast[30, 2], @fastcast[i+10, 2], @fastcast[i+12, 2], @fastcast[i+14, 2])
600
- end
601
- case @fastcast[i+17]
602
- when "0"
603
- local[:warning] = false # 警報を含むかどうか
604
- when "1"
605
- local[:warning] = true
606
- when "/", "2".."9"
607
- local[:warning] = nil
608
- else
609
- raise Error, "電文の形式が不正でです(警報の判別[EBI])"
610
- end
611
- case @fastcast[i+18]
612
- when "0"
613
- local[:arrival] = false # 既に到達しているかどうか
614
- when "1"
615
- local[:arrival] = true
616
- when "/", "2".."9"
617
- local[:arrival] = nil
618
- else
619
- raise Error, "電文の形式が不正でです(主要動の到達予測状況[EBI])"
620
- end
621
- @ebi << local
595
+ local_str = @fastcast[i, 20]
596
+ area_code = ebi_area_code(local_str)
597
+ local = {
598
+ area_code: area_code,
599
+ area_name: ebi_area_name(area_code),
600
+ intensity: ebi_intensity(local_str),
601
+ arrival_time: ebi_arrival_time(local_str),
602
+ warning: ebi_warning(local_str),
603
+ arrival: ebi_arrival(local_str)
604
+ }
605
+ local.freeze
606
+ @ebi.push(local)
622
607
  i += 20
623
608
  end
624
609
  @ebi.freeze
625
610
  return @ebi.dup
626
611
  end
612
+
613
+ private
614
+
615
+ # 電文フォーマットの震度を文字列に変換
616
+ def to_seismic_intensity(str)
617
+ SeismicIntensity.fetch(str)
618
+ rescue KeyError
619
+ raise Error, "電文の形式が不正です(震度: #{str})"
620
+ end
621
+
622
+ def ebi_area_code(local_str)
623
+ return Integer(local_str[0, 3])
624
+ rescue ArgumentError
625
+ raise Error, "電文の形式が不正です(EBI: 地域コード)"
626
+ end
627
+
628
+ def ebi_area_name(area_code)
629
+ return AreaCode.fetch(area_code)
630
+ rescue KeyError
631
+ raise Error, "電文の形式が不正です(EBI: 地域名称)"
632
+ end
633
+
634
+ def ebi_intensity(local_str)
635
+ return to_seismic_intensity(local_str[5, 2]) + "以上" if local_str[7, 2] == "//" # 最大予測震度
636
+ return to_seismic_intensity(local_str[5, 2]) if local_str[5, 2] == local_str[7, 2]
637
+ return "#{to_seismic_intensity(local_str[7, 2])}から#{to_seismic_intensity(local_str[5, 2])}"
638
+ end
639
+
640
+ # 予想到達時刻
641
+ def ebi_arrival_time(local_str)
642
+ return nil if local_str[10, 6] == "//////"
643
+ return Time.local("20" + @fastcast[26, 2], @fastcast[28, 2], @fastcast[30, 2], local_str[10, 2], local_str[12, 2], local_str[14, 2])
644
+ rescue ArgumentError
645
+ raise Error, "電文の形式が不正です (EBI: 地震発生時刻)"
646
+ end
647
+
648
+ def ebi_warning(local_str)
649
+ case local_str[17]
650
+ when "0"
651
+ return false
652
+ when "1"
653
+ return true
654
+ when "/", "2".."9"
655
+ return nil
656
+ else
657
+ raise Error, "電文の形式が不正です(EBI: 警報の判別)"
658
+ end
659
+ end
660
+
661
+ def ebi_arrival(local_str)
662
+ case local_str[18]
663
+ when "0"
664
+ return false
665
+ when "1"
666
+ return true
667
+ when "/", "2".."9"
668
+ return nil
669
+ else
670
+ raise Error, "電文の形式が不正です(EBI: 主要動の到達予測状況)"
671
+ end
672
+ end
627
673
  end
628
674
  end
629
675
 
@@ -646,40 +692,7 @@ EOS
646
692
 
647
693
  fc = EEW::Parser.new(str)
648
694
  p fc
649
- p fc.fastcast
650
- p fc.to_hash
651
-
652
- puts <<FC
653
- 電文種別コード: #{fc.type}
654
- 発信官署: #{fc.from}
655
- 訓練等の識別符: #{fc.drill_type}
656
- 電文の発表時刻: #{fc.report_time}
657
- 電文がこの電文を含め何通あるか: #{fc.number_of_telegram}
658
- コードが続くかどうか: #{fc.continue?}
659
- 地震発生時刻もしくは地震検知時刻: #{fc.earthquake_time}
660
- 地震識別番号: #{fc.id}
661
- 発表状況(訂正等)の指示: #{fc.status}
662
- 発表する高度利用者向け緊急地震速報の番号(地震単位での通番): #{fc.number}
663
- 震央地名コード: #{fc.epicenter}
664
- 震央の位置: #{fc.position}
665
- 震源の深さ(単位 km)(不明・未設定時,キャンセル時:///): #{fc.depth}
666
- マグニチュード(不明・未設定時、キャンセル時:///): #{fc.magnitude}
667
- 最大予測震度(不明・未設定時、キャンセル時://): #{fc.seismic_intensity}
668
- 震央の確からしさ: #{fc.probability_of_position}
669
- 震源の深さの確からしさ: #{fc.probability_of_depth}
670
- マグニチュードの確からしさ: #{fc.probability_of_magnitude}
671
- 震央の確からしさ(気象庁の部内システムでの利用): #{fc.probability_of_position_jma}
672
- 震源の深さの確からしさ(気象庁の部内システムでの利用): #{fc.probability_of_depth_jma}
673
- 震央位置の海陸判定: #{fc.land_or_sea}
674
- 警報を含む内容かどうか: #{fc.warning?}
675
- 最大予測震度の変化: #{fc.change}
676
- 最大予測震度の変化の理由: #{fc.reason_of_change}
677
- FC
678
- fc.ebi.each do |local|
679
- puts "地域コード: #{local[:area_code]} 地域名: #{local[:area_name]} 最大予測震度: #{local[:intensity]} 予想到達時刻: #{local[:arrival_time]}"
680
- puts "警報を含むかどうか: #{local[:warning]} 既に到達しているかどうか: #{local[:arrival]}"
681
- end
682
-
695
+ puts fc.fastcast
696
+ pp fc.to_hash
683
697
  puts fc.print
684
- p EEW::AreaCode.values.max_by(&:size).size
685
698
  end
@@ -1,3 +1,6 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
1
4
  module EEW
2
5
  # 震央地名コードをkey,震央地名称をvalueとするHash
3
6
  EpicenterCode = {
@@ -43,6 +43,8 @@ EBI 251 S6+6- ////// 11 300 S5+5- ////// 11 250 S5+5- ////// 11
43
43
 
44
44
  its(:type) { is_expected.to eq("マグニチュード、最大予測震度及び主要動到達予測時刻の高度利用者向け緊急地震速報(グリッドサーチ法、EPOS自動処理手法)") }
45
45
 
46
+ it { is_expected.not_to be_canceled }
47
+
46
48
  its(:from) { is_expected.to eq("東京") }
47
49
 
48
50
  its(:drill_type) { is_expected.to eq("通常") }
@@ -99,7 +101,7 @@ EBI 251 S6+6- ////// 11 300 S5+5- ////// 11 250 S5+5- ////// 11
99
101
 
100
102
  its(:land_or_sea) { is_expected.to eq("陸域") }
101
103
 
102
- it { is_expected.to be_warning }
104
+ its(:warning?) { is_expected.to be true }
103
105
 
104
106
  its(:prediction_method) { is_expected.to eq("不明又は未設定") }
105
107
 
@@ -167,7 +169,7 @@ ND20110415005001 NCN001 JD////////////// JN///
167
169
  it "can be verified" do
168
170
  expect {
169
171
  eew = EEW::Parser.new(invalid)
170
- eew.verify
172
+ eew.valid?
171
173
  }.not_to raise_error
172
174
  end
173
175
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eew_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Matsushita
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-20 00:00:00.000000000 Z
11
+ date: 2018-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -98,7 +98,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - ">="
100
100
  - !ruby/object:Gem::Version
101
- version: '0'
101
+ version: 2.3.0
102
102
  required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  requirements:
104
104
  - - ">="