-
Notifications
You must be signed in to change notification settings - Fork 7
/
usgsgeojson.ts
315 lines (291 loc) · 10.8 KB
/
usgsgeojson.ts
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
import {
Quake,
Origin,
Magnitude,
CreationInfo,
EventDescription,
EventParameters,
} from './quakeml';
import {
JSON_MIME,
doFetchWithTimeout,
defaultFetchInitObj,
} from "./util";
import { DateTime} from 'luxon';
import type {Feature, Point} from 'geojson';
const timeoutSec = 10;
export const hourSummarySignificantUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_hour.geojson";
export const hourSummaryM4_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_hour.geojson";
export const hourSummaryM2_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_hour.geojson";
export const hourSummaryM1_0Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_hour.geojson";
export const hourSummaryAllUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson";
export const daySummarySignificantUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_day.geojson";
export const daySummaryM4_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_day.geojson";
export const daySummaryM2_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson";
export const daySummaryM1_0Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_day.geojson";
export const daySummaryAllUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson";
export const weekSummarySignificantUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_week.geojson";
export const weekSummaryM4_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_week.geojson";
export const weekSummaryM2_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojson";
export const weekSummaryM1_0Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_week.geojson";
export const weekSummaryAllUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson";
export const monthSummarySignificantUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_month.geojson";
export const monthSummaryM4_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_month.geojson";
export const monthSummaryM2_5Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_month.geojson";
export const monthSummaryM1_0Url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/1.0_month.geojson";
export const monthSummaryAllUrl = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson";
export function loadHourSummarySignificant(): Promise<Array<Quake>> {
return loadUSGSSummary(hourSummarySignificantUrl);
}
export function loadHourSummaryM4_5(): Promise<Array<Quake>> {
return loadUSGSSummary(hourSummaryM4_5Url);
}
export function loadHourSummaryM2_5(): Promise<Array<Quake>> {
return loadUSGSSummary(hourSummaryM2_5Url);
}
export function loadHourSummaryM1_0(): Promise<Array<Quake>> {
return loadUSGSSummary(hourSummaryM1_0Url);
}
export function loadHourSummaryAll(): Promise<Array<Quake>> {
return loadUSGSSummary(hourSummaryAllUrl);
}
export function loadDaySummarySignificant(): Promise<Array<Quake>> {
return loadUSGSSummary(daySummarySignificantUrl);
}
export function loadDaySummaryM4_5(): Promise<Array<Quake>> {
return loadUSGSSummary(daySummaryM4_5Url);
}
export function loadDaySummaryM2_5(): Promise<Array<Quake>> {
return loadUSGSSummary(daySummaryM2_5Url);
}
export function loadDaySummaryM1_0(): Promise<Array<Quake>> {
return loadUSGSSummary(daySummaryM1_0Url);
}
export function loadDaySummaryAll(): Promise<Array<Quake>> {
return loadUSGSSummary(daySummaryAllUrl);
}
export function loadWeekSummarySignificant(): Promise<Array<Quake>> {
return loadUSGSSummary(weekSummarySignificantUrl);
}
export function loadWeekSummaryM4_5(): Promise<Array<Quake>> {
return loadUSGSSummary(weekSummaryM4_5Url);
}
export function loadWeekSummaryM2_5(): Promise<Array<Quake>> {
return loadUSGSSummary(weekSummaryM2_5Url);
}
export function loadWeekSummaryM1_0(): Promise<Array<Quake>> {
return loadUSGSSummary(weekSummaryM1_0Url);
}
export function loadWeekSummaryAll(): Promise<Array<Quake>> {
return loadUSGSSummary(weekSummaryAllUrl);
}
export function loadMonthSummarySignificant(): Promise<Array<Quake>> {
return loadUSGSSummary(monthSummarySignificantUrl);
}
export function loadMonthSummaryM4_5(): Promise<Array<Quake>> {
return loadUSGSSummary(monthSummaryM4_5Url);
}
export function loadMonthSummaryM2_5(): Promise<Array<Quake>> {
return loadUSGSSummary(monthSummaryM2_5Url);
}
export function loadMonthSummaryM1_0(): Promise<Array<Quake>> {
return loadUSGSSummary(monthSummaryM1_0Url);
}
export function loadMonthSummaryAll(): Promise<Array<Quake>> {
return loadUSGSSummary(monthSummaryAllUrl);
}
export function loadUSGSSummary(url: string): Promise<Array<Quake>> {
return loadUSGSGeoJsonSummary(url).then(eventParameters => {
return eventParameters.eventList;
});
}
export function loadUSGSGeoJsonSummary(url: string): Promise<EventParameters> {
return loadRawUSGSGeoJsonSummary(url)
.then((geojson: USGSGeoJsonSummary) => {
return parseGeoJSON(geojson);
});
}
export function loadRawUSGSGeoJsonSummary(url: string): Promise<USGSGeoJsonSummary> {
const fetchInit = defaultFetchInitObj(JSON_MIME);
return doFetchWithTimeout(url, fetchInit, timeoutSec * 1000)
.then( response => {
if (response.status !== 200) {
// no data
return [];
} else {
return response.json();
}
}).then(jsonValue => {
if (isValidUSGSGeoJsonSummary(jsonValue)) {
return jsonValue;
} else {
throw new TypeError(`Oops, we did not get roottype JSON!`);
}
});
}
/*
[
{
"type":"Feature",
"properties":{
"mag":4.7,
"place":"central Mid-Atlantic Ridge",
"time":1676729263180,
"updated":1676730921040,
"tz":null,
"url":"https://earthquake.usgs.gov/earthquakes/eventpage/us6000jpxe",
"detail":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us6000jpxe.geojson",
"felt":null,
"cdi":null,
"mmi":null,
"alert":null,
"status":"reviewed",
"tsunami":0,
"sig":340,
"net":"us",
"code":"6000jpxe",
"ids":",us6000jpxe,",
"sources":",us,",
"types":",origin,phase-data,",
"nst":27,
"dmin":14.339,
"rms":0.71,
"gap":90,
"magType":"mb",
"type":"earthquake",
"title":"M 4.7 - central Mid-Atlantic Ridge"
},
"geometry":{
"type":"Point",
"coordinates":[-36.0365,7.3653,10]
},
"id":"us6000jpxe"}
],
"bbox":[-149.9803,7.3653,3.98,-36.0365,61.4684,32.6]
}
*/
/**
* Parses geojson from USGS feeds. Not all fields are parsed, just
* basic origin and magnitude along with the id.
* See https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php
* @param geojson text from USGS feed
* @returns EventParameters, which holds an array of Quake objects
*/
export function parseGeoJSON(geojson: USGSGeoJsonSummary): EventParameters {
const quakeList = [];
const description = geojson.metadata.title;
for (const f of geojson.features) {
const quake = parseFeatureAsQuake(f);
quakeList.push(quake);
}
const out = new EventParameters();
out.creationInfo = new CreationInfo();
out.creationInfo.agencyURI = geojson.metadata.url;
out.creationInfo.creationTime = DateTime.fromMillis(geojson.metadata.generated);
out.eventList = quakeList;
out.description = description;
return out;
}
/**
* Parses a single GeoJson feature into a Quake.
* @param feature from USGS style geojson
* @returns Quake with origin and magnitude
*/
export function parseFeatureAsQuake(feature: USGSGeoJsonFeature): Quake {
const quake = new Quake();
quake.publicId = `quakeml:earthquake.usgs.gov/fdsnws/event/1/query?eventid={feature.id}`;
const p = feature.properties;
if ( p == null) { throw new Error("Geojson missing properties");}
quake.descriptionList.push(new EventDescription(p.title));
const origin = new Origin(DateTime.fromMillis(p.time),
feature.geometry.coordinates[1],
feature.geometry.coordinates[0]);
origin.depth = feature.geometry.coordinates[2]*1000;
quake.originList.push(origin);
const mag = new Magnitude(p.mag);
mag.type = p.magType;
quake.magnitudeList.push(mag);
quake.preferredOrigin = origin;
quake.preferredMagnitude = mag;
return quake;
}
export interface USGSGeoJsonMetaData {
generated: number;
url: string;
title: string;
api: string;
count: number;
status: number;
}
export interface USGSGeoJsonProperties {
mag: number;
place: string;
time: number;
updated: number;
tz: number;
url: string;
detail: string;
felt:number;
cdi: number;
mmi: number;
alert: string;
status: string;
tsunami: number;
sig:number;
net: string;
code: string;
ids: string;
sources: string;
types: string;
nst: number;
dmin: number;
rms: number;
gap: number;
magType: string;
type: string;
title: string;
}
export interface USGSGeoJsonFeature extends Feature<Point, USGSGeoJsonProperties> {
}
// subtype of FeatureCollection
export interface USGSGeoJsonSummary {
type: 'FeatureCollection';
metadata: USGSGeoJsonMetaData;
features: Array<USGSGeoJsonFeature>;
}
export function isValidUSGSGeoJsonSummary(jsonValue: unknown): jsonValue is USGSGeoJsonSummary {
if (! jsonValue || typeof jsonValue !== 'object') {
throw new TypeError("json is not object");
}
const jsonObj = jsonValue as Record<string, unknown>;
if ( ! (typeof jsonObj.type === 'string' && jsonObj.type === "FeatureCollection") ) {
throw new TypeError("geojson is not valid for USGS GeoJson, type should be FeatureCollection");
}
if ( ! (typeof jsonObj.metadata === 'object')) {
throw new TypeError("geojson is not valid for USGS GeoJson, missing metadata");
}
if ( ! Array.isArray(jsonObj.features)) {
throw new TypeError("geojson is not valid for USGS GeoJson, features should be array");
} else {
if ( ! jsonObj.features.every(isValidUSGSGeoJsonQuake)) {
throw new TypeError("geojson is not valid for USGS GeoJson, feature should be USGSGeoJsonFeature");
}
}
return true;
}
export function isValidUSGSGeoJsonQuake(jsonValue: unknown): jsonValue is USGSGeoJsonFeature {
if (! jsonValue || typeof jsonValue !== 'object') {
throw new TypeError("json is not object");
}
const jsonObj = jsonValue as Record<string, unknown>;
if ( ! (typeof jsonObj.type === 'string' && jsonObj.type === "Feature") ) {
throw new TypeError("geojson is not valid for USGS GeoJson, type should be Feature");
}
if ( ! (typeof jsonObj.properties === 'object')) {
throw new TypeError("geojson is not valid for USGS GeoJson, missing properties");
}
if ( ! (typeof jsonObj.id === 'string') ) {
throw new TypeError("geojson is not valid for USGS GeoJson, id should be string");
}
return true;
}