UNPKG

@helgoland/core

Version:

1,751 lines (1,724 loc) 211 kB
import { Injectable, Inject, InjectionToken, Optional, Pipe, NgModule, EventEmitter, Input, HostListener, Output } from '@angular/core'; import { HttpClient, HttpHandler, HttpClientModule, HttpHeaders, HttpParams } from '@angular/common/http'; import { Observable, of, forkJoin } from 'rxjs'; import { DatePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import moment from 'moment'; import { plainToClass, deserialize, deserializeArray } from 'class-transformer'; import { map } from 'rxjs/operators'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class ColorService { /** * Creates a random color and return it as a hex string. * @return {?} */ getColor() { return this.getRandomColor(); } /** * Converts a hex string and opacity in percent to RGBA color as string. * @param {?} hex * @param {?} opacity * @return {?} */ convertHexToRGBA(hex, opacity) { hex = hex.replace('#', ''); /** @type {?} */ const r = parseInt(hex.substring(0, 2), 16); /** @type {?} */ const g = parseInt(hex.substring(2, 4), 16); /** @type {?} */ const b = parseInt(hex.substring(4, 6), 16); return 'rgba(' + r + ',' + g + ',' + b + ',' + opacity / 100 + ')'; } /** * @return {?} */ getRandomColor() { /** @type {?} */ const letters = '0123456789ABCDEF'; /** @type {?} */ let color = '#'; for (let i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; } } ColorService.decorators = [ { type: Injectable }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @enum {number} */ const DatasetApiVersion = { V1: 0, V2: 1, }; DatasetApiVersion[DatasetApiVersion.V1] = 'V1'; DatasetApiVersion[DatasetApiVersion.V2] = 'V2'; class DatasetApiMapping { /** * @param {?} http */ constructor(http) { this.http = http; this.cache = new Map(); } /** * @param {?} apiUrl * @return {?} */ getApiVersion(apiUrl) { return new Observable((observer) => { if (this.cache.has(apiUrl)) { this.confirmVersion(observer, this.cache.get(apiUrl)); } else { this.http.get(apiUrl).subscribe((result) => { /** @type {?} */ let version = DatasetApiVersion.V1; result.forEach((entry) => { if (entry.id === 'platforms') { version = DatasetApiVersion.V2; } }); this.cache.set(apiUrl, version); this.confirmVersion(observer, version); }); } }); } /** * @param {?} observer * @param {?} version * @return {?} */ confirmVersion(observer, version) { observer.next(version); observer.complete(); } } DatasetApiMapping.decorators = [ { type: Injectable }, ]; /** @nocollapse */ DatasetApiMapping.ctorParameters = () => [ { type: HttpClient } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class StatusIntervalResolverService { constructor() { } /** * @param {?} value * @param {?} statusIntervals * @return {?} */ getMatchingInterval(value, statusIntervals) { if (value && statusIntervals) { return statusIntervals.find((interval) => { /** @type {?} */ const upper = interval.upper ? parseFloat(interval.upper) : Number.MAX_VALUE; /** @type {?} */ const lower = interval.lower ? parseFloat(interval.lower) : Number.MIN_VALUE; if (lower <= value && value < upper) { return true; } }); } } } StatusIntervalResolverService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ StatusIntervalResolverService.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ const HTTP_SERVICE_INTERCEPTORS = new InjectionToken('HTTP_SERVICE_INTERCEPTORS'); class HttpService { /** * @param {?} httpHandler * @param {?} interceptors */ constructor(httpHandler, interceptors) { this.httpHandler = httpHandler; /** @type {?} */ let handler = { handle: (req, options) => httpHandler.handle(req) }; if (interceptors) { handler = interceptors.reduceRight((next, interceptor) => ({ handle: (req, options) => interceptor.intercept(req, options, next) }), handler); } this.handler = handler; } /** * @param {?=} options * @return {?} */ client(options = {}) { return new HttpClient({ handle: (req) => this.handler.handle(req, options) }); } } HttpService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ HttpService.ctorParameters = () => [ { type: HttpHandler }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [HTTP_SERVICE_INTERCEPTORS,] }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ const INTERNAL_ID_SEPERATOR = '__'; /** * Service to generate or resolve internal dataset IDs */ class InternalIdHandler { /** * Generates an internal id for the given dataset. * @param {?} dataset The dataset for which the internal id will be generated and saved. * @return {?} */ generateInternalId(dataset) { dataset.internalId = dataset.url + INTERNAL_ID_SEPERATOR + dataset.id; } /** * Resolves the internal ID to the url and the API specific dataset id. * @param {?} internalId The internal id as string * @return {?} Construct of url and API id */ resolveInternalId(internalId) { /** @type {?} */ const split = internalId.split(INTERNAL_ID_SEPERATOR); if (split.length !== 2) { console.error('InternalID ' + internalId + ' is not resolvable'); } else { return { url: split[0], id: split[1] }; } } } InternalIdHandler.decorators = [ { type: Injectable }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * LocalStorage save objects with a given key * * @export */ class LocalStorage { constructor() { this.localStorageEnabled = false; if (typeof (Storage) !== 'undefined') { this.localStorageEnabled = true; } } /** * Saves the object with the key in the local storage * * \@memberof LocalStorage * @param {?} key * @param {?} object * @return {?} successfull saving */ save(key, object) { if (this.localStorageEnabled) { localStorage.setItem(key, JSON.stringify(object)); return true; } return false; } /** * loads the object with for the key * * \@memberof LocalStorage * @template T * @param {?} key * @return {?} the object if exists, else null */ load(key) { if (this.localStorageEnabled) { /** @type {?} */ const result = localStorage.getItem(key); if (result) { return JSON.parse(result); } return null; } } /** * loads an array of objects for the key * * \@memberof LocalStorage * @template T * @param {?} key * @return {?} the array of objects if exists, else null */ loadArray(key) { if (this.localStorageEnabled) { /** @type {?} */ const result = localStorage.getItem(key); if (result) { return JSON.parse(result); } return null; } } /** * load a textual string for the given key * * \@memberof LocalStorage * @param {?} key * @return {?} the string if exists, else null */ loadTextual(key) { if (this.localStorageEnabled) { /** @type {?} */ const result = localStorage.getItem(key); if (result) { return result; } } return null; } } LocalStorage.decorators = [ { type: Injectable }, ]; /** @nocollapse */ LocalStorage.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ const ID = 'helgoland-notifier'; /** @type {?} */ const TIME_IN_MS = 3000; class NotifierService { constructor() { /** @type {?} */ const notifierElement = document.getElementById(ID); if (!notifierElement) { /** @type {?} */ const node = document.createElement('div'); node.id = ID; node.className = 'hide'; /** @type {?} */ const textNode = document.createTextNode(''); node.appendChild(textNode); document.body.appendChild(node); } } /** * @param {?} text * @return {?} */ notify(text) { clearTimeout(this.notifierTimeout); /** @type {?} */ const notifierElement = document.getElementById(ID); notifierElement.innerHTML = text; notifierElement.className = notifierElement.className.replace('hide', 'show'); this.notifierTimeout = setTimeout(() => { notifierElement.className = notifierElement.className.replace('show', 'hide'); }, TIME_IN_MS); } } NotifierService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ NotifierService.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class DateProxyPipe { /** * @param {?} translate */ constructor(translate) { this.translate = translate; } /** * @param {?} value * @param {?=} pattern * @return {?} */ transform(value, pattern = 'mediumDate') { /** @type {?} */ const builtinDatePipe = new DatePipe(this.translate.currentLang || 'en'); try { return builtinDatePipe.transform(value, pattern); } catch (error) { console.error(error); return new DatePipe('en').transform(value, pattern); } } } DateProxyPipe.decorators = [ { type: Pipe, args: [{ name: 'dateI18n', pure: false },] }, ]; /** @nocollapse */ DateProxyPipe.ctorParameters = () => [ { type: TranslateService } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class SumValuesService { constructor() { } /** * @param {?} startOf * @param {?} period * @param {?} data * @return {?} */ sum(startOf, period, data) { /** @type {?} */ const result = []; if (data.length === 0) { return result; } /** @type {?} */ let currentBucketStart = moment(data[0][0]).startOf(startOf); /** @type {?} */ let currentBucketEnd = moment(currentBucketStart).add(period).subtract(1, 'millisecond'); /** @type {?} */ let bucketVals = []; for (let i = 0; i < data.length; i++) { /** @type {?} */ const time = moment(data[i][0]); /** @type {?} */ const value = data[i][1]; while (!(currentBucketStart.isSameOrBefore(time) && currentBucketEnd.isSameOrAfter(time))) { if (bucketVals.length > 0) { /** @type {?} */ let sum = 0; /** @type {?} */ let hasValues = false; bucketVals.forEach(e => { if (typeof e === 'number') { sum += e; hasValues = true; } }); result.push([currentBucketStart.unix() * 1000, hasValues ? sum : 'NaN']); } else { result.push([currentBucketStart.unix() * 1000, 'NaN']); } bucketVals = []; currentBucketStart = currentBucketStart.add(period); currentBucketEnd = currentBucketEnd.add(period); } bucketVals.push(value); } return result; } } SumValuesService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ SumValuesService.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @abstract */ class TimeInterval { } class Timespan extends TimeInterval { /** * @param {?} from * @param {?=} to */ constructor(from, to) { super(); this.from = from; if (to) { this.to = to; } else { this.to = from; } } } class BufferedTime extends TimeInterval { /** * @param {?} timestamp * @param {?} bufferInterval */ constructor(timestamp, bufferInterval) { super(); this.timestamp = timestamp; this.bufferInterval = bufferInterval; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @enum {string} */ const DefinedTimespan = { LASTHOUR: 'last_hour', TODAY: 'today', YESTERDAY: 'yesterday', TODAY_YESTERDAY: 'today_yesterday', CURRENT_WEEK: 'current_week', LAST_WEEK: 'last_week', CURRENT_MONTH: 'current_month', LAST_MONTH: 'last_month', CURRENT_YEAR: 'current_year', LAST_YEAR: 'last_year', }; class DefinedTimespanService { constructor() { this.intervals = new Map(); this.intervals.set(DefinedTimespan.LASTHOUR, () => { /** @type {?} */ const from = moment().subtract(1, 'hours').unix() * 1000; /** @type {?} */ const to = moment().unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.TODAY, () => { /** @type {?} */ const from = moment().startOf('day').unix() * 1000; /** @type {?} */ const to = moment().endOf('day').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.YESTERDAY, () => { /** @type {?} */ const from = moment().subtract(1, 'days').startOf('day').unix() * 1000; /** @type {?} */ const to = moment().subtract(1, 'days').endOf('day').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.TODAY_YESTERDAY, () => { /** @type {?} */ const from = moment().subtract(1, 'days').startOf('day').unix() * 1000; /** @type {?} */ const to = moment().endOf('day').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.CURRENT_WEEK, () => { /** @type {?} */ const from = moment().startOf('isoWeek').unix() * 1000; /** @type {?} */ const to = moment().endOf('isoWeek').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.LAST_WEEK, () => { /** @type {?} */ const from = moment().subtract(1, 'weeks').startOf('isoWeek').unix() * 1000; /** @type {?} */ const to = moment().subtract(1, 'weeks').endOf('isoWeek').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.CURRENT_MONTH, () => { /** @type {?} */ const from = moment().startOf('month').unix() * 1000; /** @type {?} */ const to = moment().endOf('month').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.LAST_MONTH, () => { /** @type {?} */ const from = moment().subtract(1, 'months').startOf('month').unix() * 1000; /** @type {?} */ const to = moment().subtract(1, 'months').endOf('month').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.CURRENT_YEAR, () => { /** @type {?} */ const from = moment().startOf('year').unix() * 1000; /** @type {?} */ const to = moment().endOf('year').unix() * 1000; return new Timespan(from, to); }); this.intervals.set(DefinedTimespan.LAST_YEAR, () => { /** @type {?} */ const from = moment().subtract(1, 'years').startOf('year').unix() * 1000; /** @type {?} */ const to = moment().subtract(1, 'years').endOf('year').unix() * 1000; return new Timespan(from, to); }); } /** * @param {?} intervalDescriber * @return {?} */ getInterval(intervalDescriber) { if (this.intervals.has(intervalDescriber)) { return this.intervals.get(intervalDescriber)(); } } } DefinedTimespanService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ DefinedTimespanService.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class Time { /** * @param {?} localStorage */ constructor(localStorage) { this.localStorage = localStorage; } /** * @param {?} timespan * @param {?} date * @return {?} */ centerTimespan(timespan, date) { /** @type {?} */ const halfduration = this.getDuration(timespan).asMilliseconds() / 2; /** @type {?} */ const from = moment(date).subtract(halfduration).unix() * 1000; /** @type {?} */ const to = moment(date).add(halfduration).unix() * 1000; return new Timespan(from, to); } /** * @param {?} timespan * @param {?} duration * @return {?} */ centerTimespanWithDuration(timespan, duration) { /** @type {?} */ const half = duration.asMilliseconds() / 2; /** @type {?} */ const center = this.getCenterOfTimespan(timespan); return new Timespan(center - half, center + half); } /** * @param {?} timespan * @return {?} */ getCenterOfTimespan(timespan) { return timespan.from + (timespan.to - timespan.from) / 2; } /** * @param {?} timespan * @return {?} */ stepBack(timespan) { /** @type {?} */ const duration = this.getDuration(timespan); /** @type {?} */ const from = moment(timespan.from).subtract(duration).unix() * 1000; /** @type {?} */ const to = moment(timespan.to).subtract(duration).unix() * 1000; return new Timespan(from, to); } /** * @param {?} timespan * @return {?} */ stepForward(timespan) { /** @type {?} */ const duration = this.getDuration(timespan); /** @type {?} */ const from = moment(timespan.from).add(duration).unix() * 1000; /** @type {?} */ const to = moment(timespan.to).add(duration).unix() * 1000; return new Timespan(from, to); } /** * @param {?} timeInterval * @param {?} from * @param {?} to * @return {?} */ overlaps(timeInterval, from, to) { /** @type {?} */ const timespan = this.createTimespanOfInterval(timeInterval); if (timespan.from <= to && timespan.to >= from) { return true; } return false; } /** * @param {?} timeInterval * @return {?} */ createTimespanOfInterval(timeInterval) { if (timeInterval instanceof Timespan) { return timeInterval; } else if (timeInterval instanceof BufferedTime) { /** @type {?} */ const duration = moment.duration(timeInterval.bufferInterval / 2); /** @type {?} */ const from = moment(timeInterval.timestamp).subtract(duration).unix() * 1000; /** @type {?} */ const to = moment(timeInterval.timestamp).add(duration).unix() * 1000; return new Timespan(from, to); } else { console.error('Wrong time interval!'); } } /** * @param {?} timespan * @param {?} factor * @return {?} */ getBufferedTimespan(timespan, factor) { /** @type {?} */ const durationMillis = this.getDuration(timespan).asMilliseconds(); /** @type {?} */ const from = moment(timespan.from).subtract(durationMillis * factor).unix() * 1000; /** @type {?} */ const to = moment(timespan.to).add(durationMillis * factor).unix() * 1000; return new Timespan(from, to); } /** * @param {?} param * @param {?} timespan * @return {?} */ saveTimespan(param, timespan) { this.localStorage.save(param, timespan); } /** * @param {?} param * @return {?} */ loadTimespan(param) { /** @type {?} */ const json = this.localStorage.load(param); if (json) { return plainToClass(Timespan, json); } return null; } /** * @return {?} */ initTimespan() { /** @type {?} */ const now = new Date(); /** @type {?} */ const start = moment(now).startOf('day').unix() * 1000; /** @type {?} */ const end = moment(now).endOf('day').unix() * 1000; return new Timespan(start, end); } /** * @param {?} timespan * @return {?} */ getDuration(timespan) { /** @type {?} */ const from = moment(timespan.from); /** @type {?} */ const to = moment(timespan.to); return moment.duration(to.diff(from)); } } Time.decorators = [ { type: Injectable }, ]; /** @nocollapse */ Time.ctorParameters = () => [ { type: LocalStorage } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class HelgolandCoreModule { } HelgolandCoreModule.decorators = [ { type: NgModule, args: [{ declarations: [ DateProxyPipe ], imports: [ HttpClientModule ], exports: [ DateProxyPipe ], providers: [ ColorService, DatasetApiMapping, DefinedTimespanService, InternalIdHandler, LocalStorage, NotifierService, StatusIntervalResolverService, SumValuesService, HttpService, Time ] },] }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @abstract */ class ApiInterface { /** * @param {?} apiUrl * @param {?} endpoint * @param {?=} id * @return {?} */ createRequestUrl(apiUrl, endpoint, id) { /** @type {?} */ let requestUrl = apiUrl + endpoint; if (id) { requestUrl += '/' + id; } return requestUrl; } /** * @param {?} timespan * @return {?} */ createRequestTimespan(timespan) { return encodeURI(moment(timespan.from).format() + '/' + moment(timespan.to).format()); } /** * @param {?} token * @return {?} */ createBasicAuthHeader(token) { /** @type {?} */ const headers = new HttpHeaders(); if (token) { return headers.set('Authorization', token); } return headers; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ // unsupported: template constraints. /** * @abstract * @template T */ class DatasetService { constructor() { this.datasetIds = []; this.datasetOptions = new Map(); this.datasetIdsChanged = new EventEmitter(); } /** * Adds the dataset to the selection * * @param {?} internalId * @param {?=} options * @return {?} Successfull added the dataset. */ addDataset(internalId, options) { if (this.datasetIds.indexOf(internalId) < 0) { this.datasetIds.push(internalId); if (options) { this.datasetOptions.set(internalId, options); } else { this.datasetOptions.set(internalId, this.createStyles(internalId)); } this.saveState(); } else if (options instanceof Array) { /** @type {?} */ const temp = (/** @type {?} */ (this.datasetOptions.get(internalId))); options.forEach((e) => temp.push(e)); this.saveState(); } this.datasetIdsChanged.emit(this.datasetIds); return of(true); } /** * @return {?} */ removeAllDatasets() { this.datasetIds.length = 0; this.datasetOptions.clear(); this.datasetIdsChanged.emit(this.datasetIds); this.saveState(); } /** * @param {?} internalId * @return {?} */ removeDataset(internalId) { /** @type {?} */ const datasetIdx = this.datasetIds.indexOf(internalId); if (datasetIdx > -1) { this.datasetIds.splice(datasetIdx, 1); this.datasetOptions.delete(internalId); } this.datasetIdsChanged.emit(this.datasetIds); this.saveState(); } /** * @return {?} */ hasDatasets() { return this.datasetIds.length > 0; } /** * @param {?} id * @return {?} */ hasDataset(id) { return this.datasetIds.indexOf(id) >= 0; } /** * @param {?} options * @param {?} internalId * @return {?} */ updateDatasetOptions(options, internalId) { this.datasetOptions.set(internalId, options); this.saveState(); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ // unsupported: template constraints. /** * @abstract * @template T */ class RenderingHintsDatasetService extends DatasetService { /** * @param {?} api */ constructor(api) { super(); this.api = api; } /** * @param {?} internalId * @param {?=} options * @return {?} */ addDataset(internalId, options) { return new Observable((observer) => { if (options) { this.datasetIds.push(internalId); this.datasetOptions.set(internalId, options); observer.next(true); observer.complete(); this.datasetIdsChanged.emit(this.datasetIds); } else if (this.datasetIds.indexOf(internalId) < 0) { this.api.getSingleTimeseriesByInternalId(internalId).subscribe((timeseries) => this.addLoadedDataset(timeseries, observer), (error) => { this.api.getDatasetByInternalId(internalId).subscribe((dataset) => this.addLoadedDataset(dataset, observer)); }); } }); } /** * @param {?} dataset * @param {?} observer * @return {?} */ addLoadedDataset(dataset, observer) { this.datasetIds.push(dataset.internalId); this.datasetOptions.set(dataset.internalId, this.createOptionsOfRenderingHints(dataset)); observer.next(true); observer.complete(); this.datasetIdsChanged.emit(this.datasetIds); this.saveState(); } /** * @param {?} dataset * @return {?} */ createOptionsOfRenderingHints(dataset) { /** @type {?} */ const options = /** @type {?} */ (this.createStyles(dataset.internalId)); if (dataset.renderingHints) { if (dataset.renderingHints.properties && dataset.renderingHints.properties.color) { options.color = dataset.renderingHints.properties.color; } switch (dataset.renderingHints.chartType) { case 'line': this.handleLineRenderingHints(/** @type {?} */ (dataset.renderingHints), options); break; case 'bar': this.handleBarRenderingHints(/** @type {?} */ (dataset.renderingHints), options); break; default: break; } } return /** @type {?} */ (options); } /** * @param {?} lineHints * @param {?} options * @return {?} */ handleLineRenderingHints(lineHints, options) { if (lineHints.properties.width) { options.lineWidth = Math.round(parseFloat(lineHints.properties.width)); } } /** * @param {?} barHints * @param {?} options * @return {?} */ handleBarRenderingHints(barHints, options) { if (barHints.properties.width) { options.lineWidth = Math.round(parseFloat(barHints.properties.width)); } } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class UriParameterCoder { /** * @param {?} key * @return {?} */ encodeKey(key) { return encodeURIComponent(key); } /** * @param {?} value * @return {?} */ encodeValue(value) { return encodeURIComponent(value); } /** * @param {?} key * @return {?} */ decodeKey(key) { return key; } /** * @param {?} value * @return {?} */ decodeValue(value) { return value; } } /** * @abstract */ class DatasetApiInterface extends ApiInterface { /** * @param {?} httpService * @param {?} translate */ constructor(httpService, translate) { super(); this.httpService = httpService; this.translate = translate; } /** * @template T * @param {?} url * @param {?=} params * @param {?=} options * @return {?} */ requestApi(url, params = {}, options = {}) { return this.httpService.client(options).get(url, { params: this.prepareParams(params), headers: this.createBasicAuthHeader(options.basicAuthToken) }); } /** * @param {?} params * @return {?} */ prepareParams(params) { if (this.translate && this.translate.currentLang) { params["locale"] = this.translate.currentLang; } /** @type {?} */ let httpParams = new HttpParams({ encoder: new UriParameterCoder() }); Object.getOwnPropertyNames(params) .forEach((key) => httpParams = httpParams.set(key, params[key])); return httpParams; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class ParameterConstellation { } class FirstLastValue { } class ReferenceValue { } class DatasetParameterConstellation extends ParameterConstellation { } class Dataset { } class Timeseries { constructor() { this.hasData = false; } } class TimeseriesData { } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class DatasetImplApiInterface extends DatasetApiInterface { /** * @param {?} httpservice * @param {?} internalDatasetId * @param {?} translate */ constructor(httpservice, internalDatasetId, translate) { super(httpservice, translate); this.httpservice = httpservice; this.internalDatasetId = internalDatasetId; this.translate = translate; } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getServices(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'services'); if (params) { params.expanded = true; } else { params = { expanded: true }; } return this.requestApi(url, params, options).pipe(map((result) => { result.forEach((entry) => entry.apiUrl = apiUrl); return result; })); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getService(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'services', id); return this.requestApi(url, params, options).pipe(map((result) => { result.apiUrl = apiUrl; return result; })); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getStations(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'stations'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getStation(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'stations', id); return this.requestApi(url, params, options); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getTimeseries(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'timeseries'); return new Observable((observer) => { this.requestApiTexted(url, params, options).subscribe((result) => { /** @type {?} */ const timeseriesList = deserializeArray(Timeseries, result); timeseriesList.forEach((entry) => { entry.url = apiUrl; this.internalDatasetId.generateInternalId(entry); }); observer.next(timeseriesList); }, (error) => observer.error(error), () => observer.complete()); }); } /** * @param {?} apiUrl * @param {?} ids * @param {?} timespan * @param {?=} options * @return {?} */ getTimeseriesData(apiUrl, ids, timespan, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'timeseries/getData'); return new Observable((observer) => { this.requestApiTextedPost(url, { timespan: this.createRequestTimespan(timespan), timeseries: ids }, options).subscribe((result) => { /** @type {?} */ const timeseriesList = []; for (const id in result) { if (id) { timeseriesList.push({ id: id, url: apiUrl, data: result[id].values }); } } observer.next(timeseriesList); }, (error) => observer.error(error), () => observer.complete()); }); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @return {?} */ getSingleTimeseries(id, apiUrl, params) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'timeseries', id); return this.requestApiTexted(url, params).pipe(map((result) => { /** @type {?} */ const timeseries = deserialize(Timeseries, result); timeseries.url = apiUrl; this.internalDatasetId.generateInternalId(timeseries); return timeseries; })); } /** * @param {?} internalId * @param {?=} params * @return {?} */ getSingleTimeseriesByInternalId(internalId, params) { /** @type {?} */ const resolvedId = this.internalDatasetId.resolveInternalId(internalId); return this.getSingleTimeseries(resolvedId.id, resolvedId.url, params); } /** * @param {?} id * @param {?} apiUrl * @return {?} */ getTimeseriesExtras(id, apiUrl) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'timeseries', id); return this.requestApi(url + '/extras'); } /** * @template T * @param {?} id * @param {?} apiUrl * @param {?} timespan * @param {?=} params * @param {?=} options * @return {?} */ getTsData(id, apiUrl, timespan, params = {}, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'timeseries', id) + '/getData'; params.timespan = this.createRequestTimespan(timespan); return this.requestApi(url, params, options).pipe(map((res) => { if (params.expanded) { res = res[id]; } return res; })); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getCategories(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'categories'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @return {?} */ getCategory(id, apiUrl, params) { // const url = this.createRequestUrl(apiUrl, 'categories', id); throw new Error('Not implemented'); // return this.requestApi(url, params) // .map(this.extractData); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getPhenomena(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'phenomena'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getPhenomenon(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'phenomena', id); return this.requestApi(url, params, options); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getOfferings(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'offerings'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getOffering(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'offerings', id); return this.requestApi(url, params, options); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getFeatures(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'features'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getFeature(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'features', id); return this.requestApi(url, params, options); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getProcedures(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'procedures'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getProcedure(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'procedures', id); return this.requestApi(url, params, options); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getPlatforms(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'platforms'); return this.requestApi(url, params, options); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getPlatform(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'platforms', id); return this.requestApi(url, params, options); } /** * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getDatasets(apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'datasets'); return this.requestApi(url, params, options).pipe(map((list) => list.map((entry) => this.prepareDataset(entry, apiUrl)))); } /** * @param {?} id * @param {?} apiUrl * @param {?=} params * @param {?=} options * @return {?} */ getDataset(id, apiUrl, params, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'datasets', id); return this.requestApi(url, params, options).pipe(map((res) => this.prepareDataset(res, apiUrl))); } /** * @param {?} internalId * @param {?=} params * @param {?=} options * @return {?} */ getDatasetByInternalId(internalId, params, options) { /** @type {?} */ const resolvedId = this.internalDatasetId.resolveInternalId(internalId); return this.getDataset(resolvedId.id, resolvedId.url, params, options); } /** * @template T * @param {?} id * @param {?} apiUrl * @param {?} timespan * @param {?=} params * @param {?=} options * @return {?} */ getData(id, apiUrl, timespan, params = {}, options) { /** @type {?} */ const url = this.createRequestUrl(apiUrl, 'datasets', id) + '/data'; params.timespan = this.createRequestTimespan(timespan); return this.requestApi(url, params, options); } /** * @param {?} url * @param {?=} params * @param {?=} options * @return {?} */ requestApiTexted(url, params = {}, options = {}) { return this.httpservice.client(options).get(url, { params: this.prepareParams(params), responseType: 'text' }); } /** * @param {?} url * @param {?=} params * @param {?=} options * @return {?} */ requestApiTextedPost(url, params = {}, options = {}) { return this.httpservice.client().post(url, params, { responseType: 'json' }); } /** * @param {?} datasetObj * @param {?} apiUrl * @return {?} */ prepareDataset(datasetObj, apiUrl) { /** @type {?} */ const dataset = deserialize(Dataset, JSON.stringify(datasetObj)); dataset.url = apiUrl; this.internalDatasetId.generateInternalId(dataset); if (dataset.seriesParameters) { dataset.parameters = dataset.seriesParameters; delete dataset.seriesParameters; } return dataset; } } DatasetImplApiInterface.decorators = [ { type: Injectable }, ]; /** @nocollapse */ DatasetImplApiInterface.ctorParameters = () => [ { type: HttpService }, { type: InternalIdHandler }, { type: TranslateService } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class SplittedDataDatasetApiInterface extends DatasetImplApiInterface { /** * @param {?} httpservice * @param {?} internalDatasetId * @param {?} translate */ constructor(httpservice, internalDatasetId, translate) { super(httpservice, internalDatasetId, translate); this.httpservice = httpservice; this.internalDatasetId = internalDatasetId; this.translate = translate; } /** * @template T * @param {?} id * @param {?} apiUrl * @param {?} timespan * @param {?=} params * @param {?=} options * @return {?} */ getTsData(id, apiUrl, timespan, params = {}, options) { /** @type {?} */ const maxTimeExtent = moment.duration(1, 'year').asMilliseconds(); if ((timespan.to - timespan.from) > maxTimeExtent) { /** @type {?} */ const requests = []; /** @type {?} */ let start = moment(timespan.from).startOf('year'); /** @type {?} */ let end = moment(timespan.from).endOf('year'); while (start.isBefore(moment(timespan.to))) { /** @type {?} */ const chunkSpan = new Timespan(start.unix() * 1000, end.unix() * 1000); requests.push(super.getTsData(id, apiUrl, chunkSpan, params, options)); start = end.add(1, 'millisecond'); end = moment(start).endOf('year'); } return forkJoin(requests).pipe(map((entry) => { return entry.reduce((previous, current) => { /** @type {?} */ const next = { referenceValues: {}, values: previous.values.concat(current.values) }; for (const key in previous.referenceValues) { if (previous.referenceValues.hasOwnProperty(key)) { next.referenceValues[key] = previous.referenceValues[key].concat(current.referenceValues[key]); } } return next; }); })); } else { return super.getTsData(id, apiUrl, timespan, params, options); } } } SplittedDataDatasetApiInterface.decorators = [ { type: Injectable }, ]; /** @nocollapse */ SplittedDataDatasetApiInterface.ctorParameters = () => [ { type: HttpService }, { type: InternalIdHandler }, { type: TranslateService } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @abstract */ class LanguageChangNotifier { /** * @param {?} translate */ constructor(translate) { this.translate = translate; this.translate.onLangChange.subscribe(() => this.languageChanged()); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @abstract */ class LocalSelectorComponent { /** * @param {?} translate */ constructor(translate) { this.translate = translate; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes["languageList"]) { this.setCurrentLang(); } } /** * @param {?} lang * @return {?} */ setLanguage(lang) { this.translate.use(lang.code); this.setCurrentLang(); } /** * @return {?} */ setCurrentLang() { this.currentLang = this.languageList.find((e) => e.code === this.translate.currentLang); } } LocalSelectorComponent.propDecorators = { languageList: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ // unsupported: template constraints. /** * @template T */ class ReferenceValues { } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class Station { } class TimeseriesCollection { } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @enum {string} */ const PlatformTypes = { stationary: 'stationary', mobile: 'mobile', mobileInsitu: 'mobile_insitu', }; /** @enum {string} */ const ValueTypes = { quantity: 'quantity', quantityProfile: 'quantity-profile', }; /** @enum {number} */ const DatasetTypes = { measurement: 0, }; DatasetTypes[DatasetTypes.measurement] = 'measurement'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ class Filter { } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * Options for each dataset. * * @export */ class DatasetOption