-
Notifications
You must be signed in to change notification settings - Fork 405
/
wfs.js
97 lines (89 loc) · 3.67 KB
/
wfs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/**
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
import {Observable} from 'rxjs';
import {normalizeSRS} from '../CoordinatesUtils';
import { getLayerUrl } from '../LayersUtils';
import { isObject } from 'lodash';
import { optionsToVendorParams } from '../VendorParamsUtils';
import { describeFeatureType, getFeature } from '../../api/WFS';
import { extractGeometryAttributeName } from '../WFSLayerUtils';
import {addAuthenticationToSLD} from '../SecurityUtils';
import assign from 'object-assign';
/**
* Creates the request object and it's metadata for WFS GetFeature to simulate GetFeatureInfo.
* @param {object} layer
* @param {object} options
* @param {string} infoFormat
* @param {string} viewer
* @return {object} an object with `request`, containing request params, `metadata` with some info about the layer and the request, and `url` to send the request to.
*/
const buildRequest = (layer, { map = {}, point, currentLocale, params, maxItems = 10 } = {}, infoFormat, viewer, featureInfo) => {
/* In order to create a valid feature info request
* we create a bbox of 101x101 pixel that wrap the point.
* center point is re-projected then is built a box of 101x101pixel around it
*/
return {
request: addAuthenticationToSLD({
point, // THIS WILL NOT BE PASSED TO FINAL REQUEST, BUT USED IN getRetrieveFlow
service: 'WFS',
version: '1.1.1',
request: 'GetFeature',
outputFormat: 'application/json',
exceptions: 'application/json',
id: layer.id,
typeName: layer.name,
srs: normalizeSRS(map.projection) || 'EPSG:4326',
feature_count: maxItems,
...assign({ params })
}, layer),
metadata: {
title: isObject(layer.title) ? layer.title[currentLocale] || layer.title.default : layer.title,
regex: layer.featureInfoRegex,
viewer,
featureInfo
},
url: getLayerUrl(layer).replace(/[?].*$/g, '')
};
};
const getIdentifyGeometry = point => {
const geometry = point?.geometricFilter?.value?.geometry;
if (geometry) {
return geometry;
}
// Create a simple point filter if the geometryFilter (typically an emulation of the feature info click filter) is not present.
let wrongLng = point.latlng.lng;
// longitude restricted to the [-180°,+180°] range
let lngCorrected = wrongLng - 360 * Math.floor(wrongLng / 360 + 0.5);
return {
coordinates: [lngCorrected, point.latlng.lat],
projection: "EPSG:4326",
type: "Point"
};
};
export default {
buildRequest,
getIdentifyFlow: (layer, baseURL, defaultParams) => {
const { point, ...baseParams} = defaultParams;
const geometry = getIdentifyGeometry(point);
return Observable.defer( () => describeFeatureType(layer.url, layer.name) // TODO: cache this
.then(describe => {
const attribute = extractGeometryAttributeName(describe);
const params = optionsToVendorParams({
layerFilter: layer.layerFilter,
filterObj: {
spatialField: {
attribute,
operation: "INTERSECTS",
geometry: geometry
}
},
params: assign({}, layer.baseParams, layer.params, baseParams)
});
return getFeature(baseURL, layer.name, params);
}));
}};