UNPKG

@seismo/core

Version:

This is the package for the core library of Seismo, a JavaScript library for seismic data processing and visualization. It provides utilities for handling seismic data, including FDSN web services, waveform processing, and event handling. The library is d

890 lines (889 loc) 28.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventQuery = exports.USGS_HOST = exports.SERVICE_NAME = exports.SERVICE_VERSION = void 0; /* * Philip Crotwell * University of South Carolina, 2019 * https://www.seis.sc.edu */ const common_1 = require("./common"); const quakeml_1 = require("../events/quakeml"); Object.defineProperty(exports, "USGS_HOST", { enumerable: true, get: function () { return quakeml_1.USGS_HOST; } }); const utils_1 = require("../utils"); /** * Major version of the FDSN spec supported here. * Currently is 1. */ exports.SERVICE_VERSION = 1; /** * Service name as used in the FDSN DataCenters registry, * https://www.fdsn.org/datacenters */ exports.SERVICE_NAME = `fdsnws-event-${exports.SERVICE_VERSION}`; /** * Query to a FDSN Event web service. * * @see https://www.fdsn.org/webservices/ * @param host optional host to connect to, defaults to USGS */ class EventQuery extends common_1.FDSNCommon { /** @private */ _eventId; /** @private */ _startTime; /** @private */ _endTime; /** @private */ _updatedAfter; /** @private */ _minMag; /** @private */ _maxMag; /** @private */ _magnitudeType; /** @private */ _minDepth; /** @private */ _maxDepth; /** @private */ _minLat; /** @private */ _maxLat; /** @private */ _minLon; /** @private */ _maxLon; /** @private */ _latitude; /** @private */ _longitude; /** @private */ _minRadius; /** @private */ _maxRadius; /** @private */ _includeArrivals; /** @private */ _includeAllOrigins; /** @private */ _includeAllMagnitudes; /** @private */ _limit; /** @private */ _offset; /** @private */ _orderBy; /** @private */ _contributor; /** @private */ _catalog; /** @private */ _format; constructor(host) { if (!(0, utils_1.isNonEmptyStringArg)(host)) { host = quakeml_1.USGS_HOST; } super(host); } /** * Gets/Sets the version of the fdsnws spec, 1 is currently the only value. * Setting this is probably a bad idea as the code may not be compatible with * the web service. * * @param value optional new value if setting * @returns new value if getting, this if setting */ specVersion(value) { (0, utils_1.doStringGetterSetter)(this, "specVersion", value); return this; } getSpecVersion() { return this._specVersion; } /** * Gets/Sets the protocol, http or https. This should match the protocol * of the page loaded, but is autocalculated and generally need not be set. * * @param value optional new value if setting * @returns new value if getting, this if setting */ protocol(value) { (0, utils_1.doStringGetterSetter)(this, "protocol", value); return this; } getProtocol() { return this._protocol; } /** * Gets/Sets the remote host to connect to. * * @param value optional new value if setting * @returns new value if getting, this if setting */ host(value) { (0, utils_1.doStringGetterSetter)(this, "host", value); return this; } getHost() { return this._host; } /** * Gets/Sets the remote port to connect to. * * @param value optional new value if setting * @returns new value if getting, this if setting */ port(value) { (0, utils_1.doIntGetterSetter)(this, "port", value); return this; } getPort() { return this._port; } /** * Gets/Sets the nodata parameter, usually 404 or 204 (default), controlling * the status code when no matching data is found by the service. * * @param value optional new value if setting * @returns new value if getting, this if setting */ nodata(value) { (0, utils_1.doIntGetterSetter)(this, "nodata", value); return this; } getNodata() { return this._nodata; } /** * Get/Set the timeout in seconds for the request. Default is 30. * * @param value optional new value if setting * @returns new value if getting, this if setting */ timeout(value) { (0, utils_1.doFloatGetterSetter)(this, "timeoutSec", value); return this; } getTimeout() { return this._timeoutSec; } /** * Get/Set the eventid query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ eventId(value) { (0, utils_1.doStringGetterSetter)(this, "eventId", value); return this; } getEventId() { return this._eventId; } /** * Get/Set the starttime query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ startTime(value) { (0, utils_1.doMomentGetterSetter)(this, "startTime", value); return this; } getStartTime() { return this._startTime; } /** * Get/Set the endtime query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ endTime(value) { (0, utils_1.doMomentGetterSetter)(this, "endTime", value); return this; } getEndTime() { return this._endTime; } /** * Sets startTime and endTime using the given time window * * @param se time window * @returns this */ timeRange(se) { this.startTime((0, utils_1.validStartTime)(se)); this.endTime((0, utils_1.validEndTime)(se)); return this; } /** * Get/Set the updatedafter query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ updatedAfter(value) { (0, utils_1.doMomentGetterSetter)(this, "updatedAfter", value); return this; } getUpdatedAfter() { return this._updatedAfter; } /** * Get/Set the minmag query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ minMag(value) { (0, utils_1.doFloatGetterSetter)(this, "minMag", value); return this; } getMinMag() { return this._minMag; } /** * Get/Set the maxmag query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ maxMag(value) { (0, utils_1.doFloatGetterSetter)(this, "maxMag", value); return this; } getMaxMag() { return this._maxMag; } /** * Get/Set the magnitudetype query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ magnitudeType(value) { (0, utils_1.doStringGetterSetter)(this, "magnitudeType", value); return this; } getMagnitudeType() { return this._magnitudeType; } /** * Get/Set the mindepth query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ minDepth(value) { (0, utils_1.doFloatGetterSetter)(this, "minDepth", value); return this; } getMinDepth() { return this._minDepth; } /** * Get/Set the maxdepth query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ maxDepth(value) { (0, utils_1.doFloatGetterSetter)(this, "maxDepth", value); return this; } getMaxDepth() { return this._maxDepth; } /** * Get/Set the minlat query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ minLat(value) { (0, utils_1.doFloatGetterSetter)(this, "minLat", value); return this; } getMinLat() { return this._minLat; } /** * Get/Set the maxlat query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ maxLat(value) { (0, utils_1.doFloatGetterSetter)(this, "maxLat", value); return this; } getMaxLat() { return this._maxLat; } /** * Get/Set the minlon query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ minLon(value) { (0, utils_1.doFloatGetterSetter)(this, "minLon", value); return this; } getMinLon() { return this._minLon; } /** * Get/Set the maxlon query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ maxLon(value) { (0, utils_1.doFloatGetterSetter)(this, "maxLon", value); return this; } getMaxLon() { return this._maxLon; } /** * Get/Set the latitude query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ latitude(value) { (0, utils_1.doFloatGetterSetter)(this, "latitude", value); return this; } getLatitude() { return this._latitude; } /** * Get/Set the longitude query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ longitude(value) { (0, utils_1.doFloatGetterSetter)(this, "longitude", value); return this; } getLongitude() { return this._longitude; } /** * Get/Set the minradius query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ minRadius(value) { (0, utils_1.doFloatGetterSetter)(this, "minRadius", value); return this; } getMinRadius() { return this._minRadius; } /** * Get/Set the maxradius query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ maxRadius(value) { (0, utils_1.doFloatGetterSetter)(this, "maxRadius", value); return this; } getMaxRadius() { return this._maxRadius; } /** * Get/Set the includearrivals query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ includeArrivals(value) { (0, utils_1.doBoolGetterSetter)(this, "includeArrivals", value); return this; } getIncludeArrivals() { return this._includeArrivals; } /** * Get/Set the includeallorigins query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ includeAllOrigins(value) { (0, utils_1.doBoolGetterSetter)(this, "includeAllOrigins", value); return this; } getIncludeAllOrigins() { return this._includeAllOrigins; } /** * Get/Set the includeallmagnitudes query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ includeAllMagnitudes(value) { (0, utils_1.doBoolGetterSetter)(this, "includeAllMagnitudes", value); return this; } getIncludeAllMagnitudes() { return this._includeAllMagnitudes; } /** * Get/Set the format query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ format(value) { (0, utils_1.doStringGetterSetter)(this, "format", value); return this; } getFormat() { return this._format; } /** * Get/Set the limit query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ limit(value) { (0, utils_1.doIntGetterSetter)(this, "limit", value); return this; } getLimit() { return this._limit; } /** * Get/Set the offset query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ offset(value) { (0, utils_1.doIntGetterSetter)(this, "offset", value); return this; } getOffset() { return this._offset; } /** * Get/Set the orderby query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ orderBy(value) { (0, utils_1.doStringGetterSetter)(this, "orderBy", value); return this; } getOrderBy() { return this._orderBy; } /** * Get/Set the catalog query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ catalog(value) { (0, utils_1.doStringGetterSetter)(this, "catalog", value); return this; } getCatalog() { return this._catalog; } /** * Get/Set the contributor query parameter. * * @param value optional new value if setting * @returns new value if getting, this if setting */ contributor(value) { (0, utils_1.doStringGetterSetter)(this, "contributor", value); return this; } getContributor() { return this._contributor; } latLonRegion(value) { if (value instanceof common_1.LatLonBox) { this._minLat = value.south; this._maxLat = value.north; this._minLon = value.west; this._maxLon = value.east; // unset this._latitude = undefined; this._longitude = undefined; this._minRadius = undefined; this._maxRadius = undefined; } else if (value instanceof common_1.LatLonRadius) { this._latitude = value.latitude; this._longitude = value.longitude; this._minRadius = value.minRadius; this._maxRadius = value.maxRadius; // unset this._minLat = undefined; this._maxLat = undefined; this._minLon = undefined; this._maxLon = undefined; } else if (!(0, utils_1.isDef)(value)) { // unset this._latitude = undefined; this._longitude = undefined; this._minRadius = undefined; this._maxRadius = undefined; this._minLat = undefined; this._maxLat = undefined; this._minLon = undefined; this._maxLon = undefined; } else { throw new Error(`value argument is optional or LatLonRegion, but was type ${typeof value}, '${(0, utils_1.stringify)(value)}' `); } return this; } /** * Checks to see if any parameter that would limit the data * returned is set. This is a crude, coarse check to make sure * the client doesn't ask for EVERYTHING the server has. * * @returns true is some parameter is set */ isSomeParameterSet() { return ((0, utils_1.isDef)(this._eventId) || (0, utils_1.isDef)(this._startTime) || (0, utils_1.isDef)(this._endTime) || (0, utils_1.isDef)(this._minLat) || (0, utils_1.isDef)(this._maxLat) || (0, utils_1.isDef)(this._minLon) || (0, utils_1.isDef)(this._maxLon) || (0, utils_1.isDef)(this._latitude) || (0, utils_1.isDef)(this._longitude) || (0, utils_1.isDef)(this._minRadius) || (0, utils_1.isDef)(this._maxRadius) || (0, utils_1.isDef)(this._minDepth) || (0, utils_1.isDef)(this._maxDepth) || (0, utils_1.isDef)(this._limit) || (0, utils_1.isDef)(this._minMag) || (0, utils_1.isDef)(this._maxMag) || (0, utils_1.isDef)(this._updatedAfter) || (0, utils_1.isDef)(this._catalog) || (0, utils_1.isDef)(this._contributor)); } /** * Queries the remote service and parses the returned xml. * * @returns Promise to an Array of Quake objects. */ query() { return this.queryEventParameters().then((eventParameters) => { return eventParameters.eventList; }); } queryEventParameters() { return this.queryRawXml().then((rawXml) => { return (0, quakeml_1.parseQuakeML)(rawXml, this._host); }); } /** * Queries the remote server, to get QuakeML xml. * * @returns xml Document */ queryRawXml() { if (!this.isSomeParameterSet()) { throw new Error("Must set some parameter to avoid asking for everything."); } const url = this.formURL(); const fetchInit = (0, utils_1.defaultFetchInitObj)(utils_1.XML_MIME); return (0, utils_1.doFetchWithTimeout)(url, fetchInit, this._timeoutSec * 1000) .then((response) => { if (response.status === 200) { return response.text(); } else if (response.status === 204 || ((0, utils_1.isDef)(this._nodata) && response.status === this._nodata)) { // 204 is nodata, so successful but empty return quakeml_1.FAKE_EMPTY_XML; } else { throw new Error(`Status not successful: ${response.status}`); } }) .then(function (rawXmlText) { return new DOMParser().parseFromString(rawXmlText, utils_1.XML_MIME); }); } /** * Forms the basic URL to contact the web service, without any query paramters * * @returns the url */ formBaseURL() { let colon = ":"; if (!this._host || this._host === quakeml_1.USGS_HOST) { this._host = quakeml_1.USGS_HOST; // usgs does 301 moved permanently to https this._protocol = "https:"; } if (this._protocol.endsWith(colon)) { colon = ""; } return (this._protocol + colon + "//" + this._host + (this._port === 80 ? "" : ":" + (0, utils_1.stringify)(this._port)) + "/fdsnws/event/" + this._specVersion); } /** * Forms the URL to get catalogs from the web service, without any query paramters * * @returns the url */ formCatalogsURL() { return this.formBaseURL() + "/catalogs"; } /** * Queries the remote web service to get known catalogs * * @returns Promise to Array of catalog names */ queryCatalogs() { const url = this.formCatalogsURL(); const fetchInit = (0, utils_1.defaultFetchInitObj)(utils_1.XML_MIME); return (0, utils_1.doFetchWithTimeout)(url, fetchInit, this._timeoutSec * 1000) .then((response) => { if (response.status === 200) { return response.text(); } else { throw new Error(`Status not 200: ${response.status}`); } }) .then((rawXmlText) => { return new DOMParser().parseFromString(rawXmlText, utils_1.XML_MIME); }) .then((rawXml) => { if (!rawXml) { throw new Error("raw xml from DOMParser is null."); } const top = rawXml.documentElement; if (!top) { throw new Error("documentElement in xml from DOMParser is null."); } const catalogArray = top.getElementsByTagName("Catalog"); const out = []; if (catalogArray) { for (let i = 0; i < catalogArray.length; i++) { const item = catalogArray.item(i); if (item && (0, utils_1.isDef)(item.textContent)) { out.push(item.textContent); } } } return out; }); } /** * Forms the URL to get contributors from the web service, without any query paramters * * @returns the url */ formContributorsURL() { return this.formBaseURL() + "/contributors"; } /** * Queries the remote web service to get known contributors * * @returns Promise to Array of contributor names */ queryContributors() { const url = this.formContributorsURL(); const fetchInit = (0, utils_1.defaultFetchInitObj)(utils_1.XML_MIME); return (0, utils_1.doFetchWithTimeout)(url, fetchInit, this._timeoutSec * 1000) .then((response) => { if (response.status === 200) { return response.text(); } else { throw new Error(`Status not 200: ${response.status}`); } }) .then(function (rawXmlText) { return new DOMParser().parseFromString(rawXmlText, utils_1.XML_MIME); }) .then(function (rawXml) { const top = rawXml.documentElement; if (!top) { throw new Error("documentElement in xml from DOMParser is null."); } const contributorArray = top.getElementsByTagName("Contributor"); const out = []; if (contributorArray) { for (let i = 0; i < contributorArray.length; i++) { const item = contributorArray.item(i); if (item && (0, utils_1.isDef)(item.textContent)) { out.push(item.textContent); } } } return out; }); } /** * Forms the URL to get version from the web service, without any query paramters * * @returns the url */ formVersionURL() { return this.formBaseURL() + "/version"; } /** * Queries the remote web service to get its version * * @returns Promise to version string */ queryVersion() { const url = this.formVersionURL(); const fetchInit = (0, utils_1.defaultFetchInitObj)(utils_1.TEXT_MIME); return (0, utils_1.doFetchWithTimeout)(url, fetchInit, this._timeoutSec * 1000).then((response) => { if (response.status === 200) { return response.text(); } else { throw new Error(`Status not 200: ${response.status}`); } }); } /** * Form URL to query the remote web service, encoding the query parameters. * * @returns url */ formURL() { let colon = ":"; if (this._protocol.endsWith(colon)) { colon = ""; } let url = this.formBaseURL() + "/query?"; if (this._eventId) { url = url + (0, utils_1.makeParam)("eventid", this._eventId); } if (this._startTime) { url = url + (0, utils_1.makeParam)("starttime", (0, utils_1.toIsoWoZ)(this._startTime)); } if (this._endTime) { url = url + (0, utils_1.makeParam)("endtime", (0, utils_1.toIsoWoZ)(this._endTime)); } if ((0, utils_1.isNumArg)(this._minMag)) { url = url + (0, utils_1.makeParam)("minmag", this._minMag); } if ((0, utils_1.isNumArg)(this._maxMag)) { url = url + (0, utils_1.makeParam)("maxmag", this._maxMag); } if ((0, utils_1.isStringArg)(this._magnitudeType)) { url = url + (0, utils_1.makeParam)("magnitudetype", this._magnitudeType); } if ((0, utils_1.isNumArg)(this._minDepth)) { url = url + (0, utils_1.makeParam)("mindepth", this._minDepth); } if ((0, utils_1.isNumArg)(this._maxDepth)) { url = url + (0, utils_1.makeParam)("maxdepth", this._maxDepth); } if ((0, utils_1.isNumArg)(this._minLat)) { url = url + (0, utils_1.makeParam)("minlat", this._minLat); } if ((0, utils_1.isNumArg)(this._maxLat)) { url = url + (0, utils_1.makeParam)("maxlat", this._maxLat); } if ((0, utils_1.isNumArg)(this._minLon)) { url = url + (0, utils_1.makeParam)("minlon", this._minLon); } if ((0, utils_1.isNumArg)(this._maxLon)) { url = url + (0, utils_1.makeParam)("maxlon", this._maxLon); } if ((0, utils_1.isNumArg)(this._minRadius) || (0, utils_1.isNumArg)(this._maxRadius)) { if ((0, utils_1.isNumArg)(this._latitude) && (0, utils_1.isNumArg)(this._longitude)) { url = url + (0, utils_1.makeParam)("latitude", this._latitude) + (0, utils_1.makeParam)("longitude", this._longitude); if ((0, utils_1.isNumArg)(this._minRadius)) { url = url + (0, utils_1.makeParam)("minradius", this._minRadius); } if ((0, utils_1.isNumArg)(this._maxRadius)) { url = url + (0, utils_1.makeParam)("maxradius", this._maxRadius); } } else { throw new Error(`Cannot use minRadius or maxRadius without latitude and longitude: lat=` + `${this._latitude} lon= ${this._longitude}`); } } if (this._includeArrivals) { if (this._host !== quakeml_1.USGS_HOST) { url = url + "includearrivals=true&"; } else { // USGS does not support includearrivals, but does actually // include the arrivals for an eventid= style query if (this._eventId) { // ok, works without the param } else { throw new Error("USGS host, earthquake.usgs.gov, does not support includearrivals parameter."); } } } if ((0, utils_1.isObject)(this._updatedAfter)) { url = url + (0, utils_1.makeParam)("updatedafter", this._updatedAfter); } if ((0, utils_1.isDef)(this._includeAllOrigins)) { url = url + (0, utils_1.makeParam)("includeallorigins", this._includeAllOrigins); } if ((0, utils_1.isDef)(this._includeAllMagnitudes)) { url = url + (0, utils_1.makeParam)("includeallmagnitudes", this._includeAllMagnitudes); } if ((0, utils_1.isStringArg)(this._format)) { url = url + (0, utils_1.makeParam)("format", this._format); } if ((0, utils_1.isNumArg)(this._limit)) { url = url + (0, utils_1.makeParam)("limit", this._limit); } if ((0, utils_1.isNumArg)(this._offset)) { url = url + (0, utils_1.makeParam)("offset", this._offset); } if ((0, utils_1.isStringArg)(this._orderBy)) { url = url + (0, utils_1.makeParam)("orderby", this._orderBy); } if ((0, utils_1.isStringArg)(this._catalog)) { url = url + (0, utils_1.makeParam)("catalog", this._catalog); } if ((0, utils_1.isStringArg)(this._contributor)) { url = url + (0, utils_1.makeParam)("contributor", this._contributor); } if ((0, utils_1.isDef)(this._nodata)) { url = url + (0, utils_1.makeParam)("nodata", this._nodata); } if (url.endsWith("&") || url.endsWith("?")) { url = url.substr(0, url.length - 1); // zap last & or ? } return url; } } exports.EventQuery = EventQuery;