• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 8876085066

29 Apr 2024 09:09AM UTC coverage: 76.853% (+0.02%) from 76.834%
8876085066

push

github

web-flow
Fix #10233 Add support for HTML response for WFS layer (#10234)

* Fix #10233 Add support for HTML response for WFS layer

* requested changes

30671 of 47991 branches covered (63.91%)

33 of 34 new or added lines in 5 files covered. (97.06%)

1 existing line in 1 file now uncovered.

38491 of 50084 relevant lines covered (76.85%)

32.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.48
/web/client/api/WFS.js
1
/**
2
 * Copyright 2016, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8
import axios from '../libs/ajax';
9
import urlUtil from 'url';
10
import assign from 'object-assign';
11
import xml2js from 'xml2js';
12
import ConfigUtils from '../utils/ConfigUtils';
13
import requestBuilder from '../utils/ogc/WFS/RequestBuilder';
14
import {toOGCFilterParts} from '../utils/FilterUtils';
15
import { getDefaultUrl } from '../utils/URLUtils';
16
import { castArray } from 'lodash';
17
import { isValidGetFeatureInfoFormat } from '../utils/WMSUtils';
18

19
const capabilitiesCache = {};
1✔
20

21
export const toDescribeURL = (url, typeName) => {
1✔
22
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
6✔
23
    return urlUtil.format(
6✔
24
        {
25
            ...parsed,
26
            search: undefined, // this allows to merge parameters correctly
27
            query: {
28
                ...parsed.query,
29

30
                service: "WFS",
31
                version: "1.1.0",
32
                typeName,
33
                outputFormat: 'application/json',
34
                request: "DescribeFeatureType"
35
            }
36
        });
37
};
38
/**
39
 * Simple getFeature using http GET method with json format
40
 */
41
export const getFeatureSimple = function(baseUrl, params) {
1✔
42
    return axios.get(baseUrl + '?service=WFS&version=1.1.0&request=GetFeature', {
21✔
43
        params: assign({
44
            outputFormat: "application/json"
45
        }, params)
46
    }).then((response) => {
47
        if (typeof response.data !== 'object') {
20!
48
            return JSON.parse(response.data);
×
49
        }
50
        return response.data;
20✔
51
    });
52
};
53

54
export const getCapabilitiesURL = (url, {version = "1.1.0"} = {}) => {
1✔
55
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
6✔
56
    return urlUtil.format(assign({}, parsed, {
6✔
57
        search: undefined, // this allows to merge parameters correctly
58
        query: assign({
59
            version,
60
            ...parsed.query,
61
            service: "WFS",
62
            request: "GetCapabilities"
63
        })
64
    }));
65
};
66

67
export const getFeatureURL = (url, typeName, { version = "1.1.0", ...params } = {}) => {
1✔
68
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
19✔
69
    return urlUtil.format(assign({}, parsed, {
19✔
70
        search: undefined, // this allows to merge parameters correctly
71
        query: assign({
72
            typeName,
73
            version,
74
            ...parsed.query,
75
            service: "WFS",
76
            request: "GetFeature",
77
            ...params
78
        })
79
    }));
80
};
81
/**
82
 * Performs a getFeature request (using axios POST) to a WFS service for a given MapStore layer WFS layer object.
83
 * @param {object} layer MapStore layer object
84
 * @param {object} requestOptions additional request options. Can include:
85
 * - `version`: WFS version. Default: `1.1.0`
86
 * - `filter`: optional array of mapstore filters. If the layer has a `layerFilter` property or filterObj, it will be added to the filter in a logic AND.
87
 * - `proj`: projection string
88
 * - `outputFormat`: output format string. Default: `application/json`
89
 * - `resultType`: result type string. Default: `results`
90
 * @param {object} config axios request config (headers, etc...)
91
 * @returns
92
 */
