/
epicenter.go
110 lines (90 loc) · 2.38 KB
/
epicenter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package src
import (
"fmt"
"regexp"
"strconv"
"github.com/earthquake-alert/erarthquake-alert-v2/src/jma"
)
var COORDINATE_REGEXP = regexp.MustCompile(`([+-][0-9.]+)([+-][0-9.]+)([+-][0-9]+)?/`)
type Epicenter struct {
// 緯度経度
// 震源要素が不明な場合はnilになる
Lat *float64
Lon *float64
// 日本測地系かどうか
IsDatumJapan bool
// 深さ
// 震源要素が不明だったり、深さ不明だった場合はnilになる
Depth *int
Name string
// 遠地地震の場合、ここに震源決定機関が入る
Source string
H *jma.Hypocenter
}
func ParseEpicenter(h *jma.Hypocenter) (*Epicenter, error) {
name := h.Area.Name
if h.Area.NameFromMark != "" {
// 日本の地震の場合で、NameFromMarkがある場合は追加する
// `三陸沖(牡鹿半島の東南東130km付近)` のようになる
name = fmt.Sprintf("%s(%s)", name, Convert(h.Area.NameFromMark, true))
} else if h.Area.DetailedName != "" {
// 遠地地震の場合、DetailedNameを使用する
// `南太平洋 フィジー諸島`のようになる`
name = fmt.Sprintf("%s %s", name, Convert(h.Area.DetailedName, true))
}
isJapanDatum := false
if h.Area.Coordinate.Datum == "日本測地系" {
isJapanDatum = true
}
var latG *float64
var lonG *float64
var depthG *int
if h.Area.Coordinate.Value != "" {
lat, lon, depth, err := ParseCoordinate(h.Area.Coordinate.Value)
if err != nil {
return nil, err
}
latG = &lat
lonG = &lon
depthG = &depth
}
return &Epicenter{
Lat: latG,
Lon: lonG,
IsDatumJapan: isJapanDatum,
Depth: depthG,
Name: name,
Source: Convert(h.Source, true),
H: h,
}, nil
}
// 深さを返す
func (e *Epicenter) FormatDepth() string {
return FormatDepth(e.Depth)
}
// 震源要素を解析する。
// 例:
// "-17.2+178.6-570000/"
// --> (-17.2, 178.6, -570000, nil)
//
// returns: (lat, lon, depth, error)
// depthは不明の場合は1、ごく浅い場合は0
func ParseCoordinate(v string) (float64, float64, int, error) {
r := COORDINATE_REGEXP.FindStringSubmatch(v)
lat, err := strconv.ParseFloat(r[1], 64)
if err != nil {
return 0, 0, 1, err
}
lon, err := strconv.ParseFloat(r[2], 64)
if err != nil {
return 0, 0, 1, err
}
depth := 1
if len(r) == 4 && r[3] != "" {
depth, err = strconv.Atoi(r[3])
if err != nil {
return 0, 0, 1, err
}
}
return lat, lon, depth, nil
}