-
Notifications
You must be signed in to change notification settings - Fork 4
/
usgs.go
119 lines (96 loc) 路 2.54 KB
/
usgs.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
111
112
113
114
115
116
117
118
119
package trace
import (
"encoding/json"
"fmt"
"time"
"github.com/anyshake/observer/utils/duration"
"github.com/anyshake/observer/utils/request"
)
type USGS struct {
DataSourceCache
}
func (u *USGS) Property() string {
return "United States Geological Survey"
}
func (u *USGS) Fetch() ([]byte, error) {
if duration.Difference(time.Now(), u.Time) <= EXPIRATION {
return u.Cache, nil
}
res, err := request.GET(
"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson",
10*time.Second, time.Second, 3, false, nil,
)
if err != nil {
return nil, err
}
u.Time = time.Now()
u.Cache = make([]byte, len(res))
copy(u.Cache, res)
return res, nil
}
func (u *USGS) Parse(data []byte) (map[string]any, error) {
var result map[string]any
err := json.Unmarshal(data, &result)
if err != nil {
return nil, err
}
return result, nil
}
func (u *USGS) Format(latitude, longitude float64, data map[string]any) ([]Event, error) {
events, ok := data["features"]
if !ok {
return nil, fmt.Errorf("source data is not valid")
}
var list []Event
for _, v := range events.([]any) {
if !hasKey(v.(map[string]any), []string{"properties"}) {
continue
}
properties := v.(map[string]any)["properties"]
if !hasKey(properties.(map[string]any), []string{
"mag", "place", "time", "type", "title",
}) {
continue
}
geometry := v.(map[string]any)["geometry"]
if !hasKey(geometry.(map[string]any), []string{"coordinates"}) {
continue
}
coordinates := geometry.(map[string]any)["coordinates"]
if len(coordinates.([]any)) != 3 {
continue
}
if properties.(map[string]any)["type"].(string) != "earthquake" {
continue
}
l := Event{
Depth: coordinates.([]any)[2].(float64),
Verfied: true,
Timestamp: int64(properties.(map[string]any)["time"].(float64)),
Event: properties.(map[string]any)["title"].(string),
Region: properties.(map[string]any)["place"].(string),
Latitude: coordinates.([]any)[1].(float64),
Longitude: coordinates.([]any)[0].(float64),
Magnitude: properties.(map[string]any)["mag"].(float64),
}
l.Distance = getDistance(latitude, l.Latitude, longitude, l.Longitude)
l.Estimation = getEstimation(l.Depth, l.Distance)
list = append(list, l)
}
return list, nil
}
func (u *USGS) List(latitude, longitude float64) ([]Event, error) {
res, err := u.Fetch()
if err != nil {
return nil, err
}
data, err := u.Parse(res)
if err != nil {
return nil, err
}
list, err := u.Format(latitude, longitude, data)
if err != nil {
return nil, err
}
return list, nil
}