Class: EEW::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/eew_parser.rb

Defined Under Namespace

Classes: Error

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str) ⇒ Parser

引数には緊急地震速報の電文を与えます。

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
# File 'lib/eew_parser.rb', line 30

def initialize(str)
  raise ArgumentError unless str.is_a?(String)
  @fastcast = str.dup
  @fastcast.force_encoding(Encoding::ASCII)
  @fastcast.freeze
  raise Error, "電文のサイズが不正です" if @fastcast.bytesize < 135
end

Instance Attribute Details

#fastcastObject (readonly)

Returns the value of attribute fastcast.



38
39
40
# File 'lib/eew_parser.rb', line 38

def fastcast
  @fastcast
end

Instance Method Details

#<=>(other) ⇒ Object



48
49
50
# File 'lib/eew_parser.rb', line 48

def <=>(other)
  id + number <=> other.id + other.number
end

#==(other) ⇒ Object



44
45
46
# File 'lib/eew_parser.rb', line 44

def ==(other)
  @fastcast == other.fastcast
end

#canceled?Boolean

キャンセル報かどうか

Returns:

  • (Boolean)


87
88
89
90
# File 'lib/eew_parser.rb', line 87

def canceled?
  return true if @fastcast[0, 2] == "39"
  return false
end

#changeObject

最大予測震度の変化



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/eew_parser.rb', line 454

def change
  case @fastcast[129]
  when "0"
    "ほとんど変化無し"
  when "1"
    "最大予測震度が1.0以上大きくなった"
  when "2"
    "最大予測震度が1.0以上小さくなった"
  when "3".."9"
    "未定義"
  when "/"
    "不明又は未設定"  
  else
    raise Error, "電文の形式が不正です(最大予測震度の変化)"
  end
end

#changed?Boolean

最大予測震度に変化があったかどうか

Returns:

  • (Boolean)


472
473
474
475
476
477
478
479
# File 'lib/eew_parser.rb', line 472

def changed?
  case @fastcast[129]
  when "0", "3".."9", "/"
    return false
  when "1", "2"
    return true
  end
end

#continue?Boolean

コードが続くかどうか

Returns:

  • (Boolean)


160
161
162
163
164
165
166
167
168
169
# File 'lib/eew_parser.rb', line 160

def continue?
  case @fastcast[24]
  when "1"
    true
  when "0"
    false
  else
    raise Error, "電文の形式が不正です"
  end
end

#depthObject

震源の深さ(単位 km)



264
265
266
267
268
269
270
271
272
273
# File 'lib/eew_parser.rb', line 264

def depth
  depth = @fastcast[101, 3]
  if depth == "///"
    return "不明又は未設定"
  else
    return Integer(depth, 10)
  end
rescue ArgumentError
  raise Error, "電文の形式が不正です(震源の深さ)"
end

#drill?Boolean

訓練かどうか

Returns:

  • (Boolean)


133
134
135
136
137
138
139
140
141
142
# File 'lib/eew_parser.rb', line 133

def drill?
  case @fastcast[6, 2]
  when "00", "10", "20"
    return false
  when "01", "11", "30"
    return true
  else
    raise Error, "電文の形式が不正です(識別符)"
  end
end

#drill_typeObject

訓練等の識別符



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/eew_parser.rb', line 113

def drill_type
  case @fastcast[6, 2]
  when "00"
    "通常"
  when "01"
    "訓練"
  when "10"
    "取り消し"
  when "11"
    "訓練取り消し"
  when "20"
    "参考情報またはテキスト"
  when "30"
    "コード部のみの配信試験"
  else
    raise Error, "電文の形式が不正です(識別符)"
  end
end

#earthquake_timeObject

地震発生時刻もしくは地震検知時刻のTimeオブジェクトを返します。



172
173
174
175
176
# File 'lib/eew_parser.rb', line 172

def earthquake_time
  Time.strptime(@fastcast[26, 12], "%y%m%d%H%M%S")
rescue ArgumentError
  raise Error, "電文の形式が不正です (地震発生時刻: #{@fastcast[26, 12]})"
end

#ebiObject

地域毎の警報の判別、最大予測震度及び主要動到達予測時刻

EBIがあればHashを格納したArrayを、なければ空のArrayを返します。Hashに格納されるkeyとvalueはそれぞれ次のようになっています。
:area_name 地域名称
:intensity 最大予測震度
:arrival_time 予想到達時刻のTimeオブジェクト。既に到達している場合はnil
:warning 警報を含んでいればtrue、含んでいなければfalse、電文にこの項目が設定されていなければnil
:arrival 既に到達していればtrue、そうでなければfalse、電文にこの項目が設定されていなければnil


518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
# File 'lib/eew_parser.rb', line 518

def ebi
  return [] unless has_ebi?
  return @ebi.dup if @ebi

  @ebi = []
  i = 139
  while i + 20 < @fastcast.bytesize
    local_str = @fastcast[i, 20]
    area_code = ebi_area_code(local_str)
    local = {
      area_code: area_code,
      area_name: ebi_area_name(area_code),
      intensity: ebi_intensity(local_str),
      arrival_time: ebi_arrival_time(local_str),
      warning: ebi_warning(local_str),
      arrival: ebi_arrival(local_str)
    }
    local.freeze
    @ebi.push(local)
    i += 20
  end
  @ebi.freeze
  return @ebi.dup
end

#epicenterObject

震央の名称



243
244
245
246
247
248
249
250
# File 'lib/eew_parser.rb', line 243

def epicenter
  code = @fastcast[86, 3]
  return "不明又は未設定" if code == "///"
  code = Integer(code, 10)
  EpicenterCode.fetch(code)
rescue ArgumentError, KeyError
  raise Error, "電文の形式が不正です(震央地名コード: #{code})"
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/eew_parser.rb', line 52

def eql?(other)
  @fastcast.eql?(other.fastcast)
end

#final?Boolean

最終報であればtrueを、そうでなければfalseを返します。

Returns:

  • (Boolean)


221
222
223
224
225
226
227
228
229
230
# File 'lib/eew_parser.rb', line 221

def final?
  case @fastcast[59]
  when "9"
    true
  when "0", "6", "7", "8", "/"
    false
  else
    raise Error, "電文の形式が不正です"
  end
end

#first?Boolean

第1報であればtrueを、そうでなければfalseを返します。

Returns:

  • (Boolean)


215
216
217
218
# File 'lib/eew_parser.rb', line 215

def first? 
  return true if self.number == 1
  return false
end

#fromObject

発信官署



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/eew_parser.rb', line 93

def from
  case @fastcast[3, 2]
  when "01"
    "札幌"
  when "02"
    "仙台"
  when "03"
    "東京"
  when "04"
    "大阪"
  when "05"
    "福岡"
  when "06"
    "沖縄"
  else
    raise Error, "電文の形式が不正です(発信官署)"
  end
end

#has_ebi?Boolean

EBIを含むかどうか

Returns:

  • (Boolean)


506
507
508
509
# File 'lib/eew_parser.rb', line 506

def has_ebi?
  return true if @fastcast[135, 3] == "EBI"
  return false
end

#hashObject



56
57
58
# File 'lib/eew_parser.rb', line 56

def hash
  @fastcast.hash
end

#idObject

地震識別番号(String)



179
180
181
182
183
184
185
186
# File 'lib/eew_parser.rb', line 179

def id
  return @id if @id
  @id = @fastcast[41, 14]
  Integer(@id, 10) # verify
  return @id
rescue ArgumentError
  raise Error, "電文の形式が不正です(地震識別番号: #{id})"
end

#inspectObject



40
41
42
# File 'lib/eew_parser.rb', line 40

def inspect
  "#<EEWParser:#{id} (第#{number}報) #{epicenter} 震度#{seismic_intensity}>"
end