93
export const getFeatureLayer = (layer, {version =  "1.1.0", filters, proj, outputFormat = 'application/json', resultType = 'results'} = {}, config) => {
1✔
94
    const {url, name: typeName, params } = layer;
7✔
95
    const {layerFilter, filterObj: featureGridFilter} = layer; // TODO: add
7✔
96
    const {getFeature: wfsGetFeature, query, filter, and} = requestBuilder({wfsVersion: version});
7✔
97
    const allFilters = []
7✔
98
        .concat(filters ?? [])
9✔
99
        .concat(layerFilter ? layerFilter : [])
7✔
100
        .concat(featureGridFilter ? featureGridFilter : []);
7!
101
    const reqBody = wfsGetFeature(query(
7✔
102
        typeName,
103
        allFilters.length > 0
7✔
104
            ? filter(
105
                and(
106
                    allFilters
107
                        .map(f => toOGCFilterParts(f, version, "ogc"))
6✔
108
                )
109

110
            ) : "",
111
        {srsName: proj} // 3rd for query is optional
112
    ),
113
    {outputFormat, resultType}
114
    );
115
    return axios.post(url, reqBody, {
7✔
116
        ...config,
117
        params,
118
        headers: {
119
            ...config?.headers,
120
            'Content-Type': 'application/xml'
121
        }
122
    });
123
};
124

125
/**
126
 * Performs a WFS GetFeature request (using axios GET) with the given parameters.
127
 * @param {string} url URL of the WFS service
128
 * @param {string} typeName layer name
129
 * @param {object} params the params to add to the request
130
 * @param {object} config axios request config (headers, etc...)
131
 * @returns {Promise} the axios promise
132
 */
133
export const getFeature = (url, typeName, params, config) => {
1✔
134
    return axios.get(getFeatureURL(url, typeName, params), config);
16✔
135
};
136

137
export const getCapabilities = function(url) {
1✔
138
    const cached = capabilitiesCache[url];
7✔
139
    if (cached && new Date().getTime() < cached.timestamp + (ConfigUtils.getConfigProp('cacheExpire') || 60) * 1000) {
7✔
140
        return Promise.resolve(cached.data);
2✔
141
    }
142
    return axios.get(getCapabilitiesURL(url))
5✔
143
        .then((response) => {
144
            let json;
145
            xml2js.parseString(response.data, { explicitArray: false, stripPrefix: true }, (ignore, result) => {
5✔
146
                json = { ...result, url };
5✔
147
            });
148
            capabilitiesCache[url] = {
5✔
149
                timestamp: new Date().getTime(),
150
                data: json
151
            };
152
            return json;
5✔
153
        });
154
};
155
/**
156
 * @deprecated
157
 */
158
export const describeFeatureTypeOGCSchemas = function(url, typeName) {
1✔
159
    const parsed = urlUtil.parse(getDefaultUrl(url), true);
×
160
    const describeLayerUrl = urlUtil.format(assign({}, parsed, {
×
161
        query: assign({
162
            service: "WFS",
163
            version: "1.1.0",
164
            typeName: typeName,
165
            request: "DescribeFeatureType"
166
        }, parsed.query)
167
    }));
168
    return new Promise((resolve) => {
×
169
        require.ensure(['../utils/ogc/WFS'], () => {
×
170
            const {unmarshaller} = require('../utils/ogc/WFS');
×
171
            resolve(axios.get(describeLayerUrl).then((response) => {
×
172
                let json = unmarshaller.unmarshalString(response.data);
×
173
                return json && json.value;
×
174

175
            }));
176
        });
177
    });
178
};
179

180
export const describeFeatureType = function(url, typeName) {
1✔
181
    return axios.get(toDescribeURL(url, typeName)).then(({data}) => data);
5✔
182
};
183

184
/**
185
 * Fetch the supported formats of the WFS service
186
 * @param url
187
 * @return {object} { infoFormats }
188
 */
189
export const getSupportedFormat = (url) => {
1✔
190
    return getCapabilities(url)
3✔
191
        .then((response) => {
192
            const operations = castArray(response?.['wfs:WFS_Capabilities']?.['ows:OperationsMetadata']?.['ows:Operation'] || []);
3✔
193
            const getFeatureOperation = operations.find(operation => operation?.$?.name === 'GetFeature');
3✔
194
            const parameters = castArray(getFeatureOperation?.['ows:Parameter'] || []);
3✔
195
            const outputFormats = parameters.find((parameter) => parameter?.$?.name === 'outputFormat')?.['ows:Value'] || [];
3✔
196
            const infoFormats = outputFormats.filter(isValidGetFeatureInfoFormat);
3✔
197
            return {
3✔
198
                infoFormats: infoFormats?.length ? infoFormats : ['application/json']
3✔
199
            };
200
        })
NEW
201
        .catch(() => ({ infoFormats: ['application/json'] }));
×
202
};
203

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc