UNPKG

dasf-web

Version:

Web frontend components for the data analytics software framework (DASF)

163 lines (140 loc) 6.94 kB
import GeometryType from 'ol/geom/GeometryType'; import Layer from 'ol/layer/Layer'; import Source from 'ol/source/Source'; import VectorSource from 'ol/source/Vector'; import Geometry from 'ol/geom/Geometry'; import Feature from 'ol/Feature'; import { ProjectionLike } from 'ol/proj'; import LayerGroup from 'ol/layer/Group'; import LayerColorScale from '../model/LayerColorScale'; import NumericalParameter from '../model/Parameter'; import TemporalImageLayer from '../model/TemporalImageLayer'; import VectorLayer from 'ol/layer/Vector'; import GeoJSON from 'ol/format/GeoJSON'; import NetcdfRasterSource from '../model/NetcdfRasterSource'; import getBackendModule from '../../dataAcquisition/RasterBackendModule'; import FileUtils from '../../util/FileUtils'; import Demap from '../Demap.vue'; export default class LayerUtils { /** * Extracts the first 'valid' geometry from the given layer and returns it in the given targetCRS. * * @param layer * @param targetCRS * @param allowedGeometryTypes */ public static extractGeometryFromLayer(layer: Layer, targetCRS: string = 'EPSG:4326', allowedGeometryTypes: string[] = [GeometryType.POLYGON, GeometryType.MULTI_POLYGON, GeometryType.LINEAR_RING]): Geometry | undefined { let source: Source = layer.getSource(); if (source && (typeof source['getFeatures'] === "function") || source instanceof VectorSource) { // get features from source let features: Feature[] = source['getFeatures'](); if (features && features.length) { for (let feature of features) { // get the features geometry let geom: Geometry = feature.getGeometry(); // assert geometry type and return geometry if (allowedGeometryTypes.includes(geom.getType())) { let geomTarget = geom.clone(); if (targetCRS && targetCRS.length > 0) { // target projection given let srcProj: ProjectionLike = source.getProjection(); // if (!srcProj) { // // check layer // srcProj = layer.getProjection(); // } if (!srcProj) { // assume web mercator srcProj = 'EPSG:3857'; } if (srcProj != targetCRS) { // transform the geometry from map-view projection to wgs84 geomTarget.transform(srcProj, targetCRS); } } // return the geometry return geomTarget; } } } } // either not a vector source or an empty source or not containing a polygon return undefined; } public static containsGeometry(layer: Layer, allowedGeometryTypes: string[] = [GeometryType.POLYGON, GeometryType.MULTI_POLYGON, GeometryType.LINEAR_RING]): boolean { return this.extractGeometryFromLayer(layer) != undefined; } public static downloadAsGeojson(layer: VectorLayer): void { let features: Feature<Geometry>[] = []; (layer.getSource() as VectorSource).forEachFeature((f: Feature<Geometry>) => { features.push(new Feature(f.getGeometry().clone().transform('EPSG:3857', 'EPSG:4326'))); }); FileUtils.forceFileDownload(layer.get('title') + '.geojson', new GeoJSON().writeFeatures(features, { decimals: 6 })); } public static downloadAsNetcdf(layer: TemporalImageLayer | ArrayBuffer, filename?: string): void { if(layer instanceof TemporalImageLayer) { let src = layer.getSource(); if (src instanceof NetcdfRasterSource) { getBackendModule().requestNetcdfBytes((status: string, netcdf: ArrayBuffer | string) => { if (status == 'success') { // we received the netcdf bytestream - force file download if(!filename) { // use layer title filename = layer.get('title') + '.nc'; } FileUtils.forceFileDownload(filename, netcdf); } else { throw new Error(netcdf as string); } }, src); } } else if(layer instanceof ArrayBuffer) { // we already have an array buffer given - force download directly if(!filename) { filename = 'raster.nc'; } FileUtils.forceFileDownload(filename, layer); } else { throw new Error('unsupported argument type for netcdf download'); } } public static downloadLayer(layer: Layer): void { if (layer instanceof VectorLayer) { LayerUtils.downloadAsGeojson(layer as VectorLayer); } else if (layer instanceof TemporalImageLayer) { LayerUtils.downloadAsNetcdf(layer as TemporalImageLayer); } else { throw Error('download of this layer type is not yet implemented'); } } public static splitIntoPropertyLayers(layer: Layer, group: LayerGroup): void { // console.log('splitting layer ', layer); let colorScale: LayerColorScale = layer.get(LayerColorScale.KEY); if (colorScale === undefined) { console.warn('cannot split layers without existing colorscale'); return; } let layerTitle: string = layer.get('title'); let parameters: NumericalParameter[] = colorScale.getAvailableParameters(); let demap: Demap = layer.get('demap') as Demap; for (let param of parameters) { if (layer instanceof TemporalImageLayer) { // split temporal image layer let source = layer.getSource(); if (source instanceof NetcdfRasterSource) { let splitSource: NetcdfRasterSource = source.cloneParameterSource(param); let splitLayer: TemporalImageLayer = new TemporalImageLayer({ title: param.getName() + "::" + layerTitle, source: splitSource }); demap.addLayer(splitLayer); } else { console.warn('splitting not yet supported for given source type', source); return; } } else if (layer instanceof VectorLayer) { console.warn('splitting of vector layers is not yet supported'); } } } }