#land_or_seaObject

震央位置の海陸判定



412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/eew_parser.rb', line 412

def land_or_sea
  case @fastcast[121]
  when "0"
    "陸域"
  when "1"
    "海域"
  when "/"
    "不明又は未設定"
  when "2".."9"
    "未定義"
  else
    raise Error, "電文の形式が不正です(震央位置の海陸判定)"
  end
end

#magnitudeObject

マグニチュード

マグニチュードが不明又は未設定である場合は"不明又は未設定"を返します。
そうでなければ、マグニチュードをFloatで返します。


278
279
280
281
282
283
284
285
286
287
# File 'lib/eew_parser.rb', line 278

def magnitude
  magnitude = @fastcast[105, 2]
  if magnitude == "//"
    return "不明又は未設定"
  else
    return Float(magnitude[0] + "." + magnitude[1])
  end
rescue ArgumentError
  raise Error, "電文の形式が不正です(マグニチュード)"
end

#normal?Boolean

発表状況と訓練識別が通常かどうか

Returns:

  • (Boolean)


209
210
211
212
# File 'lib/eew_parser.rb', line 209

def normal?
  return true if (@fastcast[59] == "0" || @fastcast[59] == 9) && @fastcast[6, 2] == "00"
  return false
end

#numberObject Also known as: revision

発表する高度利用者向け緊急地震速報の番号(地震単位での通番)(Integer)



233
234
235
236
237
238
# File 'lib/eew_parser.rb', line 233

def number
  number = @fastcast[60, 2]
  return Integer(number, 10)
rescue ArgumentError
  raise Error, "電文の形式が不正です(高度利用者向け緊急地震速報の番号: #{number})"
end

#number_of_telegramObject

電文がこの電文を含め何通あるか(Integer)



152
153
154
155
156
157
# File 'lib/eew_parser.rb', line 152

def number_of_telegram
  number_of_telegram = @fastcast[23]
  return Integer(number_of_telegram, 10)
rescue ArgumentError
  raise Error, "電文の形式が不正です"
end

#observation_points_of_magnitudeObject Also known as: probability_of_position_jma

マグニチュード使用観測点(※気象庁の部内システムでの利用)



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/eew_parser.rb', line 365

def observation_points_of_magnitude
  case @fastcast[116]
  when "1"
    "1点、P波/S波レベル超え、または仮定震源要素"
  when "2"
    "2点"
  when "3"
    "3点"
  when "4"
    "4点"
  when "5"
    "5点以上"
  when "/"
    "不明又は未設定"
  when "6".."9", "0"
    "未定義"
  else
    raise Error, "電文の形式が不正です(マグニチュード使用観測点[気象庁の部内システムでの利用])"
  end
end

#positionObject

震央の位置



253
254
255
256
257
258
259
260
261
# File 'lib/eew_parser.rb', line 253

def position
  position = @fastcast[90, 10]
  if position == "//// /////"
    "不明又は未設定"
  else
    raise Error, "電文の形式が不正です(震央の位置)" unless position.match(/(?:N|S)\d{3} (?:E|W)\d{4}/)
    position.insert(3, ".").insert(10, ".")
  end
end

#prediction_methodObject

予測手法



440
441
442
443
444
445
446
447
448
449
450
451
# File 'lib/eew_parser.rb', line 440

def prediction_method 
  case @fastcast[123]
  when "9"
    "震源とマグニチュードによる震度推定手法において震源要素が推定できず、PLUM 法による震度予測のみが有効である場合"
  when "0".."8"
    "未定義"
  when "/"
    "不明又は未設定"
  else
    raise Error, "電文の形式が不正です(警報の判別)"
  end
end

緊急地震速報の内容をテキストで出力します。



579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
# File 'lib/eew_parser.rb', line 579

def print
  return @print.dup if @print

  @print = <<-EOS
