dasf-web
Version:
Web frontend components for the data analytics software framework (DASF)
157 lines (131 loc) • 5.47 kB
text/typescript
import axios, { AxiosResponse } from 'axios';
import * as xmljs from 'xml-js';
import getBackendModule from '../../../dataAcquisition/RasterBackendModule';
import NetcdfRasterSource from '../NetcdfRasterSource';
import Geometry from 'ol/geom/Geometry';
export class WcsCoverageSummary {
public lowerCorner: string[] = [];
public upperCorner: string[] = [];
public axis: string[] = [];
public type: string = 'unknown';
public coverageId = '';
public xIdx = 0;
public yIdx = 1;
public tIdx = Number.NaN;
constructor(json: object) {
this.parse(json);
}
private parse(json: object): void {
this.lowerCorner = (WCS.getAttribute(json, ['ows:BoundingBox', 'ows:LowerCorner', '_text']) as unknown as string).split(' ');
this.upperCorner = (WCS.getAttribute(json, ['ows:BoundingBox', 'ows:UpperCorner', '_text']) as unknown as string).split(' ');
this.axis = WCS.getAxisList(json)
this.type = (WCS.getAttribute(json, ['wcs:CoverageSubtype', '_text']) as unknown as string);
this.coverageId = WCS.getAttribute(json, ['wcs:CoverageId', '_text']) as unknown as string;
this.setAxisIdx();
}
private setAxisIdx(): void {
for(let i=0; i<this.axis.length; ++i) {
switch(this.axis[i].toLocaleLowerCase()) {
case 'lon':
case 'lng':
case 'long':
case 'longitude':
case 'x':
this.xIdx = i;
break;
case 'lat':
case 'latitude':
case 'y':
this.yIdx = i;
break;
case 'ansi':
case 'time':
case 'date':
case 'ansidate':
this.tIdx = i;
break;
default:
break;
}
}
}
public hasTime(): boolean {
return !Number.isNaN(this.tIdx);
}
}
export class WcsCapabilities {
public coverages: WcsCoverageSummary[];
}
export default class WCS {
constructor(private baseUrl: string) {
}
public async getCapabilities(): Promise<WcsCapabilities> {
// https://data.awi.de/rasdaman/ows?&SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCapabilities
let capabilitiesUrl = this.baseUrl + '?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCapabilities'
let result: AxiosResponse = await axios.get(capabilitiesUrl);
if (result && result.status == 200 && result.data) {
return this.parseCapabilities(result.data);
} else {
throw new Error('error requesting wcs capabilites from ' + capabilitiesUrl);
}
}
public async getCoverage(coverage: string | WcsCoverageSummary, subset: string[], roiMask?: Geometry): Promise<NetcdfRasterSource> {
let id = coverage instanceof WcsCoverageSummary ? coverage.coverageId : coverage;
let coverageUrl = this.baseUrl + '?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCoverage&COVERAGEID=' + id;
// append subset
for(let sub of subset) {
coverageUrl += '&SUBSET='+sub;
}
// append netcdf format
coverageUrl += '&FORMAT=application/netcdf'
// since we don't know whether we get a compatible netcdf version 3 file
// from the wcs server, we pipe the request through the raster backend module
// to ensure that we get a version 3 netcdf
return new Promise<NetcdfRasterSource>((resolve, reject) => {
getBackendModule().requestNetcdfFromUrl((status: string, netcdf: string | NetcdfRasterSource) => {
if(status == 'success') {
resolve(netcdf as NetcdfRasterSource);
} else {
reject(netcdf);
}
}, coverageUrl, roiMask);
});
// let result = await axios.get(coverageUrl, {proxy: false});
// if (result && result.status == 200 && result.data) {
// return result.data
// } else {
// throw new Error('error requesting wcs coverage from ' + coverageUrl);
// }
}
public static getAxisList(json: object): string[] {
const params = WCS.getAttribute(json, ['ows:AdditionalParameters'])['ows:AdditionalParameter']
for(let param of params) {
if ( ( WCS.getAttribute(param, ['ows:Name', '_text']) as unknown as string ) === 'axisList' ) {
return (WCS.getAttribute(param, ['ows:Value', '_text']) as unknown as string).split(',')
}
}
return []
}
public parseCapabilities(capabilitiesXML): WcsCapabilities {
// convert to json
let jC = xmljs.xml2js(capabilitiesXML, { compact: true });
// parse converage summaries
let coverages: object[] = WCS.getAttribute(jC, ['wcs:Capabilities', 'wcs:Contents', 'wcs:CoverageSummary']) as object[];
let parsedCov: WcsCoverageSummary[] = [];
for (let coverage of coverages) {
parsedCov.push(new WcsCoverageSummary(coverage));
}
let c = new WcsCapabilities();
c.coverages = parsedCov;
return c;
}
public static getAttribute(json: object, path: string[]): object {
while (path.length > 0) {
json = json[path.shift()]
if (json == undefined) {
throw new Error('error extracting xml nodes or attributes');
}
}
return json;
}
}