Skip to content

Commit

Permalink
feat: add support for WFS layers in parser
Browse files Browse the repository at this point in the history
  • Loading branch information
dnlkoch committed Jun 20, 2022
1 parent ab64557 commit 720b38b
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 22 deletions.
124 changes: 106 additions & 18 deletions src/parser/ShogunApplicationUtil.spec.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import OlView, { ViewOptions } from 'ol/View';
import OlSourceTileWMS from 'ol/source/TileWMS';
import OlLayerTile from 'ol/layer/Tile';
import OlSourceImageWMS from 'ol/source/ImageWMS';
import OlSourceWMTS, { optionsFromCapabilities } from 'ol/source/WMTS';
import OlSourceTileWMS from 'ol/source/TileWMS';
import OlLayerImage from 'ol/layer/Image';
import OlLayerBase from 'ol/layer/Base';
import OlLayerGroup from 'ol/layer/Group';
import OlLayerTile from 'ol/layer/Tile';
import OlLayerVector from 'ol/layer/Vector';
import OlSourceVector from 'ol/source/Vector';
import OlFormatGeoJSON from 'ol/format/GeoJSON';
import OlTileGrid from 'ol/tilegrid/TileGrid';
import { bbox as olStrategyBbox } from 'ol/loadingstrategy';
import { getUid } from 'ol/util';

import Application from '../model/Application';
import Layer from '../model/Layer';
import fetchSpy, {
failureResponse,
successResponse
} from '../spec/fetchSpy';

import ShogunApplicationUtil from './ShogunApplicationUtil';

describe('AuthService', () => {
describe('ShogunApplicationUtil', () => {
let fetchMock: jest.SpyInstance;
let util: ShogunApplicationUtil<Application, Layer>;

Expand Down Expand Up @@ -103,15 +100,12 @@ describe('AuthService', () => {
maxResolution: myLayer.clientConfig?.maxResolution
});

// expected.ol_uid = expect.any(String);
// expected.getSource().ol_uid = expect.any(String);

// @ts-ignore
// eslint-disable-next-line camelcase
expected.ol_uid = layer.ol_uid;
expected.ol_uid = getUid(layer);
// @ts-ignore
// eslint-disable-next-line camelcase
expected.getSource().ol_uid = layer.getSource().ol_uid;
expected.getSource().ol_uid = getUid(layer.getSource());

expected.set('shogunId', myLayer.id);
expected.set('name', myLayer.name);
Expand All @@ -132,15 +126,109 @@ describe('AuthService', () => {
name: 'Layer A',
type: 'TILEWMS',
clientConfig: {},
sourceConfig: {
url: 'https://ows.terrestris.de/osm/service?',
layerNames: 'OSM-WMS',
tileSize: 512,
tileOrigin: [0, 0],
resolutions: [
16,
8,
4,
2,
1
]
}
};

const layer = await util.parseLayer(myLayer);

const expected = new OlLayerTile({
source: new OlSourceTileWMS({
url: myLayer.sourceConfig.url,
tileGrid: new OlTileGrid({
resolutions: myLayer.sourceConfig.resolutions!,
tileSize: [
myLayer.sourceConfig.tileSize!,
myLayer.sourceConfig.tileSize!
],
origin: myLayer.sourceConfig.tileOrigin
}),
attributions: myLayer.sourceConfig.attribution,
params: {
'LAYERS': myLayer.sourceConfig.layerNames,
'TRANSPARENT': true
},
crossOrigin: myLayer.clientConfig?.crossOrigin,
projection: 'EPSG:3857'
}),
minResolution: myLayer.clientConfig?.minResolution,
maxResolution: myLayer.clientConfig?.maxResolution
});

// @ts-ignore
// eslint-disable-next-line camelcase
expected.ol_uid = getUid(layer);
// @ts-ignore
// eslint-disable-next-line camelcase
expected.getSource().ol_uid = getUid(layer.getSource());

expected.set('shogunId', myLayer.id);
expected.set('name', myLayer.name);
expected.set('type', myLayer.type);
expected.set('searchable', myLayer.clientConfig?.searchable);
expected.set('propertyConfig', myLayer.clientConfig?.propertyConfig);
expected.set('legendUrl', myLayer.sourceConfig.legendUrl);
expected.set('hoverable', myLayer.clientConfig?.hoverable);

expect(JSON.stringify(layer)).toEqual(JSON.stringify(expected));
});

it('is capable to parse a WFS layer (parseWFSLayer)', async () => {
const myLayer: Layer = {
id: 1909,
created: new Date(),
modified: new Date(),
name: 'Layer A',
type: 'WFS',
clientConfig: {},
sourceConfig: {
url: 'https://ows.terrestris.de/osm/service?',
layerNames: 'OSM-WMS'
}
};

const mapView = await util.parseLayer(myLayer);
const layer = await util.parseLayer(myLayer);

expect(mapView).toBeDefined();
const expected = new OlLayerVector({
source: new OlSourceVector({
format: new OlFormatGeoJSON(),
attributions: myLayer.sourceConfig.attribution,
strategy: olStrategyBbox,
url: () => {
return '';
}
}),
minResolution: myLayer.clientConfig?.minResolution,
maxResolution: myLayer.clientConfig?.maxResolution
});

expected.set('shogunId', myLayer.id);
expected.set('name', myLayer.name);
expected.set('type', myLayer.type);
expected.set('searchable', myLayer.clientConfig?.searchable);
expected.set('propertyConfig', myLayer.clientConfig?.propertyConfig);
expected.set('legendUrl', myLayer.sourceConfig.legendUrl);
expected.set('hoverable', myLayer.clientConfig?.hoverable);

// @ts-ignore
// eslint-disable-next-line camelcase
expected.ol_uid = getUid(layer);
// @ts-ignore
// eslint-disable-next-line camelcase
expected.getSource().ol_uid = getUid(layer.getSource());

expect(JSON.stringify(layer)).toEqual(JSON.stringify(expected));
});

});
60 changes: 56 additions & 4 deletions src/parser/ShogunApplicationUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import OlImageLayer from 'ol/layer/Image';
import OlLayerBase from 'ol/layer/Base';
import OlLayerGroup from 'ol/layer/Group';
import OlTileGrid from 'ol/tilegrid/TileGrid';
import OlSourceVector from 'ol/source/Vector';
import OlWMTSCapabilities from 'ol/format/WMTSCapabilities';
import OlFormatGeoJSON from 'ol/format/GeoJSON';
import OlLayerVector from 'ol/layer/Vector';
import {
fromLonLat,
ProjectionLike
} from 'ol/proj';
import { bbox as olStrategyBbox } from 'ol/loadingstrategy';

import { UrlUtil } from '@terrestris/base-util/dist/UrlUtil/UrlUtil';

Expand Down Expand Up @@ -107,6 +111,7 @@ class ShogunApplicationUtil<T extends Application, S extends Layer> {
continue;
}

// TODO Fetch via graphlQL (multiple at once)
const layer = await this.client.layer<S>().findOne(node.layerId);

const olLayer = await this.parseLayer(layer, projection);
Expand Down Expand Up @@ -146,8 +151,12 @@ class ShogunApplicationUtil<T extends Application, S extends Layer> {
return await this.parseWMTSLayer(layer, projection);
}

// TODO Support others
throw new Error('Currently only WMTS, WMS and TILEWMS layers are supported.');
if (layer.type === 'WFS') {
return this.parseWFSLayer(layer, projection);
}

// TODO Add support for VECTORTILE, XYZ and WMSTime
throw new Error('Currently only WMTS, WMS, TILEWMS and WFS layers are supported.');
}

parseImageLayer(layer: S) {
Expand Down Expand Up @@ -184,7 +193,7 @@ class ShogunApplicationUtil<T extends Application, S extends Layer> {
return imageLayer;
}

parseTileLayer(layer: S, projection?: ProjectionLike) {
parseTileLayer(layer: S, projection: ProjectionLike = 'EPSG:3857') {
const {
attribution,
url,
Expand Down Expand Up @@ -215,7 +224,8 @@ class ShogunApplicationUtil<T extends Application, S extends Layer> {
attributions: attribution,
projection,
params: {
'LAYERS': layerNames
'LAYERS': layerNames,
'TRANSPARENT': true
},
crossOrigin
});
Expand Down Expand Up @@ -287,6 +297,48 @@ class ShogunApplicationUtil<T extends Application, S extends Layer> {
return wmtsLayer;
}

parseWFSLayer(layer: S, projection: ProjectionLike = 'EPSG:3857') {
const {
attribution,
url,
layerNames
} = layer.sourceConfig || {};

const {
minResolution,
maxResolution
} = layer.clientConfig || {};

const source = new OlSourceVector({
format: new OlFormatGeoJSON(),
attributions: attribution,
url: extent => {
const params = UrlUtil.objectToRequestString({
SERVICE: 'WFS',
VERSION: '2.0.0',
REQUEST: 'GetFeature',
TYPENAMES: layerNames,
OUTPUTFORMAT: 'application/json',
SRSNAME: projection,
BBOX: `${extent.join(',')},${projection}`
});

return `${url}${url.endsWith('?') ? '' : '?'}${params}`;
},
strategy: olStrategyBbox
});

const vectorLayer = new OlLayerVector({
source,
minResolution,
maxResolution
});

this.setLayerProperties(vectorLayer, layer);

return vectorLayer;
}

getMapScales(resolutions: number[], projUnit: string = 'm'): number[] {
return resolutions
.map((res: number) =>
Expand Down

0 comments on commit 720b38b

Please sign in to comment.