緊急地震速報 (第#{number}報)
電文種別: #{type}
発信官署: #{from}
訓練等の識別符: #{drill_type}
電文の発表時刻: #{report_time.strftime("%F %T")}
電文がこの電文を含め何通あるか: #{number_of_telegram}
コードが続くかどうか: #{continue?}
地震発生時刻もしくは地震検知時刻: #{earthquake_time.strftime("%F %T")}
地震識別番号: #{id}
発表状況(訂正等)の指示: #{status}
発表する高度利用者向け緊急地震速報の番号(地震単位での通番): #{number}
震央地名: #{epicenter}
震央の位置: #{position}
震源の深さ(単位 km)(不明・未設定時,キャンセル時:///): #{depth}
マグニチュード(不明・未設定時、キャンセル時:///): #{magnitude}
最大予測震度(不明・未設定時、キャンセル時://): #{seismic_intensity}
震央の確からしさ: #{probability_of_position}
震源の深さの確からしさ: #{probability_of_depth}
マグニチュードの確からしさ: #{probability_of_magnitude}
震源の深さの確からしさ(気象庁の部内システムでの利用): #{probability_of_depth_jma}
震央位置の海陸判定: #{land_or_sea}
警報を含む内容かどうか: #{warning?}
予測手法: #{prediction_method}
最大予測震度の変化: #{change}
最大予測震度の変化の理由: #{reason_of_change}
  EOS

  if has_ebi?
    @print << "\n地域毎の警報の判別、最大予測震度及び主要動到達予測時刻(EBI):\n"
    ebi.each do |local|
      arrival_time = local[:arrival] ? "すでに到達" : local[:arrival_time]&.strftime("%T")
      @print << "#{local[:area_name].ljust(10, " ")} 最大予測震度: #{local[:intensity].ljust(6, " ")} 予想到達時刻: #{arrival_time} 警報: #{local[:warning]}\n"
    end
  end

  @print.freeze
  return @print.dup
end

#probability_of_depthObject

震源の深さの確からしさ



330
331
332
333
334
# File 'lib/eew_parser.rb', line 330

def probability_of_depth
  OriginProbability.fetch(@fastcast[114])
rescue KeyError
  raise Error, "電文の形式が不正です(震央の確からしさ)"
end

#probability_of_depth_jmaObject

震源の深さの確からしさ(※気象庁の部内システムでの利用)



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/eew_parser.rb', line 390

def probability_of_depth_jma
  case @fastcast[117]
  when "1"
    "P波/S波レベル越え、IPF法(1点)、または仮定震源要素"
  when "2"
    "IPF法(2点)"
  when "3"
    "IPF法(3点/4点)"
  when "4"
    "IPF法(5点以上)"
  when "9"
    "震源とマグニチュードに基づく震度予測手法の精度が最終報相当"
  when "/"
    "不明又は未設定"
  when "5".."8", "0"
    "未定義"
  else
    raise Error, "電文の形式が不正です(震源の深さの確からしさ[気象庁の部内システムでの利用])"
  end
end

#probability_of_magnitudeObject

マグニチュードの確からしさ



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/eew_parser.rb', line 337

def probability_of_magnitude
  case @fastcast[115]
  when "1"
    "未定義"
  when "2"
    "防災科研システム[防災科研Hi-netデータ]"
  when "3"
    "全点P相"
  when "4"
    "P相/全相混在"
  when "5"
    "全点全相"
  when "6"
    "EPOS"
  when "7"
    "未定義"
  when "8"
    "P波/S波レベル越え または仮定震源要素の場合"
  when "9"
    "予備"
  when "/", "0"
    "不明又は未設定"
  else
    raise Error, "電文の形式が不正です(マグニチュードの確からしさ)"
  end
end

#probability_of_positionObject

震央の確からしさ



323
324
325
326
327
# File 'lib/eew_parser.rb', line 323

def probability_of_position
  OriginProbability.fetch(@fastcast[113])
rescue KeyError
  raise Error, "電文の形式が不正です(震央の確からしさ)"
end

#reason_of_changeObject

最大予測震度の変化の理由



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/eew_parser.rb', line 482

def reason_of_change
  case @fastcast[130]
  when "0"
    "変化無し"
  when "1"
    "主としてMが変化したため(1.0以上)"
  when "2"
    "主として震源位置が変化したため(10.0km以上)"
  when "3"
    "M及び震源位置が変化したため"
  when "4"
    "震源の深さが変化したため"
  when "9"
    "PLUM 法による予測により変化したため"
  when "/"
    "不明又は未設定"
  when "5".."8"
    "未定義"
  else
    raise Error, "電文の形式が不正です(最大予測震度の変化の理由)"
  end
end

#report_timeObject

電文の発表時刻のTimeオブジェクトを返します。



145
146
147
148
149
# File 'lib/eew_parser.rb', line 145

def report_time
  Time.strptime(@fastcast[9, 12], "%y%m%d%H%M%S")
rescue ArgumentError
  raise Error, "電文の形式が不正です (発表時刻: #{@fastcast[9, 12]})"
end

#seismic_intensityObject

最大予測震度



304
305
306
# File 'lib/eew_parser.rb', line 304

def seismic_intensity
  to_seismic_intensity(@fastcast[108, 2]) 
end

#sizeObject

電文のサイズを返します。



66
67
68
# File 'lib/eew_parser.rb', line 66

def size
  @fastcast.bytesize
end

#statusObject

発表状況(訂正等)の指示



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/eew_parser.rb', line 189

def status
  case @fastcast[59]
  when "0"
    "通常発表"
  when "6"
    "情報内容の訂正"
  when "7"
    "キャンセルを誤って発表した場合の訂正"
  when "8"
    "訂正事項を盛り込んだ最終の高度利用者向け緊急地震速報"
  when "9"
    "最終の高度利用者向け緊急地震速報"
  when "/"
    "未設定"
  else
    raise Error, "電文の形式が不正です"     
  end
end

#to_hashObject

電文を解析した結果をHashで返します。



551
552
553
554
555
556
557
558
559
560
# File 'lib/eew_parser.rb', line 551

def to_hash
  unless @hash
    @hash = {}
    Attributes.each do |attribute|
      @hash[attribute] = __send__(attribute)
    end
    @hash.freeze
  end
  return @hash.dup
end

#to_sObject

initializeに与えられた電文を返します。



61
62
63
# File 'lib/eew_parser.rb', line 61

def to_s
  @fastcast.dup
end

#typeObject

電文種別コード



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/eew_parser.rb', line 71

def type
  case @fastcast[0, 2]
  when "35"
    "最大予測震度のみの高度利用者向け緊急地震速報"
  when "36"
    "マグニチュード、最大予測震度及び主要動到達予測時刻の高度利用者向け緊急地震速報(B-Δ法、テリトリ法)"
  when "37"
    "マグニチュード、最大予測震度及び主要動到達予測時刻の高度利用者向け緊急地震速報(グリッドサーチ法、EPOS自動処理手法)"
  when "39"
    "キャンセル報"
  else
    raise Error, "電文の形式が不正です(電文種別コード)"
  end
end

#valid?Boolean

正しい電文であるかを返します

Returns:

  • (Boolean)


563
564
565
566
567
568
569
570
571
572
573
574
575
576
# File 'lib/eew_parser.rb', line 563

def valid?
  unless @valid
    begin
      Attributes.each do |attribute|
        __send__(attribute)
      end
    rescue Error
      @valid = false
    else
      @valid = true
    end
  end
  return @valid
end

#warning?Boolean

警報を含む内容であればtrue、そうでなければfalse

Returns:

  • (Boolean)


428
429
430
431
432
433
434
435
436
437
# File 'lib/eew_parser.rb', line 428

def warning?
  case @fastcast[122]
  when "0", "/", "2".."9"
    false
  when "1"
    true
  else
    raise Error, "電文の形式が不正です(警報の判別)"
  end
end